1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use std::fs::OpenOptions;

use std::sync::Arc;

use ::rustls::ClientConfig as TlsClientConfig;
use ::rustls::RootCertStore;
use ::tokio_rustls::TlsConnector;

use crate::AnyError;

#[derive(Debug, Clone, ::structopt::StructOpt)]
pub struct CARootsConfig {
    #[structopt(long = "add-ca-roots", env = "ADD_CA_ROOTS")]
    pub files: Vec<String>,
}

impl CARootsConfig {
    pub fn create_tls_connector(&self) -> Result<TlsConnector, AnyError> {
        let mut root_cert_store = RootCertStore::empty();
        for ca_roots_file in &self.files {
            let ca_roots_fd = OpenOptions::new().read(true).open(ca_roots_file)?;
            let (roots_added, roots_ignored) = root_cert_store
                .add_pem_file(&mut std::io::BufReader::new(ca_roots_fd))
                .expect("Failed to add CA-roots");
            log::debug!(
                "CA-roots [added: {}; ignored: {}]",
                roots_added,
                roots_ignored
            );
        }

        let mut client_config = TlsClientConfig::default();
        client_config.root_store = root_cert_store;
        let client_config = Arc::new(client_config);
        let tls_connector = TlsConnector::from(client_config);

        Ok(tls_connector)
    }
}