Skip to main content

rustls/server/
config.rs

1use alloc::borrow::Cow;
2use alloc::vec::Vec;
3use core::fmt::Debug;
4use core::marker::PhantomData;
5
6#[cfg(feature = "webpki")]
7use pki_types::PrivateKeyDer;
8use pki_types::{DnsName, FipsStatus, UnixTime};
9
10use super::{ServerSessionKey, handy};
11use crate::builder::{ConfigBuilder, WantsVerifier};
12#[cfg(doc)]
13use crate::crypto;
14use crate::crypto::kx::NamedGroup;
15use crate::crypto::{
16    CipherSuite, CryptoProvider, SelectedCredential, SignatureScheme, TicketProducer,
17};
18#[cfg(feature = "webpki")]
19use crate::crypto::{Credentials, Identity, SingleCredential};
20use crate::enums::{ApplicationProtocol, CertificateType, ProtocolVersion};
21use crate::error::{Error, PeerMisbehaved};
22use crate::msgs::{ClientHelloPayload, ClientTicketRequest, ServerNamePayload};
23use crate::suites::Suite;
24use crate::sync::Arc;
25use crate::time_provider::{DefaultTimeProvider, TimeProvider};
26use crate::verify::{ClientVerifier, DistinguishedName, NoClientAuth};
27use crate::{KeyLog, NoKeyLog, Tls12CipherSuite, Tls13CipherSuite, compress};
28
29/// Common configuration for a set of server sessions.
30///
31/// Making one of these is cheap, though one of the inputs may be expensive: gathering trust roots
32/// from the operating system to add to the [`RootCertStore`] passed to a `ClientVerifier`
33/// builder may take on the order of a few hundred milliseconds.
34///
35/// These must be created via the [`ServerConfig::builder()`] or [`ServerConfig::builder_with_details()`]
36/// function.
37///
38/// # Defaults
39///
40/// * [`ServerConfig::max_fragment_size`]: the default is `None` (meaning 16kB).
41/// * [`ServerConfig::session_storage`]: if the `std` feature is enabled, the default stores 256
42///   sessions in memory. If the `std` feature is not enabled, the default is to not store any
43///   sessions. In a no-std context, by enabling the `hashbrown` feature you may provide your
44///   own `session_storage` using [`ServerSessionMemoryCache`] and a `crate::lock::MakeMutex`
45///   implementation.
46/// * [`ServerConfig::alpn_protocols`]: the default is empty -- no ALPN protocol is negotiated.
47/// * [`ServerConfig::key_log`]: key material is not logged.
48/// * [`ServerConfig::send_tls13_tickets`]: 2 tickets are sent, with a maximum of 2.
49/// * [`ServerConfig::cert_compressors`]: depends on the crate features, see [`compress::default_cert_compressors()`].
50/// * [`ServerConfig::cert_compression_cache`]: caches the most recently used 4 compressions
51/// * [`ServerConfig::cert_decompressors`]: depends on the crate features, see [`compress::default_cert_decompressors()`].
52///
53/// # Sharing resumption storage between `ServerConfig`s
54///
55/// In a program using many `ServerConfig`s it may improve resumption rates
56/// (which has a significant impact on connection performance) if those
57/// configs share [`ServerConfig::session_storage`] or [`ServerConfig::ticketer`].
58///
59/// However, caution is needed: other fields influence the security of a session
60/// and resumption between them can be surprising.  If sharing
61/// [`ServerConfig::session_storage`] or [`ServerConfig::ticketer`] between two
62/// `ServerConfig`s, you should also evaluate the following fields and ensure
63/// they are equivalent:
64///
65/// * `ServerConfig::verifier` -- client authentication requirements,
66/// * [`ServerConfig::cert_resolver`] -- server identities.
67///
68/// To illustrate, imagine two `ServerConfig`s `A` and `B`.  `A` requires
69/// client authentication, `B` does not.  If `A` and `B` shared a resumption store,
70/// it would be possible for a session originated by `B` (that is, an unauthenticated client)
71/// to be inserted into the store, and then resumed by `A`.  This would give a false
72/// impression to the user of `A` that the client was authenticated.  This is possible
73/// whether the resumption is performed statefully (via [`ServerConfig::session_storage`])
74/// or statelessly (via [`ServerConfig::ticketer`]).
75///
76/// _Unlike_ `ClientConfig`, rustls does not enforce any policy here.
77///
78/// [`RootCertStore`]: crate::RootCertStore
79/// [`ServerSessionMemoryCache`]: crate::server::handy::ServerSessionMemoryCache
80#[derive(Clone, Debug)]
81pub struct ServerConfig {
82    /// Source of randomness and other crypto.
83    pub(crate) provider: Arc<CryptoProvider>,
84
85    /// How to select a cipher suite to use for a TLS session.
86    pub cipher_suite_selector: &'static dyn CipherSuiteSelector,
87
88    /// The maximum size of plaintext input to be emitted in a single TLS record.
89    /// A value of None is equivalent to the [TLS maximum] of 16 kB.
90    ///
91    /// rustls enforces an arbitrary minimum of 32 bytes for this field.
92    /// Out of range values are reported as errors from [ServerConnection::new].
93    ///
94    /// Setting this value to a little less than the TCP MSS may improve latency
95    /// for stream-y workloads.
96    ///
97    /// [TLS maximum]: https://datatracker.ietf.org/doc/html/rfc8446#section-5.1
98    /// [ServerConnection::new]: crate::server::ServerConnection::new
99    pub max_fragment_size: Option<usize>,
100
101    /// How to store client sessions.
102    ///
103    /// See [ServerConfig#sharing-resumption-storage-between-serverconfigs]
104    /// for a warning related to this field.
105    pub session_storage: Arc<dyn StoresServerSessions>,
106
107    /// How to produce tickets.
108    ///
109    /// See [ServerConfig#sharing-resumption-storage-between-serverconfigs]
110    /// for a warning related to this field.
111    pub ticketer: Option<Arc<dyn TicketProducer>>,
112
113    /// How to choose a server cert and key. This is usually set by
114    /// [ConfigBuilder::with_single_cert] or [ConfigBuilder::with_server_credential_resolver].
115    pub cert_resolver: Arc<dyn ServerCredentialResolver>,
116
117    /// Protocol names we support, most preferred first.
118    /// If empty we don't do ALPN at all.
119    pub alpn_protocols: Vec<ApplicationProtocol<'static>>,
120
121    /// How to verify client certificates.
122    pub(super) verifier: Arc<dyn ClientVerifier>,
123
124    /// How to output key material for debugging.  The default
125    /// does nothing.
126    pub key_log: Arc<dyn KeyLog>,
127
128    /// Allows traffic secrets to be extracted after the handshake,
129    /// e.g. for kTLS setup.
130    pub enable_secret_extraction: bool,
131
132    /// Amount of early data to accept for sessions created by
133    /// this config.  Specify 0 to disable early data.  The
134    /// default is 0.
135    ///
136    /// Read the early data via
137    /// [`ServerConnection::early_data()`][super::ServerConnection::early_data()].
138    ///
139    /// The units for this are _both_ plaintext bytes, _and_ ciphertext
140    /// bytes, depending on whether the server accepts a client's early_data
141    /// or not.  It is therefore recommended to include some slop in
142    /// this value to account for the unknown amount of ciphertext
143    /// expansion in the latter case.
144    pub max_early_data_size: u32,
145
146    /// Whether the server should send "0.5RTT" data.  This means the server
147    /// sends data after its first flight of handshake messages, without
148    /// waiting for the client to complete the handshake.
149    ///
150    /// This can improve TTFB latency for either server-speaks-first protocols,
151    /// or client-speaks-first protocols when paired with "0RTT" data.  This
152    /// comes at the cost of a subtle weakening of the normal handshake
153    /// integrity guarantees that TLS provides.  Note that the initial
154    /// `ClientHello` is indirectly authenticated because it is included
155    /// in the transcript used to derive the keys used to encrypt the data.
156    ///
157    /// This only applies to TLS1.3 connections.  TLS1.2 connections cannot
158    /// do this optimisation and this setting is ignored for them.  It is
159    /// also ignored for TLS1.3 connections that even attempt client
160    /// authentication.
161    ///
162    /// This defaults to false.  This means the first application data
163    /// sent by the server comes after receiving and validating the client's
164    /// handshake up to the `Finished` message.  This is the safest option.
165    pub send_half_rtt_data: bool,
166
167    /// How many TLS1.3 tickets to send immediately after a successful
168    /// handshake.
169    ///
170    /// Because TLS1.3 tickets are single-use, this allows
171    /// a client to perform multiple resumptions.
172    ///
173    /// See [`Tls13Tickets`] for the meaning of the default and maximum
174    /// counts.
175    pub send_tls13_tickets: Tls13Tickets,
176
177    /// If set to `true`, requires the client to support the extended
178    /// master secret extraction method defined in [RFC 7627].
179    ///
180    /// The default is `true` if the configured [`CryptoProvider`] is FIPS-compliant,
181    /// false otherwise.
182    ///
183    /// It must be set to `true` to meet FIPS requirement mentioned in section
184    /// **D.Q Transition of the TLS 1.2 KDF to Support the Extended Master
185    /// Secret** from [FIPS 140-3 IG.pdf].
186    ///
187    /// [RFC 7627]: https://datatracker.ietf.org/doc/html/rfc7627
188    /// [FIPS 140-3 IG.pdf]: https://csrc.nist.gov/csrc/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf
189    pub require_ems: bool,
190
191    /// Provides the current system time
192    pub time_provider: Arc<dyn TimeProvider>,
193
194    /// How to compress the server's certificate chain.
195    ///
196    /// If a client supports this extension, and advertises support
197    /// for one of the compression algorithms included here, the
198    /// server certificate will be compressed according to [RFC8879].
199    ///
200    /// This only applies to TLS1.3 connections.  It is ignored for
201    /// TLS1.2 connections.
202    ///
203    /// [RFC8879]: https://datatracker.ietf.org/doc/rfc8879/
204    pub cert_compressors: Vec<&'static dyn compress::CertCompressor>,
205
206    /// Caching for compressed certificates.
207    ///
208    /// This is optional: [`compress::CompressionCache::Disabled`] gives
209    /// a cache that does no caching.
210    pub cert_compression_cache: Arc<compress::CompressionCache>,
211
212    /// How to decompress the clients's certificate chain.
213    ///
214    /// If this is non-empty, the [RFC8879] certificate compression
215    /// extension is offered when requesting client authentication,
216    /// and any compressed certificates are transparently decompressed
217    /// during the handshake.
218    ///
219    /// This only applies to TLS1.3 connections.  It is ignored for
220    /// TLS1.2 connections.
221    ///
222    /// [RFC8879]: https://datatracker.ietf.org/doc/rfc8879/
223    pub cert_decompressors: Vec<&'static dyn compress::CertDecompressor>,
224
225    /// Policy for how an invalid Server Name Indication (SNI) value from a client is handled.
226    pub invalid_sni_policy: InvalidSniPolicy,
227}
228
229impl ServerConfig {
230    /// Create a builder for a server configuration with a specific [`CryptoProvider`].
231    ///
232    /// This will use the provider's configured ciphersuites.  This implies which TLS
233    /// protocol versions are enabled.
234    ///
235    /// This function always succeeds.  Any internal consistency problems with `provider`
236    /// are reported at the end of the builder process.
237    ///
238    /// For more information, see the [`ConfigBuilder`] documentation.
239    pub fn builder(provider: Arc<CryptoProvider>) -> ConfigBuilder<Self, WantsVerifier> {
240        Self::builder_with_details(provider, Arc::new(DefaultTimeProvider))
241    }
242
243    /// Create a builder for a server configuration with no default implementation details.
244    ///
245    /// This API must be used by `no_std` users.
246    ///
247    /// You must provide a specific [`TimeProvider`].
248    ///
249    /// You must provide a specific [`CryptoProvider`].
250    ///
251    /// This will use the provider's configured ciphersuites.  This implies which TLS
252    /// protocol versions are enabled.
253    ///
254    /// This function always succeeds.  Any internal consistency problems with `provider`
255    /// are reported at the end of the builder process.
256    ///
257    /// For more information, see the [`ConfigBuilder`] documentation.
258    pub fn builder_with_details(
259        provider: Arc<CryptoProvider>,
260        time_provider: Arc<dyn TimeProvider>,
261    ) -> ConfigBuilder<Self, WantsVerifier> {
262        ConfigBuilder {
263            state: WantsVerifier {
264                client_ech_mode: None,
265            },
266            provider,
267            time_provider,
268            side: PhantomData,
269        }
270    }
271
272    /// Return the FIPS validation status for connections made with this configuration.
273    ///
274    /// This is different from [`CryptoProvider::fips()`]: [`CryptoProvider::fips()`]
275    /// is concerned only with cryptography, whereas this _also_ covers TLS-level
276    /// configuration that NIST recommends.
277    pub fn fips(&self) -> FipsStatus {
278        match self.require_ems {
279            true => self.provider.fips(),
280            false => FipsStatus::Unvalidated,
281        }
282    }
283
284    /// Return the crypto provider used to construct this server configuration.
285    pub fn crypto_provider(&self) -> &Arc<CryptoProvider> {
286        &self.provider
287    }
288
289    pub(crate) fn supports_version(&self, v: ProtocolVersion) -> bool {
290        self.provider.supports_version(v)
291    }
292
293    pub(super) fn current_time(&self) -> Result<UnixTime, Error> {
294        self.time_provider
295            .current_time()
296            .ok_or(Error::FailedToGetCurrentTime)
297    }
298}
299
300/// How many TLS 1.3 session tickets the server sends after a handshake.
301#[expect(clippy::exhaustive_structs)]
302#[derive(Clone, Copy, Debug)]
303pub struct Tls13Tickets {
304    /// Tickets sent when the client does not request a specific number.
305    pub default: usize,
306
307    /// Upper bound on the number of tickets sent.
308    pub max: usize,
309}
310
311impl Tls13Tickets {
312    pub(super) fn resolve(&self, requested: Option<&ClientTicketRequest>, resuming: bool) -> usize {
313        let Some(req) = requested else {
314            return self.default;
315        };
316
317        Ord::min(
318            usize::from(match resuming {
319                true => req.resumption_count,
320                false => req.new_session_count,
321            }),
322            self.max,
323        )
324    }
325}
326
327impl Default for Tls13Tickets {
328    fn default() -> Self {
329        Self { default: 2, max: 2 }
330    }
331}
332
333/// A trait for the ability to store server session data.
334///
335/// The keys and values are opaque.
336///
337/// Inserted keys are randomly chosen by the library and have
338/// no internal structure (in other words, you may rely on all
339/// bits being uniformly random).  Queried keys are untrusted data.
340///
341/// Both the keys and values should be treated as
342/// **highly sensitive data**, containing enough key material
343/// to break all security of the corresponding sessions.
344///
345/// Implementations can be lossy (in other words, forgetting
346/// key/value pairs) without any negative security consequences.
347///
348/// However, note that `take` **must** reliably delete a returned
349/// value.  If it does not, there may be security consequences.
350///
351/// `put` and `take` are mutating operations; this isn't expressed
352/// in the type system to allow implementations freedom in
353/// how to achieve interior mutability.  `Mutex` is a common
354/// choice.
355pub trait StoresServerSessions: Debug + Send + Sync {
356    /// Store session secrets encoded in `value` against `key`,
357    /// overwrites any existing value against `key`.  Returns `true`
358    /// if the value was stored.
359    fn put(&self, key: ServerSessionKey<'_>, value: Vec<u8>) -> bool;
360
361    /// Find a value with the given `key`.  Return it, or None
362    /// if it doesn't exist.
363    fn get(&self, key: ServerSessionKey<'_>) -> Option<Vec<u8>>;
364
365    /// Find a value with the given `key`.  Return it and delete it;
366    /// or None if it doesn't exist.
367    fn take(&self, key: ServerSessionKey<'_>) -> Option<Vec<u8>>;
368
369    /// Whether the store can cache another session. This is used to indicate to clients
370    /// whether their session can be resumed; the implementation is not required to remember
371    /// a session even if it returns `true` here.
372    fn can_cache(&self) -> bool;
373}
374
375/// How to choose a certificate chain and signing key for use
376/// in server authentication.
377///
378/// This is suitable when selecting a certificate does not require
379/// I/O or when the application is using blocking I/O anyhow.
380pub trait ServerCredentialResolver: Debug + Send + Sync {
381    /// Choose a certificate chain and matching key given simplified ClientHello information.
382    ///
383    /// The `SelectedCredential` returned from this method contains an identity and a
384    /// one-time-use [`Signer`] wrapping the private key. This is usually obtained via a
385    /// [`Credentials`], on which an implementation can call [`Credentials::signer()`].
386    /// An implementation can either store long-lived [`Credentials`] values, or instantiate
387    /// them as needed using one of its constructors.
388    ///
389    /// Yielding an `Error` will abort the handshake. Some relevant error variants:
390    ///
391    /// * [`PeerIncompatible::NoSignatureSchemesInCommon`]
392    /// * [`PeerIncompatible::NoServerNameProvided`]
393    /// * [`Error::NoSuitableCertificate`]
394    ///
395    /// [`Credentials`]: crate::crypto::Credentials
396    /// [`Credentials::signer()`]: crate::crypto::Credentials::signer
397    /// [`Signer`]: crate::crypto::Signer
398    /// [`PeerIncompatible::NoSignatureSchemesInCommon`]: crate::error::PeerIncompatible::NoSignatureSchemesInCommon
399    /// [`PeerIncompatible::NoServerNameProvided`]: crate::error::PeerIncompatible::NoServerNameProvided
400    fn resolve(&self, client_hello: &ClientHello<'_>) -> Result<SelectedCredential, Error>;
401
402    /// Returns which [`CertificateType`]s this resolver supports.
403    ///
404    /// Returning an empty slice will result in an error. The default implementation signals
405    /// support for X.509 certificates. Implementations should return the same value every time.
406    ///
407    /// See [RFC 7250](https://tools.ietf.org/html/rfc7250) for more information.
408    fn supported_certificate_types(&self) -> &'static [CertificateType] {
409        &[CertificateType::X509]
410    }
411}
412
413/// A struct representing the received Client Hello
414#[derive(Debug)]
415pub struct ClientHello<'a> {
416    pub(super) server_name: Option<Cow<'a, DnsName<'a>>>,
417    pub(super) signature_schemes: &'a [SignatureScheme],
418    pub(super) alpn: Option<&'a Vec<ApplicationProtocol<'a>>>,
419    pub(super) server_cert_types: Option<&'a [CertificateType]>,
420    pub(super) client_cert_types: Option<&'a [CertificateType]>,
421    pub(super) cipher_suites: &'a [CipherSuite],
422    /// The [certificate_authorities] extension, if it was sent by the client.
423    ///
424    /// [certificate_authorities]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
425    pub(super) certificate_authorities: Option<&'a [DistinguishedName]>,
426    pub(super) named_groups: Option<&'a [NamedGroup]>,
427}
428
429impl<'a> ClientHello<'a> {
430    #[cfg(test)]
431    pub(super) fn empty() -> Self {
432        Self {
433            server_name: None,
434            signature_schemes: &[],
435            alpn: None,
436            server_cert_types: None,
437            client_cert_types: None,
438            cipher_suites: &[],
439            certificate_authorities: None,
440            named_groups: None,
441        }
442    }
443
444    pub(super) fn new(
445        payload: &'a ClientHelloPayload,
446        signature_schemes: Option<&'a [SignatureScheme]>,
447        server_name: Option<Cow<'a, DnsName<'a>>>,
448        version: Option<ProtocolVersion>,
449    ) -> Self {
450        Self {
451            server_name,
452            signature_schemes: signature_schemes.unwrap_or_else(|| {
453                payload
454                    .signature_schemes
455                    .as_deref()
456                    .unwrap_or_default()
457            }),
458            alpn: payload.protocols.as_ref(),
459            server_cert_types: payload
460                .server_certificate_types
461                .as_deref(),
462            client_cert_types: payload
463                .client_certificate_types
464                .as_deref(),
465            cipher_suites: &payload.cipher_suites,
466            // We adhere to the TLS 1.2 RFC by not exposing this to the cert resolver if TLS version is 1.2
467            certificate_authorities: match version {
468                Some(ProtocolVersion::TLSv1_2) => None,
469                _ => payload
470                    .certificate_authority_names
471                    .as_deref(),
472            },
473            named_groups: payload.named_groups.as_deref(),
474        }
475    }
476
477    /// Get the server name indicator.
478    ///
479    /// Returns `None` if the client did not supply a SNI.
480    pub fn server_name(&self) -> Option<&DnsName<'_>> {
481        self.server_name.as_deref()
482    }
483
484    /// Get the compatible signature schemes.
485    ///
486    /// Returns standard-specified default if the client omitted this extension.
487    pub fn signature_schemes(&self) -> &[SignatureScheme] {
488        self.signature_schemes
489    }
490
491    /// Get the ALPN protocol identifiers submitted by the client.
492    ///
493    /// Returns `None` if the client did not include an ALPN extension.
494    ///
495    /// Application Layer Protocol Negotiation (ALPN) is a TLS extension that lets a client
496    /// submit a set of identifiers that each a represent an application-layer protocol.
497    /// The server will then pick its preferred protocol from the set submitted by the client.
498    /// Each identifier is represented as a byte array, although common values are often ASCII-encoded.
499    /// See the official RFC-7301 specifications at <https://datatracker.ietf.org/doc/html/rfc7301>
500    /// for more information on ALPN.
501    ///
502    /// For example, a HTTP client might specify "http/1.1" and/or "h2". Other well-known values
503    /// are listed in the at IANA registry at
504    /// <https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids>.
505    ///
506    /// The server can specify supported ALPN protocols by setting [`ServerConfig::alpn_protocols`].
507    /// During the handshake, the server will select the first protocol configured that the client supports.
508    pub fn alpn(&self) -> Option<impl Iterator<Item = &'a [u8]> + use<'a>> {
509        self.alpn.map(|protocols| {
510            protocols
511                .iter()
512                .map(|proto| proto.as_ref())
513        })
514    }
515
516    /// Get cipher suites.
517    pub fn cipher_suites(&self) -> &[CipherSuite] {
518        self.cipher_suites
519    }
520
521    /// Get the server certificate types offered in the ClientHello.
522    ///
523    /// Returns `None` if the client did not include a certificate type extension.
524    pub fn server_cert_types(&self) -> Option<&'a [CertificateType]> {
525        self.server_cert_types
526    }
527
528    /// Get the client certificate types offered in the ClientHello.
529    ///
530    /// Returns `None` if the client did not include a certificate type extension.
531    pub fn client_cert_types(&self) -> Option<&'a [CertificateType]> {
532        self.client_cert_types
533    }
534
535    /// Get the [certificate_authorities] extension sent by the client.
536    ///
537    /// Returns `None` if the client did not send this extension.
538    ///
539    /// [certificate_authorities]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
540    pub fn certificate_authorities(&self) -> Option<&'a [DistinguishedName]> {
541        self.certificate_authorities
542    }
543
544    /// Get the [`named_groups`] extension sent by the client.
545    ///
546    /// This means different things in different versions of TLS:
547    ///
548    /// Originally it was introduced as the "[`elliptic_curves`]" extension for TLS1.2.
549    /// It described the elliptic curves supported by a client for all purposes: key
550    /// exchange, signature verification (for server authentication), and signing (for
551    /// client auth).  Later [RFC7919] extended this to include FFDHE "named groups",
552    /// but FFDHE groups in this context only relate to key exchange.
553    ///
554    /// In TLS1.3 it was renamed to "[`named_groups`]" and now describes all types
555    /// of key exchange mechanisms, and does not relate at all to elliptic curves
556    /// used for signatures.
557    ///
558    /// [`elliptic_curves`]: https://datatracker.ietf.org/doc/html/rfc4492#section-5.1.1
559    /// [RFC7919]: https://datatracker.ietf.org/doc/html/rfc7919#section-2
560    /// [`named_groups`]:https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.7
561    pub fn named_groups(&self) -> Option<&'a [NamedGroup]> {
562        self.named_groups
563    }
564}
565
566/// A policy describing how an invalid Server Name Indication (SNI) value from a client is handled by the server.
567///
568/// The only valid form of SNI according to relevant RFCs ([RFC6066], [RFC1035]) is
569/// non-IP-address host name, however some misconfigured clients may send a bare IP address, or
570/// another invalid value. Some servers may wish to ignore these invalid values instead of producing
571/// an error.
572///
573/// By default, Rustls will ignore invalid values that are an IP address (the most common misconfiguration)
574/// and error for all other invalid values.
575///
576/// When an SNI value is ignored, Rustls treats the client as if it sent no SNI at all.
577///
578/// [RFC1035]: https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.1
579/// [RFC6066]: https://datatracker.ietf.org/doc/html/rfc6066#section-3
580#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
581#[non_exhaustive]
582pub enum InvalidSniPolicy {
583    /// Reject all ClientHello messages that contain an invalid SNI value.
584    RejectAll,
585    /// Ignore an invalid SNI value in ClientHello messages if the value is an IP address.
586    ///
587    /// "Ignoring SNI" means accepting the ClientHello message, but acting as if the client sent no SNI.
588    #[default]
589    IgnoreIpAddresses,
590    /// Ignore all invalid SNI in ClientHello messages.
591    ///
592    /// "Ignoring SNI" means accepting the ClientHello message, but acting as if the client sent no SNI.
593    IgnoreAll,
594}
595
596impl InvalidSniPolicy {
597    /// Returns the valid SNI value, or ignores the invalid SNI value if allowed by this policy; otherwise returns
598    /// an error.
599    pub(super) fn accept(
600        &self,
601        payload: Option<&ServerNamePayload<'_>>,
602    ) -> Result<Option<DnsName<'static>>, Error> {
603        let Some(payload) = payload else {
604            return Ok(None);
605        };
606        if let Some(server_name) = payload.to_dns_name_normalized() {
607            return Ok(Some(server_name));
608        }
609        match (self, payload) {
610            (Self::IgnoreAll, _) => Ok(None),
611            (Self::IgnoreIpAddresses, ServerNamePayload::IpAddress) => Ok(None),
612            _ => Err(Error::PeerMisbehaved(
613                PeerMisbehaved::ServerNameMustContainOneHostName,
614            )),
615        }
616    }
617}
618
619impl ConfigBuilder<ServerConfig, WantsVerifier> {
620    /// Choose how to verify client certificates.
621    pub fn with_client_cert_verifier(
622        self,
623        client_cert_verifier: Arc<dyn ClientVerifier>,
624    ) -> ConfigBuilder<ServerConfig, WantsServerCert> {
625        ConfigBuilder {
626            state: WantsServerCert {
627                verifier: client_cert_verifier,
628            },
629            provider: self.provider,
630            time_provider: self.time_provider,
631            side: PhantomData,
632        }
633    }
634
635    /// Disable client authentication.
636    pub fn with_no_client_auth(self) -> ConfigBuilder<ServerConfig, WantsServerCert> {
637        self.with_client_cert_verifier(Arc::new(NoClientAuth))
638    }
639}
640
641/// A config builder state where the caller must supply how to provide a server certificate to
642/// the connecting peer.
643///
644/// For more information, see the [`ConfigBuilder`] documentation.
645#[derive(Clone, Debug)]
646pub struct WantsServerCert {
647    verifier: Arc<dyn ClientVerifier>,
648}
649
650impl ConfigBuilder<ServerConfig, WantsServerCert> {
651    /// Sets a single certificate chain and matching private key.  This
652    /// certificate and key is used for all subsequent connections,
653    /// irrespective of things like SNI hostname.
654    ///
655    /// Note that the end-entity certificate must have the
656    /// [Subject Alternative Name](https://tools.ietf.org/html/rfc6125#section-4.1)
657    /// extension to describe, e.g., the valid DNS name. The `commonName` field is
658    /// disregarded.
659    ///
660    /// `cert_chain` is a vector of DER-encoded certificates.
661    /// `key_der` is a DER-encoded private key as PKCS#1, PKCS#8, or SEC1. The
662    /// `aws-lc-rs` and `ring` [`CryptoProvider`]s support
663    /// all three encodings, but other `CryptoProvider`s may not.
664    ///
665    /// This function fails if `key_der` is invalid, or if the
666    /// `SubjectPublicKeyInfo` from the private key does not match the public
667    /// key for the end-entity certificate from the `cert_chain`.
668    #[cfg(feature = "webpki")]
669    pub fn with_single_cert(
670        self,
671        identity: Arc<Identity<'static>>,
672        key_der: PrivateKeyDer<'static>,
673    ) -> Result<ServerConfig, Error> {
674        let credentials = Credentials::from_der(identity, key_der, self.crypto_provider())?;
675        self.with_server_credential_resolver(Arc::new(SingleCredential::from(credentials)))
676    }
677
678    /// Sets a single certificate chain, matching private key and optional OCSP
679    /// response.  This certificate and key is used for all
680    /// subsequent connections, irrespective of things like SNI hostname.
681    ///
682    /// `cert_chain` is a vector of DER-encoded certificates.
683    /// `key_der` is a DER-encoded private key as PKCS#1, PKCS#8, or SEC1. The
684    /// `aws-lc-rs` and `ring` [`CryptoProvider`]s support
685    /// all three encodings, but other `CryptoProvider`s may not.
686    /// `ocsp` is a DER-encoded OCSP response.  Ignored if zero length.
687    ///
688    /// This function fails if `key_der` is invalid, or if the
689    /// `SubjectPublicKeyInfo` from the private key does not match the public
690    /// key for the end-entity certificate from the `cert_chain`.
691    #[cfg(feature = "webpki")]
692    pub fn with_single_cert_with_ocsp(
693        self,
694        identity: Arc<Identity<'static>>,
695        key_der: PrivateKeyDer<'static>,
696        ocsp: Arc<[u8]>,
697    ) -> Result<ServerConfig, Error> {
698        let mut credentials = Credentials::from_der(identity, key_der, self.crypto_provider())?;
699        if !ocsp.is_empty() {
700            credentials.ocsp = Some(ocsp);
701        }
702        self.with_server_credential_resolver(Arc::new(SingleCredential::from(credentials)))
703    }
704
705    /// Sets a custom [`ServerCredentialResolver`].
706    pub fn with_server_credential_resolver(
707        self,
708        cert_resolver: Arc<dyn ServerCredentialResolver>,
709    ) -> Result<ServerConfig, Error> {
710        self.provider.consistency_check()?;
711        let require_ems = !matches!(self.provider.fips(), FipsStatus::Unvalidated);
712        Ok(ServerConfig {
713            provider: self.provider,
714            cipher_suite_selector: &PreferClientOrder,
715            max_fragment_size: None,
716            session_storage: handy::ServerSessionMemoryCache::new(256),
717            ticketer: None,
718            cert_resolver,
719            alpn_protocols: Vec::new(),
720            verifier: self.state.verifier,
721            key_log: Arc::new(NoKeyLog {}),
722            enable_secret_extraction: false,
723            max_early_data_size: 0,
724            send_half_rtt_data: false,
725            send_tls13_tickets: Tls13Tickets::default(),
726            require_ems,
727            time_provider: self.time_provider,
728            cert_compressors: compress::default_cert_compressors().to_vec(),
729            cert_compression_cache: Arc::new(compress::CompressionCache::default()),
730            cert_decompressors: compress::default_cert_decompressors().to_vec(),
731            invalid_sni_policy: InvalidSniPolicy::default(),
732        })
733    }
734}
735
736/// A [`CipherSuiteSelector`] implementation that prioritizes client order.
737#[expect(clippy::exhaustive_structs)]
738#[derive(Debug)]
739pub struct PreferClientOrder;
740
741impl CipherSuiteSelector for PreferClientOrder {
742    fn select_tls12_cipher_suite(
743        &self,
744        client: &mut dyn Iterator<Item = &'static Tls12CipherSuite>,
745        server: &[&'static Tls12CipherSuite],
746    ) -> Option<&'static Tls12CipherSuite> {
747        self.select(client, server)
748    }
749
750    fn select_tls13_cipher_suite(
751        &self,
752        client: &mut dyn Iterator<Item = &'static Tls13CipherSuite>,
753        server: &[&'static Tls13CipherSuite],
754    ) -> Option<&'static Tls13CipherSuite> {
755        self.select(client, server)
756    }
757}
758
759impl PreferClientOrder {
760    fn select<T: Suite>(
761        &self,
762        client: &mut dyn Iterator<Item = &'static T>,
763        _server: &[&'static T],
764    ) -> Option<&'static T> {
765        client.next()
766    }
767}
768
769/// A [`CipherSuiteSelector`] implementation that prioritizes server order.
770#[expect(clippy::exhaustive_structs)]
771#[derive(Debug)]
772pub struct PreferServerOrder;
773
774impl CipherSuiteSelector for PreferServerOrder {
775    fn select_tls12_cipher_suite(
776        &self,
777        client: &mut dyn Iterator<Item = &'static Tls12CipherSuite>,
778        server: &[&'static Tls12CipherSuite],
779    ) -> Option<&'static Tls12CipherSuite> {
780        client
781            .filter_map(|cs| {
782                server
783                    .iter()
784                    .position(|&ss| ss == cs)
785                    .map(|pos| (pos, cs))
786            })
787            .min_by_key(|&(pos, _)| pos)
788            .map(|(_, cs)| cs)
789    }
790
791    fn select_tls13_cipher_suite(
792        &self,
793        client: &mut dyn Iterator<Item = &'static Tls13CipherSuite>,
794        server: &[&'static Tls13CipherSuite],
795    ) -> Option<&'static Tls13CipherSuite> {
796        client
797            .filter_map(|cs| {
798                server
799                    .iter()
800                    .position(|&ss| ss == cs)
801                    .map(|pos| (pos, cs))
802            })
803            .min_by_key(|&(pos, _)| pos)
804            .map(|(_, cs)| cs)
805    }
806}
807
808impl<T: CipherSuiteSelector + ?Sized> VersionSuiteSelector<Tls12CipherSuite> for T {
809    fn select(
810        &self,
811        client: &mut dyn Iterator<Item = &'static Tls12CipherSuite>,
812        server: &[&'static Tls12CipherSuite],
813    ) -> Option<&'static Tls12CipherSuite> {
814        self.select_tls12_cipher_suite(client, server)
815    }
816}
817
818impl<T: CipherSuiteSelector + ?Sized> VersionSuiteSelector<Tls13CipherSuite> for T {
819    fn select(
820        &self,
821        client: &mut dyn Iterator<Item = &'static Tls13CipherSuite>,
822        server: &[&'static Tls13CipherSuite],
823    ) -> Option<&'static Tls13CipherSuite> {
824        self.select_tls13_cipher_suite(client, server)
825    }
826}
827
828pub(super) trait VersionSuiteSelector<T> {
829    fn select(
830        &self,
831        client: &mut dyn Iterator<Item = &'static T>,
832        server: &[&'static T],
833    ) -> Option<&'static T>;
834}
835
836/// A filter that chooses the cipher suite to use for a TLS session.
837pub trait CipherSuiteSelector: Debug + Send + Sync {
838    /// Choose a cipher suite, given the client's and server's options, in preference order.
839    ///
840    /// The `client` list is generated in order from the [`CipherSuite`] values received in the
841    /// `ClientHello`, filtered to only contain suites that the server supports. The `server`
842    /// list comes from the [`ServerConfig`]'s [`CryptoProvider`].
843    ///
844    /// Yields the chosen cipher suite supported by both sides, or `None` to indicate that no
845    /// mutually supported cipher suite could be agreed on.
846    fn select_tls12_cipher_suite(
847        &self,
848        client: &mut dyn Iterator<Item = &'static Tls12CipherSuite>,
849        server: &[&'static Tls12CipherSuite],
850    ) -> Option<&'static Tls12CipherSuite>;
851
852    /// Choose a cipher suite, given the client's and server's options, in preference order.
853    ///
854    /// The `client` list is generated in order from the [`CipherSuite`] values received in the
855    /// `ClientHello`, filtered to only contain suites that the server supports. The `server`
856    /// list comes from the [`ServerConfig`]'s [`CryptoProvider`].
857    ///
858    /// Yields the chosen cipher suite supported by both sides, or `None` to indicate that no
859    /// mutually supported cipher suite could be agreed on.
860    fn select_tls13_cipher_suite(
861        &self,
862        client: &mut dyn Iterator<Item = &'static Tls13CipherSuite>,
863        server: &[&'static Tls13CipherSuite],
864    ) -> Option<&'static Tls13CipherSuite>;
865}