1use alloc::vec::Vec;
2
3use pki_types::{DnsName, UnixTime};
4
5use crate::crypto::cipher::Payload;
6use crate::crypto::{CipherSuite, Identity};
7use crate::enums::{ApplicationProtocol, ProtocolVersion};
8use crate::error::InvalidMessage;
9use crate::msgs::{Codec, MaybeEmpty, Reader, SessionId, SizedPayload};
10pub use crate::verify::NoClientAuth;
11use crate::verify::VerifiedIdentity;
12#[cfg(feature = "webpki")]
13pub use crate::webpki::{
14 ClientVerifierBuilder, ParsedCertificate, VerifierBuilderError, WebPkiClientVerifier,
15};
16
17pub(crate) mod config;
18pub use config::{
19 CipherSuiteSelector, ClientHello, InvalidSniPolicy, KeyExchangeSelector, OfferedKxGroup,
20 PreferClientOrder, PreferServerOrder, ServerConfig, ServerCredentialResolver,
21 StoresServerSessions, Tls13Tickets, WantsServerCert,
22};
23
24mod connection;
25pub use connection::{ServerHandshake, ServerSide};
26
27pub use crate::conn::Accepted;
28
29pub(crate) mod handy;
30#[cfg(feature = "webpki")]
31pub use handy::ServerNameResolver;
32pub use handy::{NoServerSessionStorage, ServerSessionMemoryCache};
33
34mod hs;
35pub(crate) use hs::{ChooseConfig, ServerHandler, ServerState};
36
37mod tls12;
38pub(crate) use tls12::TLS12_HANDLER;
39use tls12::Tls12ServerSessionValue;
40
41mod tls13;
42pub(crate) use tls13::TLS13_HANDLER;
43use tls13::Tls13ServerSessionValue;
44
45pub mod danger {
47 pub use crate::verify::{ClientIdentity, ClientVerifier, SignatureVerificationInput};
48}
49
50#[cfg(test)]
51mod test;
52
53pub(crate) enum ServerSessionValue<'a> {
54 Tls12(Tls12ServerSessionValue<'a>),
55 Tls13(Tls13ServerSessionValue<'a>),
56}
57
58impl<'a> Codec<'a> for ServerSessionValue<'a> {
59 fn encode(&self, bytes: &mut Vec<u8>) {
60 match self {
61 Self::Tls12(value) => {
62 ProtocolVersion::TLSv1_2.encode(bytes);
63 value.encode(bytes);
64 }
65 Self::Tls13(value) => {
66 ProtocolVersion::TLSv1_3.encode(bytes);
67 value.encode(bytes);
68 }
69 }
70 }
71
72 fn read(r: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
73 match ProtocolVersion::read(r)? {
74 ProtocolVersion::TLSv1_2 => Ok(Self::Tls12(Tls12ServerSessionValue::read(r)?)),
75 ProtocolVersion::TLSv1_3 => Ok(Self::Tls13(Tls13ServerSessionValue::read(r)?)),
76 _ => Err(InvalidMessage::UnknownProtocolVersion),
77 }
78 }
79}
80
81pub(crate) struct CommonServerSessionValue<'a> {
82 pub(crate) creation_time_sec: u64,
83 pub(crate) sni: Option<DnsName<'a>>,
84 pub(crate) cipher_suite: CipherSuite,
85 pub(crate) peer_identity: Option<VerifiedIdentity<'a>>,
86 pub(crate) alpn: Option<ApplicationProtocol<'a>>,
87 pub(crate) application_data: SizedPayload<'a, u16, MaybeEmpty>,
88}
89
90impl<'a> CommonServerSessionValue<'a> {
91 pub(crate) fn new(
92 sni: Option<&DnsName<'a>>,
93 cipher_suite: CipherSuite,
94 peer_identity: Option<VerifiedIdentity<'a>>,
95 alpn: Option<ApplicationProtocol<'a>>,
96 application_data: Vec<u8>,
97 creation_time: UnixTime,
98 ) -> Self {
99 Self {
100 creation_time_sec: creation_time.as_secs(),
101 sni: sni.map(|s| s.to_owned()),
102 cipher_suite,
103 peer_identity,
104 alpn,
105 application_data: SizedPayload::from(Payload::new(application_data)),
106 }
107 }
108
109 fn into_owned(self) -> CommonServerSessionValue<'static> {
110 CommonServerSessionValue {
111 creation_time_sec: self.creation_time_sec,
112 sni: self.sni.map(|s| s.to_owned()),
113 cipher_suite: self.cipher_suite,
114 peer_identity: self
115 .peer_identity
116 .map(|i| i.into_owned()),
117 alpn: self.alpn.map(|a| a.to_owned()),
118 application_data: self.application_data.into_owned(),
119 }
120 }
121
122 pub(crate) fn can_resume(&self, suite: CipherSuite, sni: Option<&DnsName<'_>>) -> bool {
123 self.cipher_suite == suite && self.sni.as_ref() == sni
134 }
135}
136
137impl Codec<'_> for CommonServerSessionValue<'_> {
138 fn encode(&self, bytes: &mut Vec<u8>) {
139 self.creation_time_sec.encode(bytes);
140 if let Some(sni) = &self.sni {
141 1u8.encode(bytes);
142 let sni_bytes: &str = sni.as_ref();
143 SizedPayload::<u8, MaybeEmpty>::from(Payload::Borrowed(sni_bytes.as_bytes()))
144 .encode(bytes);
145 } else {
146 0u8.encode(bytes);
147 }
148 self.cipher_suite.encode(bytes);
149 if let Some(identity) = &self.peer_identity {
150 1u8.encode(bytes);
151 identity.encode(bytes);
152 } else {
153 0u8.encode(bytes);
154 }
155 if let Some(alpn) = &self.alpn {
156 1u8.encode(bytes);
157 alpn.encode(bytes);
158 } else {
159 0u8.encode(bytes);
160 }
161 self.application_data.encode(bytes);
162 }
163
164 fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
165 let creation_time_sec = u64::read(r)?;
166 let sni = match u8::read(r)? {
167 1 => {
168 let dns_name = SizedPayload::<u8, MaybeEmpty>::read(r)?;
169 let dns_name = match DnsName::try_from(dns_name.bytes()) {
170 Ok(dns_name) => dns_name.to_owned(),
171 Err(_) => return Err(InvalidMessage::InvalidServerName),
172 };
173
174 Some(dns_name)
175 }
176 _ => None,
177 };
178
179 Ok(Self {
180 creation_time_sec,
181 sni,
182 cipher_suite: CipherSuite::read(r)?,
183 peer_identity: match u8::read(r)? {
184 1 => Some(VerifiedIdentity::assertion(Identity::read(r)?.into_owned())),
185 _ => None,
186 },
187 alpn: match u8::read(r)? {
188 1 => Some(ApplicationProtocol::read(r)?.to_owned()),
189 _ => None,
190 },
191 application_data: SizedPayload::read(r)?.into_owned(),
192 })
193 }
194}
195
196pub struct ServerSessionKey<'a> {
198 inner: &'a [u8],
199}
200
201impl<'a> ServerSessionKey<'a> {
202 pub(crate) fn new(inner: &'a [u8]) -> Self {
203 Self { inner }
204 }
205}
206
207impl<'a> From<&'a SessionId> for ServerSessionKey<'a> {
208 fn from(session_id: &'a SessionId) -> Self {
209 Self::new(session_id.as_ref())
210 }
211}
212
213impl AsRef<[u8]> for ServerSessionKey<'_> {
214 fn as_ref(&self) -> &[u8] {
215 self.inner
216 }
217}