1use crate::builder::{ConfigBuilder, WantsVerifier};
2use crate::client::handy;
3use crate::client::{ClientConfig, ResolvesClientCert};
4use crate::crypto::CryptoProvider;
5use crate::error::Error;
6use crate::key_log::NoKeyLog;
7use crate::msgs::handshake::CertificateChain;
8use crate::webpki::{self, WebPkiServerVerifier};
9use crate::{verify, versions};
10
11use super::client_conn::Resumption;
12
13use pki_types::{CertificateDer, PrivateKeyDer};
14
15use alloc::sync::Arc;
16use alloc::vec::Vec;
17use core::marker::PhantomData;
18
19impl ConfigBuilder<ClientConfig, WantsVerifier> {
20 pub fn with_root_certificates(
34 self,
35 root_store: impl Into<Arc<webpki::RootCertStore>>,
36 ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
37 let algorithms = self
38 .state
39 .provider
40 .signature_verification_algorithms;
41 self.with_webpki_verifier(
42 WebPkiServerVerifier::new_without_revocation(root_store, algorithms).into(),
43 )
44 }
45
46 pub fn with_webpki_verifier(
51 self,
52 verifier: Arc<WebPkiServerVerifier>,
53 ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
54 ConfigBuilder {
55 state: WantsClientCert {
56 provider: self.state.provider,
57 versions: self.state.versions,
58 verifier,
59 },
60 side: PhantomData,
61 }
62 }
63
64 pub fn dangerous(self) -> danger::DangerousClientConfigBuilder {
67 danger::DangerousClientConfigBuilder { cfg: self }
68 }
69}
70
71pub(super) mod danger {
73 use alloc::sync::Arc;
74 use core::marker::PhantomData;
75
76 use crate::client::WantsClientCert;
77 use crate::{verify, ClientConfig, ConfigBuilder, WantsVerifier};
78
79 #[derive(Debug)]
81 pub struct DangerousClientConfigBuilder {
82 pub cfg: ConfigBuilder<ClientConfig, WantsVerifier>,
84 }
85
86 impl DangerousClientConfigBuilder {
87 pub fn with_custom_certificate_verifier(
89 self,
90 verifier: Arc<dyn verify::ServerCertVerifier>,
91 ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
92 ConfigBuilder {
93 state: WantsClientCert {
94 provider: self.cfg.state.provider,
95 versions: self.cfg.state.versions,
96 verifier,
97 },
98 side: PhantomData,
99 }
100 }
101 }
102}
103
104#[derive(Clone)]
109pub struct WantsClientCert {
110 provider: Arc<CryptoProvider>,
111 versions: versions::EnabledVersions,
112 verifier: Arc<dyn verify::ServerCertVerifier>,
113}
114
115impl ConfigBuilder<ClientConfig, WantsClientCert> {
116 pub fn with_client_auth_cert(
126 self,
127 cert_chain: Vec<CertificateDer<'static>>,
128 key_der: PrivateKeyDer<'static>,
129 ) -> Result<ClientConfig, Error> {
130 let private_key = self
131 .state
132 .provider
133 .key_provider
134 .load_private_key(key_der)?;
135 let resolver =
136 handy::AlwaysResolvesClientCert::new(private_key, CertificateChain(cert_chain))?;
137 Ok(self.with_client_cert_resolver(Arc::new(resolver)))
138 }
139
140 pub fn with_no_client_auth(self) -> ClientConfig {
142 self.with_client_cert_resolver(Arc::new(handy::FailResolveClientCert {}))
143 }
144
145 pub fn with_client_cert_resolver(
147 self,
148 client_auth_cert_resolver: Arc<dyn ResolvesClientCert>,
149 ) -> ClientConfig {
150 ClientConfig {
151 provider: self.state.provider,
152 alpn_protocols: Vec::new(),
153 resumption: Resumption::default(),
154 max_fragment_size: None,
155 client_auth_cert_resolver,
156 versions: self.state.versions,
157 enable_sni: true,
158 verifier: self.state.verifier,
159 key_log: Arc::new(NoKeyLog {}),
160 enable_secret_extraction: false,
161 enable_early_data: false,
162 }
163 }
164}