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