ntp_proto/
tls_utils.rs

1#[cfg(feature = "rustls23")]
2mod rustls23_shim {
3    /// The intent of this ClientCertVerifier is that it accepts any connections that are either
4    /// a.) not presenting a client certificate
5    /// b.) are presenting a well-formed, but otherwise not checked (against a trust root) client certificate
6    ///
7    /// This is because RusTLS apparently doesn't accept every kind of self-signed certificate.
8    ///
9    /// The only goal of this ClientCertVerifier is to achieve that, if a client presents a TLS certificate,
10    /// this certificate shows up in the .peer_certificates() for that connection.
11    #[cfg(feature = "nts-pool")]
12    #[derive(Debug)]
13    pub struct AllowAnyAnonymousOrCertificateBearingClient {
14        supported_algs: WebPkiSupportedAlgorithms,
15    }
16
17    #[cfg(feature = "nts-pool")]
18    use rustls23::{
19        crypto::{CryptoProvider, WebPkiSupportedAlgorithms},
20        pki_types::CertificateDer,
21        server::danger::ClientCertVerified,
22    };
23
24    #[cfg(feature = "nts-pool")]
25    impl AllowAnyAnonymousOrCertificateBearingClient {
26        pub fn new(provider: &CryptoProvider) -> Self {
27            AllowAnyAnonymousOrCertificateBearingClient {
28                supported_algs: provider.signature_verification_algorithms,
29            }
30        }
31    }
32
33    #[cfg(feature = "nts-pool")]
34    impl rustls23::server::danger::ClientCertVerifier for AllowAnyAnonymousOrCertificateBearingClient {
35        fn verify_client_cert(
36            &self,
37            _end_entity: &CertificateDer,
38            _intermediates: &[CertificateDer],
39            _now: rustls23::pki_types::UnixTime,
40        ) -> Result<ClientCertVerified, rustls23::Error> {
41            Ok(ClientCertVerified::assertion())
42        }
43
44        fn client_auth_mandatory(&self) -> bool {
45            false
46        }
47
48        fn root_hint_subjects(&self) -> &[rustls23::DistinguishedName] {
49            &[]
50        }
51
52        fn verify_tls12_signature(
53            &self,
54            message: &[u8],
55            cert: &rustls23::pki_types::CertificateDer<'_>,
56            dss: &rustls23::DigitallySignedStruct,
57        ) -> Result<rustls23::client::danger::HandshakeSignatureValid, rustls23::Error> {
58            rustls23::crypto::verify_tls12_signature(message, cert, dss, &self.supported_algs)
59        }
60
61        fn verify_tls13_signature(
62            &self,
63            message: &[u8],
64            cert: &rustls23::pki_types::CertificateDer<'_>,
65            dss: &rustls23::DigitallySignedStruct,
66        ) -> Result<rustls23::client::danger::HandshakeSignatureValid, rustls23::Error> {
67            rustls23::crypto::verify_tls13_signature(message, cert, dss, &self.supported_algs)
68        }
69
70        fn supported_verify_schemes(&self) -> Vec<rustls23::SignatureScheme> {
71            self.supported_algs.supported_schemes()
72        }
73    }
74
75    pub use rustls23::pki_types::InvalidDnsNameError;
76    pub use rustls23::pki_types::ServerName;
77    pub use rustls23::server::NoClientAuth;
78    pub use rustls23::version::TLS13;
79    pub use rustls23::ClientConfig;
80    pub use rustls23::ClientConnection;
81    pub use rustls23::ConnectionCommon;
82    pub use rustls23::Error;
83    pub use rustls23::RootCertStore;
84    pub use rustls23::ServerConfig;
85    pub use rustls23::ServerConnection;
86
87    pub type Certificate = rustls23::pki_types::CertificateDer<'static>;
88    pub type PrivateKey = rustls23::pki_types::PrivateKeyDer<'static>;
89
90    pub mod pemfile {
91        pub use rustls_native_certs7::load_native_certs;
92        pub use rustls_pemfile2::certs;
93        pub use rustls_pemfile2::pkcs8_private_keys;
94        pub use rustls_pemfile2::private_key;
95
96        pub fn rootstore_ref_shim(cert: &super::Certificate) -> super::Certificate {
97            cert.clone()
98        }
99    }
100
101    pub trait CloneKeyShim {}
102
103    pub fn client_config_builder(
104    ) -> rustls23::ConfigBuilder<rustls23::ClientConfig, rustls23::WantsVerifier> {
105        ClientConfig::builder()
106    }
107
108    pub fn client_config_builder_with_protocol_versions(
109        versions: &[&'static rustls23::SupportedProtocolVersion],
110    ) -> rustls23::ConfigBuilder<rustls23::ClientConfig, rustls23::WantsVerifier> {
111        ClientConfig::builder_with_protocol_versions(versions)
112    }
113
114    pub fn server_config_builder(
115    ) -> rustls23::ConfigBuilder<rustls23::ServerConfig, rustls23::WantsVerifier> {
116        ServerConfig::builder()
117    }
118
119    pub fn server_config_builder_with_protocol_versions(
120        versions: &[&'static rustls23::SupportedProtocolVersion],
121    ) -> rustls23::ConfigBuilder<rustls23::ServerConfig, rustls23::WantsVerifier> {
122        ServerConfig::builder_with_protocol_versions(versions)
123    }
124}
125
126#[cfg(feature = "rustls22")]
127mod rustls22_shim {
128    pub use rustls22::server::NoClientAuth;
129    pub use rustls22::version::TLS13;
130    pub use rustls22::ClientConfig;
131    pub use rustls22::ClientConnection;
132    pub use rustls22::ConnectionCommon;
133    pub use rustls22::Error;
134    pub use rustls22::RootCertStore;
135    pub use rustls22::ServerConfig;
136    pub use rustls22::ServerConnection;
137    pub use rustls_pki_types::InvalidDnsNameError;
138    pub use rustls_pki_types::ServerName;
139
140    pub type Certificate = rustls_pki_types::CertificateDer<'static>;
141    pub type PrivateKey = rustls_pki_types::PrivateKeyDer<'static>;
142
143    pub mod pemfile {
144        pub use rustls_native_certs7::load_native_certs;
145        pub use rustls_pemfile2::certs;
146        pub use rustls_pemfile2::pkcs8_private_keys;
147        pub use rustls_pemfile2::private_key;
148
149        pub fn rootstore_ref_shim(cert: &super::Certificate) -> super::Certificate {
150            cert.clone()
151        }
152    }
153
154    pub trait CloneKeyShim {}
155
156    pub fn client_config_builder(
157    ) -> rustls22::ConfigBuilder<rustls22::ClientConfig, rustls22::WantsVerifier> {
158        ClientConfig::builder()
159    }
160
161    pub fn client_config_builder_with_protocol_versions(
162        versions: &[&'static rustls22::SupportedProtocolVersion],
163    ) -> rustls22::ConfigBuilder<rustls22::ClientConfig, rustls22::WantsVerifier> {
164        ClientConfig::builder_with_protocol_versions(versions)
165    }
166
167    pub fn server_config_builder(
168    ) -> rustls22::ConfigBuilder<rustls22::ServerConfig, rustls22::WantsVerifier> {
169        ServerConfig::builder()
170    }
171
172    pub fn server_config_builder_with_protocol_versions(
173        versions: &[&'static rustls22::SupportedProtocolVersion],
174    ) -> rustls22::ConfigBuilder<rustls22::ServerConfig, rustls22::WantsVerifier> {
175        ServerConfig::builder_with_protocol_versions(versions)
176    }
177}
178
179#[cfg(feature = "rustls21")]
180mod rustls21_shim {
181    pub use rustls21::client::InvalidDnsNameError;
182    pub use rustls21::client::ServerName;
183    pub use rustls21::server::NoClientAuth;
184    pub use rustls21::version::TLS13;
185    pub use rustls21::Certificate;
186    pub use rustls21::ClientConfig;
187    pub use rustls21::ClientConnection;
188    pub use rustls21::ConnectionCommon;
189    pub use rustls21::Error;
190    pub use rustls21::PrivateKey;
191    pub use rustls21::RootCertStore;
192    pub use rustls21::ServerConfig;
193    pub use rustls21::ServerConnection;
194
195    pub fn client_config_builder(
196    ) -> rustls21::ConfigBuilder<rustls21::ClientConfig, rustls21::WantsVerifier> {
197        ClientConfig::builder().with_safe_defaults()
198    }
199
200    pub fn server_config_builder(
201    ) -> rustls21::ConfigBuilder<rustls21::ServerConfig, rustls21::WantsVerifier> {
202        ServerConfig::builder().with_safe_defaults()
203    }
204
205    pub fn client_config_builder_with_protocol_versions(
206        versions: &[&'static rustls21::SupportedProtocolVersion],
207    ) -> rustls21::ConfigBuilder<rustls21::ClientConfig, rustls21::WantsVerifier> {
208        // Expect is ok here as this should never fail (not user controlled)
209        ClientConfig::builder()
210            .with_safe_default_cipher_suites()
211            .with_safe_default_kx_groups()
212            .with_protocol_versions(versions)
213            .expect("Could not set protocol versions")
214    }
215    pub fn server_config_builder_with_protocol_versions(
216        versions: &[&'static rustls21::SupportedProtocolVersion],
217    ) -> rustls21::ConfigBuilder<rustls21::ServerConfig, rustls21::WantsVerifier> {
218        // Expect is ok here as this should never fail (not user controlled)
219        ServerConfig::builder()
220            .with_safe_default_cipher_suites()
221            .with_safe_default_kx_groups()
222            .with_protocol_versions(versions)
223            .expect("Could not set protocol versions")
224    }
225
226    pub trait CloneKeyShim {
227        fn clone_key(&self) -> Self;
228    }
229
230    impl CloneKeyShim for PrivateKey {
231        fn clone_key(&self) -> Self {
232            self.clone()
233        }
234    }
235
236    pub mod pemfile {
237        enum Either<T, U> {
238            L(T),
239            R(U),
240        }
241        impl<T, U, V> Iterator for Either<T, U>
242        where
243            T: Iterator<Item = V>,
244            U: Iterator<Item = V>,
245        {
246            type Item = V;
247
248            fn next(&mut self) -> Option<Self::Item> {
249                match self {
250                    Self::L(l) => l.next(),
251                    Self::R(r) => r.next(),
252                }
253            }
254        }
255
256        pub fn certs(
257            rd: &mut dyn std::io::BufRead,
258        ) -> impl Iterator<Item = Result<super::Certificate, std::io::Error>> {
259            match rustls_pemfile1::certs(rd) {
260                Ok(v) => Either::L(v.into_iter().map(super::Certificate).map(Ok)),
261                Err(e) => Either::R(core::iter::once(Err(e))),
262            }
263        }
264
265        pub fn pkcs8_private_keys(
266            rd: &mut dyn std::io::BufRead,
267        ) -> impl Iterator<Item = Result<super::PrivateKey, std::io::Error>> {
268            match rustls_pemfile1::pkcs8_private_keys(rd) {
269                Ok(v) => Either::L(v.into_iter().map(super::PrivateKey).map(Ok)),
270                Err(e) => Either::R(core::iter::once(Err(e))),
271            }
272        }
273
274        pub fn private_key(
275            rd: &mut dyn std::io::BufRead,
276        ) -> Result<Option<super::PrivateKey>, std::io::Error> {
277            for item in std::iter::from_fn(|| rustls_pemfile1::read_one(rd).transpose()) {
278                match item {
279                    Ok(rustls_pemfile1::Item::RSAKey(key))
280                    | Ok(rustls_pemfile1::Item::PKCS8Key(key))
281                    | Ok(rustls_pemfile1::Item::ECKey(key)) => {
282                        return Ok(Some(super::PrivateKey(key)))
283                    }
284                    Err(e) => return Err(e),
285                    _ => {}
286                }
287            }
288
289            Ok(None)
290        }
291
292        pub fn load_native_certs() -> Result<Vec<super::Certificate>, std::io::Error> {
293            Ok(rustls_native_certs6::load_native_certs()?
294                .into_iter()
295                .map(|v| super::Certificate(v.0))
296                .collect())
297        }
298
299        pub fn rootstore_ref_shim(cert: &super::Certificate) -> &super::Certificate {
300            cert
301        }
302    }
303}
304
305#[cfg(feature = "rustls23")]
306pub use rustls23_shim::*;
307
308#[cfg(all(feature = "rustls22", not(feature = "rustls23")))]
309pub use rustls22_shim::*;
310
311#[cfg(all(
312    feature = "rustls21",
313    not(any(feature = "rustls23", feature = "rustls22"))
314))]
315pub use rustls21_shim::*;