use std::path::Path;
use rustls::RootCertStore;
use rustls_pki_types::{CertificateDer, pem::PemObject};
use crate::Error;
const ANCHOR_DIRECTORIES: [&str; 2] = [
"/apex/com.android.conscrypt/cacerts",
"/system/etc/security/cacerts",
];
pub fn system_roots() -> Result<RootCertStore, Error> {
let mut store = RootCertStore::empty();
for directory in ANCHOR_DIRECTORIES.map(Path::new) {
let Ok(entries) = std::fs::read_dir(directory) else {
continue;
};
for entry in entries {
let path = match entry {
Ok(entry) => entry.path(),
Err(error) => {
tracing::warn!(%error, directory = %directory.display(), "skipping an unreadable trust anchor entry");
continue;
}
};
match CertificateDer::from_pem_file(&path) {
Ok(anchor) => match store.add(anchor) {
Ok(()) => {}
Err(error) => {
tracing::warn!(%error, path = %path.display(), "skipping a trust anchor webpki rejects");
}
},
Err(error) => {
tracing::warn!(%error, path = %path.display(), "skipping an unreadable trust anchor");
}
}
}
}
if store.is_empty() {
return Err(Error::tls(format!(
"no system trust anchors could be read from {}",
ANCHOR_DIRECTORIES.join(" or ")
)));
}
tracing::debug!(
anchors = store.len(),
"loaded the Android system trust anchors"
);
Ok(store)
}