clia_rustls_mod/client/
builder.rs1use alloc::sync::Arc;
2use alloc::vec::Vec;
3use core::marker::PhantomData;
4
5use pki_types::{CertificateDer, PrivateKeyDer};
6
7use super::client_conn::Resumption;
8use crate::builder::{ConfigBuilder, WantsVerifier};
9use crate::client::{handy, ClientConfig, ResolvesClientCert};
10use crate::crypto::CryptoProvider;
11use crate::error::Error;
12use crate::key_log::NoKeyLog;
13use crate::msgs::handshake::CertificateChain;
14use crate::time_provider::TimeProvider;
15use crate::webpki::{self, WebPkiServerVerifier};
16use crate::{verify, versions};
17
18impl ConfigBuilder<ClientConfig, WantsVerifier> {
19 pub fn with_root_certificates(
33 self,
34 root_store: impl Into<Arc<webpki::RootCertStore>>,
35 ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
36 let algorithms = self
37 .state
38 .provider
39 .signature_verification_algorithms;
40 self.with_webpki_verifier(
41 WebPkiServerVerifier::new_without_revocation(root_store, algorithms).into(),
42 )
43 }
44
45 pub fn with_webpki_verifier(
50 self,
51 verifier: Arc<WebPkiServerVerifier>,
52 ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
53 ConfigBuilder {
54 state: WantsClientCert {
55 provider: self.state.provider,
56 versions: self.state.versions,
57 verifier,
58 time_provider: self.state.time_provider,
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 time_provider: self.cfg.state.time_provider,
98 },
99 side: PhantomData,
100 }
101 }
102 }
103}
104
105#[derive(Clone)]
110pub struct WantsClientCert {
111 provider: Arc<CryptoProvider>,
112 versions: versions::EnabledVersions,
113 verifier: Arc<dyn verify::ServerCertVerifier>,
114 time_provider: Arc<dyn TimeProvider>,
115}
116
117impl ConfigBuilder<ClientConfig, WantsClientCert> {
118 pub fn with_client_auth_cert(
128 self,
129 cert_chain: Vec<CertificateDer<'static>>,
130 key_der: PrivateKeyDer<'static>,
131 ) -> Result<ClientConfig, Error> {
132 let private_key = self
133 .state
134 .provider
135 .key_provider
136 .load_private_key(key_der)?;
137 let resolver =
138 handy::AlwaysResolvesClientCert::new(private_key, CertificateChain(cert_chain))?;
139 Ok(self.with_client_cert_resolver(Arc::new(resolver)))
140 }
141
142 pub fn with_no_client_auth(self) -> ClientConfig {
144 self.with_client_cert_resolver(Arc::new(handy::FailResolveClientCert {}))
145 }
146
147 pub fn with_client_cert_resolver(
149 self,
150 client_auth_cert_resolver: Arc<dyn ResolvesClientCert>,
151 ) -> ClientConfig {
152 ClientConfig {
153 provider: self.state.provider,
154 alpn_protocols: Vec::new(),
155 resumption: Resumption::default(),
156 max_fragment_size: None,
157 client_auth_cert_resolver,
158 versions: self.state.versions,
159 enable_sni: true,
160 verifier: self.state.verifier,
161 key_log: Arc::new(NoKeyLog {}),
162 enable_secret_extraction: false,
163 enable_early_data: false,
164 #[cfg(feature = "tls12")]
165 require_ems: cfg!(feature = "fips"),
166 time_provider: self.state.time_provider,
167 }
168 }
169}