From a96eb355075e8d5e95bb42dd825afdde8a0f1016 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 23 Jul 2023 16:37:59 -0600 Subject: [PATCH] pkcs8: eagerly decode PEM labels 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()) }