From 6d54f2157c875af95557aa2b4904726b255cf067 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 20 Jun 2025 13:29:28 -0600 Subject: [PATCH] der: add `Reader::read_value`, auto-nest `DecodeValue` Previously `der` lacked an abstraction for automatically setting up nested readers when decoding values, so every `DecodeValue` impl ended up handling its own nesting. This adds a new provided method to the `Reader` trait which automatically handles nesting. This change is backwards compatible in that if a `DecodeValue` impl does its own `reader.read_nested`, it will just create another nested reader of the same length, which is redundant but doesn't break anything. However, we should remove all of the `read_nested` calls from `DecodeValue` impls with this approach anyway as they're redundant. Using a provided method for this opens up the possibility of reader-specific handling of field decoding, which would be useful for addressing indefinite length handling for BER decoding (#779). --- der/src/asn1/internal_macros.rs | 6 +-- der/src/asn1/sequence_of.rs | 64 +++++++++++------------ der/src/asn1/set_of.rs | 34 ++++++------ der/src/decode.rs | 2 +- der/src/reader.rs | 14 ++++- der_derive/src/sequence.rs | 20 +++---- pkcs1/src/params.rs | 55 +++++++++---------- pkcs1/src/private_key.rs | 44 ++++++++-------- pkcs1/src/private_key/other_prime_info.rs | 12 ++--- pkcs1/src/public_key.rs | 10 ++-- pkcs12/src/safe_bag.rs | 26 +++++---- pkcs8/src/encrypted_private_key_info.rs | 10 ++-- pkcs8/src/private_key_info.rs | 61 ++++++++++----------- sec1/src/private_key.rs | 34 ++++++------ spki/src/algorithm.rs | 10 ++-- spki/src/spki.rs | 10 ++-- x509-cert/src/time.rs | 25 +++++---- x509-cert/tests/certificate.rs | 46 ++++++++-------- 18 files changed, 227 insertions(+), 256 deletions(-) diff --git a/der/src/asn1/internal_macros.rs b/der/src/asn1/internal_macros.rs index aeea1b2f6..ec1a48727 100644 --- a/der/src/asn1/internal_macros.rs +++ b/der/src/asn1/internal_macros.rs @@ -151,8 +151,8 @@ macro_rules! impl_custom_class { return Err(header.tag.non_canonical_error().into()); } - // read_nested checks if header matches decoded length - let value = reader.read_nested(header.length, |reader| { + // read_value checks if header matches decoded length + let value = reader.read_value(header, |reader| { // Decode inner IMPLICIT value T::decode_value(reader, header) })?; @@ -192,7 +192,7 @@ macro_rules! impl_custom_class { Tag::$class_enum_name { number, .. } => Ok(Self { tag_number: number, tag_mode: TagMode::default(), - value: reader.read_nested(header.length, |reader| { + value: reader.read_value(header, |reader| { // Decode inner tag-length-value of EXPLICIT T::decode(reader) })?, diff --git a/der/src/asn1/sequence_of.rs b/der/src/asn1/sequence_of.rs index 10eda349c..021cbc328 100644 --- a/der/src/asn1/sequence_of.rs +++ b/der/src/asn1/sequence_of.rs @@ -68,16 +68,14 @@ where { type Error = T::Error; - fn decode_value>(reader: &mut R, header: Header) -> Result { - reader.read_nested(header.length, |reader| { - let mut sequence_of = Self::new(); + fn decode_value>(reader: &mut R, _header: Header) -> Result { + let mut sequence_of = Self::new(); - while !reader.is_finished() { - sequence_of.add(T::decode(reader)?)?; - } + while !reader.is_finished() { + sequence_of.add(T::decode(reader)?)?; + } - Ok(sequence_of) - }) + Ok(sequence_of) } } @@ -133,6 +131,21 @@ impl<'a, T> Iterator for SequenceOfIter<'a, T> { impl ExactSizeIterator for SequenceOfIter<'_, T> {} +impl EncodeValue for [T] { + fn value_len(&self) -> Result { + self.iter() + .try_fold(Length::ZERO, |len, elem| len + elem.encoded_len()?) + } + + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { + for elem in self { + elem.encode(writer)?; + } + + Ok(()) + } +} + impl<'a, T, const N: usize> DecodeValue<'a> for [T; N] where T: Decode<'a>, @@ -164,11 +177,7 @@ where } fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { - for elem in self { - elem.encode(writer)?; - } - - Ok(()) + self.as_slice().encode_value(writer) } } @@ -185,19 +194,6 @@ where } } -#[cfg(feature = "alloc")] -fn decode_value_vec_inner<'a, T: Decode<'a>, R: Reader<'a>>( - reader: &mut R, -) -> Result, T::Error> { - let mut sequence_of = Vec::::new(); - - while !reader.is_finished() { - sequence_of.push(T::decode(reader)?); - } - - Ok(sequence_of) -} - #[cfg(feature = "alloc")] impl<'a, T> DecodeValue<'a> for Vec where @@ -205,8 +201,14 @@ where { type Error = T::Error; - fn decode_value>(reader: &mut R, header: Header) -> Result { - reader.read_nested(header.length, decode_value_vec_inner) + fn decode_value>(reader: &mut R, _header: Header) -> Result { + let mut sequence_of = Vec::::new(); + + while !reader.is_finished() { + sequence_of.push(T::decode(reader)?); + } + + Ok(sequence_of) } } @@ -221,11 +223,7 @@ where } fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { - for elem in self { - elem.encode(writer)?; - } - - Ok(()) + self.as_slice().encode_value(writer) } } diff --git a/der/src/asn1/set_of.rs b/der/src/asn1/set_of.rs index 2eb07cff4..b1452c4f8 100644 --- a/der/src/asn1/set_of.rs +++ b/der/src/asn1/set_of.rs @@ -110,18 +110,16 @@ where { type Error = T::Error; - fn decode_value>(reader: &mut R, header: Header) -> Result { - reader.read_nested(header.length, |reader| { - let mut result = Self::new(); + fn decode_value>(reader: &mut R, _header: Header) -> Result { + let mut result = Self::new(); - while !reader.is_finished() { - result.inner.push(T::decode(reader)?)?; - } + while !reader.is_finished() { + result.inner.push(T::decode(reader)?)?; + } - // Ensure elements of the `SetOf` are sorted and will serialize as valid DER - der_sort(result.inner.as_mut())?; - Ok(result) - }) + // Ensure elements of the `SetOf` are sorted and will serialize as valid DER + der_sort(result.inner.as_mut())?; + Ok(result) } } @@ -334,17 +332,15 @@ where { type Error = T::Error; - fn decode_value>(reader: &mut R, header: Header) -> Result { - reader.read_nested(header.length, |reader| { - let mut inner = Vec::new(); + fn decode_value>(reader: &mut R, _header: Header) -> Result { + let mut inner = Vec::new(); - while !reader.is_finished() { - inner.push(T::decode(reader)?); - } + while !reader.is_finished() { + inner.push(T::decode(reader)?); + } - der_sort(inner.as_mut())?; - Ok(Self { inner }) - }) + der_sort(inner.as_mut())?; + Ok(Self { inner }) } } diff --git a/der/src/decode.rs b/der/src/decode.rs index f3bb878c0..207fcf2ca 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -65,7 +65,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) + reader.read_value(header, |r| T::decode_value(r, header)) } } diff --git a/der/src/reader.rs b/der/src/reader.rs index f5549851a..845bb8c1f 100644 --- a/der/src/reader.rs +++ b/der/src/reader.rs @@ -35,6 +35,18 @@ pub trait Reader<'r>: Sized { E: From, F: FnOnce(&mut Self) -> Result; + /// Read a value (i.e. the "V" part of a "TLV" field) using the provided header. + /// + /// This calls the provided function `f` with a nested reader created using + /// [`Reader::read_nested`]. + fn read_value(&mut self, header: Header, f: F) -> Result + where + E: From, + F: FnOnce(&mut Self) -> Result, + { + self.read_nested(header.length, f) + } + /// Attempt to read data borrowed directly from the input as a slice, /// updating the internal cursor position. /// @@ -163,7 +175,7 @@ pub trait Reader<'r>: Sized { { let header = Header::decode(self)?; header.tag.assert_eq(Tag::Sequence)?; - self.read_nested(header.length, f) + self.read_value(header, f) } /// Obtain a slice of bytes contain a complete TLV production suitable for parsing later. diff --git a/der_derive/src/sequence.rs b/der_derive/src/sequence.rs index 5963d0ab8..6cb463d92 100644 --- a/der_derive/src/sequence.rs +++ b/der_derive/src/sequence.rs @@ -104,18 +104,6 @@ impl DeriveSequence { let error = self.error.to_token_stream(); quote! { - impl #impl_generics #ident #ty_generics #where_clause { - #[doc(hidden)] - fn decode_value_inner>(reader: &mut R) -> ::core::result::Result { - use ::der::{Decode as _, DecodeValue as _, Reader as _}; - #(#decode_body)* - - Ok(Self { - #(#decode_result),* - }) - } - } - impl #impl_generics ::der::DecodeValue<#lifetime> for #ident #ty_generics #where_clause { type Error = #error; @@ -123,7 +111,12 @@ impl DeriveSequence { reader: &mut R, header: ::der::Header, ) -> ::core::result::Result { - reader.read_nested(header.length, Self::decode_value_inner) + use ::der::{Decode as _, DecodeValue as _, Reader as _}; + #(#decode_body)* + + Ok(Self { + #(#decode_result),* + }) } } } @@ -146,7 +139,6 @@ impl DeriveSequence { } quote! { - impl #impl_generics ::der::EncodeValue for #ident #ty_generics #where_clause { fn value_len(&self) -> ::der::Result<::der::Length> { use ::der::Encode as _; diff --git a/pkcs1/src/params.rs b/pkcs1/src/params.rs index 20e8f019c..099a21893 100644 --- a/pkcs1/src/params.rs +++ b/pkcs1/src/params.rs @@ -182,22 +182,20 @@ impl Default for RsaPssParams<'_> { impl<'a> DecodeValue<'a> for RsaPssParams<'a> { type Error = der::Error; - fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - hash: reader - .context_specific(TagNumber(0), TagMode::Explicit)? - .unwrap_or(SHA_1_AI), - mask_gen: reader - .context_specific(TagNumber(1), TagMode::Explicit)? - .unwrap_or_else(default_mgf1_sha1), - salt_len: reader - .context_specific(TagNumber(2), TagMode::Explicit)? - .unwrap_or(RsaPssParams::SALT_LEN_DEFAULT), - trailer_field: reader - .context_specific(TagNumber(3), TagMode::Explicit)? - .unwrap_or_default(), - }) + fn decode_value>(reader: &mut R, _header: der::Header) -> der::Result { + Ok(Self { + hash: reader + .context_specific(TagNumber(0), TagMode::Explicit)? + .unwrap_or(SHA_1_AI), + mask_gen: reader + .context_specific(TagNumber(1), TagMode::Explicit)? + .unwrap_or_else(default_mgf1_sha1), + salt_len: reader + .context_specific(TagNumber(2), TagMode::Explicit)? + .unwrap_or(RsaPssParams::SALT_LEN_DEFAULT), + trailer_field: reader + .context_specific(TagNumber(3), TagMode::Explicit)? + .unwrap_or_default(), }) } } @@ -347,19 +345,18 @@ impl Default for RsaOaepParams<'_> { impl<'a> DecodeValue<'a> for RsaOaepParams<'a> { type Error = der::Error; - fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - hash: reader - .context_specific(TagNumber(0), TagMode::Explicit)? - .unwrap_or(SHA_1_AI), - mask_gen: reader - .context_specific(TagNumber(1), TagMode::Explicit)? - .unwrap_or_else(default_mgf1_sha1), - p_source: reader - .context_specific(TagNumber(2), TagMode::Explicit)? - .unwrap_or_else(default_pempty_string), - }) + + fn decode_value>(reader: &mut R, _header: der::Header) -> der::Result { + Ok(Self { + hash: reader + .context_specific(TagNumber(0), TagMode::Explicit)? + .unwrap_or(SHA_1_AI), + mask_gen: reader + .context_specific(TagNumber(1), TagMode::Explicit)? + .unwrap_or_else(default_mgf1_sha1), + p_source: reader + .context_specific(TagNumber(2), TagMode::Explicit)? + .unwrap_or_else(default_pempty_string), }) } } diff --git a/pkcs1/src/private_key.rs b/pkcs1/src/private_key.rs index 4b1bb8eb0..781c487b3 100644 --- a/pkcs1/src/private_key.rs +++ b/pkcs1/src/private_key.rs @@ -95,29 +95,27 @@ impl<'a> RsaPrivateKey<'a> { impl<'a> DecodeValue<'a> for RsaPrivateKey<'a> { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - let version = Version::decode(reader)?; - - let result = Self { - modulus: reader.decode()?, - public_exponent: reader.decode()?, - private_exponent: reader.decode()?, - prime1: reader.decode()?, - prime2: reader.decode()?, - exponent1: reader.decode()?, - exponent2: reader.decode()?, - coefficient: reader.decode()?, - other_prime_infos: reader.decode()?, - }; - - // Ensure version is set correctly for two-prime vs multi-prime key. - if version.is_multi() != result.other_prime_infos.is_some() { - return Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer })); - } - - Ok(result) - }) + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + let version = Version::decode(reader)?; + + let result = Self { + modulus: reader.decode()?, + public_exponent: reader.decode()?, + private_exponent: reader.decode()?, + prime1: reader.decode()?, + prime2: reader.decode()?, + exponent1: reader.decode()?, + exponent2: reader.decode()?, + coefficient: reader.decode()?, + other_prime_infos: reader.decode()?, + }; + + // Ensure version is set correctly for two-prime vs multi-prime key. + if version.is_multi() != result.other_prime_infos.is_some() { + return Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer })); + } + + Ok(result) } } diff --git a/pkcs1/src/private_key/other_prime_info.rs b/pkcs1/src/private_key/other_prime_info.rs index c26828f38..bc6185bf2 100644 --- a/pkcs1/src/private_key/other_prime_info.rs +++ b/pkcs1/src/private_key/other_prime_info.rs @@ -32,13 +32,11 @@ pub struct OtherPrimeInfo<'a> { impl<'a> DecodeValue<'a> for OtherPrimeInfo<'a> { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - prime: reader.decode()?, - exponent: reader.decode()?, - coefficient: reader.decode()?, - }) + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + Ok(Self { + prime: reader.decode()?, + exponent: reader.decode()?, + coefficient: reader.decode()?, }) } } diff --git a/pkcs1/src/public_key.rs b/pkcs1/src/public_key.rs index 8eef118d1..bf8e59c49 100644 --- a/pkcs1/src/public_key.rs +++ b/pkcs1/src/public_key.rs @@ -35,12 +35,10 @@ pub struct RsaPublicKey<'a> { impl<'a> DecodeValue<'a> for RsaPublicKey<'a> { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - modulus: reader.decode()?, - public_exponent: reader.decode()?, - }) + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + Ok(Self { + modulus: reader.decode()?, + public_exponent: reader.decode()?, }) } } diff --git a/pkcs12/src/safe_bag.rs b/pkcs12/src/safe_bag.rs index 6c12bfc6c..eb4ffb61f 100644 --- a/pkcs12/src/safe_bag.rs +++ b/pkcs12/src/safe_bag.rs @@ -37,24 +37,22 @@ pub struct SafeBag { } impl<'a> ::der::DecodeValue<'a> for SafeBag { - type Error = ::der::Error; + type Error = der::Error; fn decode_value>( reader: &mut R, - header: ::der::Header, + _header: ::der::Header, ) -> ::der::Result { - reader.read_nested(header.length, |reader| { - let bag_id = reader.decode()?; - let bag_value = match reader.tlv_bytes() { - Ok(v) => v.to_vec(), - Err(e) => return Err(e), - }; - let bag_attributes = reader.decode()?; - Ok(Self { - bag_id, - bag_value, - bag_attributes, - }) + let bag_id = reader.decode()?; + let bag_value = match reader.tlv_bytes() { + Ok(v) => v.to_vec(), + Err(e) => return Err(e), + }; + let bag_attributes = reader.decode()?; + Ok(Self { + bag_id, + bag_value, + bag_attributes, }) } } diff --git a/pkcs8/src/encrypted_private_key_info.rs b/pkcs8/src/encrypted_private_key_info.rs index c32c25000..91454213f 100644 --- a/pkcs8/src/encrypted_private_key_info.rs +++ b/pkcs8/src/encrypted_private_key_info.rs @@ -98,12 +98,10 @@ where { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - encryption_algorithm: reader.decode()?, - encrypted_data: reader.decode()?, - }) + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + Ok(Self { + encryption_algorithm: reader.decode()?, + encrypted_data: reader.decode()?, }) } } diff --git a/pkcs8/src/private_key_info.rs b/pkcs8/src/private_key_info.rs index c862f0d9c..d5320eb44 100644 --- a/pkcs8/src/private_key_info.rs +++ b/pkcs8/src/private_key_info.rs @@ -196,40 +196,37 @@ where { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - // Parse and validate `version` INTEGER. - let version = Version::decode(reader)?; - let algorithm = reader.decode()?; - let private_key = Key::decode(reader)?; - - let _attributes = - reader.context_specific::>(ATTRIBUTES_TAG, TagMode::Implicit)?; - - let public_key = - reader.context_specific::(PUBLIC_KEY_TAG, TagMode::Implicit)?; - - if version.has_public_key() != public_key.is_some() { - return Err(reader.error( - der::Tag::ContextSpecific { - constructed: true, - number: PUBLIC_KEY_TAG, - } - .value_error() - .kind(), - )); - } + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + // Parse and validate `version` INTEGER. + let version = Version::decode(reader)?; + let algorithm = reader.decode()?; + let private_key = Key::decode(reader)?; + + let _attributes = + reader.context_specific::>(ATTRIBUTES_TAG, TagMode::Implicit)?; + + let public_key = reader.context_specific::(PUBLIC_KEY_TAG, TagMode::Implicit)?; + + if version.has_public_key() != public_key.is_some() { + return Err(reader.error( + der::Tag::ContextSpecific { + constructed: true, + number: PUBLIC_KEY_TAG, + } + .value_error() + .kind(), + )); + } - // Ignore any remaining extension fields - while !reader.is_finished() { - reader.decode::>>()?; - } + // Ignore any remaining extension fields + while !reader.is_finished() { + reader.decode::>>()?; + } - Ok(Self { - algorithm, - private_key, - public_key, - }) + Ok(Self { + algorithm, + private_key, + public_key, }) } } diff --git a/sec1/src/private_key.rs b/sec1/src/private_key.rs index 5156ee52f..37a7c96ed 100644 --- a/sec1/src/private_key.rs +++ b/sec1/src/private_key.rs @@ -97,24 +97,22 @@ impl<'a> EcPrivateKey<'a> { impl<'a> DecodeValue<'a> for EcPrivateKey<'a> { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - if u8::decode(reader)? != VERSION { - return Err(Tag::Integer.value_error()); - } - - let private_key = OctetStringRef::decode(reader)?.as_bytes(); - let parameters = reader.context_specific(EC_PARAMETERS_TAG, TagMode::Explicit)?; - let public_key = reader - .context_specific::>(PUBLIC_KEY_TAG, TagMode::Explicit)? - .map(|bs| bs.as_bytes().ok_or_else(|| Tag::BitString.value_error())) - .transpose()?; - - Ok(EcPrivateKey { - private_key, - parameters, - public_key, - }) + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + if u8::decode(reader)? != VERSION { + return Err(Tag::Integer.value_error()); + } + + let private_key = OctetStringRef::decode(reader)?.as_bytes(); + let parameters = reader.context_specific(EC_PARAMETERS_TAG, TagMode::Explicit)?; + let public_key = reader + .context_specific::>(PUBLIC_KEY_TAG, TagMode::Explicit)? + .map(|bs| bs.as_bytes().ok_or_else(|| Tag::BitString.value_error())) + .transpose()?; + + Ok(EcPrivateKey { + private_key, + parameters, + public_key, }) } } diff --git a/spki/src/algorithm.rs b/spki/src/algorithm.rs index 403bf942b..a9bd330bb 100644 --- a/spki/src/algorithm.rs +++ b/spki/src/algorithm.rs @@ -37,12 +37,10 @@ where { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - oid: reader.decode()?, - parameters: reader.decode()?, - }) + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + Ok(Self { + oid: reader.decode()?, + parameters: reader.decode()?, }) } } diff --git a/spki/src/spki.rs b/spki/src/spki.rs index 6251d2ea1..f322a2e28 100644 --- a/spki/src/spki.rs +++ b/spki/src/spki.rs @@ -97,12 +97,10 @@ where { type Error = der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - algorithm: reader.decode()?, - subject_public_key: Key::decode(reader)?, - }) + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + Ok(Self { + algorithm: reader.decode()?, + subject_public_key: Key::decode(reader)?, }) } } diff --git a/x509-cert/src/time.rs b/x509-cert/src/time.rs index 6a37491d2..4e78e21b4 100644 --- a/x509-cert/src/time.rs +++ b/x509-cert/src/time.rs @@ -189,19 +189,18 @@ where } impl<'a, P: Profile> DecodeValue<'a> for Validity

{ - type Error = ::der::Error; - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - let not_before = reader.decode()?; - let not_after = reader.decode()?; - let out = Self { - not_before, - not_after, - _profile: PhantomData, - }; - - Ok(out) - }) + type Error = der::Error; + + fn decode_value>(reader: &mut R, _header: Header) -> der::Result { + let not_before = reader.decode()?; + let not_after = reader.decode()?; + let out = Self { + not_before, + not_after, + _profile: PhantomData, + }; + + Ok(out) } } diff --git a/x509-cert/tests/certificate.rs b/x509-cert/tests/certificate.rs index 6550b0700..b17e2cc6f 100644 --- a/x509-cert/tests/certificate.rs +++ b/x509-cert/tests/certificate.rs @@ -42,14 +42,12 @@ impl<'a> DecodeValue<'a> for DeferDecodeCertificate<'a> { fn decode_value>( reader: &mut R, - header: Header, + _header: Header, ) -> der::Result> { - reader.read_nested(header.length, |reader| { - Ok(Self { - tbs_certificate: reader.tlv_bytes()?, - signature_algorithm: reader.tlv_bytes()?, - signature: reader.tlv_bytes()?, - }) + Ok(Self { + tbs_certificate: reader.tlv_bytes()?, + signature_algorithm: reader.tlv_bytes()?, + signature: reader.tlv_bytes()?, }) } } @@ -87,25 +85,23 @@ impl<'a> DecodeValue<'a> for DeferDecodeTbsCertificate<'a> { fn decode_value>( reader: &mut R, - header: Header, + _header: Header, ) -> der::Result> { - reader.read_nested(header.length, |reader| { - let version = ContextSpecific::decode_explicit(reader, ::der::TagNumber(0))? - .map(|cs| cs.value) - .unwrap_or_else(Default::default); - - Ok(Self { - version, - serial_number: reader.tlv_bytes()?, - signature: reader.tlv_bytes()?, - issuer: reader.tlv_bytes()?, - validity: reader.tlv_bytes()?, - subject: reader.tlv_bytes()?, - subject_public_key_info: reader.tlv_bytes()?, - issuer_unique_id: reader.decode()?, - subject_unique_id: reader.decode()?, - extensions: reader.tlv_bytes()?, - }) + let version = ContextSpecific::decode_explicit(reader, ::der::TagNumber(0))? + .map(|cs| cs.value) + .unwrap_or_else(Default::default); + + Ok(Self { + version, + serial_number: reader.tlv_bytes()?, + signature: reader.tlv_bytes()?, + issuer: reader.tlv_bytes()?, + validity: reader.tlv_bytes()?, + subject: reader.tlv_bytes()?, + subject_public_key_info: reader.tlv_bytes()?, + issuer_unique_id: reader.decode()?, + subject_unique_id: reader.decode()?, + extensions: reader.tlv_bytes()?, }) } }