From f0726cc7a84bc7c34851fb17a5ab60b8ce155516 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 23 Apr 2024 17:33:10 -0600 Subject: [PATCH] der: add `Decode::from_ber` Support for decoding an input byte slice while specifying what encoding rules should be used with the given reader. --- der/src/decode.rs | 12 +++++++++++- der/src/reader/slice.rs | 12 ++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/der/src/decode.rs b/der/src/decode.rs index ccb487f52..4f856995c 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -1,6 +1,6 @@ //! Trait definition for [`Decode`]. -use crate::{Error, FixedTag, Header, Reader, SliceReader}; +use crate::{EncodingRules, Error, FixedTag, Header, Reader, SliceReader}; use core::marker::PhantomData; #[cfg(feature = "pem")] @@ -23,6 +23,16 @@ pub trait Decode<'a>: Sized + 'a { /// Attempt to decode this message using the provided decoder. fn decode>(decoder: &mut R) -> Result; + /// Parse `Self` from the provided BER-encoded byte slice. + /// + /// Note that most usages should probably use [`Decode::from_der`]. This method allows some + /// BER productions which are not allowed under DER. + fn from_ber(bytes: &'a [u8]) -> Result { + let mut reader = SliceReader::new_with_encoding_rules(bytes, EncodingRules::Ber)?; + let result = Self::decode(&mut reader)?; + Ok(reader.finish(result)?) + } + /// Parse `Self` from the provided DER-encoded byte slice. fn from_der(bytes: &'a [u8]) -> Result { let mut reader = SliceReader::new(bytes)?; diff --git a/der/src/reader/slice.rs b/der/src/reader/slice.rs index 30345daf5..a9e1cabe7 100644 --- a/der/src/reader/slice.rs +++ b/der/src/reader/slice.rs @@ -21,9 +21,17 @@ pub struct SliceReader<'a> { impl<'a> SliceReader<'a> { /// Create a new slice reader for the given byte slice. pub fn new(bytes: &'a [u8]) -> Result { + Self::new_with_encoding_rules(bytes, EncodingRules::default()) + } + + /// Create a new slice reader with the given encoding rules. + pub fn new_with_encoding_rules( + bytes: &'a [u8], + encoding_rules: EncodingRules, + ) -> Result { Ok(Self { bytes: BytesRef::new(bytes)?, - encoding_rules: EncodingRules::default(), + encoding_rules, failed: false, position: Length::ZERO, }) @@ -196,7 +204,7 @@ mod tests { assert_eq!( ErrorKind::TrailingData { decoded: 3u8.into(), - remaining: 1u8.into() + remaining: 1u8.into(), }, err.kind() );