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