hyper_rustls/
config.rs

1use rustls::client::WantsTransparencyPolicyOrClientCert;
2use rustls::{ClientConfig, ConfigBuilder, WantsVerifier};
3
4/// Methods for configuring roots
5///
6/// This adds methods (gated by crate features) for easily configuring
7/// TLS server roots a rustls ClientConfig will trust.
8pub trait ConfigBuilderExt {
9    /// This configures the platform's trusted certs, as implemented by
10    /// rustls-native-certs
11    #[cfg(feature = "rustls-native-certs")]
12    #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))]
13    fn with_native_roots(self) -> ConfigBuilder<ClientConfig, WantsTransparencyPolicyOrClientCert>;
14
15    /// This configures the webpki roots, which are Mozilla's set of
16    /// trusted roots as packaged by webpki-roots.
17    #[cfg(feature = "webpki-roots")]
18    #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))]
19    fn with_webpki_roots(self) -> ConfigBuilder<ClientConfig, WantsTransparencyPolicyOrClientCert>;
20}
21
22impl ConfigBuilderExt for ConfigBuilder<ClientConfig, WantsVerifier> {
23    #[cfg(feature = "rustls-native-certs")]
24    #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))]
25    #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
26    fn with_native_roots(self) -> ConfigBuilder<ClientConfig, WantsTransparencyPolicyOrClientCert> {
27        let mut roots = rustls::RootCertStore::empty();
28        let mut valid_count = 0;
29        let mut invalid_count = 0;
30
31        for cert in rustls_native_certs::load_native_certs().expect("could not load platform certs")
32        {
33            let cert = rustls::Certificate(cert.0);
34            match roots.add(&cert) {
35                Ok(_) => valid_count += 1,
36                Err(err) => {
37                    crate::log::trace!("invalid cert der {:?}", cert.0);
38                    crate::log::debug!("certificate parsing failed: {:?}", err);
39                    invalid_count += 1
40                }
41            }
42        }
43        crate::log::debug!(
44            "with_native_roots processed {} valid and {} invalid certs",
45            valid_count,
46            invalid_count
47        );
48        assert!(!roots.is_empty(), "no CA certificates found");
49
50        self.with_root_certificates(roots)
51    }
52
53    #[cfg(feature = "webpki-roots")]
54    #[cfg_attr(docsrs, doc(cfg(feature = "webpki-roots")))]
55    fn with_webpki_roots(self) -> ConfigBuilder<ClientConfig, WantsTransparencyPolicyOrClientCert> {
56        let mut roots = rustls::RootCertStore::empty();
57        roots.add_trust_anchors(
58            webpki_roots::TLS_SERVER_ROOTS
59                .iter()
60                .map(|ta| {
61                    rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
62                        ta.subject,
63                        ta.spki,
64                        ta.name_constraints,
65                    )
66                }),
67        );
68        self.with_root_certificates(roots)
69    }
70}