Skip to content

Commit

Permalink
Use PEM decoding from rustls-pki-types directly
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Oct 18, 2024
1 parent c44c331 commit 79dc22e
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 25 deletions.
14 changes: 2 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
34 changes: 25 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")))]
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
///
Expand Down Expand Up @@ -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),
}
}
}
Expand Down Expand Up @@ -333,6 +345,7 @@ impl StdError for Error {
Some(match &self.kind {
ErrorKind::Io { inner, .. } => inner,
ErrorKind::Os(err) => &**err,
ErrorKind::Pem(err) => err,
})
}
}
Expand All @@ -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),
}
}
}
Expand All @@ -355,6 +369,7 @@ impl fmt::Display for Error {
pub enum ErrorKind {
Io { inner: io::Error, path: PathBuf },
Os(Box<dyn StdError + Send + Sync + 'static>),
Pem(pem::Error),
}

const ENV_CERT_FILE: &str = "SSL_CERT_FILE";
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions tests/smoketests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 79dc22e

Please sign in to comment.