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