@@ -89,6 +89,43 @@ pub fn cert_is_valid_for_at_least(cert_der: &[u8], buffer_days: u16) -> bool {
8989 is_valid_for_at_least ( cert_der, i64:: from ( buffer_days) ) . is_some ( )
9090}
9191
92+ /// Mozilla's webpki roots as a lazily-initialized [`rustls::RootCertStore`].
93+ ///
94+ /// In some places where we must trust Mozilla's webpki roots, we add the trust
95+ /// anchors manually to avoid enabling reqwest's `rustls-tls-webpki-roots`
96+ /// feature, which propagates to other crates via feature unification.
97+ ///
98+ /// It's safer to add the Mozilla roots manually than to have to remember to set
99+ /// `.tls_built_in_root_certs(false)` in every [`reqwest`] client builder.
100+ ///
101+ /// # Example
102+ ///
103+ /// ```
104+ /// # use std::time::Duration;
105+ /// # use anyhow::Context;
106+ /// use lexe_api::tls;
107+ ///
108+ /// fn build_reqwest_client() -> anyhow::Result<reqwest::Client> {
109+ /// let tls_config = tls::client_config_builder()
110+ /// .with_root_certificates(tls::WEBPKI_ROOT_CERTS.clone())
111+ /// .with_no_client_auth();
112+ ///
113+ /// let client = reqwest::ClientBuilder::new()
114+ /// .https_only(true)
115+ /// .use_preconfigured_tls(tls_config)
116+ /// .timeout(Duration::from_secs(10))
117+ /// .build()
118+ /// .context("reqwest::ClientBuilder::build failed")?;
119+ ///
120+ /// Ok(client)
121+ /// }
122+ /// ```
123+ pub static WEBPKI_ROOT_CERTS : LazyLock < Arc < rustls:: RootCertStore > > =
124+ LazyLock :: new ( || {
125+ let roots = webpki_roots:: TLS_SERVER_ROOTS . to_vec ( ) ;
126+ Arc :: new ( rustls:: RootCertStore { roots } )
127+ } ) ;
128+
92129/// Our [`rustls::crypto::CryptoProvider`].
93130/// Use this instead of [`rustls::crypto::ring::default_provider`].
94131pub static LEXE_CRYPTO_PROVIDER : LazyLock < Arc < rustls:: crypto:: CryptoProvider > > =
0 commit comments