use crate::anchors;
use crate::builder::{ConfigBuilder, WantsVerifier};
use crate::client::handy;
use crate::client::{ClientConfig, ResolvesClientCert};
use crate::error::Error;
use crate::key;
use crate::kx::SupportedKxGroup;
use crate::suites::SupportedCipherSuite;
use crate::verify::{self, CertificateTransparencyPolicy};
use crate::versions;
use crate::NoKeyLog;
use std::marker::PhantomData;
use std::sync::Arc;
use std::time::SystemTime;
impl ConfigBuilder<ClientConfig, WantsVerifier> {
pub fn with_root_certificates(
self,
root_store: anchors::RootCertStore,
) -> ConfigBuilder<ClientConfig, WantsTransparencyPolicyOrClientCert> {
ConfigBuilder {
state: WantsTransparencyPolicyOrClientCert {
cipher_suites: self.state.cipher_suites,
kx_groups: self.state.kx_groups,
versions: self.state.versions,
root_store,
},
side: PhantomData::default(),
}
}
#[cfg(feature = "dangerous_configuration")]
pub fn with_custom_certificate_verifier(
self,
verifier: Arc<dyn verify::ServerCertVerifier>,
) -> ConfigBuilder<ClientConfig, WantsClientCert> {
ConfigBuilder {
state: WantsClientCert {
cipher_suites: self.state.cipher_suites,
kx_groups: self.state.kx_groups,
versions: self.state.versions,
verifier,
},
side: PhantomData::default(),
}
}
}
#[derive(Clone, Debug)]
pub struct WantsTransparencyPolicyOrClientCert {
cipher_suites: Vec<SupportedCipherSuite>,
kx_groups: Vec<&'static SupportedKxGroup>,
versions: versions::EnabledVersions,
root_store: anchors::RootCertStore,
}
impl ConfigBuilder<ClientConfig, WantsTransparencyPolicyOrClientCert> {
pub fn with_certificate_transparency_logs(
self,
logs: &'static [&'static sct::Log],
validation_deadline: SystemTime,
) -> ConfigBuilder<ClientConfig, WantsClientCert> {
self.with_logs(Some(CertificateTransparencyPolicy::new(
logs,
validation_deadline,
)))
}
pub fn with_single_cert(
self,
cert_chain: Vec<key::Certificate>,
key_der: key::PrivateKey,
) -> Result<ClientConfig, Error> {
self.with_logs(None)
.with_single_cert(cert_chain, key_der)
}
pub fn with_no_client_auth(self) -> ClientConfig {
self.with_logs(None)
.with_client_cert_resolver(Arc::new(handy::FailResolveClientCert {}))
}
pub fn with_client_cert_resolver(
self,
client_auth_cert_resolver: Arc<dyn ResolvesClientCert>,
) -> ClientConfig {
self.with_logs(None)
.with_client_cert_resolver(client_auth_cert_resolver)
}
fn with_logs(
self,
ct_policy: Option<CertificateTransparencyPolicy>,
) -> ConfigBuilder<ClientConfig, WantsClientCert> {
ConfigBuilder {
state: WantsClientCert {
cipher_suites: self.state.cipher_suites,
kx_groups: self.state.kx_groups,
versions: self.state.versions,
verifier: Arc::new(verify::WebPkiVerifier::new(
self.state.root_store,
ct_policy,
)),
},
side: PhantomData,
}
}
}
#[derive(Clone, Debug)]
pub struct WantsClientCert {
cipher_suites: Vec<SupportedCipherSuite>,
kx_groups: Vec<&'static SupportedKxGroup>,
versions: versions::EnabledVersions,
verifier: Arc<dyn verify::ServerCertVerifier>,
}
impl ConfigBuilder<ClientConfig, WantsClientCert> {
pub fn with_single_cert(
self,
cert_chain: Vec<key::Certificate>,
key_der: key::PrivateKey,
) -> Result<ClientConfig, Error> {
let resolver = handy::AlwaysResolvesClientCert::new(cert_chain, &key_der)?;
Ok(self.with_client_cert_resolver(Arc::new(resolver)))
}
pub fn with_no_client_auth(self) -> ClientConfig {
self.with_client_cert_resolver(Arc::new(handy::FailResolveClientCert {}))
}
pub fn with_client_cert_resolver(
self,
client_auth_cert_resolver: Arc<dyn ResolvesClientCert>,
) -> ClientConfig {
ClientConfig {
cipher_suites: self.state.cipher_suites,
kx_groups: self.state.kx_groups,
alpn_protocols: Vec::new(),
session_storage: handy::ClientSessionMemoryCache::new(256),
max_fragment_size: None,
client_auth_cert_resolver,
enable_tickets: true,
versions: self.state.versions,
enable_sni: true,
verifier: self.state.verifier,
key_log: Arc::new(NoKeyLog {}),
#[cfg(feature = "secret_extraction")]
enable_secret_extraction: false,
enable_early_data: false,
}
}
}