From 0b029a23475a44511eef280276d0ecae1bc43b7a Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Tue, 6 May 2025 15:00:47 +0200 Subject: [PATCH 1/7] der: add indefinite length demo cargo fmt --- der/src/length.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/der/src/length.rs b/der/src/length.rs index d1a2b16da..6b6f2143f 100644 --- a/der/src/length.rs +++ b/der/src/length.rs @@ -1,6 +1,9 @@ //! Length calculations for encoded ASN.1 DER values -use crate::{Decode, DerOrd, Encode, Error, ErrorKind, Reader, Result, SliceWriter, Tag, Writer}; +use crate::{ + Decode, DerOrd, Encode, EncodingRules, Error, ErrorKind, Reader, Result, SliceWriter, Tag, + Writer, +}; use core::{ cmp::Ordering, fmt, @@ -25,8 +28,8 @@ impl Length { /// Length of `1` pub const ONE: Self = Self(1); - /// Maximum length (`u32::MAX`). - pub const MAX: Self = Self(u32::MAX); + /// Maximum length (`u32::MAX` - 1). + pub const MAX: Self = Self(u32::MAX - 1); /// Maximum number of octets in a DER encoding of a [`Length`] using the /// rules implemented by this crate. @@ -44,7 +47,7 @@ impl Length { /// This function is const-safe and therefore useful for [`Length`] constants. #[allow(clippy::cast_possible_truncation)] pub(crate) const fn new_usize(len: usize) -> Result { - if len > (u32::MAX as usize) { + if len > (u32::MAX as usize) - 1 { Err(Error::from_kind(ErrorKind::Overflow)) } else { Ok(Length(len as u32)) @@ -57,6 +60,12 @@ impl Length { value == 0 } + /// Is this length indefinite? + pub const fn is_indefinite(self) -> bool { + let value = self.0; + value == u32::MAX + } + /// Get the length of DER Tag-Length-Value (TLV) encoded data if `self` /// is the length of the inner "value" portion of the message. pub fn for_tlv(self, tag: Tag) -> Result { @@ -90,7 +99,7 @@ impl Length { 0x80..=0xFF => Some(0x81), 0x100..=0xFFFF => Some(0x82), 0x10000..=0xFFFFFF => Some(0x83), - 0x1000000..=0xFFFFFFFF => Some(0x84), + 0x1000000..=0xFFFFFFFE => Some(0x84), _ => None, } } @@ -214,6 +223,9 @@ impl<'a> Decode<'a> for Length { // Note: per X.690 Section 8.1.3.6.1 the byte 0x80 encodes indefinite // lengths, which are not allowed in DER, so disallow that byte. len if len < INDEFINITE_LENGTH_OCTET => Ok(len.into()), + INDEFINITE_LENGTH_OCTET if reader.encoding_rules() == EncodingRules::Ber => { + Ok(Self(u32::MAX)) + } INDEFINITE_LENGTH_OCTET => Err(ErrorKind::IndefiniteLength.into()), // 1-4 byte variable-sized length prefix tag @ 0x81..=0x84 => { From 47a1cd9d1110ead388b032318b42c4a0a1315f2a Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Mon, 12 May 2025 19:11:35 +0200 Subject: [PATCH 2/7] der: add indefinite length as `u32::MAX` --- der/src/header.rs | 6 ++--- der/src/length.rs | 60 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/der/src/header.rs b/der/src/header.rs index 0964174ff..42f5b984d 100644 --- a/der/src/header.rs +++ b/der/src/header.rs @@ -103,7 +103,7 @@ mod tests { #[test] fn peek_max_header() { - const MAX_HEADER: [u8; 11] = hex!("BF8FFFFFFF7F 84FFFFFFFF"); + const MAX_HEADER: [u8; 11] = hex!("BF8FFFFFFF7F 84FFFFFFFE"); let reader = SliceReader::new(&MAX_HEADER).expect("slice to be valid length"); let header = Header::peek(&reader).expect("peeked tag"); @@ -116,14 +116,14 @@ mod tests { ); assert_eq!( header.length, - Length::new_usize(0xFFFFFFFF).expect("u32 to fit") + Length::new_usize(0xFFFFFFFE).expect("u32 to fit") ); assert_eq!(header.encoded_len(), Ok(Length::new(11))); assert_eq!(reader.position(), Length::ZERO); // Position unchanged } #[test] fn negative_peek_overlength_header() { - const MAX_HEADER: [u8; 12] = hex!("BF8FFFFFFFFF7F 84FFFFFFFF"); + const MAX_HEADER: [u8; 12] = hex!("BF8FFFFFFFFF7F 84FFFFFFFE"); let reader = SliceReader::new(&MAX_HEADER).expect("slice to be valid length"); // Should not decode Header::peek(&reader).expect_err("overlength error"); diff --git a/der/src/length.rs b/der/src/length.rs index 6b6f2143f..a60a62cfd 100644 --- a/der/src/length.rs +++ b/der/src/length.rs @@ -10,6 +10,9 @@ use core::{ ops::{Add, Sub}, }; +/// Maximum length as a `u32`. +const MAX_U32: u32 = u32::MAX - 1; + /// Octet identifying an indefinite length as described in X.690 Section /// 8.1.3.6.1: /// @@ -29,7 +32,7 @@ impl Length { pub const ONE: Self = Self(1); /// Maximum length (`u32::MAX` - 1). - pub const MAX: Self = Self(u32::MAX - 1); + pub const MAX: Self = Self(MAX_U32); /// Maximum number of octets in a DER encoding of a [`Length`] using the /// rules implemented by this crate. @@ -47,7 +50,7 @@ impl Length { /// This function is const-safe and therefore useful for [`Length`] constants. #[allow(clippy::cast_possible_truncation)] pub(crate) const fn new_usize(len: usize) -> Result { - if len > (u32::MAX as usize) - 1 { + if len > Self::MAX.0 as usize { Err(Error::from_kind(ErrorKind::Overflow)) } else { Ok(Length(len as u32)) @@ -74,7 +77,12 @@ impl Length { /// Perform saturating addition of two lengths. pub fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) + let sum = self.0.saturating_add(rhs.0); + if sum < Self::MAX.0 { + Self(sum) + } else { + Self::MAX + } } /// Perform saturating subtraction of two lengths. @@ -99,7 +107,7 @@ impl Length { 0x80..=0xFF => Some(0x81), 0x100..=0xFFFF => Some(0x82), 0x10000..=0xFFFFFF => Some(0x83), - 0x1000000..=0xFFFFFFFE => Some(0x84), + 0x1000000..=MAX_U32 => Some(0x84), _ => None, } } @@ -112,7 +120,7 @@ impl Add for Length { self.0 .checked_add(other.0) .ok_or_else(|| ErrorKind::Overflow.into()) - .map(Self) + .and_then(TryInto::try_into) } } @@ -136,7 +144,7 @@ impl Add for Length { type Output = Result; fn add(self, other: u32) -> Result { - self + Length::from(other) + self + Length::try_from(other)? } } @@ -187,9 +195,21 @@ impl From for Length { } } -impl From for Length { - fn from(len: u32) -> Length { - Length(len) +// impl From for Length { +// fn from(len: u32) -> Length { +// Length(len) +// } +// } + +impl TryFrom for Length { + type Error = Error; + + fn try_from(len: u32) -> Result { + if len <= Self::MAX.0 { + Ok(Length(len)) + } else { + Err(ErrorKind::Overflow.into()) + } } } @@ -238,7 +258,7 @@ impl<'a> Decode<'a> for Length { | u32::from(reader.read_byte()?); } - let length = Length::from(decoded_len); + let length = Length::try_from(decoded_len)?; // X.690 Section 10.1: DER lengths must be encoded with a minimum // number of octets @@ -312,7 +332,7 @@ impl fmt::Display for Length { #[cfg(feature = "arbitrary")] impl<'a> arbitrary::Arbitrary<'a> for Length { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - Ok(Self(u.arbitrary()?)) + Ok(Self(u.int_in_range(0..=MAX_U32)?)) } fn size_hint(depth: usize) -> (usize, Option) { @@ -349,12 +369,16 @@ mod tests { ); assert_eq!( - Length::from(0x10000u32), + Length::try_from(0x10000u32).unwrap(), Length::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap() ); assert_eq!( - Length::from(0xFFFFFFFFu32), - Length::from_der(&[0x84, 0xFF, 0xFF, 0xFF, 0xFF]).unwrap() + Length::try_from(0xFFFFFFFEu32).unwrap(), + Length::from_der(&[0x84, 0xFF, 0xFF, 0xFF, 0xFE]).unwrap() + ); + assert_eq!( + Length::from_der(&[0x84, 0xFF, 0xFF, 0xFF, 0xFF]), + Err(ErrorKind::Overflow.into()) ); } @@ -386,13 +410,15 @@ mod tests { assert_eq!( &[0x83, 0x01, 0x00, 0x00], - Length::from(0x10000u32) + Length::try_from(0x10000u32) + .unwrap() .encode_to_slice(&mut buffer) .unwrap() ); assert_eq!( - &[0x84, 0xFF, 0xFF, 0xFF, 0xFF], - Length::from(0xFFFFFFFFu32) + &[0x84, 0xFF, 0xFF, 0xFF, 0xFE], + Length::try_from(0xFFFFFFFEu32) + .unwrap() .encode_to_slice(&mut buffer) .unwrap() ); From 09699d35c4f71bfa00a187f6fc5e7aed716b32b8 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Mon, 12 May 2025 19:15:38 +0200 Subject: [PATCH 3/7] der: cleanup --- der/src/length.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/der/src/length.rs b/der/src/length.rs index a60a62cfd..6956f89c1 100644 --- a/der/src/length.rs +++ b/der/src/length.rs @@ -195,12 +195,6 @@ impl From for Length { } } -// impl From for Length { -// fn from(len: u32) -> Length { -// Length(len) -// } -// } - impl TryFrom for Length { type Error = Error; From c8ef18f9eeb21eff56734b43364920691f0cc1cc Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Mon, 12 May 2025 19:26:36 +0200 Subject: [PATCH 4/7] der: add `self.is_indefinite()` checks --- der/src/length.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/der/src/length.rs b/der/src/length.rs index 6956f89c1..812e82b79 100644 --- a/der/src/length.rs +++ b/der/src/length.rs @@ -34,6 +34,9 @@ impl Length { /// Maximum length (`u32::MAX` - 1). pub const MAX: Self = Self(MAX_U32); + /// Indefinite length (encoded as `0x80`). + pub const INDEFINITE: Self = Self(u32::MAX); + /// Maximum number of octets in a DER encoding of a [`Length`] using the /// rules implemented by this crate. pub(crate) const MAX_SIZE: usize = 5; @@ -77,6 +80,9 @@ impl Length { /// Perform saturating addition of two lengths. pub fn saturating_add(self, rhs: Self) -> Self { + if self.is_indefinite() || rhs.is_indefinite() { + return Self::INDEFINITE; + } let sum = self.0.saturating_add(rhs.0); if sum < Self::MAX.0 { Self(sum) @@ -87,6 +93,9 @@ impl Length { /// Perform saturating subtraction of two lengths. pub fn saturating_sub(self, rhs: Self) -> Self { + if self.is_indefinite() || rhs.is_indefinite() { + return Self::INDEFINITE; + } Self(self.0.saturating_sub(rhs.0)) } @@ -117,6 +126,9 @@ impl Add for Length { type Output = Result; fn add(self, other: Self) -> Result { + if self.is_indefinite() || other.is_indefinite() { + return Ok(Self::INDEFINITE); + } self.0 .checked_add(other.0) .ok_or_else(|| ErrorKind::Overflow.into()) @@ -238,7 +250,7 @@ impl<'a> Decode<'a> for Length { // lengths, which are not allowed in DER, so disallow that byte. len if len < INDEFINITE_LENGTH_OCTET => Ok(len.into()), INDEFINITE_LENGTH_OCTET if reader.encoding_rules() == EncodingRules::Ber => { - Ok(Self(u32::MAX)) + Ok(Self::INDEFINITE) } INDEFINITE_LENGTH_OCTET => Err(ErrorKind::IndefiniteLength.into()), // 1-4 byte variable-sized length prefix @@ -277,11 +289,15 @@ impl Encode for Length { 0x80..=0xFF => Ok(Length(2)), 0x100..=0xFFFF => Ok(Length(3)), 0x10000..=0xFFFFFF => Ok(Length(4)), - 0x1000000..=0xFFFFFFFF => Ok(Length(5)), + 0x1000000..=MAX_U32 => Ok(Length(5)), + u32::MAX => Ok(Length(1)), } } fn encode(&self, writer: &mut impl Writer) -> Result<()> { + if self.is_indefinite() { + return Err(ErrorKind::IndefiniteLength.into()); + } match self.initial_octet() { Some(tag_byte) => { writer.write_byte(tag_byte)?; From e6c6f5bc3666f97b2b73081632c64db9d12be6a0 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Mon, 12 May 2025 21:10:02 +0200 Subject: [PATCH 5/7] der: BER decoding using fn `DecodeValue::decode_nested_value` --- der/src/asn1/any.rs | 4 +- der/src/decode.rs | 38 +++++++++++- der/src/length.rs | 10 ++- der/src/reader.rs | 37 ++++++++++++ der/src/reader/pem.rs | 5 ++ der/src/reader/slice.rs | 4 ++ der/tests/ber.rs | 131 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 223 insertions(+), 6 deletions(-) create mode 100644 der/tests/ber.rs diff --git a/der/src/asn1/any.rs b/der/src/asn1/any.rs index 69ac854bf..2935a1e30 100644 --- a/der/src/asn1/any.rs +++ b/der/src/asn1/any.rs @@ -106,7 +106,7 @@ impl<'a> Decode<'a> for AnyRef<'a> { fn decode>(reader: &mut R) -> Result, Error> { let header = Header::decode(reader)?; - Self::decode_value(reader, header) + Self::decode_nested_value(reader, header) } } @@ -254,7 +254,7 @@ mod allocating { fn decode>(reader: &mut R) -> Result { let header = Header::decode(reader)?; - Self::decode_value(reader, header) + Self::decode_nested_value(reader, header) } } diff --git a/der/src/decode.rs b/der/src/decode.rs index 59e4a51d1..f01edcd1d 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -63,7 +63,7 @@ where fn decode>(reader: &mut R) -> Result>::Error> { let header = Header::decode(reader)?; header.tag.assert_eq(T::TAG)?; - T::decode_value(reader, header) + T::decode_nested_value(reader, header) } } @@ -119,6 +119,42 @@ pub trait DecodeValue<'a>: Sized { /// Attempt to decode this message using the provided [`Reader`]. fn decode_value>(reader: &mut R, header: Header) -> Result; + + /// Attempt to decode this nested message using the provided [`Reader`]. + /// + /// When indefinite length occurs, trailing '00 00' bytes are eaten. + fn decode_nested_value>( + reader: &mut R, + header: Header, + ) -> Result { + let fixed_header = swap_header_if_indefinite(reader, header)?; + + // Now expected length is known + let result = reader.read_nested(fixed_header.length, |reader| { + Self::decode_value(reader, fixed_header) + }); + if header.length.is_indefinite() { + reader.read_end_of_contents()?; + } + result + } +} + +/// Returns valid length if indefinite length was given. +/// +/// [`Reader`] must support peeking the remaining bytes. +fn swap_header_if_indefinite<'a, R: Reader<'a>>( + reader: &mut R, + header: Header, +) -> Result { + if header.length.is_indefinite() { + Ok(Header { + tag: header.tag, + length: reader.peek_indefinite_length()?, + }) + } else { + Ok(header) + } } #[cfg(feature = "alloc")] diff --git a/der/src/length.rs b/der/src/length.rs index 812e82b79..f5a198976 100644 --- a/der/src/length.rs +++ b/der/src/length.rs @@ -220,8 +220,8 @@ impl TryFrom for Length { } impl From for u32 { - fn from(length: Length) -> u32 { - length.0 + fn from(len: Length) -> u32 { + if len == Length::INDEFINITE { 0 } else { len.0 } } } @@ -237,7 +237,11 @@ impl TryFrom for usize { type Error = Error; fn try_from(len: Length) -> Result { - len.0.try_into().map_err(|_| ErrorKind::Overflow.into()) + if len == Length::INDEFINITE { + Ok(0) + } else { + len.0.try_into().map_err(|_| ErrorKind::Overflow.into()) + } } } diff --git a/der/src/reader.rs b/der/src/reader.rs index 6941cf6a9..91678a393 100644 --- a/der/src/reader.rs +++ b/der/src/reader.rs @@ -12,6 +12,11 @@ use crate::{ #[cfg(feature = "alloc")] use alloc::vec::Vec; +/// End of contents length +const EOC_LENGTH: Length = Length::new(2); +/// End of contents +const EOC_BYTES: [u8; 2] = [0x00, 0x00]; + /// Reader trait which reads DER-encoded input. pub trait Reader<'r>: Sized { /// Get the [`EncodingRules`] which should be applied when decoding the input. @@ -121,6 +126,9 @@ pub trait Reader<'r>: Sized { Tag::peek(self) } + /// Attempt to peek remaining bytes. + fn peek_remaining(&mut self) -> Result<&'r [u8], Error>; + /// Read a single byte. fn read_byte(&mut self) -> Result { let mut buf = [0]; @@ -172,4 +180,33 @@ pub trait Reader<'r>: Sized { let header_len = header.encoded_len()?; self.read_slice((header_len + header.length)?) } + + /// Returns length of current indefinite segment + fn peek_indefinite_length(&mut self) -> Result { + let remaining_len = self.remaining_len(); + + let slice = self.peek_remaining()?; + if remaining_len < EOC_LENGTH { + return Err(ErrorKind::Incomplete { + expected_len: EOC_LENGTH, + actual_len: remaining_len, + } + .into()); + } + let content_len = (remaining_len - EOC_LENGTH)?; + let content_usize = usize::try_from(content_len)?; + if &slice[content_usize..] != &EOC_BYTES { + return Err(ErrorKind::IndefiniteLength.into()); + } + Ok(content_len) + } + /// Reads 2 end-of-contents bytes [0x00, 0x00] + fn read_end_of_contents(&mut self) -> Result<(), Error> { + let mut eoc_buf = [0u8; 2]; + self.read_into(&mut eoc_buf)?; + if eoc_buf != EOC_BYTES { + return Err(ErrorKind::IndefiniteLength.into()); + } + Ok(()) + } } diff --git a/der/src/reader/pem.rs b/der/src/reader/pem.rs index cfbe89e46..16770a538 100644 --- a/der/src/reader/pem.rs +++ b/der/src/reader/pem.rs @@ -100,4 +100,9 @@ impl<'i> Reader<'i> for PemReader<'i> { self.position = new_position; Ok(buf) } + + fn peek_remaining(&mut self) -> Result<&'i [u8], Error> { + // Can't borrow from PEM because it requires decoding + Err(ErrorKind::Reader.into()) + } } diff --git a/der/src/reader/slice.rs b/der/src/reader/slice.rs index 6df3f58a3..e93f85cd5 100644 --- a/der/src/reader/slice.rs +++ b/der/src/reader/slice.rs @@ -162,6 +162,10 @@ impl<'a> Reader<'a> for SliceReader<'a> { debug_assert!(self.position <= self.input_len()); self.input_len().saturating_sub(self.position) } + + fn peek_remaining(&mut self) -> Result<&'a [u8], Error> { + self.remaining() + } } #[cfg(test)] diff --git a/der/tests/ber.rs b/der/tests/ber.rs new file mode 100644 index 000000000..154d04700 --- /dev/null +++ b/der/tests/ber.rs @@ -0,0 +1,131 @@ +//! PEM decoding and encoding tests. +#![cfg(all(feature = "derive", feature = "oid", feature = "alloc"))] + +use const_oid::ObjectIdentifier; +use der::{Any, Decode, Sequence, asn1::BitString}; +use hex_literal::hex; + +/// X.509 `AlgorithmIdentifier` +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] +pub struct AlgorithmIdentifier { + pub algorithm: ObjectIdentifier, + pub parameters: Option, +} + +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] +pub struct SpkiOwned { + pub algorithm: AlgorithmIdentifier, + pub subject_public_key: BitString, +} + +#[test] +fn from_ber() { + let _any1 = Any::from_ber(&BER_CERT).expect("from_ber 1"); + + //let any2 = Any::from_ber(any1.value()).expect("from_ber 2"); +} + +const BER_CERT: [u8; 1630] = hex!( + "30 80 06 09 2a 86 48 86 f7 0d 01 07 02 a0 80 30 +80 02 01 01 31 0b 30 09 06 05 2b 0e 03 02 1a 05 +00 30 80 06 09 2a 86 48 86 f7 0d 01 07 01 00 00 +a0 82 04 49 30 82 04 45 30 82 02 2d a0 03 02 01 +02 02 01 10 30 0d 06 09 2a 86 48 86 f7 0d 01 01 +0b 05 00 30 4c 31 0b 30 09 06 03 55 04 06 13 02 +55 53 31 10 30 0e 06 03 55 04 0a 13 07 73 63 65 +70 2d 63 61 31 10 30 0e 06 03 55 04 0b 13 07 53 +43 45 50 20 43 41 31 19 30 17 06 03 55 04 03 13 +10 4d 49 43 52 4f 4d 44 4d 20 53 43 45 50 20 43 +41 30 1e 17 0d 32 32 31 31 32 39 31 35 34 34 32 +38 5a 17 0d 32 33 31 31 32 39 31 35 34 34 32 38 +5a 30 17 31 15 30 13 06 03 55 04 03 13 0c 61 73 +64 66 31 32 33 34 61 73 64 66 30 82 01 22 30 0d +06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 82 01 +0f 00 30 82 01 0a 02 82 01 01 00 bc c2 53 f6 be +75 54 96 ea 15 98 08 9b 45 cc ab 63 3b dc 33 8d +9b 5e 77 0a 86 b7 22 9f f3 68 5d 42 34 9e e3 a3 +50 27 99 b5 29 29 5c 3f 45 ea 53 fb 74 dd 4c ce +50 0f 23 63 99 05 0e 3a 86 91 aa c6 f1 67 2c e0 +6a 13 be ce 6e af 77 0f a2 54 b2 c9 84 e5 5a d5 +5a 41 ff a0 f0 4a a2 f5 77 56 3d 90 4a a4 d4 a1 +98 d2 28 8d 25 f7 6a 84 de 93 23 25 67 e2 5e cc +fc 26 fc 9d e6 cd 22 64 91 22 4d 67 3c f7 0e 50 +30 4f ed 1e a7 63 88 2c 16 5a 79 53 aa 36 c4 f9 +a5 e8 8e 00 f5 0a d9 9d 09 81 9c 44 75 14 c1 3b +3e fb 59 df 71 b5 a0 13 d2 e1 73 7b b4 30 79 6f +0f 31 a9 89 48 f6 7d b3 56 63 d4 f9 ae c4 39 2b +85 ca e6 ba d4 93 dd f7 df 3c 16 d1 05 96 c8 17 +06 74 59 c2 b3 69 c2 99 1d 4c 19 03 81 5d a2 06 +70 21 e0 a5 39 5f 87 24 4a 2b 30 a5 f1 bb 46 14 +d0 d5 27 ab c0 eb 8d c2 00 ac bd 02 03 01 00 01 +a3 67 30 65 30 0e 06 03 55 1d 0f 01 01 ff 04 04 +03 02 07 80 30 13 06 03 55 1d 25 04 0c 30 0a 06 +08 2b 06 01 05 05 07 03 02 30 1d 06 03 55 1d 0e +04 16 04 14 a2 07 75 c6 b8 1b 9a 8e bc c0 be 99 +7a 4f 91 84 d5 01 76 73 30 1f 06 03 55 1d 23 04 +18 30 16 80 14 06 0a d7 48 64 c9 78 f8 99 6f 95 +41 c7 85 6c 95 69 d2 16 2d 30 0d 06 09 2a 86 48 +86 f7 0d 01 01 0b 05 00 03 82 02 01 00 50 65 be +56 57 78 f9 bf 07 1d fd d9 18 29 d6 2c 28 b8 6f +1f ad e3 53 cd 6b 15 f9 8c 6b 41 0c 4a f0 d5 c0 +cf 3f 4f f1 72 f9 77 ee eb 94 0c 6f b9 38 f2 36 +2b f4 a1 b3 8f a5 93 fd ac ef ca 7a db 5c 14 ad +e2 cb ab 7d 31 a4 05 14 4f 36 d7 9f 65 92 e7 3f +3d 0d c4 ab 83 db fc da 87 b9 60 92 39 71 74 5e +46 dd 23 18 87 04 1c ee c7 14 1c bd d1 13 33 c0 +16 09 07 0d 87 b7 04 38 3b ca e4 7a 84 12 fe 64 +db 3b 4c ba b1 99 27 19 55 91 c8 9e eb 44 a6 64 +4f a3 49 24 31 ef 49 fe 12 d7 44 8f 5e f9 d6 57 +53 fe d9 d9 4a f7 15 e6 7c 36 6e 36 17 9c 9e 37 +21 fb 64 24 9c 63 f1 6c e9 8c b0 3d 6b 40 a5 5c +44 6b c9 68 4f 52 f9 b7 b1 d0 63 03 7b ef 72 5d +6b d1 c1 90 a2 30 8d c1 af d2 48 b8 fa ed 78 3f +fd 71 6f 4a 9c 84 12 26 3b c1 98 c0 a8 79 79 a8 +e9 8a 5d ac f4 18 9e 63 95 a0 43 ac da 75 4d c3 +f8 2b 3c d8 cf b9 12 bd d5 53 cf 47 a4 9f 6d 23 +d5 4d ae 3b 8a 3d f2 87 2b 1f 22 12 a9 88 63 e5 +b0 4b f6 2c ef 4a ee 5f 7f fb 55 90 69 d0 ec d1 +b7 00 4f 30 0b aa 2b 73 a2 32 5d d2 e3 f1 5d bf +d5 ea d3 f6 bd ab f9 f7 84 15 1c 05 f4 15 e5 b8 +03 7c 21 ca 35 be 22 bf b5 da f2 03 d6 63 ec fc +78 f4 32 a6 c1 e0 99 26 11 51 c1 ec 5f 36 35 90 +9a e2 a6 bc 0e cb f3 af be b6 d4 ee ac ff 92 61 +4f 53 e9 bd 47 a7 b7 3a c2 32 6f 33 d7 76 6e 40 +27 f7 bc 49 4c f1 ce bb 6d 5f dd 97 24 7a fa 47 +77 60 be 94 9d 3a 5a 12 88 fc b0 27 18 36 25 14 +d7 e7 04 6e af 8e 86 97 a7 51 b6 f9 e4 ea 80 d1 +bd 05 96 6d 02 52 13 fb a8 21 e5 43 00 e8 8c a7 +7f c6 ba f8 a8 2a 66 7f 38 a0 52 98 95 8c 71 25 +9b e8 25 9b a4 e1 4d f8 d7 09 fb b7 f3 4f 04 74 +da aa e2 e7 24 8e d6 07 a5 54 25 dd d4 31 82 01 +d7 30 82 01 d3 02 01 01 30 51 30 4c 31 0b 30 09 +06 03 55 04 06 13 02 55 53 31 10 30 0e 06 03 55 +04 0a 13 07 73 63 65 70 2d 63 61 31 10 30 0e 06 +03 55 04 0b 13 07 53 43 45 50 20 43 41 31 19 30 +17 06 03 55 04 03 13 10 4d 49 43 52 4f 4d 44 4d +20 53 43 45 50 20 43 41 02 01 10 30 09 06 05 2b +0e 03 02 1a 05 00 a0 5d 30 18 06 09 2a 86 48 86 +f7 0d 01 09 03 31 0b 06 09 2a 86 48 86 f7 0d 01 +07 01 30 1c 06 09 2a 86 48 86 f7 0d 01 09 05 31 +0f 17 0d 32 32 31 31 32 39 31 35 34 34 33 31 5a +30 23 06 09 2a 86 48 86 f7 0d 01 09 04 31 16 04 +14 92 04 58 96 9e b3 01 02 d8 01 65 5a 93 5d 3c +ed 78 a1 4b c7 30 0d 06 09 2a 86 48 86 f7 0d 01 +01 05 05 00 04 82 01 00 3f 18 aa 88 30 ed c9 79 +64 f7 2e 0c d0 67 c8 ba 7f 3f 40 fd 6a 4c 18 11 +9e dd 28 be de 1a b6 3c 03 00 50 dc ed a9 c0 32 +ec 4e d7 c6 77 21 1e a6 f8 4a 3c 71 02 62 82 e6 +e0 a3 63 98 47 a8 11 d7 5a 5f 6d 96 a3 64 da 9f +bf 96 94 03 08 bc b6 3c 48 22 8d 5d 8e f5 2d 25 +81 ab 73 92 4b f3 c3 62 44 46 ac 7c 97 ec b3 0e +b3 35 9f 11 59 8c 58 d3 0e 92 2f df 4e 18 7b ee +76 98 e6 45 23 6b 6e 49 d3 cf 10 db bb 86 d5 9a +33 e5 ef 40 a3 d5 df ce 12 31 d0 a0 d4 77 90 67 +71 d3 19 7c 35 3b 03 9b 46 25 bc 06 f3 a0 f5 79 +ee 55 04 b2 1a b8 71 15 af 5a 63 54 b5 02 ac c4 +58 26 70 f9 cf 93 21 14 e1 0a c9 a6 74 94 29 14 +03 fb d3 32 3d f8 e9 ae ee f6 90 56 6f 5d 82 ed +1c 72 82 ff 8d 43 8b d7 27 8f 55 3d 0d 67 b0 47 +d4 c8 ae a1 f1 c1 aa 44 9c c1 3f 31 57 ec 97 52 +1a 43 00 53 7b 05 f3 d1 00 00 00 00 00 00" +); From ac7cd50e36af1d4b61d6e94d6b4d06309ff5481e Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Mon, 12 May 2025 21:14:18 +0200 Subject: [PATCH 6/7] der: cargo clippy + typos --- der/src/reader.rs | 2 +- der/tests/ber.rs | 109 +------------------------------ der/tests/examples/ber_pkcs7.bin | Bin 0 -> 1630 bytes 3 files changed, 3 insertions(+), 108 deletions(-) create mode 100644 der/tests/examples/ber_pkcs7.bin diff --git a/der/src/reader.rs b/der/src/reader.rs index 91678a393..e336db880 100644 --- a/der/src/reader.rs +++ b/der/src/reader.rs @@ -195,7 +195,7 @@ pub trait Reader<'r>: Sized { } let content_len = (remaining_len - EOC_LENGTH)?; let content_usize = usize::try_from(content_len)?; - if &slice[content_usize..] != &EOC_BYTES { + if slice[content_usize..] != EOC_BYTES { return Err(ErrorKind::IndefiniteLength.into()); } Ok(content_len) diff --git a/der/tests/ber.rs b/der/tests/ber.rs index 154d04700..85376ef19 100644 --- a/der/tests/ber.rs +++ b/der/tests/ber.rs @@ -20,112 +20,7 @@ pub struct SpkiOwned { #[test] fn from_ber() { - let _any1 = Any::from_ber(&BER_CERT).expect("from_ber 1"); - - //let any2 = Any::from_ber(any1.value()).expect("from_ber 2"); + let _any1 = Any::from_ber(BER_CERT).expect("from_ber 1"); } -const BER_CERT: [u8; 1630] = hex!( - "30 80 06 09 2a 86 48 86 f7 0d 01 07 02 a0 80 30 -80 02 01 01 31 0b 30 09 06 05 2b 0e 03 02 1a 05 -00 30 80 06 09 2a 86 48 86 f7 0d 01 07 01 00 00 -a0 82 04 49 30 82 04 45 30 82 02 2d a0 03 02 01 -02 02 01 10 30 0d 06 09 2a 86 48 86 f7 0d 01 01 -0b 05 00 30 4c 31 0b 30 09 06 03 55 04 06 13 02 -55 53 31 10 30 0e 06 03 55 04 0a 13 07 73 63 65 -70 2d 63 61 31 10 30 0e 06 03 55 04 0b 13 07 53 -43 45 50 20 43 41 31 19 30 17 06 03 55 04 03 13 -10 4d 49 43 52 4f 4d 44 4d 20 53 43 45 50 20 43 -41 30 1e 17 0d 32 32 31 31 32 39 31 35 34 34 32 -38 5a 17 0d 32 33 31 31 32 39 31 35 34 34 32 38 -5a 30 17 31 15 30 13 06 03 55 04 03 13 0c 61 73 -64 66 31 32 33 34 61 73 64 66 30 82 01 22 30 0d -06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 82 01 -0f 00 30 82 01 0a 02 82 01 01 00 bc c2 53 f6 be -75 54 96 ea 15 98 08 9b 45 cc ab 63 3b dc 33 8d -9b 5e 77 0a 86 b7 22 9f f3 68 5d 42 34 9e e3 a3 -50 27 99 b5 29 29 5c 3f 45 ea 53 fb 74 dd 4c ce -50 0f 23 63 99 05 0e 3a 86 91 aa c6 f1 67 2c e0 -6a 13 be ce 6e af 77 0f a2 54 b2 c9 84 e5 5a d5 -5a 41 ff a0 f0 4a a2 f5 77 56 3d 90 4a a4 d4 a1 -98 d2 28 8d 25 f7 6a 84 de 93 23 25 67 e2 5e cc -fc 26 fc 9d e6 cd 22 64 91 22 4d 67 3c f7 0e 50 -30 4f ed 1e a7 63 88 2c 16 5a 79 53 aa 36 c4 f9 -a5 e8 8e 00 f5 0a d9 9d 09 81 9c 44 75 14 c1 3b -3e fb 59 df 71 b5 a0 13 d2 e1 73 7b b4 30 79 6f -0f 31 a9 89 48 f6 7d b3 56 63 d4 f9 ae c4 39 2b -85 ca e6 ba d4 93 dd f7 df 3c 16 d1 05 96 c8 17 -06 74 59 c2 b3 69 c2 99 1d 4c 19 03 81 5d a2 06 -70 21 e0 a5 39 5f 87 24 4a 2b 30 a5 f1 bb 46 14 -d0 d5 27 ab c0 eb 8d c2 00 ac bd 02 03 01 00 01 -a3 67 30 65 30 0e 06 03 55 1d 0f 01 01 ff 04 04 -03 02 07 80 30 13 06 03 55 1d 25 04 0c 30 0a 06 -08 2b 06 01 05 05 07 03 02 30 1d 06 03 55 1d 0e -04 16 04 14 a2 07 75 c6 b8 1b 9a 8e bc c0 be 99 -7a 4f 91 84 d5 01 76 73 30 1f 06 03 55 1d 23 04 -18 30 16 80 14 06 0a d7 48 64 c9 78 f8 99 6f 95 -41 c7 85 6c 95 69 d2 16 2d 30 0d 06 09 2a 86 48 -86 f7 0d 01 01 0b 05 00 03 82 02 01 00 50 65 be -56 57 78 f9 bf 07 1d fd d9 18 29 d6 2c 28 b8 6f -1f ad e3 53 cd 6b 15 f9 8c 6b 41 0c 4a f0 d5 c0 -cf 3f 4f f1 72 f9 77 ee eb 94 0c 6f b9 38 f2 36 -2b f4 a1 b3 8f a5 93 fd ac ef ca 7a db 5c 14 ad -e2 cb ab 7d 31 a4 05 14 4f 36 d7 9f 65 92 e7 3f -3d 0d c4 ab 83 db fc da 87 b9 60 92 39 71 74 5e -46 dd 23 18 87 04 1c ee c7 14 1c bd d1 13 33 c0 -16 09 07 0d 87 b7 04 38 3b ca e4 7a 84 12 fe 64 -db 3b 4c ba b1 99 27 19 55 91 c8 9e eb 44 a6 64 -4f a3 49 24 31 ef 49 fe 12 d7 44 8f 5e f9 d6 57 -53 fe d9 d9 4a f7 15 e6 7c 36 6e 36 17 9c 9e 37 -21 fb 64 24 9c 63 f1 6c e9 8c b0 3d 6b 40 a5 5c -44 6b c9 68 4f 52 f9 b7 b1 d0 63 03 7b ef 72 5d -6b d1 c1 90 a2 30 8d c1 af d2 48 b8 fa ed 78 3f -fd 71 6f 4a 9c 84 12 26 3b c1 98 c0 a8 79 79 a8 -e9 8a 5d ac f4 18 9e 63 95 a0 43 ac da 75 4d c3 -f8 2b 3c d8 cf b9 12 bd d5 53 cf 47 a4 9f 6d 23 -d5 4d ae 3b 8a 3d f2 87 2b 1f 22 12 a9 88 63 e5 -b0 4b f6 2c ef 4a ee 5f 7f fb 55 90 69 d0 ec d1 -b7 00 4f 30 0b aa 2b 73 a2 32 5d d2 e3 f1 5d bf -d5 ea d3 f6 bd ab f9 f7 84 15 1c 05 f4 15 e5 b8 -03 7c 21 ca 35 be 22 bf b5 da f2 03 d6 63 ec fc -78 f4 32 a6 c1 e0 99 26 11 51 c1 ec 5f 36 35 90 -9a e2 a6 bc 0e cb f3 af be b6 d4 ee ac ff 92 61 -4f 53 e9 bd 47 a7 b7 3a c2 32 6f 33 d7 76 6e 40 -27 f7 bc 49 4c f1 ce bb 6d 5f dd 97 24 7a fa 47 -77 60 be 94 9d 3a 5a 12 88 fc b0 27 18 36 25 14 -d7 e7 04 6e af 8e 86 97 a7 51 b6 f9 e4 ea 80 d1 -bd 05 96 6d 02 52 13 fb a8 21 e5 43 00 e8 8c a7 -7f c6 ba f8 a8 2a 66 7f 38 a0 52 98 95 8c 71 25 -9b e8 25 9b a4 e1 4d f8 d7 09 fb b7 f3 4f 04 74 -da aa e2 e7 24 8e d6 07 a5 54 25 dd d4 31 82 01 -d7 30 82 01 d3 02 01 01 30 51 30 4c 31 0b 30 09 -06 03 55 04 06 13 02 55 53 31 10 30 0e 06 03 55 -04 0a 13 07 73 63 65 70 2d 63 61 31 10 30 0e 06 -03 55 04 0b 13 07 53 43 45 50 20 43 41 31 19 30 -17 06 03 55 04 03 13 10 4d 49 43 52 4f 4d 44 4d -20 53 43 45 50 20 43 41 02 01 10 30 09 06 05 2b -0e 03 02 1a 05 00 a0 5d 30 18 06 09 2a 86 48 86 -f7 0d 01 09 03 31 0b 06 09 2a 86 48 86 f7 0d 01 -07 01 30 1c 06 09 2a 86 48 86 f7 0d 01 09 05 31 -0f 17 0d 32 32 31 31 32 39 31 35 34 34 33 31 5a -30 23 06 09 2a 86 48 86 f7 0d 01 09 04 31 16 04 -14 92 04 58 96 9e b3 01 02 d8 01 65 5a 93 5d 3c -ed 78 a1 4b c7 30 0d 06 09 2a 86 48 86 f7 0d 01 -01 05 05 00 04 82 01 00 3f 18 aa 88 30 ed c9 79 -64 f7 2e 0c d0 67 c8 ba 7f 3f 40 fd 6a 4c 18 11 -9e dd 28 be de 1a b6 3c 03 00 50 dc ed a9 c0 32 -ec 4e d7 c6 77 21 1e a6 f8 4a 3c 71 02 62 82 e6 -e0 a3 63 98 47 a8 11 d7 5a 5f 6d 96 a3 64 da 9f -bf 96 94 03 08 bc b6 3c 48 22 8d 5d 8e f5 2d 25 -81 ab 73 92 4b f3 c3 62 44 46 ac 7c 97 ec b3 0e -b3 35 9f 11 59 8c 58 d3 0e 92 2f df 4e 18 7b ee -76 98 e6 45 23 6b 6e 49 d3 cf 10 db bb 86 d5 9a -33 e5 ef 40 a3 d5 df ce 12 31 d0 a0 d4 77 90 67 -71 d3 19 7c 35 3b 03 9b 46 25 bc 06 f3 a0 f5 79 -ee 55 04 b2 1a b8 71 15 af 5a 63 54 b5 02 ac c4 -58 26 70 f9 cf 93 21 14 e1 0a c9 a6 74 94 29 14 -03 fb d3 32 3d f8 e9 ae ee f6 90 56 6f 5d 82 ed -1c 72 82 ff 8d 43 8b d7 27 8f 55 3d 0d 67 b0 47 -d4 c8 ae a1 f1 c1 aa 44 9c c1 3f 31 57 ec 97 52 -1a 43 00 53 7b 05 f3 d1 00 00 00 00 00 00" -); +const BER_CERT: &[u8] = include_bytes!("examples/ber_pkcs7.bin"); diff --git a/der/tests/examples/ber_pkcs7.bin b/der/tests/examples/ber_pkcs7.bin new file mode 100644 index 0000000000000000000000000000000000000000..0e11b98fc5dae7751221e393eda0d63119ad0e77 GIT binary patch literal 1630 zcmb_c`#aQW6#w34Cilw>hNW^DD%t&h$7KnNMK00EL^V%CHKY;}LhO@fg>8{2mxw_m zgt8*J*CSN!V?rWDkxL>>l%4FZ`~my^@;;yQIp;j@bI#}epka8SZ4uTH3t}Jv;)J1L z5C~!-s1P2fDGoylH~?Lj00IDqjo6@U#1dsgS{xVxAqbR2#nyU&B7zFL)dsK=f+s>w zbW9Qz#|wZkk>JO2Kc&Sw{9i0Mpgcq3SaPP+KO7-EAU zP}M-6uL;gyw8@P(Sy9_%8Nu{?y+{0)=hG|#NcD!lEFBp1E#nY7U-^ang$DabV7LCTp8u`XnbplNdSsw^p=GqPJ7Hj9 z&`7oem)InS_dn23db}Y;$xa?V&&b|-kB?%B*K@b=sgsqNKiGqlt!uSoEco2spz!0h=n6Z*LB8!l+2my^1KU|Bg zs;fykOS>G-1<&}Qo4(Pi2pN?PBjJU4)^5!~izz-=%^qJkdG&awtk(Kf2t)$2ArNqI zuW{ZN#IGeNed#4{?b*Ji!e`U%*YszeGW=*yGf~?Q+`2Xs+RSNw;MDsoqCWTaKk8}D zWtLvbN%&GY-Ey}7AnEq-lY-x{8#oe8kC)*d|JKA<>`}q*{mXrk_YcJz`1-r-98e`k zB8pRwNs84SMD03RA%a+BIihda^5$%~^jEijL%Yg5DH`%lmz&bxTjaXYvTf9`X`8Ro zJc~;%{GNUEuf4st3o@gjdfs|+Y3V;JFS)6uv1U$=MVA+_ob`3^fs#-8D6Sf`y#`O#vda!H>pV9ieinF?3&*`Z9C<9ZpkU`c>6?0IY2{2 z@-_XksLamSGt64M}MiDnBGg1MED!1s?sMMDAeS~{h6U#w!)ZF@^6m_XR z^%Jgox^dTrbF0Lk%of+&>z*oHi9bxEk5yaUEZ@;U_0i^?@ix_1sIsw}X?@`3I*_Dx z_On&sp_(h#cQB-*mP<6qdK41xE#h4q8SBl{E6OF`&4 z=*~!B8chae?s~jl+c+G6utC6toF9cwHV3;c{3zP)(NuZP#PrJvJF-;zz?Pbq3ipg) zz~RN@tvc$&ZeC-c^2XdnTO(iS2zzuWo0V*pC&gp9dL?GN^<~s1UV%4M-7~UQiDAZm z(xRL%@QdFy`|yax&ce{7iBj=W-3+M%(fhl^<9{05O%9nllRRpv>gjFM)h5~hAcA{M zdt}-)n>*MljkR;S1LHh=yW~T44dK+Clq&oz=Tq>M6LMFf!dIr4!P;8}6+YUpev03g zpiFut+??xwWh)6@>Y^GijulPK$2t2j*^`Q=*()*TfATagIT?$2lvs5)6=lxU=Ub%J Vn_&AUk{lJx0eT2-wgXr_e*=&hih2M5 literal 0 HcmV?d00001 From f7e8f17092994e32ca7f97aa51446a6f11b392ab Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Mon, 12 May 2025 22:24:16 +0200 Subject: [PATCH 7/7] cms+der: trying to fix `peek_indefinite_length` --- cms/tests/examples/ber_pkcs7.bin | Bin 0 -> 1630 bytes cms/tests/tests_from_pkcs7_crate.rs | 6 ++++ der/src/decode.rs | 37 +++++++------------ der/src/reader.rs | 53 ++++++++++++++++++---------- der/src/reader/pem.rs | 2 +- der/src/reader/slice.rs | 2 +- der/tests/ber.rs | 1 - 7 files changed, 55 insertions(+), 46 deletions(-) create mode 100644 cms/tests/examples/ber_pkcs7.bin diff --git a/cms/tests/examples/ber_pkcs7.bin b/cms/tests/examples/ber_pkcs7.bin new file mode 100644 index 0000000000000000000000000000000000000000..0e11b98fc5dae7751221e393eda0d63119ad0e77 GIT binary patch literal 1630 zcmb_c`#aQW6#w34Cilw>hNW^DD%t&h$7KnNMK00EL^V%CHKY;}LhO@fg>8{2mxw_m zgt8*J*CSN!V?rWDkxL>>l%4FZ`~my^@;;yQIp;j@bI#}epka8SZ4uTH3t}Jv;)J1L z5C~!-s1P2fDGoylH~?Lj00IDqjo6@U#1dsgS{xVxAqbR2#nyU&B7zFL)dsK=f+s>w zbW9Qz#|wZkk>JO2Kc&Sw{9i0Mpgcq3SaPP+KO7-EAU zP}M-6uL;gyw8@P(Sy9_%8Nu{?y+{0)=hG|#NcD!lEFBp1E#nY7U-^ang$DabV7LCTp8u`XnbplNdSsw^p=GqPJ7Hj9 z&`7oem)InS_dn23db}Y;$xa?V&&b|-kB?%B*K@b=sgsqNKiGqlt!uSoEco2spz!0h=n6Z*LB8!l+2my^1KU|Bg zs;fykOS>G-1<&}Qo4(Pi2pN?PBjJU4)^5!~izz-=%^qJkdG&awtk(Kf2t)$2ArNqI zuW{ZN#IGeNed#4{?b*Ji!e`U%*YszeGW=*yGf~?Q+`2Xs+RSNw;MDsoqCWTaKk8}D zWtLvbN%&GY-Ey}7AnEq-lY-x{8#oe8kC)*d|JKA<>`}q*{mXrk_YcJz`1-r-98e`k zB8pRwNs84SMD03RA%a+BIihda^5$%~^jEijL%Yg5DH`%lmz&bxTjaXYvTf9`X`8Ro zJc~;%{GNUEuf4st3o@gjdfs|+Y3V;JFS)6uv1U$=MVA+_ob`3^fs#-8D6Sf`y#`O#vda!H>pV9ieinF?3&*`Z9C<9ZpkU`c>6?0IY2{2 z@-_XksLamSGt64M}MiDnBGg1MED!1s?sMMDAeS~{h6U#w!)ZF@^6m_XR z^%Jgox^dTrbF0Lk%of+&>z*oHi9bxEk5yaUEZ@;U_0i^?@ix_1sIsw}X?@`3I*_Dx z_On&sp_(h#cQB-*mP<6qdK41xE#h4q8SBl{E6OF`&4 z=*~!B8chae?s~jl+c+G6utC6toF9cwHV3;c{3zP)(NuZP#PrJvJF-;zz?Pbq3ipg) zz~RN@tvc$&ZeC-c^2XdnTO(iS2zzuWo0V*pC&gp9dL?GN^<~s1UV%4M-7~UQiDAZm z(xRL%@QdFy`|yax&ce{7iBj=W-3+M%(fhl^<9{05O%9nllRRpv>gjFM)h5~hAcA{M zdt}-)n>*MljkR;S1LHh=yW~T44dK+Clq&oz=Tq>M6LMFf!dIr4!P;8}6+YUpev03g zpiFut+??xwWh)6@>Y^GijulPK$2t2j*^`Q=*()*TfATagIT?$2lvs5)6=lxU=Ub%J Vn_&AUk{lJx0eT2-wgXr_e*=&hih2M5 literal 0 HcmV?d00001 diff --git a/cms/tests/tests_from_pkcs7_crate.rs b/cms/tests/tests_from_pkcs7_crate.rs index e422b141f..9a7cf2aa2 100644 --- a/cms/tests/tests_from_pkcs7_crate.rs +++ b/cms/tests/tests_from_pkcs7_crate.rs @@ -141,3 +141,9 @@ fn cms_decode_signed_der() { // should match the original assert_eq!(reencoded_der_signed_data_in_ci, der_signed_data_in_ci) } + +#[test] +fn cms_decode_ber() { + let ber_pkcs7 = include_bytes!("../tests/examples/ber_pkcs7.bin"); + let _ci = ContentInfo::from_ber(ber_pkcs7).expect("decoded ber"); +} diff --git a/der/src/decode.rs b/der/src/decode.rs index f01edcd1d..0655af89b 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -127,33 +127,22 @@ pub trait DecodeValue<'a>: Sized { reader: &mut R, header: Header, ) -> Result { - let fixed_header = swap_header_if_indefinite(reader, header)?; + if !header.length.is_indefinite() { + // TODO: maybe refactor whole der to read_nested here + Self::decode_value(reader, header) + } else { + let fixed_header = Header { + tag: header.tag, + length: reader.peek_indefinite_length()?, + }; + // Now expected length is known + let result = reader.read_nested(fixed_header.length, |reader| { + Self::decode_value(reader, fixed_header) + }); - // Now expected length is known - let result = reader.read_nested(fixed_header.length, |reader| { - Self::decode_value(reader, fixed_header) - }); - if header.length.is_indefinite() { reader.read_end_of_contents()?; + result } - result - } -} - -/// Returns valid length if indefinite length was given. -/// -/// [`Reader`] must support peeking the remaining bytes. -fn swap_header_if_indefinite<'a, R: Reader<'a>>( - reader: &mut R, - header: Header, -) -> Result { - if header.length.is_indefinite() { - Ok(Header { - tag: header.tag, - length: reader.peek_indefinite_length()?, - }) - } else { - Ok(header) } } diff --git a/der/src/reader.rs b/der/src/reader.rs index e336db880..522491fe0 100644 --- a/der/src/reader.rs +++ b/der/src/reader.rs @@ -5,12 +5,13 @@ pub(crate) mod pem; pub(crate) mod slice; use crate::{ - Decode, DecodeValue, Encode, EncodingRules, Error, ErrorKind, FixedTag, Header, Length, Tag, - TagMode, TagNumber, asn1::ContextSpecific, + AnyRef, Decode, DecodeValue, Encode, EncodingRules, Error, ErrorKind, FixedTag, Header, Length, + Tag, TagMode, TagNumber, asn1::ContextSpecific, }; #[cfg(feature = "alloc")] use alloc::vec::Vec; +use slice::SliceReader; /// End of contents length const EOC_LENGTH: Length = Length::new(2); @@ -127,7 +128,7 @@ pub trait Reader<'r>: Sized { } /// Attempt to peek remaining bytes. - fn peek_remaining(&mut self) -> Result<&'r [u8], Error>; + fn peek_remaining(&self) -> Result<&'r [u8], Error>; /// Read a single byte. fn read_byte(&mut self) -> Result { @@ -183,29 +184,43 @@ pub trait Reader<'r>: Sized { /// Returns length of current indefinite segment fn peek_indefinite_length(&mut self) -> Result { - let remaining_len = self.remaining_len(); + //let remaining_len = self.remaining_len(); + + // if remaining_len < EOC_LENGTH { + // return Err(ErrorKind::Incomplete { + // expected_len: EOC_LENGTH, + // actual_len: remaining_len, + // } + // .into()); + // } let slice = self.peek_remaining()?; - if remaining_len < EOC_LENGTH { - return Err(ErrorKind::Incomplete { - expected_len: EOC_LENGTH, - actual_len: remaining_len, + + let mut peeker = SliceReader::new_with_encoding_rules(slice, EncodingRules::Ber)?; + for _ in 0..10000 { + let mut eoc_buf = [0u8; 2]; + peeker.peek_into(&mut eoc_buf)?; + if eoc_buf == EOC_BYTES { + peeker.read_slice(EOC_LENGTH)?; + break; } - .into()); + let header = Header::decode(&mut peeker)?; + let len = if header.length.is_indefinite() && header.tag.is_constructed() { + (peeker.peek_indefinite_length()? + EOC_LENGTH)? + } else { + header.length + }; + peeker.read_slice(len)?; } - let content_len = (remaining_len - EOC_LENGTH)?; - let content_usize = usize::try_from(content_len)?; - if slice[content_usize..] != EOC_BYTES { - return Err(ErrorKind::IndefiniteLength.into()); - } - Ok(content_len) + + peeker.offset() - EOC_LENGTH } /// Reads 2 end-of-contents bytes [0x00, 0x00] fn read_end_of_contents(&mut self) -> Result<(), Error> { - let mut eoc_buf = [0u8; 2]; - self.read_into(&mut eoc_buf)?; - if eoc_buf != EOC_BYTES { - return Err(ErrorKind::IndefiniteLength.into()); + //let mut eoc_buf = [0u8; 2]; + let eoc_bytes = self.read_slice(EOC_LENGTH)?; + if eoc_bytes != EOC_BYTES { + return Err(ErrorKind::FileNotFound.into()); } Ok(()) } diff --git a/der/src/reader/pem.rs b/der/src/reader/pem.rs index 16770a538..a7d4456c7 100644 --- a/der/src/reader/pem.rs +++ b/der/src/reader/pem.rs @@ -101,7 +101,7 @@ impl<'i> Reader<'i> for PemReader<'i> { Ok(buf) } - fn peek_remaining(&mut self) -> Result<&'i [u8], Error> { + fn peek_remaining(&self) -> Result<&'i [u8], Error> { // Can't borrow from PEM because it requires decoding Err(ErrorKind::Reader.into()) } diff --git a/der/src/reader/slice.rs b/der/src/reader/slice.rs index e93f85cd5..c6b6485d2 100644 --- a/der/src/reader/slice.rs +++ b/der/src/reader/slice.rs @@ -163,7 +163,7 @@ impl<'a> Reader<'a> for SliceReader<'a> { self.input_len().saturating_sub(self.position) } - fn peek_remaining(&mut self) -> Result<&'a [u8], Error> { + fn peek_remaining(&self) -> Result<&'a [u8], Error> { self.remaining() } } diff --git a/der/tests/ber.rs b/der/tests/ber.rs index 85376ef19..05abdcf4d 100644 --- a/der/tests/ber.rs +++ b/der/tests/ber.rs @@ -3,7 +3,6 @@ use const_oid::ObjectIdentifier; use der::{Any, Decode, Sequence, asn1::BitString}; -use hex_literal::hex; /// X.509 `AlgorithmIdentifier` #[derive(Clone, Debug, Eq, PartialEq, Sequence)]