From 1ff2bf5ef5b04861bc4e1b16525daafe94175b02 Mon Sep 17 00:00:00 2001 From: turbocool3r Date: Mon, 8 May 2023 23:16:51 +0300 Subject: [PATCH] Add custom error types support to the Decode and DecodeValue traits. --- crmf/src/pop.rs | 2 + der/derive/src/choice.rs | 2 + der/derive/src/enumerated.rs | 2 + der/derive/src/sequence.rs | 2 + der/src/asn1/any.rs | 58 +++++++++++++---------- der/src/asn1/bit_string.rs | 6 +++ der/src/asn1/bmp_string.rs | 2 + der/src/asn1/boolean.rs | 2 + der/src/asn1/context_specific.rs | 39 ++++++++------- der/src/asn1/generalized_time.rs | 16 +++++-- der/src/asn1/integer/int.rs | 12 +++-- der/src/asn1/integer/uint.rs | 10 +++- der/src/asn1/internal_macros.rs | 8 ++-- der/src/asn1/null.rs | 4 ++ der/src/asn1/octet_string.rs | 32 ++++++++----- der/src/asn1/oid.rs | 2 + der/src/asn1/optional.rs | 16 ++++--- der/src/asn1/real.rs | 6 ++- der/src/asn1/sequence.rs | 5 +- der/src/asn1/sequence_of.rs | 38 ++++++++------- der/src/asn1/set_of.rs | 58 ++++++++++++----------- der/src/asn1/utc_time.rs | 2 + der/src/asn1/utf8_string.rs | 2 + der/src/bytes_owned.rs | 2 + der/src/bytes_ref.rs | 2 + der/src/decode.rs | 42 ++++++++++------ der/src/document.rs | 58 +++++++++++++---------- der/src/header.rs | 4 +- der/src/length.rs | 4 ++ der/src/lib.rs | 2 + der/src/reader.rs | 42 +++++++++------- der/src/reader/slice.rs | 20 ++++---- der/src/str_owned.rs | 6 ++- der/src/str_ref.rs | 4 +- der/src/tag.rs | 2 + gss-api/src/lib.rs | 2 + pkcs1/src/params.rs | 5 ++ pkcs1/src/private_key.rs | 2 + pkcs1/src/private_key/other_prime_info.rs | 2 + pkcs1/src/public_key.rs | 1 + pkcs1/src/version.rs | 1 + pkcs12/src/safe_bag.rs | 2 + pkcs5/src/lib.rs | 2 + pkcs5/src/pbes1.rs | 4 ++ pkcs5/src/pbes2.rs | 4 ++ pkcs5/src/pbes2/kdf.rs | 5 ++ pkcs5/src/pbes2/kdf/salt.rs | 2 + pkcs8/src/encrypted_private_key_info.rs | 2 + pkcs8/src/private_key_info.rs | 2 + pkcs8/src/version.rs | 2 + sec1/src/parameters.rs | 2 + sec1/src/private_key.rs | 2 + spki/src/algorithm.rs | 11 +++-- spki/src/spki.rs | 30 ++++++------ x509-cert/src/certificate.rs | 12 +++-- x509-cert/src/macros.rs | 2 + x509-cert/src/serial_number.rs | 2 + x509-cert/tests/certificate.rs | 4 ++ 58 files changed, 400 insertions(+), 217 deletions(-) diff --git a/crmf/src/pop.rs b/crmf/src/pop.rs index dbb56ac3b..e2aa88bf7 100644 --- a/crmf/src/pop.rs +++ b/crmf/src/pop.rs @@ -231,6 +231,8 @@ impl<'a> ::der::Choice<'a> for EncKeyWithIdChoice<'a> { } } impl<'a> ::der::Decode<'a> for EncKeyWithIdChoice<'a> { + type Error = ::der::Error; + fn decode>(reader: &mut R) -> ::der::Result { let t = reader.peek_tag()?; if t == as ::der::FixedTag>::TAG { diff --git a/der/derive/src/choice.rs b/der/derive/src/choice.rs index fb2ff0c91..707ca9c8e 100644 --- a/der/derive/src/choice.rs +++ b/der/derive/src/choice.rs @@ -96,6 +96,8 @@ impl DeriveChoice { } impl<#lifetime> ::der::Decode<#lifetime> for #ident<#lt_params> { + type Error = ::der::Error; + fn decode>(reader: &mut R) -> ::der::Result { use der::Reader as _; match reader.peek_tag()? { diff --git a/der/derive/src/enumerated.rs b/der/derive/src/enumerated.rs index ecf863557..303014140 100644 --- a/der/derive/src/enumerated.rs +++ b/der/derive/src/enumerated.rs @@ -117,6 +117,8 @@ impl DeriveEnumerated { quote! { impl<#default_lifetime> ::der::DecodeValue<#default_lifetime> for #ident { + type Error = ::der::Error; + fn decode_value>( reader: &mut R, header: ::der::Header diff --git a/der/derive/src/sequence.rs b/der/derive/src/sequence.rs index 26fc59f7c..81ca3d729 100644 --- a/der/derive/src/sequence.rs +++ b/der/derive/src/sequence.rs @@ -86,6 +86,8 @@ impl DeriveSequence { quote! { impl #impl_generics ::der::DecodeValue<#lifetime> for #ident #ty_generics #where_clause { + type Error = ::der::Error; + fn decode_value>( reader: &mut R, header: ::der::Header, diff --git a/der/src/asn1/any.rs b/der/src/asn1/any.rs index 2682b56ef..1ed9286c0 100644 --- a/der/src/asn1/any.rs +++ b/der/src/asn1/any.rs @@ -4,7 +4,7 @@ use crate::{ BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, Header, Length, - Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer, + Reader, SliceReader, Tag, Tagged, ValueOrd, Writer, }; use core::cmp::Ordering; @@ -40,7 +40,7 @@ impl<'a> AnyRef<'a> { }; /// Create a new [`AnyRef`] from the provided [`Tag`] and DER bytes. - pub fn new(tag: Tag, bytes: &'a [u8]) -> Result { + pub fn new(tag: Tag, bytes: &'a [u8]) -> Result { let value = BytesRef::new(bytes).map_err(|_| ErrorKind::Length { tag })?; Ok(Self { tag, value }) } @@ -56,12 +56,12 @@ impl<'a> AnyRef<'a> { } /// Attempt to decode this [`AnyRef`] type into the inner value. - pub fn decode_as(self) -> Result + pub fn decode_as(self) -> Result>::Error> where T: Choice<'a> + DecodeValue<'a>, { if !T::can_decode(self.tag) { - return Err(self.tag.unexpected_error(None)); + return Err(self.tag.unexpected_error(None).into()); } let header = Header { @@ -71,7 +71,7 @@ impl<'a> AnyRef<'a> { let mut decoder = SliceReader::new(self.value())?; let result = T::decode_value(&mut decoder, header)?; - decoder.finish(result) + Ok(decoder.finish(result)?) } /// Is this value an ASN.1 `NULL` value? @@ -81,14 +81,15 @@ impl<'a> AnyRef<'a> { /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new /// nested reader and calling the provided argument with it. - pub fn sequence(self, f: F) -> Result + pub fn sequence(self, f: F) -> Result where - F: FnOnce(&mut SliceReader<'a>) -> Result, + F: FnOnce(&mut SliceReader<'a>) -> Result, + E: From, { self.tag.assert_eq(Tag::Sequence)?; let mut reader = SliceReader::new(self.value.as_slice())?; let result = f(&mut reader)?; - reader.finish(result) + Ok(reader.finish(result)?) } } @@ -99,14 +100,18 @@ impl<'a> Choice<'a> for AnyRef<'a> { } impl<'a> Decode<'a> for AnyRef<'a> { - fn decode>(reader: &mut R) -> Result> { + type Error = Error; + + fn decode>(reader: &mut R) -> Result, Error> { let header = Header::decode(reader)?; Self::decode_value(reader, header) } } impl<'a> DecodeValue<'a> for AnyRef<'a> { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(Self { tag: header.tag, value: BytesRef::decode_value(reader, header)?, @@ -115,11 +120,11 @@ impl<'a> DecodeValue<'a> for AnyRef<'a> { } impl EncodeValue for AnyRef<'_> { - fn value_len(&self) -> Result { + fn value_len(&self) -> Result { Ok(self.value.len()) } - fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { writer.write(self.value()) } } @@ -131,7 +136,7 @@ impl Tagged for AnyRef<'_> { } impl ValueOrd for AnyRef<'_> { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { self.value.der_cmp(&other.value) } } @@ -145,7 +150,7 @@ impl<'a> From> for BytesRef<'a> { impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> { type Error = Error; - fn try_from(bytes: &'a [u8]) -> Result> { + fn try_from(bytes: &'a [u8]) -> Result, Error> { AnyRef::from_der(bytes) } } @@ -175,7 +180,7 @@ mod allocating { impl Any { /// Create a new [`Any`] from the provided [`Tag`] and DER bytes. - pub fn new(tag: Tag, bytes: impl Into>) -> Result { + pub fn new(tag: Tag, bytes: impl Into>) -> Result { let value = BytesOwned::new(bytes)?; // Ensure the tag and value are a valid `AnyRef`. @@ -189,7 +194,7 @@ mod allocating { } /// Attempt to decode this [`Any`] type into the inner value. - pub fn decode_as<'a, T>(&'a self) -> Result + pub fn decode_as<'a, T>(&'a self) -> Result>::Error> where T: Choice<'a> + DecodeValue<'a>, { @@ -197,7 +202,7 @@ mod allocating { } /// Encode the provided type as an [`Any`] value. - pub fn encode_from(msg: &T) -> Result + pub fn encode_from(msg: &T) -> Result where T: Tagged + EncodeValue, { @@ -211,9 +216,10 @@ mod allocating { /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new /// nested reader and calling the provided argument with it. - pub fn sequence<'a, F, T>(&'a self, f: F) -> Result + pub fn sequence<'a, F, T, E>(&'a self, f: F) -> Result where - F: FnOnce(&mut SliceReader<'a>) -> Result, + F: FnOnce(&mut SliceReader<'a>) -> Result, + E: From, { AnyRef::from(self).sequence(f) } @@ -234,25 +240,29 @@ mod allocating { } impl<'a> Decode<'a> for Any { - fn decode>(reader: &mut R) -> Result { + type Error = Error; + + fn decode>(reader: &mut R) -> Result { let header = Header::decode(reader)?; Self::decode_value(reader, header) } } impl<'a> DecodeValue<'a> for Any { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { let value = reader.read_vec(header.length)?; Self::new(header.tag, value) } } impl EncodeValue for Any { - fn value_len(&self) -> Result { + fn value_len(&self) -> Result { Ok(self.value.len()) } - fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { writer.write(self.value.as_slice()) } } @@ -271,7 +281,7 @@ mod allocating { } impl ValueOrd for Any { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { self.value.der_cmp(&other.value) } } diff --git a/der/src/asn1/bit_string.rs b/der/src/asn1/bit_string.rs index cd9f6d3fd..c30a06042 100644 --- a/der/src/asn1/bit_string.rs +++ b/der/src/asn1/bit_string.rs @@ -120,6 +120,8 @@ impl<'a> BitStringRef<'a> { impl_any_conversions!(BitStringRef<'a>, 'a); impl<'a> DecodeValue<'a> for BitStringRef<'a> { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let header = Header { tag: header.tag, @@ -309,6 +311,8 @@ mod allocating { impl_any_conversions!(BitString); impl<'a> DecodeValue<'a> for BitString { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let inner_len = (header.length - Length::ONE)?; let unused_bits = reader.read_byte()?; @@ -442,6 +446,8 @@ where T::Type: From, T::Type: core::ops::Shl, { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let position = reader.position(); let bits = BitStringRef::decode_value(reader, header)?; diff --git a/der/src/asn1/bmp_string.rs b/der/src/asn1/bmp_string.rs index ad5e1a2d1..fa42d1ae4 100644 --- a/der/src/asn1/bmp_string.rs +++ b/der/src/asn1/bmp_string.rs @@ -90,6 +90,8 @@ impl AsRef<[u8]> for BmpString { } impl<'a> DecodeValue<'a> for BmpString { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Self::from_ucs2(reader.read_vec(header.length)?) } diff --git a/der/src/asn1/boolean.rs b/der/src/asn1/boolean.rs index e99ad44b6..3bbc03341 100644 --- a/der/src/asn1/boolean.rs +++ b/der/src/asn1/boolean.rs @@ -15,6 +15,8 @@ const TRUE_OCTET: u8 = 0b11111111; const FALSE_OCTET: u8 = 0b00000000; impl<'a> DecodeValue<'a> for bool { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { if header.length != Length::ONE { return Err(reader.error(ErrorKind::Length { tag: Self::TAG })); diff --git a/der/src/asn1/context_specific.rs b/der/src/asn1/context_specific.rs index 09031f0d4..6867029da 100644 --- a/der/src/asn1/context_specific.rs +++ b/der/src/asn1/context_specific.rs @@ -2,7 +2,7 @@ use crate::{ asn1::AnyRef, Choice, Decode, DecodeValue, DerOrd, Encode, EncodeValue, EncodeValueRef, Error, - Header, Length, Reader, Result, Tag, TagMode, TagNumber, Tagged, ValueOrd, Writer, + Header, Length, Reader, Tag, TagMode, TagNumber, Tagged, ValueOrd, Writer, }; use core::cmp::Ordering; @@ -42,7 +42,7 @@ impl ContextSpecific { pub fn decode_explicit<'a, R: Reader<'a>>( reader: &mut R, tag_number: TagNumber, - ) -> Result> + ) -> Result, T::Error> where T: Decode<'a>, { @@ -58,16 +58,16 @@ impl ContextSpecific { pub fn decode_implicit<'a, R: Reader<'a>>( reader: &mut R, tag_number: TagNumber, - ) -> Result> + ) -> Result, T::Error> where T: DecodeValue<'a> + Tagged, { - Self::decode_with(reader, tag_number, |reader| { + Self::decode_with::<_, _, T::Error>(reader, tag_number, |reader| { let header = Header::decode(reader)?; let value = T::decode_value(reader, header)?; if header.tag.is_constructed() != value.tag().is_constructed() { - return Err(header.tag.non_canonical_error()); + return Err(header.tag.non_canonical_error().into()); } Ok(Self { @@ -80,13 +80,14 @@ impl ContextSpecific { /// Attempt to decode a context-specific field with the given /// helper callback. - fn decode_with<'a, F, R: Reader<'a>>( + fn decode_with<'a, F, R: Reader<'a>, E>( reader: &mut R, tag_number: TagNumber, f: F, - ) -> Result> + ) -> Result, E> where - F: FnOnce(&mut R) -> Result, + F: FnOnce(&mut R) -> Result, + E: From, { while let Some(octet) = reader.peek_byte() { let tag = Tag::try_from(octet)?; @@ -117,7 +118,9 @@ impl<'a, T> Decode<'a> for ContextSpecific where T: Decode<'a>, { - fn decode>(reader: &mut R) -> Result { + type Error = T::Error; + + fn decode>(reader: &mut R) -> Result { let header = Header::decode(reader)?; match header.tag { @@ -129,7 +132,7 @@ where tag_mode: TagMode::default(), value: reader.read_nested(header.length, |reader| T::decode(reader))?, }), - tag => Err(tag.unexpected_error(None)), + tag => Err(tag.unexpected_error(None).into()), } } } @@ -138,14 +141,14 @@ impl EncodeValue for ContextSpecific where T: EncodeValue + Tagged, { - fn value_len(&self) -> Result { + fn value_len(&self) -> Result { match self.tag_mode { TagMode::Explicit => self.value.encoded_len(), TagMode::Implicit => self.value.value_len(), } } - fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { match self.tag_mode { TagMode::Explicit => self.value.encode(writer), TagMode::Implicit => self.value.encode_value(writer), @@ -174,9 +177,9 @@ impl<'a, T> TryFrom> for ContextSpecific where T: Decode<'a>, { - type Error = Error; + type Error = T::Error; - fn try_from(any: AnyRef<'a>) -> Result> { + fn try_from(any: AnyRef<'a>) -> Result, Self::Error> { match any.tag() { Tag::ContextSpecific { number, @@ -186,7 +189,7 @@ where tag_mode: TagMode::default(), value: T::from_der(any.value())?, }), - tag => Err(tag.unexpected_error(None)), + tag => Err(tag.unexpected_error(None).into()), } } } @@ -195,7 +198,7 @@ impl ValueOrd for ContextSpecific where T: EncodeValue + ValueOrd + Tagged, { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { match self.tag_mode { TagMode::Explicit => self.der_cmp(other), TagMode::Implicit => self.value_cmp(other), @@ -235,11 +238,11 @@ impl<'a, T> EncodeValue for ContextSpecificRef<'a, T> where T: EncodeValue + Tagged, { - fn value_len(&self) -> Result { + fn value_len(&self) -> Result { self.encoder().value_len() } - fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { self.encoder().encode_value(writer) } } diff --git a/der/src/asn1/generalized_time.rs b/der/src/asn1/generalized_time.rs index e2b509008..7c77d26bf 100644 --- a/der/src/asn1/generalized_time.rs +++ b/der/src/asn1/generalized_time.rs @@ -4,15 +4,13 @@ use crate::{ datetime::{self, DateTime}, ord::OrdIsValueOrd, - DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, Writer, + DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, + Writer, }; use core::time::Duration; #[cfg(feature = "std")] -use { - crate::{asn1::AnyRef, Error}, - std::time::SystemTime, -}; +use {crate::asn1::AnyRef, std::time::SystemTime}; #[cfg(feature = "time")] use time::PrimitiveDateTime; @@ -77,6 +75,8 @@ impl GeneralizedTime { impl_any_conversions!(GeneralizedTime); impl<'a> DecodeValue<'a> for GeneralizedTime { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { if Self::LENGTH != usize::try_from(header.length)? { return Err(Self::TAG.value_error()); @@ -166,6 +166,8 @@ impl From<&DateTime> for GeneralizedTime { } impl<'a> DecodeValue<'a> for DateTime { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(GeneralizedTime::decode_value(reader, header)?.into()) } @@ -189,6 +191,8 @@ impl OrdIsValueOrd for DateTime {} #[cfg(feature = "std")] impl<'a> DecodeValue<'a> for SystemTime { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(GeneralizedTime::decode_value(reader, header)?.into()) } @@ -256,6 +260,8 @@ impl OrdIsValueOrd for SystemTime {} #[cfg(feature = "time")] impl<'a> DecodeValue<'a> for PrimitiveDateTime { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { GeneralizedTime::decode_value(reader, header)?.try_into() } diff --git a/der/src/asn1/integer/int.rs b/der/src/asn1/integer/int.rs index ccec93fe4..4e7755160 100644 --- a/der/src/asn1/integer/int.rs +++ b/der/src/asn1/integer/int.rs @@ -14,7 +14,9 @@ macro_rules! impl_encoding_traits { ($($int:ty => $uint:ty),+) => { $( impl<'a> DecodeValue<'a> for $int { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = $crate::Error; + + fn decode_value>(reader: &mut R, header: Header) -> $crate::Result { let mut buf = [0u8; Self::BITS as usize / 8]; let max_length = u32::from(header.length) as usize; @@ -122,6 +124,8 @@ impl<'a> IntRef<'a> { impl_any_conversions!(IntRef<'a>, 'a); impl<'a> DecodeValue<'a> for IntRef<'a> { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let bytes = BytesRef::decode_value(reader, header)?; validate_canonical(bytes.as_slice())?; @@ -167,8 +171,8 @@ mod allocating { asn1::Uint, ord::OrdIsValueOrd, referenced::{OwnedToRef, RefToOwned}, - BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result, - Tag, Writer, + BytesOwned, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, + Result, Tag, Writer, }; use alloc::vec::Vec; @@ -214,6 +218,8 @@ mod allocating { impl_any_conversions!(Int); impl<'a> DecodeValue<'a> for Int { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let bytes = BytesOwned::decode_value(reader, header)?; validate_canonical(bytes.as_slice())?; diff --git a/der/src/asn1/integer/uint.rs b/der/src/asn1/integer/uint.rs index a9bb966b0..0c65f25f8 100644 --- a/der/src/asn1/integer/uint.rs +++ b/der/src/asn1/integer/uint.rs @@ -14,6 +14,8 @@ macro_rules! impl_encoding_traits { ($($uint:ty),+) => { $( impl<'a> DecodeValue<'a> for $uint { + type Error = $crate::Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { // Integers always encodes as a signed value, unsigned gets a leading 0x00 that // needs to be stripped off. We need to provide room for it. @@ -114,6 +116,8 @@ impl<'a> UintRef<'a> { impl_any_conversions!(UintRef<'a>, 'a); impl<'a> DecodeValue<'a> for UintRef<'a> { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let bytes = BytesRef::decode_value(reader, header)?.as_slice(); let result = Self::new(decode_to_slice(bytes)?)?; @@ -160,8 +164,8 @@ mod allocating { use crate::{ ord::OrdIsValueOrd, referenced::{OwnedToRef, RefToOwned}, - BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result, - Tag, Writer, + BytesOwned, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, + Result, Tag, Writer, }; /// Unsigned arbitrary precision ASN.1 `INTEGER` type. @@ -206,6 +210,8 @@ mod allocating { impl_any_conversions!(Uint); impl<'a> DecodeValue<'a> for Uint { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let bytes = BytesOwned::decode_value(reader, header)?; let result = Self::new(decode_to_slice(bytes.as_slice())?)?; diff --git a/der/src/asn1/internal_macros.rs b/der/src/asn1/internal_macros.rs index 10ad99d23..1872c73c4 100644 --- a/der/src/asn1/internal_macros.rs +++ b/der/src/asn1/internal_macros.rs @@ -6,7 +6,7 @@ macro_rules! impl_any_conversions { impl<'__der: $($li),*, $($li),*> TryFrom<$crate::AnyRef<'__der>> for $type { type Error = $crate::Error; - fn try_from(any: $crate::AnyRef<'__der>) -> Result<$type> { + fn try_from(any: $crate::AnyRef<'__der>) -> $crate::Result<$type> { any.decode_as() } } @@ -15,7 +15,7 @@ macro_rules! impl_any_conversions { impl<'__der: $($li),*, $($li),*> TryFrom<&'__der $crate::Any> for $type { type Error = $crate::Error; - fn try_from(any: &'__der $crate::Any) -> Result<$type> { + fn try_from(any: &'__der $crate::Any) -> $crate::Result<$type> { any.decode_as() } } @@ -48,7 +48,9 @@ macro_rules! impl_string_type { } impl<'__der: $($li),*, $($li),*> DecodeValue<'__der> for $type { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = $crate::Error; + + fn decode_value>(reader: &mut R, header: Header) -> $crate::Result { Self::new(BytesRef::decode_value(reader, header)?.as_slice()) } } diff --git a/der/src/asn1/null.rs b/der/src/asn1/null.rs index 43847218c..be66e02cf 100644 --- a/der/src/asn1/null.rs +++ b/der/src/asn1/null.rs @@ -12,6 +12,8 @@ pub struct Null; impl_any_conversions!(Null); impl<'a> DecodeValue<'a> for Null { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { if header.length.is_zero() { Ok(Null) @@ -58,6 +60,8 @@ impl<'a> From<()> for AnyRef<'a> { } impl<'a> DecodeValue<'a> for () { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Null::decode_value(reader, header)?; Ok(()) diff --git a/der/src/asn1/octet_string.rs b/der/src/asn1/octet_string.rs index 12a1e0e4d..3a0a87a2d 100644 --- a/der/src/asn1/octet_string.rs +++ b/der/src/asn1/octet_string.rs @@ -1,8 +1,8 @@ //! ASN.1 `OCTET STRING` support. use crate::{ - asn1::AnyRef, ord::OrdIsValueOrd, BytesRef, Decode, DecodeValue, EncodeValue, ErrorKind, - FixedTag, Header, Length, Reader, Result, Tag, Writer, + asn1::AnyRef, ord::OrdIsValueOrd, BytesRef, Decode, DecodeValue, EncodeValue, Error, ErrorKind, + FixedTag, Header, Length, Reader, Tag, Writer, }; /// ASN.1 `OCTET STRING` type: borrowed form. @@ -18,7 +18,7 @@ pub struct OctetStringRef<'a> { impl<'a> OctetStringRef<'a> { /// Create a new ASN.1 `OCTET STRING` from a byte slice. - pub fn new(slice: &'a [u8]) -> Result { + pub fn new(slice: &'a [u8]) -> Result { BytesRef::new(slice) .map(|inner| Self { inner }) .map_err(|_| ErrorKind::Length { tag: Self::TAG }.into()) @@ -40,7 +40,7 @@ impl<'a> OctetStringRef<'a> { } /// Parse `T` from this `OCTET STRING`'s contents. - pub fn decode_into>(&self) -> Result { + pub fn decode_into>(&self) -> Result { Decode::from_der(self.as_bytes()) } } @@ -54,18 +54,20 @@ impl AsRef<[u8]> for OctetStringRef<'_> { } impl<'a> DecodeValue<'a> for OctetStringRef<'a> { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { let inner = BytesRef::decode_value(reader, header)?; Ok(Self { inner }) } } impl EncodeValue for OctetStringRef<'_> { - fn value_len(&self) -> Result { + fn value_len(&self) -> Result { self.inner.value_len() } - fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { self.inner.encode_value(writer) } } @@ -117,7 +119,7 @@ mod allocating { impl OctetString { /// Create a new ASN.1 `OCTET STRING`. - pub fn new(bytes: impl Into>) -> Result { + pub fn new(bytes: impl Into>) -> Result { let inner = bytes.into(); // Ensure the bytes parse successfully as an `OctetStringRef` @@ -156,17 +158,19 @@ mod allocating { } impl<'a> DecodeValue<'a> for OctetString { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { Self::new(reader.read_vec(header.length)?) } } impl EncodeValue for OctetString { - fn value_len(&self) -> Result { + fn value_len(&self) -> Result { self.inner.len().try_into() } - fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { writer.write(&self.inner) } } @@ -217,10 +221,14 @@ mod allocating { #[cfg(feature = "bytes")] mod bytes { use super::OctetString; - use crate::{DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, Tag, Writer}; + use crate::{ + DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader, Result, Tag, Writer, + }; use bytes::Bytes; impl<'a> DecodeValue<'a> for Bytes { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { OctetString::decode_value(reader, header).map(|octet_string| octet_string.inner.into()) } diff --git a/der/src/asn1/oid.rs b/der/src/asn1/oid.rs index a0329a879..fc72ac178 100644 --- a/der/src/asn1/oid.rs +++ b/der/src/asn1/oid.rs @@ -10,6 +10,8 @@ use const_oid::ObjectIdentifier; use super::Any; impl<'a> DecodeValue<'a> for ObjectIdentifier { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let mut buf = [0u8; ObjectIdentifier::MAX_SIZE]; let slice = buf diff --git a/der/src/asn1/optional.rs b/der/src/asn1/optional.rs index ecda4f8ec..26e24d683 100644 --- a/der/src/asn1/optional.rs +++ b/der/src/asn1/optional.rs @@ -1,13 +1,15 @@ //! ASN.1 `OPTIONAL` as mapped to Rust's `Option` type -use crate::{Choice, Decode, DerOrd, Encode, Length, Reader, Result, Tag, Writer}; +use crate::{Choice, Decode, DerOrd, Encode, Error, Length, Reader, Tag, Writer}; use core::cmp::Ordering; impl<'a, T> Decode<'a> for Option where T: Choice<'a>, // NOTE: all `Decode + Tagged` types receive a blanket `Choice` impl { - fn decode>(reader: &mut R) -> Result> { + type Error = T::Error; + + fn decode>(reader: &mut R) -> Result, Self::Error> { if let Some(byte) = reader.peek_byte() { if T::can_decode(Tag::try_from(byte)?) { return T::decode(reader).map(Some); @@ -22,7 +24,7 @@ impl DerOrd for Option where T: DerOrd, { - fn der_cmp(&self, other: &Self) -> Result { + fn der_cmp(&self, other: &Self) -> Result { match self { Some(a) => match other { Some(b) => a.der_cmp(b), @@ -37,11 +39,11 @@ impl Encode for Option where T: Encode, { - fn encoded_len(&self) -> Result { + fn encoded_len(&self) -> Result { (&self).encoded_len() } - fn encode(&self, writer: &mut impl Writer) -> Result<()> { + fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> { (&self).encode(writer) } } @@ -50,14 +52,14 @@ impl Encode for &Option where T: Encode, { - fn encoded_len(&self) -> Result { + fn encoded_len(&self) -> Result { match self { Some(encodable) => encodable.encoded_len(), None => Ok(0u8.into()), } } - fn encode(&self, encoder: &mut impl Writer) -> Result<()> { + fn encode(&self, encoder: &mut impl Writer) -> Result<(), Error> { match self { Some(encodable) => encodable.encode(encoder), None => Ok(()), diff --git a/der/src/asn1/real.rs b/der/src/asn1/real.rs index 7239dadfe..99a95527e 100644 --- a/der/src/asn1/real.rs +++ b/der/src/asn1/real.rs @@ -8,13 +8,15 @@ )] use crate::{ - BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, StrRef, Tag, - Writer, + BytesRef, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader, Result, StrRef, + Tag, Writer, }; use super::integer::uint::strip_leading_zeroes; impl<'a> DecodeValue<'a> for f64 { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let bytes = BytesRef::decode_value(reader, header)?.as_slice(); diff --git a/der/src/asn1/sequence.rs b/der/src/asn1/sequence.rs index ad4a5d52e..6c217424e 100644 --- a/der/src/asn1/sequence.rs +++ b/der/src/asn1/sequence.rs @@ -2,7 +2,8 @@ //! `SEQUENCE`s to Rust structs. use crate::{ - BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, Tag, Writer, + BytesRef, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader, Result, Tag, + Writer, }; #[cfg(feature = "alloc")] @@ -33,6 +34,8 @@ pub struct SequenceRef<'a> { } impl<'a> DecodeValue<'a> for SequenceRef<'a> { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(Self { body: BytesRef::decode_value(reader, header)?, diff --git a/der/src/asn1/sequence_of.rs b/der/src/asn1/sequence_of.rs index 0f493fa7e..d32d66ef9 100644 --- a/der/src/asn1/sequence_of.rs +++ b/der/src/asn1/sequence_of.rs @@ -1,8 +1,8 @@ //! ASN.1 `SEQUENCE OF` support. use crate::{ - arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag, - Header, Length, Reader, Result, Tag, ValueOrd, Writer, + arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, + FixedTag, Header, Length, Reader, Tag, ValueOrd, Writer, }; use core::cmp::Ordering; @@ -29,7 +29,7 @@ impl SequenceOf { } /// Add an element to this [`SequenceOf`]. - pub fn add(&mut self, element: T) -> Result<()> { + pub fn add(&mut self, element: T) -> Result<(), Error> { self.inner.push(element) } @@ -66,7 +66,9 @@ impl<'a, T, const N: usize> DecodeValue<'a> for SequenceOf where T: Decode<'a>, { - fn decode_value>(reader: &mut R, header: Header) -> Result { + 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(); @@ -83,12 +85,12 @@ impl EncodeValue for SequenceOf where T: Encode, { - fn value_len(&self) -> Result { + 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<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { for elem in self.iter() { elem.encode(writer)?; } @@ -105,7 +107,7 @@ impl ValueOrd for SequenceOf where T: DerOrd, { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { iter_cmp(self.iter(), other.iter()) } } @@ -131,7 +133,9 @@ impl<'a, T, const N: usize> DecodeValue<'a> for [T; N] where T: Decode<'a>, { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = T::Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { let sequence_of = SequenceOf::::decode_value(reader, header)?; // TODO(tarcieri): use `[T; N]::try_map` instead of `expect` when stable @@ -141,7 +145,7 @@ where .into_array() .map(|elem| elem.expect("arrayvec length mismatch"))) } else { - Err(Self::TAG.length_error()) + Err(Self::TAG.length_error().into()) } } } @@ -150,12 +154,12 @@ impl EncodeValue for [T; N] where T: Encode, { - fn value_len(&self) -> Result { + 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<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { for elem in self { elem.encode(writer)?; } @@ -172,7 +176,7 @@ impl ValueOrd for [T; N] where T: DerOrd, { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { iter_cmp(self.iter(), other.iter()) } } @@ -182,7 +186,9 @@ impl<'a, T> DecodeValue<'a> for Vec where T: Decode<'a>, { - fn decode_value>(reader: &mut R, header: Header) -> Result { + 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(); @@ -200,12 +206,12 @@ impl EncodeValue for Vec where T: Encode, { - fn value_len(&self) -> Result { + 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<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { for elem in self { elem.encode(writer)?; } @@ -224,7 +230,7 @@ impl ValueOrd for Vec where T: DerOrd, { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { iter_cmp(self.iter(), other.iter()) } } diff --git a/der/src/asn1/set_of.rs b/der/src/asn1/set_of.rs index c28ff4dde..636d04ba2 100644 --- a/der/src/asn1/set_of.rs +++ b/der/src/asn1/set_of.rs @@ -12,7 +12,7 @@ use crate::{ arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, - ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, ValueOrd, Writer, + ErrorKind, FixedTag, Header, Length, Reader, Tag, ValueOrd, Writer, }; use core::cmp::Ordering; @@ -49,12 +49,12 @@ where /// Items MUST be added in lexicographical order according to the /// [`DerOrd`] impl on `T`. #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")] - pub fn add(&mut self, new_elem: T) -> Result<()> { + pub fn add(&mut self, new_elem: T) -> Result<(), Error> { self.insert_ordered(new_elem) } /// Insert an item into this [`SetOf`]. - pub fn insert(&mut self, item: T) -> Result<()> { + pub fn insert(&mut self, item: T) -> Result<(), Error> { self.inner.push(item)?; der_sort(self.inner.as_mut()) } @@ -63,7 +63,7 @@ where /// /// Items MUST be added in lexicographical order according to the /// [`DerOrd`] impl on `T`. - pub fn insert_ordered(&mut self, item: T) -> Result<()> { + pub fn insert_ordered(&mut self, item: T) -> Result<(), Error> { // Ensure set elements are lexicographically ordered if let Some(last) = self.inner.last() { check_der_ordering(last, &item)?; @@ -108,7 +108,9 @@ impl<'a, T, const N: usize> DecodeValue<'a> for SetOf where T: Decode<'a> + DerOrd, { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = T::Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { reader.read_nested(header.length, |reader| { let mut result = Self::new(); @@ -127,12 +129,12 @@ impl<'a, T, const N: usize> EncodeValue for SetOf where T: 'a + Decode<'a> + Encode + DerOrd, { - fn value_len(&self) -> Result { + 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<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { for elem in self.iter() { elem.encode(writer)?; } @@ -154,7 +156,7 @@ where { type Error = Error; - fn try_from(mut arr: [T; N]) -> Result> { + fn try_from(mut arr: [T; N]) -> Result, Error> { der_sort(&mut arr)?; let mut result = SetOf::new(); @@ -171,7 +173,7 @@ impl ValueOrd for SetOf where T: DerOrd, { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { iter_cmp(self.iter(), other.iter()) } } @@ -232,7 +234,7 @@ where /// Note: this is an inherent method instead of an impl of the /// [`FromIterator`] trait in order to be fallible. #[allow(clippy::should_implement_trait)] - pub fn from_iter(iter: I) -> Result + pub fn from_iter(iter: I) -> Result where I: IntoIterator, { @@ -244,7 +246,7 @@ where /// Items MUST be added in lexicographical order according to the /// [`DerOrd`] impl on `T`. #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")] - pub fn add(&mut self, item: T) -> Result<()> { + pub fn add(&mut self, item: T) -> Result<(), Error> { self.insert_ordered(item) } @@ -252,7 +254,7 @@ where /// /// Note: this is an inherent method instead of an impl of the /// [`Extend`] trait in order to be fallible. - pub fn extend(&mut self, iter: I) -> Result<()> + pub fn extend(&mut self, iter: I) -> Result<(), Error> where I: IntoIterator, { @@ -261,7 +263,7 @@ where } /// Insert an item into this [`SetOfVec`]. Must be unique. - pub fn insert(&mut self, item: T) -> Result<()> { + pub fn insert(&mut self, item: T) -> Result<(), Error> { self.inner.push(item); der_sort(&mut self.inner) } @@ -270,7 +272,7 @@ where /// /// Items MUST be added in lexicographical order according to the /// [`DerOrd`] impl on `T`. - pub fn insert_ordered(&mut self, item: T) -> Result<()> { + pub fn insert_ordered(&mut self, item: T) -> Result<(), Error> { // Ensure set elements are lexicographically ordered if let Some(last) = self.inner.last() { check_der_ordering(last, &item)?; @@ -326,7 +328,9 @@ impl<'a, T> DecodeValue<'a> for SetOfVec where T: Decode<'a> + DerOrd, { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = T::Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { reader.read_nested(header.length, |reader| { let mut inner = Vec::new(); @@ -346,12 +350,12 @@ impl<'a, T> EncodeValue for SetOfVec where T: 'a + Decode<'a> + Encode + DerOrd, { - fn value_len(&self) -> Result { + 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<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> { for elem in self.iter() { elem.encode(writer)?; } @@ -385,7 +389,8 @@ where { type Error = Error; - fn try_from(mut vec: Vec) -> Result> { + fn try_from(mut vec: Vec) -> Result, Error> { + // TODO(tarcieri): use `[T]::sort_by` here? der_sort(vec.as_mut_slice())?; Ok(SetOfVec { inner: vec }) } @@ -398,7 +403,7 @@ where { type Error = Error; - fn try_from(arr: [T; N]) -> Result> { + fn try_from(arr: [T; N]) -> Result, Error> { Vec::from(arr).try_into() } } @@ -408,7 +413,7 @@ impl ValueOrd for SetOfVec where T: DerOrd, { - fn value_cmp(&self, other: &Self) -> Result { + fn value_cmp(&self, other: &Self) -> Result { iter_cmp(self.iter(), other.iter()) } } @@ -421,11 +426,8 @@ where T: DerOrd + arbitrary::Arbitrary<'a>, { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - Self::try_from( - u.arbitrary_iter()? - .collect::, _>>()?, - ) - .map_err(|_| arbitrary::Error::IncorrectFormat) + Self::try_from(u.arbitrary_iter()?.collect::, _>>()?) + .map_err(|_| arbitrary::Error::IncorrectFormat) } fn size_hint(_depth: usize) -> (usize, Option) { @@ -434,7 +436,7 @@ where } /// Ensure set elements are lexicographically ordered using [`DerOrd`]. -fn check_der_ordering(a: &T, b: &T) -> Result<()> { +fn check_der_ordering(a: &T, b: &T) -> Result<(), Error> { match a.der_cmp(b)? { Ordering::Less => Ok(()), Ordering::Equal => Err(ErrorKind::SetDuplicate.into()), @@ -452,7 +454,7 @@ fn check_der_ordering(a: &T, b: &T) -> Result<()> { /// to support heapless `no_std` targets as well as to enable bubbling up /// sorting errors. #[allow(clippy::arithmetic_side_effects)] -fn der_sort(slice: &mut [T]) -> Result<()> { +fn der_sort(slice: &mut [T]) -> Result<(), Error> { for i in 0..slice.len() { let mut j = i; @@ -473,7 +475,7 @@ fn der_sort(slice: &mut [T]) -> Result<()> { /// Validate the elements of a `SET OF`, ensuring that they are all in order /// and that there are no duplicates. -fn validate(slice: &[T]) -> Result<()> { +fn validate(slice: &[T]) -> Result<(), Error> { if let Some(len) = slice.len().checked_sub(1) { for i in 0..len { let j = i.checked_add(1).ok_or(ErrorKind::Overflow)?; diff --git a/der/src/asn1/utc_time.rs b/der/src/asn1/utc_time.rs index f19d8f66c..74e8f0322 100644 --- a/der/src/asn1/utc_time.rs +++ b/der/src/asn1/utc_time.rs @@ -82,6 +82,8 @@ impl UtcTime { impl_any_conversions!(UtcTime); impl<'a> DecodeValue<'a> for UtcTime { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { if Self::LENGTH != usize::try_from(header.length)? { return Err(Self::TAG.value_error()); diff --git a/der/src/asn1/utf8_string.rs b/der/src/asn1/utf8_string.rs index 0ba570acb..9ffdc2044 100644 --- a/der/src/asn1/utf8_string.rs +++ b/der/src/asn1/utf8_string.rs @@ -116,6 +116,8 @@ impl<'a> TryFrom> for String { #[cfg(feature = "alloc")] impl<'a> DecodeValue<'a> for String { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(String::from_utf8(reader.read_vec(header.length)?)?) } diff --git a/der/src/bytes_owned.rs b/der/src/bytes_owned.rs index b5e928e3b..38f5855f0 100644 --- a/der/src/bytes_owned.rs +++ b/der/src/bytes_owned.rs @@ -53,6 +53,8 @@ impl AsRef<[u8]> for BytesOwned { } impl<'a> DecodeValue<'a> for BytesOwned { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { reader.read_vec(header.length).and_then(Self::new) } diff --git a/der/src/bytes_ref.rs b/der/src/bytes_ref.rs index 2cee4076e..ca40e3156 100644 --- a/der/src/bytes_ref.rs +++ b/der/src/bytes_ref.rs @@ -58,6 +58,8 @@ impl AsRef<[u8]> for BytesRef<'_> { } impl<'a> DecodeValue<'a> for BytesRef<'a> { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { reader.read_slice(header.length).and_then(Self::new) } diff --git a/der/src/decode.rs b/der/src/decode.rs index fe53341b3..ccb487f52 100644 --- a/der/src/decode.rs +++ b/der/src/decode.rs @@ -1,6 +1,6 @@ //! Trait definition for [`Decode`]. -use crate::{FixedTag, Header, Reader, Result, SliceReader}; +use crate::{Error, FixedTag, Header, Reader, SliceReader}; use core::marker::PhantomData; #[cfg(feature = "pem")] @@ -16,23 +16,28 @@ use alloc::boxed::Box; /// /// This trait provides the core abstraction upon which all decoding operations /// are based. -pub trait Decode<'a>: Sized { +pub trait Decode<'a>: Sized + 'a { + /// Type returned in the event of a decoding error. + type Error: From + 'static; + /// Attempt to decode this message using the provided decoder. - fn decode>(decoder: &mut R) -> Result; + fn decode>(decoder: &mut R) -> Result; /// Parse `Self` from the provided DER-encoded byte slice. - fn from_der(bytes: &'a [u8]) -> Result { + fn from_der(bytes: &'a [u8]) -> Result { let mut reader = SliceReader::new(bytes)?; let result = Self::decode(&mut reader)?; - reader.finish(result) + Ok(reader.finish(result)?) } } impl<'a, T> Decode<'a> for T where - T: DecodeValue<'a> + FixedTag, + T: DecodeValue<'a> + FixedTag + 'a, { - fn decode>(reader: &mut R) -> Result { + type Error = >::Error; + + fn decode>(reader: &mut R) -> Result>::Error> { let header = Header::decode(reader)?; header.tag.assert_eq(T::TAG)?; T::decode_value(reader, header) @@ -43,9 +48,11 @@ where /// implementations on structs with phantom fields. impl<'a, T> Decode<'a> for PhantomData where - T: ?Sized, + T: ?Sized + 'a, { - fn decode>(_reader: &mut R) -> Result> { + type Error = Error; + + fn decode>(_reader: &mut R) -> Result, Error> { Ok(PhantomData) } } @@ -69,14 +76,14 @@ impl DecodeOwned for T where T: for<'a> Decode<'a> {} #[cfg(feature = "pem")] pub trait DecodePem: DecodeOwned + PemLabel { /// Try to decode this type from PEM. - fn from_pem(pem: impl AsRef<[u8]>) -> Result; + fn from_pem(pem: impl AsRef<[u8]>) -> Result>::Error>; } #[cfg(feature = "pem")] -impl DecodePem for T { - fn from_pem(pem: impl AsRef<[u8]>) -> Result { +impl + PemLabel> DecodePem for T { + fn from_pem(pem: impl AsRef<[u8]>) -> Result { let mut reader = PemReader::new(pem.as_ref())?; - Self::validate_pem_label(reader.type_label())?; + Self::validate_pem_label(reader.type_label()).map_err(Error::from)?; T::decode(&mut reader) } } @@ -84,8 +91,11 @@ impl DecodePem for T { /// Decode the value part of a Tag-Length-Value encoded field, sans the [`Tag`] /// and [`Length`]. pub trait DecodeValue<'a>: Sized { + /// Type returned in the event of a decoding error. + type Error: From + 'static; + /// Attempt to decode this message using the provided [`Reader`]. - fn decode_value>(reader: &mut R, header: Header) -> Result; + fn decode_value>(reader: &mut R, header: Header) -> Result; } #[cfg(feature = "alloc")] @@ -93,7 +103,9 @@ impl<'a, T> DecodeValue<'a> for Box where T: DecodeValue<'a>, { - fn decode_value>(reader: &mut R, header: Header) -> Result { + type Error = T::Error; + + fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(Box::new(T::decode_value(reader, header)?)) } } diff --git a/der/src/document.rs b/der/src/document.rs index 78355a67a..716083584 100644 --- a/der/src/document.rs +++ b/der/src/document.rs @@ -1,6 +1,6 @@ //! ASN.1 DER-encoded documents stored on the heap. -use crate::{Decode, Encode, Error, FixedTag, Length, Reader, Result, SliceReader, Tag, Writer}; +use crate::{Decode, Encode, Error, FixedTag, Length, Reader, SliceReader, Tag, Writer}; use alloc::vec::Vec; use core::fmt::{self, Debug}; @@ -65,13 +65,13 @@ impl Document { /// Try to decode the inner ASN.1 DER message contained in this /// [`Document`] as the given type. - pub fn decode_msg<'a, T: Decode<'a>>(&'a self) -> Result { + pub fn decode_msg<'a, T: Decode<'a>>(&'a self) -> Result { T::from_der(self.as_bytes()) } /// Encode the provided type as ASN.1 DER, storing the resulting encoded DER /// as a [`Document`]. - pub fn encode_msg(msg: &T) -> Result { + pub fn encode_msg(msg: &T) -> Result { msg.to_der()?.try_into() } @@ -79,7 +79,7 @@ impl Document { /// /// Returns the PEM label and decoded [`Document`] on success. #[cfg(feature = "pem")] - pub fn from_pem(pem: &str) -> Result<(&str, Self)> { + pub fn from_pem(pem: &str) -> Result<(&str, Self), Error> { let (label, der_bytes) = pem::decode_vec(pem.as_bytes())?; Ok((label, der_bytes.try_into()?)) } @@ -87,25 +87,29 @@ impl Document { /// Encode ASN.1 DER document as a PEM string with encapsulation boundaries /// containing the provided PEM type `label` (e.g. `CERTIFICATE`). #[cfg(feature = "pem")] - pub fn to_pem(&self, label: &'static str, line_ending: pem::LineEnding) -> Result { + pub fn to_pem( + &self, + label: &'static str, + line_ending: pem::LineEnding, + ) -> Result { Ok(pem::encode_string(label, line_ending, self.as_bytes())?) } /// Read ASN.1 DER document from a file. #[cfg(feature = "std")] - pub fn read_der_file(path: impl AsRef) -> Result { + pub fn read_der_file(path: impl AsRef) -> Result { fs::read(path)?.try_into() } /// Write ASN.1 DER document to a file. #[cfg(feature = "std")] - pub fn write_der_file(&self, path: impl AsRef) -> Result<()> { + pub fn write_der_file(&self, path: impl AsRef) -> Result<(), Error> { Ok(fs::write(path, self.as_bytes())?) } /// Read PEM-encoded ASN.1 DER document from a file. #[cfg(all(feature = "pem", feature = "std"))] - pub fn read_pem_file(path: impl AsRef) -> Result<(String, Self)> { + pub fn read_pem_file(path: impl AsRef) -> Result<(String, Self), Error> { Self::from_pem(&fs::read_to_string(path)?).map(|(label, doc)| (label.to_owned(), doc)) } @@ -116,7 +120,7 @@ impl Document { path: impl AsRef, label: &'static str, line_ending: pem::LineEnding, - ) -> Result<()> { + ) -> Result<(), Error> { let pem = self.to_pem(label, line_ending)?; Ok(fs::write(path, pem.as_bytes())?) } @@ -141,7 +145,9 @@ impl Debug for Document { } impl<'a> Decode<'a> for Document { - fn decode>(reader: &mut R) -> Result { + type Error = Error; + + fn decode>(reader: &mut R) -> Result { let header = reader.peek_header()?; let length = (header.encoded_len()? + header.length)?; let bytes = reader.read_slice(length)?; @@ -154,11 +160,11 @@ impl<'a> Decode<'a> for Document { } impl Encode for Document { - fn encoded_len(&self) -> Result { + fn encoded_len(&self) -> Result { Ok(self.len()) } - fn encode(&self, writer: &mut impl Writer) -> Result<()> { + fn encode(&self, writer: &mut impl Writer) -> Result<(), Error> { writer.write(self.as_bytes()) } } @@ -170,7 +176,7 @@ impl FixedTag for Document { impl TryFrom<&[u8]> for Document { type Error = Error; - fn try_from(der_bytes: &[u8]) -> Result { + fn try_from(der_bytes: &[u8]) -> Result { Self::from_der(der_bytes) } } @@ -178,7 +184,7 @@ impl TryFrom<&[u8]> for Document { impl TryFrom> for Document { type Error = Error; - fn try_from(der_bytes: Vec) -> Result { + fn try_from(der_bytes: Vec) -> Result { let mut decoder = SliceReader::new(&der_bytes)?; decode_sequence(&mut decoder)?; decoder.finish(())?; @@ -218,18 +224,18 @@ impl SecretDocument { } /// Try to decode the inner ASN.1 DER message as the given type. - pub fn decode_msg<'a, T: Decode<'a>>(&'a self) -> Result { + pub fn decode_msg<'a, T: Decode<'a>>(&'a self) -> Result { self.0.decode_msg() } /// Encode the provided type as ASN.1 DER. - pub fn encode_msg(msg: &T) -> Result { + pub fn encode_msg(msg: &T) -> Result { Document::encode_msg(msg).map(Self) } /// Decode ASN.1 DER document from PEM. #[cfg(feature = "pem")] - pub fn from_pem(pem: &str) -> Result<(&str, Self)> { + pub fn from_pem(pem: &str) -> Result<(&str, Self), Error> { Document::from_pem(pem).map(|(label, doc)| (label, Self(doc))) } @@ -239,25 +245,25 @@ impl SecretDocument { &self, label: &'static str, line_ending: pem::LineEnding, - ) -> Result> { + ) -> Result, Error> { self.0.to_pem(label, line_ending).map(Zeroizing::new) } /// Read ASN.1 DER document from a file. #[cfg(feature = "std")] - pub fn read_der_file(path: impl AsRef) -> Result { + pub fn read_der_file(path: impl AsRef) -> Result { Document::read_der_file(path).map(Self) } /// Write ASN.1 DER document to a file. #[cfg(feature = "std")] - pub fn write_der_file(&self, path: impl AsRef) -> Result<()> { + pub fn write_der_file(&self, path: impl AsRef) -> Result<(), Error> { write_secret_file(path, self.as_bytes()) } /// Read PEM-encoded ASN.1 DER document from a file. #[cfg(all(feature = "pem", feature = "std"))] - pub fn read_pem_file(path: impl AsRef) -> Result<(String, Self)> { + pub fn read_pem_file(path: impl AsRef) -> Result<(String, Self), Error> { Document::read_pem_file(path).map(|(label, doc)| (label, Self(doc))) } @@ -268,7 +274,7 @@ impl SecretDocument { path: impl AsRef, label: &'static str, line_ending: pem::LineEnding, - ) -> Result<()> { + ) -> Result<(), Error> { write_secret_file(path, self.to_pem(label, line_ending)?.as_bytes()) } } @@ -297,7 +303,7 @@ impl From for SecretDocument { impl TryFrom<&[u8]> for SecretDocument { type Error = Error; - fn try_from(der_bytes: &[u8]) -> Result { + fn try_from(der_bytes: &[u8]) -> Result { Document::try_from(der_bytes).map(Self) } } @@ -306,7 +312,7 @@ impl TryFrom<&[u8]> for SecretDocument { impl TryFrom> for SecretDocument { type Error = Error; - fn try_from(der_bytes: Vec) -> Result { + fn try_from(der_bytes: Vec) -> Result { Document::try_from(der_bytes).map(Self) } } @@ -316,7 +322,7 @@ impl ZeroizeOnDrop for SecretDocument {} /// Attempt to decode a ASN.1 `SEQUENCE` from the given decoder, returning the /// entire sequence including the header. -fn decode_sequence<'a>(decoder: &mut SliceReader<'a>) -> Result<&'a [u8]> { +fn decode_sequence<'a>(decoder: &mut SliceReader<'a>) -> Result<&'a [u8], Error> { let header = decoder.peek_header()?; header.tag.assert_eq(Tag::Sequence)?; @@ -327,7 +333,7 @@ fn decode_sequence<'a>(decoder: &mut SliceReader<'a>) -> Result<&'a [u8]> { /// Write a file containing secret data to the filesystem, restricting the /// file permissions so it's only readable by the owner #[cfg(all(unix, feature = "std", feature = "zeroize"))] -fn write_secret_file(path: impl AsRef, data: &[u8]) -> Result<()> { +fn write_secret_file(path: impl AsRef, data: &[u8]) -> Result<(), Error> { use std::{io::Write, os::unix::fs::OpenOptionsExt}; /// File permissions for secret data diff --git a/der/src/header.rs b/der/src/header.rs index ad303810c..c3d5ded7b 100644 --- a/der/src/header.rs +++ b/der/src/header.rs @@ -1,6 +1,6 @@ //! ASN.1 DER headers. -use crate::{Decode, DerOrd, Encode, ErrorKind, Length, Reader, Result, Tag, Writer}; +use crate::{Decode, DerOrd, Encode, Error, ErrorKind, Length, Reader, Result, Tag, Writer}; use core::cmp::Ordering; /// ASN.1 DER headers: tag + length component of TLV-encoded values @@ -24,6 +24,8 @@ impl Header { } impl<'a> Decode<'a> for Header { + type Error = Error; + fn decode>(reader: &mut R) -> Result
{ let tag = Tag::decode(reader)?; diff --git a/der/src/length.rs b/der/src/length.rs index 1f0b816ae..7ffdfc0cc 100644 --- a/der/src/length.rs +++ b/der/src/length.rs @@ -207,6 +207,8 @@ impl TryFrom for usize { } impl<'a> Decode<'a> for Length { + type Error = Error; + fn decode>(reader: &mut R) -> Result { match reader.read_byte()? { // Note: per X.690 Section 8.1.3.6.1 the byte 0x80 encodes indefinite @@ -356,6 +358,8 @@ impl IndefiniteLength { } impl<'a> Decode<'a> for IndefiniteLength { + type Error = Error; + fn decode>(reader: &mut R) -> Result { if reader.peek_byte() == Some(INDEFINITE_LENGTH_OCTET) { // Consume the byte we already peeked at. diff --git a/der/src/lib.rs b/der/src/lib.rs index 7ea99d849..d20ff18b0 100644 --- a/der/src/lib.rs +++ b/der/src/lib.rs @@ -110,6 +110,8 @@ //! } //! //! impl<'a> DecodeValue<'a> for AlgorithmIdentifier<'a> { +//! type Error = der::Error; +//! //! fn decode_value>(reader: &mut R, _header: Header) -> der::Result { //! // The `der::Decoder::Decode` method can be used to decode any //! // type which impls the `Decode` trait, which is impl'd for diff --git a/der/src/reader.rs b/der/src/reader.rs index ef538f1b4..10576be29 100644 --- a/der/src/reader.rs +++ b/der/src/reader.rs @@ -9,7 +9,7 @@ pub(crate) use nested::NestedReader; use crate::{ asn1::ContextSpecific, Decode, DecodeValue, Encode, EncodingRules, Error, ErrorKind, FixedTag, - Header, Length, Result, Tag, TagMode, TagNumber, + Header, Length, Tag, TagMode, TagNumber, }; #[cfg(feature = "alloc")] @@ -30,7 +30,7 @@ pub trait Reader<'r>: Sized { /// the data at the current position in the decoder. /// /// Does not modify the decoder's state. - fn peek_header(&self) -> Result
; + fn peek_header(&self) -> Result; /// Get the position within the buffer. fn position(&self) -> Length; @@ -42,13 +42,17 @@ pub trait Reader<'r>: Sized { /// - `Ok(slice)` on success /// - `Err(ErrorKind::Incomplete)` if there is not enough data /// - `Err(ErrorKind::Reader)` if the reader can't borrow from the input - fn read_slice(&mut self, len: Length) -> Result<&'r [u8]>; + fn read_slice(&mut self, len: Length) -> Result<&'r [u8], Error>; /// Attempt to decode an ASN.1 `CONTEXT-SPECIFIC` field with the /// provided [`TagNumber`]. - fn context_specific(&mut self, tag_number: TagNumber, tag_mode: TagMode) -> Result> + fn context_specific( + &mut self, + tag_number: TagNumber, + tag_mode: TagMode, + ) -> Result, T::Error> where - T: DecodeValue<'r> + FixedTag, + T: DecodeValue<'r> + FixedTag + 'r, { Ok(match tag_mode { TagMode::Explicit => ContextSpecific::::decode_explicit(self, tag_number)?, @@ -58,8 +62,8 @@ pub trait Reader<'r>: Sized { } /// Decode a value which impls the [`Decode`] trait. - fn decode>(&mut self) -> Result { - T::decode(self).map_err(|e| e.nested(self.position())) + fn decode>(&mut self) -> Result { + T::decode(self) } /// Return an error with the given [`ErrorKind`], annotating it with @@ -70,7 +74,7 @@ pub trait Reader<'r>: Sized { /// Finish decoding, returning the given value if there is no /// remaining data, or an error otherwise - fn finish(self, value: T) -> Result { + fn finish(self, value: T) -> Result { if !self.is_finished() { Err(ErrorKind::TrailingData { decoded: self.position(), @@ -100,7 +104,7 @@ pub trait Reader<'r>: Sized { /// [`Tag`] value. /// /// Does not modify the decoder's state. - fn peek_tag(&self) -> Result { + fn peek_tag(&self) -> Result { match self.peek_byte() { Some(byte) => byte.try_into(), None => Err(Error::incomplete(self.input_len())), @@ -108,7 +112,7 @@ pub trait Reader<'r>: Sized { } /// Read a single byte. - fn read_byte(&mut self) -> Result { + fn read_byte(&mut self) -> Result { let mut buf = [0]; self.read_into(&mut buf)?; Ok(buf[0]) @@ -120,25 +124,26 @@ pub trait Reader<'r>: Sized { /// # Returns /// - `Ok(slice)` if there is sufficient data /// - `Err(ErrorKind::Incomplete)` if there is not enough data - fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> { + fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8], Error> { let input = self.read_slice(buf.len().try_into()?)?; buf.copy_from_slice(input); Ok(buf) } /// Read nested data of the given length. - fn read_nested<'n, T, F>(&'n mut self, len: Length, f: F) -> Result + fn read_nested<'n, T, F, E>(&'n mut self, len: Length, f: F) -> Result where - F: FnOnce(&mut NestedReader<'n, Self>) -> Result, + F: FnOnce(&mut NestedReader<'n, Self>) -> Result, + E: From, { let mut reader = NestedReader::new(self, len)?; let ret = f(&mut reader)?; - reader.finish(ret) + Ok(reader.finish(ret)?) } /// Read a byte vector of the given length. #[cfg(feature = "alloc")] - fn read_vec(&mut self, len: Length) -> Result> { + fn read_vec(&mut self, len: Length) -> Result, Error> { let mut bytes = vec![0u8; usize::try_from(len)?]; self.read_into(&mut bytes)?; Ok(bytes) @@ -152,9 +157,10 @@ pub trait Reader<'r>: Sized { /// Read an ASN.1 `SEQUENCE`, creating a nested [`Reader`] for the body and /// calling the provided closure with it. - fn sequence<'n, F, T>(&'n mut self, f: F) -> Result + fn sequence<'n, F, T, E>(&'n mut self, f: F) -> Result where - F: FnOnce(&mut NestedReader<'n, Self>) -> Result, + F: FnOnce(&mut NestedReader<'n, Self>) -> Result, + E: From, { let header = Header::decode(self)?; header.tag.assert_eq(Tag::Sequence)?; @@ -162,7 +168,7 @@ pub trait Reader<'r>: Sized { } /// Obtain a slice of bytes contain a complete TLV production suitable for parsing later. - fn tlv_bytes(&mut self) -> Result<&'r [u8]> { + fn tlv_bytes(&mut self) -> Result<&'r [u8], Error> { let header = self.peek_header()?; let header_len = header.encoded_len()?; self.read_slice((header_len + header.length)?) diff --git a/der/src/reader/slice.rs b/der/src/reader/slice.rs index 40d5682fb..30345daf5 100644 --- a/der/src/reader/slice.rs +++ b/der/src/reader/slice.rs @@ -1,8 +1,6 @@ //! Slice reader. -use crate::{ - BytesRef, Decode, EncodingRules, Error, ErrorKind, Header, Length, Reader, Result, Tag, -}; +use crate::{BytesRef, Decode, EncodingRules, Error, ErrorKind, Header, Length, Reader, Tag}; /// [`Reader`] which consumes an input byte slice. #[derive(Clone, Debug)] @@ -22,7 +20,7 @@ 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 { + pub fn new(bytes: &'a [u8]) -> Result { Ok(Self { bytes: BytesRef::new(bytes)?, encoding_rules: EncodingRules::default(), @@ -50,7 +48,7 @@ impl<'a> SliceReader<'a> { /// Obtain the remaining bytes in this slice reader from the current cursor /// position. - fn remaining(&self) -> Result<&'a [u8]> { + fn remaining(&self) -> Result<&'a [u8], Error> { if self.is_failed() { Err(ErrorKind::Failed.at(self.position)) } else { @@ -77,7 +75,7 @@ impl<'a> Reader<'a> for SliceReader<'a> { .and_then(|bytes| bytes.first().cloned()) } - fn peek_header(&self) -> Result
{ + fn peek_header(&self) -> Result { Header::decode(&mut self.clone()) } @@ -85,7 +83,7 @@ impl<'a> Reader<'a> for SliceReader<'a> { self.position } - fn read_slice(&mut self, len: Length) -> Result<&'a [u8]> { + fn read_slice(&mut self, len: Length) -> Result<&'a [u8], Error> { if self.is_failed() { return Err(self.error(ErrorKind::Failed)); } @@ -102,14 +100,14 @@ impl<'a> Reader<'a> for SliceReader<'a> { } } - fn decode>(&mut self) -> Result { + fn decode>(&mut self) -> Result { if self.is_failed() { - return Err(self.error(ErrorKind::Failed)); + return Err(self.error(ErrorKind::Failed).into()); } T::decode(self).map_err(|e| { self.failed = true; - e.nested(self.position) + e }) } @@ -118,7 +116,7 @@ impl<'a> Reader<'a> for SliceReader<'a> { kind.at(self.position) } - fn finish(self, value: T) -> Result { + fn finish(self, value: T) -> Result { if self.is_failed() { Err(ErrorKind::Failed.at(self.position)) } else if !self.is_finished() { diff --git a/der/src/str_owned.rs b/der/src/str_owned.rs index 20bfea5bd..0bf9e72ff 100644 --- a/der/src/str_owned.rs +++ b/der/src/str_owned.rs @@ -2,8 +2,8 @@ //! library-level length limitation i.e. `Length::max()`. use crate::{ - referenced::OwnedToRef, BytesRef, DecodeValue, EncodeValue, Header, Length, Reader, Result, - StrRef, Writer, + referenced::OwnedToRef, BytesRef, DecodeValue, EncodeValue, Error, Header, Length, Reader, + Result, StrRef, Writer, }; use alloc::string::String; use core::str; @@ -69,6 +69,8 @@ impl AsRef<[u8]> for StrOwned { } impl<'a> DecodeValue<'a> for StrOwned { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Self::from_bytes(BytesRef::decode_value(reader, header)?.as_slice()) } diff --git a/der/src/str_ref.rs b/der/src/str_ref.rs index 899c7506b..d327606cd 100644 --- a/der/src/str_ref.rs +++ b/der/src/str_ref.rs @@ -1,7 +1,7 @@ //! Common handling for types backed by `str` slices with enforcement of a //! library-level length limitation i.e. `Length::max()`. -use crate::{BytesRef, DecodeValue, EncodeValue, Header, Length, Reader, Result, Writer}; +use crate::{BytesRef, DecodeValue, EncodeValue, Error, Header, Length, Reader, Result, Writer}; use core::str; /// String slice newtype which respects the [`Length::max`] limit. @@ -63,6 +63,8 @@ impl AsRef<[u8]> for StrRef<'_> { } impl<'a> DecodeValue<'a> for StrRef<'a> { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { Self::from_bytes(BytesRef::decode_value(reader, header)?.as_slice()) } diff --git a/der/src/tag.rs b/der/src/tag.rs index 848168999..4ece7cbad 100644 --- a/der/src/tag.rs +++ b/der/src/tag.rs @@ -315,6 +315,8 @@ impl From<&Tag> for u8 { } impl<'a> Decode<'a> for Tag { + type Error = Error; + fn decode>(reader: &mut R) -> Result { reader.read_byte().and_then(Self::try_from) } diff --git a/gss-api/src/lib.rs b/gss-api/src/lib.rs index 8c925ec68..59316485d 100644 --- a/gss-api/src/lib.rs +++ b/gss-api/src/lib.rs @@ -62,6 +62,8 @@ impl<'a> FixedTag for InitialContextToken<'a> { } impl<'a> DecodeValue<'a> for InitialContextToken<'a> { + type Error = der::Error; + fn decode_value>(reader: &mut R, _header: der::Header) -> der::Result { Ok(Self { this_mech: reader.decode()?, diff --git a/pkcs1/src/params.rs b/pkcs1/src/params.rs index 74a1ee486..52ce89642 100644 --- a/pkcs1/src/params.rs +++ b/pkcs1/src/params.rs @@ -37,6 +37,8 @@ impl Default for TrailerField { } impl<'a> DecodeValue<'a> for TrailerField { + type Error = der::Error; + fn decode_value>(decoder: &mut R, header: der::Header) -> der::Result { match u8::decode_value(decoder, header)? { 1 => Ok(TrailerField::BC), @@ -178,6 +180,8 @@ impl<'a> Default for RsaPssParams<'a> { } 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 { @@ -342,6 +346,7 @@ impl<'a> Default for RsaOaepParams<'a> { } 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 { diff --git a/pkcs1/src/private_key.rs b/pkcs1/src/private_key.rs index b913c4764..4103334d4 100644 --- a/pkcs1/src/private_key.rs +++ b/pkcs1/src/private_key.rs @@ -93,6 +93,8 @@ 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)?; diff --git a/pkcs1/src/private_key/other_prime_info.rs b/pkcs1/src/private_key/other_prime_info.rs index 35194a590..b2a613572 100644 --- a/pkcs1/src/private_key/other_prime_info.rs +++ b/pkcs1/src/private_key/other_prime_info.rs @@ -30,6 +30,8 @@ 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 { diff --git a/pkcs1/src/public_key.rs b/pkcs1/src/public_key.rs index 3281744cb..f8bc06932 100644 --- a/pkcs1/src/public_key.rs +++ b/pkcs1/src/public_key.rs @@ -34,6 +34,7 @@ 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 { diff --git a/pkcs1/src/version.rs b/pkcs1/src/version.rs index 2fdb19884..f880253f2 100644 --- a/pkcs1/src/version.rs +++ b/pkcs1/src/version.rs @@ -52,6 +52,7 @@ impl TryFrom for Version { } impl<'a> Decode<'a> for Version { + type Error = der::Error; fn decode>(decoder: &mut R) -> der::Result { Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error()) } diff --git a/pkcs12/src/safe_bag.rs b/pkcs12/src/safe_bag.rs index 0e5fd02a3..04c5a0cb5 100644 --- a/pkcs12/src/safe_bag.rs +++ b/pkcs12/src/safe_bag.rs @@ -37,6 +37,8 @@ pub struct SafeBag { } impl<'a> ::der::DecodeValue<'a> for SafeBag { + type Error = ::der::Error; + fn decode_value>( reader: &mut R, header: ::der::Header, diff --git a/pkcs5/src/lib.rs b/pkcs5/src/lib.rs index 550cd0d5e..6d883c027 100644 --- a/pkcs5/src/lib.rs +++ b/pkcs5/src/lib.rs @@ -144,6 +144,8 @@ impl EncryptionScheme { } impl<'a> DecodeValue<'a> for EncryptionScheme { + type Error = der::Error; + fn decode_value>(decoder: &mut R, header: Header) -> der::Result { AlgorithmIdentifierRef::decode_value(decoder, header)?.try_into() } diff --git a/pkcs5/src/pbes1.rs b/pkcs5/src/pbes1.rs index 217154795..025e2a53d 100644 --- a/pkcs5/src/pbes1.rs +++ b/pkcs5/src/pbes1.rs @@ -67,6 +67,8 @@ impl Algorithm { } impl<'a> DecodeValue<'a> for Algorithm { + type Error = der::Error; + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { AlgorithmIdentifierRef::decode_value(reader, header)?.try_into() } @@ -125,6 +127,8 @@ pub struct Parameters { } impl<'a> DecodeValue<'a> for Parameters { + type Error = der::Error; + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { AnyRef::decode_value(reader, header)?.try_into() } diff --git a/pkcs5/src/pbes2.rs b/pkcs5/src/pbes2.rs index 50483dd5e..a84ff3005 100644 --- a/pkcs5/src/pbes2.rs +++ b/pkcs5/src/pbes2.rs @@ -262,6 +262,8 @@ impl Parameters { } impl<'a> DecodeValue<'a> for Parameters { + type Error = der::Error; + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { AnyRef::decode_value(reader, header)?.try_into() } @@ -370,6 +372,8 @@ impl EncryptionScheme { } impl<'a> Decode<'a> for EncryptionScheme { + type Error = der::Error; + fn decode>(reader: &mut R) -> der::Result { AlgorithmIdentifierRef::decode(reader).and_then(TryInto::try_into) } diff --git a/pkcs5/src/pbes2/kdf.rs b/pkcs5/src/pbes2/kdf.rs index 29965e78c..b5e55563f 100644 --- a/pkcs5/src/pbes2/kdf.rs +++ b/pkcs5/src/pbes2/kdf.rs @@ -104,6 +104,8 @@ impl Kdf { } impl<'a> DecodeValue<'a> for Kdf { + type Error = der::Error; + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { AlgorithmIdentifierRef::decode_value(reader, header)?.try_into() } @@ -222,6 +224,7 @@ impl Pbkdf2Params { } impl<'a> DecodeValue<'a> for Pbkdf2Params { + type Error = der::Error; fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { AnyRef::decode_value(reader, header)?.try_into() } @@ -419,6 +422,8 @@ impl ScryptParams { } impl<'a> DecodeValue<'a> for ScryptParams { + type Error = der::Error; + fn decode_value>(reader: &mut R, header: der::Header) -> der::Result { AnyRef::decode_value(reader, header)?.try_into() } diff --git a/pkcs5/src/pbes2/kdf/salt.rs b/pkcs5/src/pbes2/kdf/salt.rs index 75c5a0758..59e961594 100644 --- a/pkcs5/src/pbes2/kdf/salt.rs +++ b/pkcs5/src/pbes2/kdf/salt.rs @@ -56,6 +56,8 @@ impl AsRef<[u8]> for Salt { } impl<'a> DecodeValue<'a> for Salt { + type Error = Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let length = usize::try_from(header.length)?; diff --git a/pkcs8/src/encrypted_private_key_info.rs b/pkcs8/src/encrypted_private_key_info.rs index e081c8e11..12fafdf21 100644 --- a/pkcs8/src/encrypted_private_key_info.rs +++ b/pkcs8/src/encrypted_private_key_info.rs @@ -97,6 +97,8 @@ impl<'a> EncryptedPrivateKeyInfo<'a> { } impl<'a> DecodeValue<'a> for EncryptedPrivateKeyInfo<'a> { + type Error = der::Error; + fn decode_value>( reader: &mut R, header: Header, diff --git a/pkcs8/src/private_key_info.rs b/pkcs8/src/private_key_info.rs index ec4c6ec04..b3550d619 100644 --- a/pkcs8/src/private_key_info.rs +++ b/pkcs8/src/private_key_info.rs @@ -171,6 +171,8 @@ impl<'a> PrivateKeyInfo<'a> { } impl<'a> DecodeValue<'a> for PrivateKeyInfo<'a> { + type Error = der::Error; + fn decode_value>( reader: &mut R, header: Header, diff --git a/pkcs8/src/version.rs b/pkcs8/src/version.rs index 0ca80bc48..d5a3c5747 100644 --- a/pkcs8/src/version.rs +++ b/pkcs8/src/version.rs @@ -26,6 +26,8 @@ impl Version { } impl<'a> Decode<'a> for Version { + type Error = der::Error; + fn decode>(decoder: &mut R) -> der::Result { Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error()) } diff --git a/sec1/src/parameters.rs b/sec1/src/parameters.rs index 20458e6e9..7f77653b1 100644 --- a/sec1/src/parameters.rs +++ b/sec1/src/parameters.rs @@ -28,6 +28,8 @@ pub enum EcParameters { } impl<'a> DecodeValue<'a> for EcParameters { + type Error = der::Error; + fn decode_value>(decoder: &mut R, header: Header) -> der::Result { ObjectIdentifier::decode_value(decoder, header).map(Self::NamedCurve) } diff --git a/sec1/src/private_key.rs b/sec1/src/private_key.rs index 531579936..dacb808f6 100644 --- a/sec1/src/private_key.rs +++ b/sec1/src/private_key.rs @@ -95,6 +95,8 @@ 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 { diff --git a/spki/src/algorithm.rs b/spki/src/algorithm.rs index 5f4b5e8c2..a49c21df0 100644 --- a/spki/src/algorithm.rs +++ b/spki/src/algorithm.rs @@ -33,8 +33,10 @@ pub struct AlgorithmIdentifier { impl<'a, Params> DecodeValue<'a> for AlgorithmIdentifier where - Params: Choice<'a>, + Params: Choice<'a, Error = der::Error>, { + type Error = der::Error; + fn decode_value>(reader: &mut R, header: Header) -> der::Result { reader.read_nested(header.length, |reader| { Ok(Self { @@ -60,11 +62,14 @@ where } } -impl<'a, Params> Sequence<'a> for AlgorithmIdentifier where Params: Choice<'a> + Encode {} +impl<'a, Params> Sequence<'a> for AlgorithmIdentifier where + Params: Choice<'a, Error = der::Error> + Encode +{ +} impl<'a, Params> TryFrom<&'a [u8]> for AlgorithmIdentifier where - Params: Choice<'a> + Encode, + Params: Choice<'a, Error = der::Error> + Encode, { type Error = Error; diff --git a/spki/src/spki.rs b/spki/src/spki.rs index 192b726a3..b2972a62e 100644 --- a/spki/src/spki.rs +++ b/spki/src/spki.rs @@ -51,10 +51,10 @@ pub struct SubjectPublicKeyInfo { impl<'a, Params, Key> SubjectPublicKeyInfo where - Params: Choice<'a> + Encode, + Params: Choice<'a, Error = der::Error> + Encode, // TODO: replace FixedTag with FixedTag once // https://github.com/rust-lang/rust/issues/92827 is fixed - Key: Decode<'a> + Encode + FixedTag, + Key: Decode<'a, Error = der::Error> + Encode + FixedTag, { /// Calculate the SHA-256 fingerprint of this [`SubjectPublicKeyInfo`] and /// encode it as a Base64 string. @@ -84,9 +84,11 @@ where impl<'a: 'k, 'k, Params, Key: 'k> DecodeValue<'a> for SubjectPublicKeyInfo where - Params: Choice<'a> + Encode, - Key: Decode<'a>, + Params: Choice<'a, Error = der::Error> + Encode, + Key: Decode<'a, Error = der::Error>, { + type Error = der::Error; + fn decode_value>(reader: &mut R, header: Header) -> der::Result { reader.read_nested(header.length, |reader| { Ok(Self { @@ -99,7 +101,7 @@ where impl<'a, Params, Key> EncodeValue for SubjectPublicKeyInfo where - Params: Choice<'a> + Encode, + Params: Choice<'a, Error = der::Error> + Encode, Key: Encode, { fn value_len(&self) -> der::Result { @@ -115,15 +117,15 @@ where impl<'a, Params, Key> Sequence<'a> for SubjectPublicKeyInfo where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, + Params: Choice<'a, Error = der::Error> + Encode, + Key: Decode<'a, Error = der::Error> + Encode + FixedTag, { } impl<'a, Params, Key> TryFrom<&'a [u8]> for SubjectPublicKeyInfo where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, + Params: Choice<'a, Error = der::Error> + Encode, + Key: Decode<'a, Error = der::Error> + Encode + FixedTag, { type Error = Error; @@ -134,7 +136,7 @@ where impl<'a, Params, Key> ValueOrd for SubjectPublicKeyInfo where - Params: Choice<'a> + DerOrd + Encode, + Params: Choice<'a, Error = der::Error> + DerOrd + Encode, Key: ValueOrd, { fn value_cmp(&self, other: &Self) -> der::Result { @@ -148,8 +150,8 @@ where #[cfg(feature = "alloc")] impl<'a: 'k, 'k, Params, Key: 'k> TryFrom> for Document where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, + Params: Choice<'a, Error = der::Error> + Encode, + Key: Decode<'a, Error = der::Error> + Encode + FixedTag, BitStringRef<'a>: From<&'k Key>, { type Error = Error; @@ -162,8 +164,8 @@ where #[cfg(feature = "alloc")] impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<&SubjectPublicKeyInfo> for Document where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, + Params: Choice<'a, Error = der::Error> + Encode, + Key: Decode<'a, Error = der::Error> + Encode + FixedTag, BitStringRef<'a>: From<&'k Key>, { type Error = Error; diff --git a/x509-cert/src/certificate.rs b/x509-cert/src/certificate.rs index c5a105dbb..0dac65e66 100644 --- a/x509-cert/src/certificate.rs +++ b/x509-cert/src/certificate.rs @@ -116,7 +116,7 @@ pub type TbsCertificate = TbsCertificateInner; #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] #[allow(missing_docs)] -pub struct TbsCertificateInner { +pub struct TbsCertificateInner { /// The certificate version /// /// Note that this value defaults to Version 1 per the RFC. However, @@ -149,12 +149,14 @@ impl TbsCertificateInner

{ /// Returns an error if multiple of these extensions is present. Returns /// `Ok(None)` if the extension is not present. Returns a decoding error /// if decoding failed. Otherwise returns the extension. - pub fn get<'a, T: Decode<'a> + AssociatedOid>(&'a self) -> Result, Error> { + pub fn get<'a, T: Decode<'a> + AssociatedOid>( + &'a self, + ) -> Result, >::Error> { let mut iter = self.filter::().peekable(); match iter.next() { None => Ok(None), Some(item) => match iter.peek() { - Some(..) => Err(ErrorKind::Failed.into()), + Some(..) => Err(der::Error::from(ErrorKind::Failed).into()), None => Ok(Some(item?)), }, } @@ -165,7 +167,7 @@ impl TbsCertificateInner

{ /// Returns a filtered iterator over all the extensions with the OID. pub fn filter<'a, T: Decode<'a> + AssociatedOid>( &'a self, - ) -> impl 'a + Iterator> { + ) -> impl 'a + Iterator>::Error>> { self.extensions .as_deref() .unwrap_or(&[]) @@ -194,7 +196,7 @@ pub type Certificate = CertificateInner; #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] #[allow(missing_docs)] -pub struct CertificateInner { +pub struct CertificateInner { pub tbs_certificate: TbsCertificateInner

, pub signature_algorithm: AlgorithmIdentifierOwned, pub signature: BitString, diff --git a/x509-cert/src/macros.rs b/x509-cert/src/macros.rs index 0333ef7b9..c9f5153d8 100644 --- a/x509-cert/src/macros.rs +++ b/x509-cert/src/macros.rs @@ -49,6 +49,8 @@ macro_rules! impl_newtype { } impl<'a> ::der::DecodeValue<'a> for $newtype { + type Error = ::der::Error; + fn decode_value>( decoder: &mut R, header: ::der::Header, diff --git a/x509-cert/src/serial_number.rs b/x509-cert/src/serial_number.rs index bd0d93947..50d2090f7 100644 --- a/x509-cert/src/serial_number.rs +++ b/x509-cert/src/serial_number.rs @@ -130,6 +130,8 @@ impl EncodeValue for SerialNumber

{ } impl<'a, P: Profile> DecodeValue<'a> for SerialNumber

{ + type Error = der::Error; + fn decode_value>(reader: &mut R, header: Header) -> Result { let inner = Int::decode_value(reader, header)?; let serial = Self { diff --git a/x509-cert/tests/certificate.rs b/x509-cert/tests/certificate.rs index d4859c2e3..8ce118017 100644 --- a/x509-cert/tests/certificate.rs +++ b/x509-cert/tests/certificate.rs @@ -38,6 +38,8 @@ pub struct DeferDecodeCertificate<'a> { } impl<'a> DecodeValue<'a> for DeferDecodeCertificate<'a> { + type Error = der::Error; + fn decode_value>( reader: &mut R, header: Header, @@ -81,6 +83,8 @@ pub struct DeferDecodeTbsCertificate<'a> { } impl<'a> DecodeValue<'a> for DeferDecodeTbsCertificate<'a> { + type Error = der::Error; + fn decode_value>( reader: &mut R, header: Header,