rustls/server/
builder.rs

1use crate::builder::{ConfigBuilder, WantsVerifier};
2use crate::crypto::CryptoProvider;
3use crate::error::Error;
4use crate::msgs::handshake::CertificateChain;
5use crate::server::handy;
6use crate::server::{ResolvesServerCert, ServerConfig};
7use crate::verify::{ClientCertVerifier, NoClientAuth};
8use crate::versions;
9use crate::NoKeyLog;
10
11use pki_types::{CertificateDer, PrivateKeyDer};
12
13use alloc::sync::Arc;
14use alloc::vec::Vec;
15use core::marker::PhantomData;
16
17impl ConfigBuilder<ServerConfig, WantsVerifier> {
18    /// Choose how to verify client certificates.
19    pub fn with_client_cert_verifier(
20        self,
21        client_cert_verifier: Arc<dyn ClientCertVerifier>,
22    ) -> ConfigBuilder<ServerConfig, WantsServerCert> {
23        ConfigBuilder {
24            state: WantsServerCert {
25                provider: self.state.provider,
26                versions: self.state.versions,
27                verifier: client_cert_verifier,
28            },
29            side: PhantomData,
30        }
31    }
32
33    /// Disable client authentication.
34    pub fn with_no_client_auth(self) -> ConfigBuilder<ServerConfig, WantsServerCert> {
35        self.with_client_cert_verifier(Arc::new(NoClientAuth))
36    }
37}
38
39/// A config builder state where the caller must supply how to provide a server certificate to
40/// the connecting peer.
41///
42/// For more information, see the [`ConfigBuilder`] documentation.
43#[derive(Clone, Debug)]
44pub struct WantsServerCert {
45    provider: Arc<CryptoProvider>,
46    versions: versions::EnabledVersions,
47    verifier: Arc<dyn ClientCertVerifier>,
48}
49
50impl ConfigBuilder<ServerConfig, WantsServerCert> {
51    /// Sets a single certificate chain and matching private key.  This
52    /// certificate and key is used for all subsequent connections,
53    /// irrespective of things like SNI hostname.
54    ///
55    /// Note that the end-entity certificate must have the
56    /// [Subject Alternative Name](https://tools.ietf.org/html/rfc6125#section-4.1)
57    /// extension to describe, e.g., the valid DNS name. The `commonName` field is
58    /// disregarded.
59    ///
60    /// `cert_chain` is a vector of DER-encoded certificates.
61    /// `key_der` is a DER-encoded private key as PKCS#1, PKCS#8, or SEC1. The
62    /// `aws-lc-rs` and `ring` [`CryptoProvider`]s support all three encodings,
63    /// but other `CryptoProviders` may not.
64    ///
65    /// This function fails if `key_der` is invalid.
66    pub fn with_single_cert(
67        self,
68        cert_chain: Vec<CertificateDer<'static>>,
69        key_der: PrivateKeyDer<'static>,
70    ) -> Result<ServerConfig, Error> {
71        let private_key = self
72            .state
73            .provider
74            .key_provider
75            .load_private_key(key_der)?;
76        let resolver = handy::AlwaysResolvesChain::new(private_key, CertificateChain(cert_chain));
77        Ok(self.with_cert_resolver(Arc::new(resolver)))
78    }
79
80    /// Sets a single certificate chain, matching private key and optional OCSP
81    /// response.  This certificate and key is used for all
82    /// subsequent connections, irrespective of things like SNI hostname.
83    ///
84    /// `cert_chain` is a vector of DER-encoded certificates.
85    /// `key_der` is a DER-encoded private key as PKCS#1, PKCS#8, or SEC1. The
86    /// `aws-lc-rs` and `ring` [`CryptoProvider`]s support all three encodings,
87    /// but other `CryptoProviders` may not.
88    /// `ocsp` is a DER-encoded OCSP response.  Ignored if zero length.
89    ///
90    /// This function fails if `key_der` is invalid.
91    pub fn with_single_cert_with_ocsp(
92        self,
93        cert_chain: Vec<CertificateDer<'static>>,
94        key_der: PrivateKeyDer<'static>,
95        ocsp: Vec<u8>,
96    ) -> Result<ServerConfig, Error> {
97        let private_key = self
98            .state
99            .provider
100            .key_provider
101            .load_private_key(key_der)?;
102        let resolver = handy::AlwaysResolvesChain::new_with_extras(
103            private_key,
104            CertificateChain(cert_chain),
105            ocsp,
106        );
107        Ok(self.with_cert_resolver(Arc::new(resolver)))
108    }
109
110    /// Sets a custom [`ResolvesServerCert`].
111    pub fn with_cert_resolver(self, cert_resolver: Arc<dyn ResolvesServerCert>) -> ServerConfig {
112        ServerConfig {
113            provider: self.state.provider,
114            verifier: self.state.verifier,
115            cert_resolver,
116            ignore_client_order: false,
117            max_fragment_size: None,
118            session_storage: handy::ServerSessionMemoryCache::new(256),
119            ticketer: Arc::new(handy::NeverProducesTickets {}),
120            alpn_protocols: Vec::new(),
121            versions: self.state.versions,
122            key_log: Arc::new(NoKeyLog {}),
123            enable_secret_extraction: false,
124            max_early_data_size: 0,
125            send_half_rtt_data: false,
126            send_tls13_tickets: 4,
127        }
128    }
129}