diff --git a/Cargo.lock b/Cargo.lock index 7c19c2f..2a7583a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -686,7 +686,6 @@ dependencies = [ "openssl-probe", "ring", "rustls", - "rustls-pemfile", "rustls-pki-types", "rustls-webpki", "schannel", @@ -698,20 +697,11 @@ dependencies = [ "x509-parser", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" diff --git a/Cargo.toml b/Cargo.toml index 206e2ed..470d463 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,7 @@ repository = "https://github.com/rustls/rustls-native-certs" categories = ["network-programming", "cryptography"] [dependencies] -rustls-pemfile = "2" -pki-types = { package = "rustls-pki-types", version = "1" } +pki-types = { package = "rustls-pki-types", version = "1.10", features = ["std"] } [dev-dependencies] ring = "0.17" diff --git a/src/lib.rs b/src/lib.rs index acd460f..9d93770 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,11 +23,10 @@ use std::error::Error as StdError; use std::ffi::OsStr; -use std::fs::{self, File}; -use std::io::{self, BufReader}; use std::path::{Path, PathBuf}; -use std::{env, fmt}; +use std::{env, fmt, fs, io}; +use pki_types::pem::{self, PemObject}; use pki_types::CertificateDer; #[cfg(all(unix, not(target_os = "macos")))] @@ -155,6 +154,19 @@ impl CertificateResult { } } + fn pem_error(&mut self, err: pem::Error, path: &Path) { + self.errors.push(Error { + context: "failed to read PEM from file", + kind: match err { + pem::Error::Io(err) => ErrorKind::Io { + inner: err, + path: path.to_owned(), + }, + _ => ErrorKind::Pem(err), + }, + }); + } + fn io_error(&mut self, err: io::Error, path: &Path, context: &'static str) { self.errors.push(Error { context, @@ -194,7 +206,7 @@ impl CertPaths { /// /// If `self.file` is `Some`, it is always used, so it must be a path to an existing, /// accessible file from which certificates can be loaded successfully. While parsing, - /// the [rustls_pemfile::certs()] parser will ignore parts of the file which are + /// the rustls-pki-types PEM parser will ignore parts of the file which are /// not considered part of a certificate. Certificates which are not in the right /// format (PEM) or are otherwise corrupted may get ignored silently. /// @@ -277,18 +289,18 @@ fn load_pem_certs_from_dir(dir: &Path, out: &mut CertificateResult) { } fn load_pem_certs(path: &Path, out: &mut CertificateResult) { - let reader = match File::open(path) { - Ok(file) => BufReader::new(file), + let iter = match CertificateDer::pem_file_iter(path) { + Ok(iter) => iter, Err(err) => { - out.io_error(err, path, "failed to open file"); + out.pem_error(err, path); return; } }; - for result in rustls_pemfile::certs(&mut BufReader::new(reader)) { + for result in iter { match result { Ok(cert) => out.certs.push(cert), - Err(err) => out.io_error(err, path, "failed to parse PEM"), + Err(err) => out.pem_error(err, path), } } } @@ -333,6 +345,7 @@ impl StdError for Error { Some(match &self.kind { ErrorKind::Io { inner, .. } => inner, ErrorKind::Os(err) => &**err, + ErrorKind::Pem(err) => err, }) } } @@ -346,6 +359,7 @@ impl fmt::Display for Error { write!(f, "{inner} at '{}'", path.display()) } ErrorKind::Os(err) => err.fmt(f), + ErrorKind::Pem(err) => err.fmt(f), } } } @@ -355,6 +369,7 @@ impl fmt::Display for Error { pub enum ErrorKind { Io { inner: io::Error, path: PathBuf }, Os(Box), + Pem(pem::Error), } const ENV_CERT_FILE: &str = "SSL_CERT_FILE"; @@ -364,6 +379,7 @@ const ENV_CERT_DIR: &str = "SSL_CERT_DIR"; mod tests { use super::*; + use std::fs::File; #[cfg(unix)] use std::fs::Permissions; use std::io::Write; diff --git a/tests/smoketests.rs b/tests/smoketests.rs index 56a4794..f1d9f27 100644 --- a/tests/smoketests.rs +++ b/tests/smoketests.rs @@ -214,7 +214,7 @@ fn google_with_dir_but_broken_file() { let first_err = res.errors.first().unwrap().to_string(); dbg!(&first_err); - assert!(first_err.contains("open file")); + assert!(first_err.contains("from file")); assert!(first_err.contains("not-exist")); check_site_with_roots("google.com", res.certs).unwrap(); @@ -259,7 +259,7 @@ fn nothing_works_with_broken_file_and_dir() { let first_err = res.errors.first().unwrap().to_string(); dbg!(&first_err); - assert!(first_err.contains("open file")); + assert!(first_err.contains("from file")); assert!(first_err.contains("not-exist")); let second_err = res.errors.get(1).unwrap().to_string();