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