use std::io;
use std::path::Path;
use crate::TlsError;
pub fn load_cert_chain(
path: &Path,
) -> Result<Vec<rustls::pki_types::CertificateDer<'static>>, TlsError> {
let bytes = std::fs::read(path).map_err(TlsError::CertLoad)?;
let mut reader = io::BufReader::new(bytes.as_slice());
rustls_pemfile::certs(&mut reader)
.collect::<Result<Vec<_>, _>>()
.map_err(|e| TlsError::CertLoad(io::Error::other(e)))
}
pub fn load_private_key(
path: &Path,
) -> Result<rustls::pki_types::PrivateKeyDer<'static>, TlsError> {
let bytes = std::fs::read(path)?;
let mut reader = io::BufReader::new(bytes.as_slice());
match rustls_pemfile::private_key(&mut reader) {
Ok(Some(key)) => Ok(key),
Ok(None) => Err(io::Error::new(
io::ErrorKind::InvalidData,
"no private key found in file",
)),
Err(e) => Err(io::Error::other(e)),
}
.map_err(TlsError::CertLoad)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn load_private_key_returns_error_when_no_key_present() {
let dir = tempfile::tempdir().unwrap();
let empty = dir.path().join("empty.key");
std::fs::write(&empty, b"# no key here\njust a comment\n").unwrap();
let err = load_private_key(&empty);
assert!(
matches!(err, Err(TlsError::CertLoad(_))),
"empty key file must yield CertLoad error, got {err:?}"
);
}
#[test]
fn load_private_key_parse_error_yields_cert_load_error() {
let dir = tempfile::tempdir().unwrap();
let garbage = dir.path().join("garbage.key");
std::fs::write(
&garbage,
b"-----BEGIN PRIVATE KEY-----\n!!!\n-----END PRIVATE KEY-----\n",
)
.unwrap();
let err = load_private_key(&garbage);
assert!(
matches!(err, Err(TlsError::CertLoad(_))),
"malformed base64 in a keyed section is a parse error (not 'no key \
found') and must yield CertLoad, got {err:?}"
);
}
#[test]
fn load_private_key_returns_error_when_file_missing() {
let err = load_private_key(Path::new("/nonexistent/alktls-coverage/missing.key"));
assert!(
matches!(err, Err(TlsError::CertLoad(_))),
"missing key file must yield CertLoad error, got {err:?}"
);
}
#[test]
fn load_cert_chain_returns_error_when_file_missing() {
let err = load_cert_chain(Path::new("/nonexistent/alktls-coverage/missing.pem"));
assert!(
matches!(err, Err(TlsError::CertLoad(_))),
"missing cert file must yield CertLoad error, got {err:?}"
);
}
}