diff --git a/cms/src/enveloped_data.rs b/cms/src/enveloped_data.rs index 71c5ff641..9d0d06d77 100644 --- a/cms/src/enveloped_data.rs +++ b/cms/src/enveloped_data.rs @@ -1,5 +1,4 @@ //! EnvelopedData-related types -use alloc::boxed::Box; use core::cmp::Ordering; use const_oid::ObjectIdentifier; @@ -52,25 +51,6 @@ pub struct EnvelopedData { pub unprotected_attrs: Option, } -// TODO: replace these handwritten impls with `Box` support in the proc macro -impl<'a> ::der::DecodeValue<'a> for Box { - fn decode_value>( - reader: &mut R, - header: ::der::Header, - ) -> ::der::Result { - Ok(Box::new(EnvelopedData::decode_value(reader, header)?)) - } -} -impl ::der::EncodeValue for Box { - fn value_len(&self) -> ::der::Result<::der::Length> { - EnvelopedData::value_len(self) - } - fn encode_value(&self, writer: &mut impl ::der::Writer) -> ::der::Result<()> { - EnvelopedData::encode_value(self, writer) - } -} -impl<'a> ::der::Sequence<'a> for Box {} - /// The `OriginatorInfo` type is defined in [RFC 5652 Section 6.1]. /// /// ```text diff --git a/crmf/src/controls.rs b/crmf/src/controls.rs index 6e0509610..698d13cc3 100644 --- a/crmf/src/controls.rs +++ b/crmf/src/controls.rs @@ -1,8 +1,9 @@ //! Controls-related types +use alloc::boxed::Box; use alloc::vec::Vec; use der::asn1::{BitString, OctetString, Utf8StringRef}; -use der::{Choice, Enumerated, Header, Reader, Sequence, Writer}; +use der::{Choice, Enumerated, Sequence}; use cms::enveloped_data::EnvelopedData; use spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoOwned}; @@ -214,139 +215,6 @@ pub struct EncryptedValue { pub enc_value: BitString, } -use alloc::boxed::Box; - -impl<'a> der::DecodeValue<'a> for Box { - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - use ::der::Reader as _; - let ev: EncryptedValue = reader.read_nested(header.length, |reader| { - let intended_alg = - ::der::asn1::ContextSpecific::decode_explicit(reader, ::der::TagNumber::N0)? - .map(|cs| cs.value); - let sym_alg = - ::der::asn1::ContextSpecific::decode_explicit(reader, ::der::TagNumber::N1)? - .map(|cs| cs.value); - let enc_sym_key = - ::der::asn1::ContextSpecific::decode_explicit(reader, ::der::TagNumber::N2)? - .map(|cs| cs.value); - let key_alg = - ::der::asn1::ContextSpecific::decode_explicit(reader, ::der::TagNumber::N3)? - .map(|cs| cs.value); - let value_hint = - ::der::asn1::ContextSpecific::decode_explicit(reader, ::der::TagNumber::N4)? - .map(|cs| cs.value); - let enc_value = reader.decode()?; - Ok(EncryptedValue { - intended_alg, - sym_alg, - enc_sym_key, - key_alg, - value_hint, - enc_value, - }) - })?; - Ok(Box::new(ev)) - } -} -impl der::EncodeValue for Box { - fn value_len(&self) -> ::der::Result<::der::Length> { - use ::der::Encode as _; - [ - self.intended_alg - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N0, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encoded_len()?, - self.sym_alg - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N1, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encoded_len()?, - self.enc_sym_key - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N2, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encoded_len()?, - self.key_alg - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N3, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encoded_len()?, - self.value_hint - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N4, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encoded_len()?, - self.enc_value.encoded_len()?, - ] - .into_iter() - .try_fold(::der::Length::ZERO, |acc, len| acc + len) - } - - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { - use ::der::Encode as _; - self.intended_alg - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N0, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encode(writer)?; - self.sym_alg - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N1, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encode(writer)?; - self.enc_sym_key - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N2, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encode(writer)?; - self.key_alg - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N3, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encode(writer)?; - self.value_hint - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N4, - tag_mode: ::der::TagMode::Explicit, - value: field, - }) - .encode(writer)?; - self.enc_value.encode(writer)?; - Ok(()) - } -} - -impl ::der::Sequence<'_> for Box {} - /// The `KeyGenParameters` control is defined in [RFC 4211 Section 6.4]. /// /// ```text diff --git a/crmf/src/pop.rs b/crmf/src/pop.rs index 0017f0c2a..dbb56ac3b 100644 --- a/crmf/src/pop.rs +++ b/crmf/src/pop.rs @@ -62,62 +62,6 @@ pub struct PopoSigningKey { pub signature: BitString, } -impl<'__der_lifetime> ::der::DecodeValue<'__der_lifetime> for Box { - fn decode_value>( - reader: &mut R, - header: ::der::Header, - ) -> ::der::Result { - use ::der::Reader as _; - let psk = reader.read_nested(header.length, |reader| { - let poposk_input = - ::der::asn1::ContextSpecific::decode_implicit(reader, ::der::TagNumber::N0)? - .map(|cs| cs.value); - let alg_id = reader.decode()?; - let signature = reader.decode()?; - Ok(PopoSigningKey { - poposk_input, - alg_id, - signature, - }) - })?; - Ok(Box::new(psk)) - } -} -impl ::der::EncodeValue for Box { - fn value_len(&self) -> ::der::Result<::der::Length> { - use ::der::Encode as _; - [ - self.poposk_input - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N0, - tag_mode: ::der::TagMode::Implicit, - value: field, - }) - .encoded_len()?, - self.alg_id.encoded_len()?, - self.signature.encoded_len()?, - ] - .into_iter() - .try_fold(::der::Length::ZERO, |acc, len| acc + len) - } - fn encode_value(&self, writer: &mut impl ::der::Writer) -> ::der::Result<()> { - use ::der::Encode as _; - self.poposk_input - .as_ref() - .map(|field| ::der::asn1::ContextSpecificRef { - tag_number: ::der::TagNumber::N0, - tag_mode: ::der::TagMode::Implicit, - value: field, - }) - .encode(writer)?; - self.alg_id.encode(writer)?; - self.signature.encode(writer)?; - Ok(()) - } -} -impl<'__der_lifetime> ::der::Sequence<'__der_lifetime> for Box {} - /// The `POPOSigningKeyInput` type is defined in [RFC 4211 Section 4.1]. /// /// ```text diff --git a/der/src/asn1/sequence.rs b/der/src/asn1/sequence.rs index 412be84bc..ad4a5d52e 100644 --- a/der/src/asn1/sequence.rs +++ b/der/src/asn1/sequence.rs @@ -5,6 +5,9 @@ use crate::{ BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, Tag, Writer, }; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + /// Marker trait for ASN.1 `SEQUENCE`s. /// /// This is mainly used for custom derive. @@ -17,6 +20,9 @@ where const TAG: Tag = Tag::Sequence; } +#[cfg(feature = "alloc")] +impl<'a, T> Sequence<'a> for Box where T: Sequence<'a> {} + /// The [`SequenceRef`] type provides raw access to the octets which comprise a /// DER-encoded `SEQUENCE`. /// diff --git a/der/src/decode.rs b/der/src/decode.rs index 1c63b322a..996faca62 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -8,6 +8,9 @@ use crate::{pem::PemLabel, PemReader}; #[cfg(doc)] use crate::{Length, Tag}; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + /// Decoding trait. /// /// This trait provides the core abstraction upon which all decoding operations @@ -74,3 +77,13 @@ pub trait DecodeValue<'a>: Sized { /// Attempt to decode this message using the provided [`Reader`]. fn decode_value>(reader: &mut R, header: Header) -> Result; } + +#[cfg(feature = "alloc")] +impl<'a, T> DecodeValue<'a> for Box +where + T: DecodeValue<'a>, +{ + fn decode_value>(reader: &mut R, header: Header) -> Result { + Ok(Box::new(T::decode_value(reader, header)?)) + } +} diff --git a/der/src/encode.rs b/der/src/encode.rs index 6536bccdc..0a227eecd 100644 --- a/der/src/encode.rs +++ b/der/src/encode.rs @@ -3,7 +3,7 @@ use crate::{Header, Length, Result, SliceWriter, Tagged, Writer}; #[cfg(feature = "alloc")] -use {alloc::vec::Vec, core::iter}; +use {alloc::boxed::Box, alloc::vec::Vec, core::iter}; #[cfg(feature = "pem")] use { @@ -131,3 +131,16 @@ pub trait EncodeValue { /// provided [`Writer`]. fn encode_value(&self, encoder: &mut impl Writer) -> Result<()>; } + +#[cfg(feature = "alloc")] +impl EncodeValue for Box +where + T: EncodeValue, +{ + fn value_len(&self) -> Result { + T::value_len(self) + } + fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { + T::encode_value(self, writer) + } +} diff --git a/x509-cert/src/certificate.rs b/x509-cert/src/certificate.rs index a5701f502..bb2a8603c 100644 --- a/x509-cert/src/certificate.rs +++ b/x509-cert/src/certificate.rs @@ -7,7 +7,7 @@ use core::cmp::Ordering; use const_oid::AssociatedOid; use der::asn1::BitString; -use der::{Decode, Enumerated, Error, ErrorKind, Header, Reader, Sequence, ValueOrd, Writer}; +use der::{Decode, Enumerated, Error, ErrorKind, Sequence, ValueOrd}; use spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoOwned}; #[cfg(feature = "pem")] @@ -172,44 +172,3 @@ impl PemLabel for Certificate { /// /// [RFC 6066]: https://datatracker.ietf.org/doc/html/rfc6066#section-10.1 pub type PkiPath = Vec; - -use alloc::boxed::Box; - -impl<'a> der::DecodeValue<'a> for Box { - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - use ::der::Reader as _; - let c: Certificate = reader.read_nested(header.length, |reader| { - let tbs_certificate = reader.decode()?; - let signature_algorithm = reader.decode()?; - let signature = reader.decode()?; - Ok(Certificate { - tbs_certificate, - signature_algorithm, - signature, - }) - })?; - Ok(Box::new(c)) - } -} -impl der::EncodeValue for Box { - fn value_len(&self) -> ::der::Result<::der::Length> { - use ::der::Encode as _; - [ - self.tbs_certificate.encoded_len()?, - self.signature_algorithm.encoded_len()?, - self.signature.encoded_len()?, - ] - .into_iter() - .try_fold(::der::Length::ZERO, |acc, len| acc + len) - } - - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { - use ::der::Encode as _; - self.tbs_certificate.encode(writer)?; - self.signature_algorithm.encode(writer)?; - self.signature.encode(writer)?; - Ok(()) - } -} - -impl ::der::Sequence<'_> for Box {}