Skip to main content

rustls/server/
mod.rs

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
44/// Dangerous configuration that should be audited and used with extreme care.
45pub 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    // not encoded vv
141    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        // The RFCs underspecify what happens if we try to resume to
235        // an unoffered/varying suite.  We merely don't resume in weird cases.
236        //
237        // RFC 6066 says "A server that implements this extension MUST NOT accept
238        // the request to resume the session if the server_name extension contains
239        // a different name. Instead, it proceeds with a full handshake to
240        // establish a new session."
241        //
242        // RFC 8446: "The server MUST ensure that it selects
243        // a compatible PSK (if any) and cipher suite."
244        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
307/// This is the maximum allowed skew between server and client clocks, over
308/// the maximum ticket lifetime period.  This encompasses TCP retransmission
309/// times in case packet loss occurs when the client sends the ClientHello
310/// or receives the NewSessionTicket, _and_ actual clock skew over this period.
311static MAX_FRESHNESS_SKEW_MS: u32 = 60 * 1000;