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