1use alloc::vec::Vec;
2
3use pki_types::{DnsName, UnixTime};
4use zeroize::Zeroizing;
5
6use crate::crypto::cipher::Payload;
7use crate::crypto::{CipherSuite, Identity};
8use crate::enums::{ApplicationProtocol, ProtocolVersion};
9use crate::error::InvalidMessage;
10use crate::msgs::{Codec, MaybeEmpty, Reader, SizedPayload};
11pub use crate::verify::NoClientAuth;
12#[cfg(feature = "webpki")]
13pub use crate::webpki::{
14 ClientVerifierBuilder, ParsedCertificate, VerifierBuilderError, WebPkiClientVerifier,
15};
16
17pub(crate) mod config;
18pub use config::{
19 ClientHello, InvalidSniPolicy, ServerConfig, ServerCredentialResolver, StoresServerSessions,
20 WantsServerCert,
21};
22
23mod connection;
24#[cfg(feature = "std")]
25pub use connection::{Accepted, AcceptedAlert, Acceptor, ReadEarlyData, ServerConnection};
26pub use connection::{ServerConnectionData, UnbufferedServerConnection};
27
28pub(crate) mod handy;
29pub use handy::NoServerSessionStorage;
30#[cfg(all(any(feature = "std", feature = "hashbrown"), feature = "webpki"))]
31pub use handy::ServerNameResolver;
32#[cfg(any(feature = "std", feature = "hashbrown"))]
33pub use handy::ServerSessionMemoryCache;
34
35mod hs;
36pub(crate) use hs::ServerHandler;
37
38mod tls12;
39pub(crate) use tls12::TLS12_HANDLER;
40
41mod tls13;
42pub(crate) use tls13::TLS13_HANDLER;
43
44pub mod danger {
46 pub use crate::verify::{
47 ClientIdentity, ClientVerifier, PeerVerified, SignatureVerificationInput,
48 };
49}
50
51#[cfg(test)]
52mod test;
53
54#[derive(Debug)]
55pub(crate) enum ServerSessionValue {
56 Tls12(Tls12ServerSessionValue),
57 Tls13(Tls13ServerSessionValue),
58}
59
60impl Codec<'_> for ServerSessionValue {
61 fn encode(&self, bytes: &mut Vec<u8>) {
62 match self {
63 Self::Tls12(value) => {
64 ProtocolVersion::TLSv1_2.encode(bytes);
65 value.encode(bytes);
66 }
67 Self::Tls13(value) => {
68 ProtocolVersion::TLSv1_3.encode(bytes);
69 value.encode(bytes);
70 }
71 }
72 }
73
74 fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
75 match ProtocolVersion::read(r)? {
76 ProtocolVersion::TLSv1_2 => Ok(Self::Tls12(Tls12ServerSessionValue::read(r)?)),
77 ProtocolVersion::TLSv1_3 => Ok(Self::Tls13(Tls13ServerSessionValue::read(r)?)),
78 _ => Err(InvalidMessage::UnknownProtocolVersion),
79 }
80 }
81}
82
83#[derive(Debug)]
84pub(crate) struct Tls12ServerSessionValue {
85 pub(crate) common: CommonServerSessionValue,
86 pub(crate) master_secret: Zeroizing<[u8; 48]>,
87 pub(crate) extended_ms: bool,
88}
89
90impl Tls12ServerSessionValue {
91 pub(crate) fn new(
92 common: CommonServerSessionValue,
93 master_secret: &[u8; 48],
94 extended_ms: bool,
95 ) -> Self {
96 Self {
97 common,
98 master_secret: Zeroizing::new(*master_secret),
99 extended_ms,
100 }
101 }
102}
103
104impl Codec<'_> for Tls12ServerSessionValue {
105 fn encode(&self, bytes: &mut Vec<u8>) {
106 self.common.encode(bytes);
107 bytes.extend_from_slice(self.master_secret.as_ref());
108 (self.extended_ms as u8).encode(bytes);
109 }
110
111 fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
112 Ok(Self {
113 common: CommonServerSessionValue::read(r)?,
114 master_secret: Zeroizing::new(
115 match r
116 .take(48)
117 .and_then(|slice| slice.try_into().ok())
118 {
119 Some(array) => array,
120 None => return Err(InvalidMessage::MessageTooShort),
121 },
122 ),
123 extended_ms: matches!(u8::read(r)?, 1),
124 })
125 }
126}
127
128impl From<Tls12ServerSessionValue> for ServerSessionValue {
129 fn from(value: Tls12ServerSessionValue) -> Self {
130 Self::Tls12(value)
131 }
132}
133
134#[derive(Debug)]
135pub(crate) struct Tls13ServerSessionValue {
136 pub(crate) common: CommonServerSessionValue,
137 pub(crate) secret: Zeroizing<SizedPayload<'static, u8>>,
138 pub(crate) age_obfuscation_offset: u32,
139
140 freshness: Option<bool>,
142}
143
144impl Tls13ServerSessionValue {
145 pub(crate) fn new(
146 common: CommonServerSessionValue,
147 secret: &[u8],
148 age_obfuscation_offset: u32,
149 ) -> Self {
150 Self {
151 common,
152 secret: Zeroizing::new(secret.to_vec().into()),
153 age_obfuscation_offset,
154 freshness: None,
155 }
156 }
157
158 pub(crate) fn set_freshness(
159 mut self,
160 obfuscated_client_age_ms: u32,
161 time_now: UnixTime,
162 ) -> Self {
163 let client_age_ms = obfuscated_client_age_ms.wrapping_sub(self.age_obfuscation_offset);
164 let server_age_ms = (time_now
165 .as_secs()
166 .saturating_sub(self.common.creation_time_sec) as u32)
167 .saturating_mul(1000);
168
169 let age_difference = server_age_ms.abs_diff(client_age_ms);
170
171 self.freshness = Some(age_difference <= MAX_FRESHNESS_SKEW_MS);
172 self
173 }
174
175 pub(crate) fn is_fresh(&self) -> bool {
176 self.freshness.unwrap_or_default()
177 }
178}
179
180impl Codec<'_> for Tls13ServerSessionValue {
181 fn encode(&self, bytes: &mut Vec<u8>) {
182 self.common.encode(bytes);
183 self.secret.encode(bytes);
184 self.age_obfuscation_offset
185 .encode(bytes);
186 }
187
188 fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
189 Ok(Self {
190 common: CommonServerSessionValue::read(r)?,
191 secret: Zeroizing::new(SizedPayload::read(r)?.into_owned()),
192 age_obfuscation_offset: u32::read(r)?,
193 freshness: None,
194 })
195 }
196}
197
198impl From<Tls13ServerSessionValue> for ServerSessionValue {
199 fn from(value: Tls13ServerSessionValue) -> Self {
200 Self::Tls13(value)
201 }
202}
203
204#[derive(Debug)]
205pub(crate) struct CommonServerSessionValue {
206 pub(crate) creation_time_sec: u64,
207 pub(crate) sni: Option<DnsName<'static>>,
208 pub(crate) cipher_suite: CipherSuite,
209 pub(crate) peer_identity: Option<Identity<'static>>,
210 pub(crate) alpn: Option<ApplicationProtocol<'static>>,
211 pub(crate) application_data: SizedPayload<'static, u16, MaybeEmpty>,
212}
213
214impl CommonServerSessionValue {
215 pub(crate) fn new(
216 sni: Option<&DnsName<'_>>,
217 cipher_suite: CipherSuite,
218 peer_identity: Option<Identity<'static>>,
219 alpn: Option<ApplicationProtocol<'static>>,
220 application_data: Vec<u8>,
221 creation_time: UnixTime,
222 ) -> Self {
223 Self {
224 creation_time_sec: creation_time.as_secs(),
225 sni: sni.map(|s| s.to_owned()),
226 cipher_suite,
227 peer_identity,
228 alpn,
229 application_data: SizedPayload::from(Payload::new(application_data)),
230 }
231 }
232
233 pub(crate) fn can_resume(&self, suite: CipherSuite, sni: Option<&DnsName<'_>>) -> bool {
234 self.cipher_suite == suite && self.sni.as_ref() == sni
245 }
246}
247
248impl Codec<'_> for CommonServerSessionValue {
249 fn encode(&self, bytes: &mut Vec<u8>) {
250 self.creation_time_sec.encode(bytes);
251 if let Some(sni) = &self.sni {
252 1u8.encode(bytes);
253 let sni_bytes: &str = sni.as_ref();
254 SizedPayload::<u8, MaybeEmpty>::from(Payload::Borrowed(sni_bytes.as_bytes()))
255 .encode(bytes);
256 } else {
257 0u8.encode(bytes);
258 }
259 self.cipher_suite.encode(bytes);
260 if let Some(identity) = &self.peer_identity {
261 1u8.encode(bytes);
262 identity.encode(bytes);
263 } else {
264 0u8.encode(bytes);
265 }
266 if let Some(alpn) = &self.alpn {
267 1u8.encode(bytes);
268 alpn.encode(bytes);
269 } else {
270 0u8.encode(bytes);
271 }
272 self.application_data.encode(bytes);
273 }
274
275 fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
276 let creation_time_sec = u64::read(r)?;
277 let sni = match u8::read(r)? {
278 1 => {
279 let dns_name = SizedPayload::<u8, MaybeEmpty>::read(r)?;
280 let dns_name = match DnsName::try_from(dns_name.bytes()) {
281 Ok(dns_name) => dns_name.to_owned(),
282 Err(_) => return Err(InvalidMessage::InvalidServerName),
283 };
284
285 Some(dns_name)
286 }
287 _ => None,
288 };
289
290 Ok(Self {
291 creation_time_sec,
292 sni,
293 cipher_suite: CipherSuite::read(r)?,
294 peer_identity: match u8::read(r)? {
295 1 => Some(Identity::read(r)?.into_owned()),
296 _ => None,
297 },
298 alpn: match u8::read(r)? {
299 1 => Some(ApplicationProtocol::read(r)?.to_owned()),
300 _ => None,
301 },
302 application_data: SizedPayload::read(r)?.into_owned(),
303 })
304 }
305}
306
307static MAX_FRESHNESS_SKEW_MS: u32 = 60 * 1000;