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