From 47a73cc282b79768dae045d89851d409e0b5b76c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 23 Jul 2023 17:01:56 -0600 Subject: [PATCH] pkcs8: eagerly decode PEM labels (#1163) This should give better errors for invalid PEM type labels even if there are subsequent Base64 processing errors, which might occur if e.g. Base64 is wrapped at a nonstandard width. Notably such errors will include the expected PEM type label. --- pem-rfc7468/src/error.rs | 8 ++++++-- pkcs8/src/traits.rs | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/pem-rfc7468/src/error.rs b/pem-rfc7468/src/error.rs index 6a93465b5..61da64776 100644 --- a/pem-rfc7468/src/error.rs +++ b/pem-rfc7468/src/error.rs @@ -45,7 +45,7 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { + match *self { Error::Base64(err) => write!(f, "PEM Base64 error: {}", err), Error::CharacterEncoding => f.write_str("PEM character encoding error"), Error::EncapsulatedText => f.write_str("PEM error in encapsulated text"), @@ -60,7 +60,11 @@ impl fmt::Display for Error { f.write_str("PEM error in post-encapsulation boundary") } Error::UnexpectedTypeLabel { expected } => { - write!(f, "unexpected PEM type label: expecting \"{}\"", expected) + write!( + f, + "unexpected PEM type label: expecting \"BEGIN {}\"", + expected + ) } } } diff --git a/pkcs8/src/traits.rs b/pkcs8/src/traits.rs index b4f80b2e7..f6165f696 100644 --- a/pkcs8/src/traits.rs +++ b/pkcs8/src/traits.rs @@ -12,10 +12,14 @@ use { }; #[cfg(feature = "pem")] -use {crate::LineEnding, alloc::string::String, der::zeroize::Zeroizing}; - -#[cfg(feature = "pem")] -use der::pem::PemLabel; +use { + crate::LineEnding, + alloc::string::String, + der::{ + pem::{self, PemLabel}, + zeroize::Zeroizing, + }, +}; #[cfg(feature = "std")] use std::path::Path; @@ -43,8 +47,11 @@ pub trait DecodePrivateKey: Sized { /// ``` #[cfg(feature = "pem")] fn from_pkcs8_pem(s: &str) -> Result { - let (label, doc) = SecretDocument::from_pem(s)?; + // Validate PEM label + let label = pem::decode_label(s.as_bytes())?; PrivateKeyInfo::validate_pem_label(label)?; + + let doc = SecretDocument::from_pem(s)?.1; Self::from_pkcs8_der(doc.as_bytes()) }