Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openssl-sys: Provide information about the default certificate paths #2260

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions openssl-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ edition = "2018"
[features]
vendored = ['openssl-src']
unstable_boringssl = ['bssl-sys']
probe = []

[dependencies]
libc = "0.2"
Expand Down
8 changes: 8 additions & 0 deletions openssl-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ mod boringssl {
#[cfg(all(boringssl, not(feature = "unstable_boringssl")))]
pub use boringssl::*;

#[cfg(all(feature = "probe", feature = "vendored"))]
#[path = "probe_vendored.rs"]
pub mod probe;

#[cfg(all(feature = "probe", not(feature = "vendored")))]
#[path = "probe_system.rs"]
pub mod probe;

#[cfg(openssl)]
#[path = "."]
mod openssl {
Expand Down
49 changes: 49 additions & 0 deletions openssl-sys/src/probe_system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::path::{Path, PathBuf};
use std::ffi::{CStr, OsStr};
use std::os::unix::ffi::{OsStrExt, OsStringExt};

#[cfg(unix)]
fn cstr_to_path(p: &CStr) -> Option<&Path> {
Some(Path::new(OsStr::from_bytes(p.to_bytes())))
}

#[cfg(not(unix))]
fn cstr_to_path(p: &CStr) -> Option<&Path> {
p.to_str().ok().map(Path::new)
}

fn system_cert_file() -> Option<&'static Path> {
let c_path: &'static CStr = unsafe {
let p = crate::X509_get_default_cert_file();
CStr::from_ptr(p)
};
cstr_to_path(c_path)
}

fn system_cert_dir() -> Option<&'static Path> {
let c_path: &'static CStr = unsafe {
let p = crate::X509_get_default_cert_dir();
CStr::from_ptr(p)
};
cstr_to_path(c_path)
}

/// Return the directories in which CA certificates should likely be found.
pub fn default_certs_dirs() -> Vec<PathBuf> {
let Some(p) = system_cert_dir() else {
return vec![];
};
vec![p.to_path_buf()]
}

/// Return the path to the file containing the default system CA certificates.
/// Any configuration provided via environment variables is ignored.
pub fn default_cert_file() -> Option<PathBuf> {
Some(system_cert_file()?.to_path_buf())
}

/// Return the path to the directory containing the default system CA certificates.
/// Any configuration provided via environment variables is ignored.
pub fn default_cert_dir() -> Option<PathBuf> {
Some(system_cert_file()?.join("certs"))
}
74 changes: 74 additions & 0 deletions openssl-sys/src/probe_vendored.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::path::{Path, PathBuf};

// see http://gagravarr.org/writing/openssl-certs/others.shtml
static CERT_DIRS: &[&str] = &[
"/var/ssl",
"/usr/share/ssl",
"/usr/local/ssl",
"/usr/local/openssl",
"/usr/local/etc/openssl",
"/usr/local/share",
"/usr/lib/ssl",
"/usr/ssl",
"/etc/openssl",
"/etc/pki/ca-trust/extracted/pem",
"/etc/pki/tls",
"/etc/ssl",
"/etc/certs",
"/opt/etc/ssl", // Entware
"/data/data/com.termux/files/usr/etc/tls",
"/boot/system/data/ssl",
];

/// Return the directories in which CA certificates should likely be found.
pub fn default_certs_dirs() -> Vec<PathBuf> {
CERT_DIRS.iter().filter_map(|p| {
let p: &Path = p.as_ref();
if p.exists() {
Some(p.to_path_buf())
} else {
None
}
}).collect()
}

/// Return the path to the file containing the default system CA certificates.
/// Any configuration provided via environment variables is ignored.
pub fn default_cert_file() -> Option<PathBuf> {
for certs_dir in CERT_DIRS.iter() {
// cert.pem looks to be an openssl 1.0.1 thing, while
// certs/ca-certificates.crt appears to be a 0.9.8 thing
let certs_dir: &'static Path = certs_dir.as_ref();
for cert_filename in [
"cert.pem",
"certs.pem",
"ca-bundle.pem",
"cacert.pem",
"ca-certificates.crt",
"certs/ca-certificates.crt",
"certs/ca-root-nss.crt",
"certs/ca-bundle.crt",
"CARootCertificates.pem",
"tls-ca-bundle.pem",
].iter() {
let cert_file = certs_dir.join(cert_filename);
if cert_file.exists() {
return Some(cert_file);
}
}
}
None
}

/// Return the path to the directory containing the default system CA certificates.
/// Any configuration provided via environment variables is ignored.
pub fn default_cert_dir() -> Option<PathBuf> {
for certs_dir in CERT_DIRS.iter() {
let certs_dir: &'static Path = certs_dir.as_ref();
let cert_dir = certs_dir.join("certs");
if cert_dir.exists() {
return Some(cert_dir);
}
}
None
}
Loading