openssl_probe/
lib.rs

1use std::env;
2use std::fs;
3use std::path::PathBuf;
4
5pub struct ProbeResult {
6    pub cert_file: Option<PathBuf>,
7    pub cert_dir: Option<PathBuf>,
8}
9
10/// Probe the system for the directory in which CA certificates should likely be
11/// found.
12///
13/// This will only search known system locations.
14pub fn find_certs_dirs() -> Vec<PathBuf> {
15    // see http://gagravarr.org/writing/openssl-certs/others.shtml
16    [
17        "/var/ssl",
18        "/usr/share/ssl",
19        "/usr/local/ssl",
20        "/usr/local/openssl",
21        "/usr/local/share",
22        "/usr/lib/ssl",
23        "/usr/ssl",
24        "/etc/openssl",
25        "/etc/pki/ca-trust/extracted/pem",
26        "/etc/pki/tls",
27        "/etc/ssl",
28        "/data/data/com.termux/files/usr/etc/tls",
29        "/boot/system/data/ssl",
30    ].iter().map(|s| PathBuf::from(*s)).filter(|p| {
31        fs::metadata(p).is_ok()
32    }).collect()
33}
34
35pub fn init_ssl_cert_env_vars() {
36    let ProbeResult { cert_file, cert_dir } = probe();
37    match cert_file {
38        Some(path) => put("SSL_CERT_FILE", path),
39        None => {}
40    }
41    match cert_dir {
42        Some(path) => put("SSL_CERT_DIR", path),
43        None => {}
44    }
45
46    fn put(var: &str, path: PathBuf) {
47        // Don't stomp over what anyone else has set
48        match env::var(var) {
49            Ok(..) => {}
50            Err(..) => env::set_var(var, &path),
51        }
52    }
53}
54
55pub fn probe() -> ProbeResult {
56    let mut result = ProbeResult {
57        cert_file: env::var_os("SSL_CERT_FILE").map(PathBuf::from),
58        cert_dir: env::var_os("SSL_CERT_DIR").map(PathBuf::from),
59    };
60    for certs_dir in find_certs_dirs().iter() {
61        // cert.pem looks to be an openssl 1.0.1 thing, while
62        // certs/ca-certificates.crt appears to be a 0.9.8 thing
63        for cert in [
64            "cert.pem",
65            "certs.pem",
66            "certs/ca-certificates.crt",
67            "certs/ca-root-nss.crt",
68            "certs/ca-bundle.crt",
69            "CARootCertificates.pem",
70            "tls-ca-bundle.pem",
71        ].iter() {
72            try(&mut result.cert_file, certs_dir.join(cert));
73        }
74        try(&mut result.cert_dir, certs_dir.join("certs"));
75    }
76    result
77}
78
79fn try(dst: &mut Option<PathBuf>, val: PathBuf) {
80    if dst.is_none() && fs::metadata(&val).is_ok() {
81        *dst = Some(val);
82    }
83}