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