Skip to main content

der/
decode.rs

1//! Trait definition for [`Decode`].
2
3use crate::{Error, FixedTag, Header, Reader, SliceReader, reader::read_value};
4
5use core::marker::PhantomData;
6
7#[cfg(feature = "pem")]
8use crate::{PemReader, pem::PemLabel};
9
10#[cfg(doc)]
11use crate::{ErrorKind, Length, Tag};
12
13#[cfg(feature = "alloc")]
14use alloc::{
15    borrow::{Cow, ToOwned},
16    boxed::Box,
17};
18
19#[cfg(feature = "ber")]
20use crate::EncodingRules;
21
22/// Decode trait parses a complete TLV (Tag-Length-Value) structure.
23///
24/// This trait provides the core abstraction upon which all decoding operations
25/// are based.
26///
27/// When decoding fails, a [`Decode::Error`] type is thrown.
28/// Most ASN.1 DER objects return a builtin der [`Error`] type as [`Decode::Error`], which can be made from [`ErrorKind`].
29///
30/// ## Example
31///
32/// ```
33/// # #[cfg(all(feature = "alloc", feature = "std"))]
34/// # {
35/// use der::{Any, Decode, Reader};
36///
37/// /// Wrapper around Any, with custom foreign trait support.
38/// ///
39/// /// For example: serde Serialize/Deserialize
40/// pub struct AnySerde(pub Any);
41///
42/// impl<'a> Decode<'a> for AnySerde {
43///     type Error = der::Error;
44///
45///     fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
46///         // calls impl Decode for Any
47///         Ok(Self(Any::decode(reader)?))
48///     }
49/// }
50/// # }
51/// ```
52#[diagnostic::on_unimplemented(
53    note = "Consider adding impls of `DecodeValue` and `FixedTag` to `{Self}`"
54)]
55pub trait Decode<'a>: Sized + 'a {
56    /// Type returned in the event of a decoding error.
57    type Error: core::error::Error + From<Error> + 'static;
58
59    /// Attempt to decode this TLV message using the provided decoder.
60    ///
61    /// # Errors
62    /// Returns [`Self::Error`] in the event a decoding error occurred.
63    fn decode<R: Reader<'a>>(decoder: &mut R) -> Result<Self, Self::Error>;
64
65    /// Parse `Self` from the provided BER-encoded byte slice.
66    ///
67    /// Note that most usages should probably use [`Decode::from_der`]. This method allows some
68    /// BER productions which are not allowed under DER.
69    ///
70    /// # Errors
71    /// Returns [`Self::Error`] in the event a decoding error occurred.
72    #[cfg(feature = "ber")]
73    fn from_ber(bytes: &'a [u8]) -> Result<Self, Self::Error> {
74        let mut reader = SliceReader::new_with_encoding_rules(bytes, EncodingRules::Ber)?;
75        let result = Self::decode(&mut reader)?;
76        reader.finish()?;
77        Ok(result)
78    }
79
80    /// Parse `Self` from the provided DER-encoded byte slice.
81    ///
82    /// # Errors
83    /// Returns [`Self::Error`] in the event a decoding error occurred.
84    fn from_der(bytes: &'a [u8]) -> Result<Self, Self::Error> {
85        let mut reader = SliceReader::new(bytes)?;
86        let result = Self::decode(&mut reader)?;
87        reader.finish()?;
88        Ok(result)
89    }
90
91    /// Parse `Self` from the provided DER-encoded byte slice.
92    ///
93    /// Returns remaining byte slice, without checking for incomplete message.
94    ///
95    /// # Errors
96    /// Returns [`Self::Error`] in the event a decoding error occurred.
97    fn from_der_partial(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), Self::Error> {
98        let mut reader = SliceReader::new(bytes)?;
99        let result = Self::decode(&mut reader)?;
100
101        let remaining = reader.remaining()?;
102        Ok((result, remaining))
103    }
104}
105
106impl<'a, T> Decode<'a> for T
107where
108    T: DecodeValue<'a> + FixedTag + 'a,
109{
110    type Error = <T as DecodeValue<'a>>::Error;
111
112    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<T, <T as DecodeValue<'a>>::Error> {
113        let header = Header::decode(reader)?;
114        header.tag().assert_eq(T::TAG)?;
115        read_value(reader, header, T::decode_value)
116    }
117}
118
119/// Dummy implementation for [`PhantomData`] which allows deriving
120/// implementations on structs with phantom fields.
121impl<'a, T> Decode<'a> for PhantomData<T>
122where
123    T: ?Sized + 'a,
124{
125    type Error = Error;
126
127    fn decode<R: Reader<'a>>(_reader: &mut R) -> Result<PhantomData<T>, Error> {
128        Ok(PhantomData)
129    }
130}
131
132/// Marker trait for data structures that can be decoded from DER without
133/// borrowing any data from the decoder.
134///
135/// This is primarily useful for trait bounds on functions which require that
136/// no data is borrowed from the decoder, for example a PEM decoder which needs
137/// to first decode data from Base64.
138///
139/// This trait is inspired by the [`DeserializeOwned` trait from `serde`](https://docs.rs/serde/latest/serde/de/trait.DeserializeOwned.html).
140#[diagnostic::on_unimplemented(
141    note = "`DecodeOwned` is auto-impl'd for all lifetime-free types which impl `Decode`"
142)]
143pub trait DecodeOwned: for<'a> Decode<'a> {}
144
145impl<T> DecodeOwned for T where T: for<'a> Decode<'a> {}
146
147/// PEM decoding trait.
148///
149/// This trait is automatically impl'd for any type which impls both
150/// [`DecodeOwned`] and [`PemLabel`].
151#[cfg(feature = "pem")]
152#[diagnostic::on_unimplemented(
153    note = "`DecodePem` is auto-impl'd for all lifetime-free types which impl both `Decode` and `PemLabel`"
154)]
155pub trait DecodePem: DecodeOwned + PemLabel {
156    /// Try to decode this type from PEM.
157    ///
158    /// # Errors
159    /// If a PEM or DER decoding error occurred.
160    fn from_pem(pem: impl AsRef<[u8]>) -> Result<Self, <Self as Decode<'static>>::Error>;
161}
162
163#[cfg(feature = "pem")]
164impl<T: DecodeOwned<Error = Error> + PemLabel> DecodePem for T {
165    fn from_pem(pem: impl AsRef<[u8]>) -> Result<T, Error> {
166        let mut reader = PemReader::new(pem.as_ref())?;
167        Self::validate_pem_label(reader.type_label()).map_err(Error::from)?;
168        T::decode(&mut reader)
169    }
170}
171
172/// `DecodeValue` trait parses the value part of a Tag-Length-Value object,
173/// sans the [`Tag`] and [`Length`].
174///
175/// As opposed to [`Decode`], implementer is expected to read the inner content only,
176/// without the [`Header`], which was decoded beforehand.
177///
178/// ## Example
179/// ```
180/// use der::{Decode, DecodeValue, ErrorKind, FixedTag, Header, Reader, Tag};
181///
182/// /// 1-byte month
183/// struct MyByteMonth(u8);
184///
185/// impl<'a> DecodeValue<'a> for MyByteMonth {
186///     type Error = der::Error;
187///
188///     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
189///         let month = reader.read_byte()?;
190///         
191///         if (0..12).contains(&month) {
192///             Ok(Self(month))
193///         } else {
194///             Err(reader.error(ErrorKind::DateTime))
195///         }
196///     }
197/// }
198///
199/// impl FixedTag for MyByteMonth {
200///     const TAG: Tag = Tag::OctetString;
201/// }
202///
203/// let month = MyByteMonth::from_der(b"\x04\x01\x09").expect("month to decode");
204///
205/// assert_eq!(month.0, 9);
206/// ```
207pub trait DecodeValue<'a>: Sized {
208    /// Type returned in the event of a decoding error.
209    type Error: core::error::Error + From<Error> + 'static;
210
211    /// Attempt to decode this value using the provided [`Reader`].
212    ///
213    /// # Errors
214    /// Returns [`Self::Error`] in the event a decoding error occurred.
215    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error>;
216}
217
218#[cfg(feature = "alloc")]
219impl<'a, T> DecodeValue<'a> for Box<T>
220where
221    T: DecodeValue<'a>,
222{
223    type Error = T::Error;
224
225    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error> {
226        Ok(Box::new(T::decode_value(reader, header)?))
227    }
228}
229
230#[cfg(feature = "alloc")]
231impl<'a, T, E> DecodeValue<'a> for Cow<'a, T>
232where
233    T: ToOwned + ?Sized,
234    &'a T: DecodeValue<'a, Error = E>,
235    T::Owned: for<'b> DecodeValue<'b, Error = E>,
236    E: core::error::Error + From<Error> + 'static,
237{
238    type Error = E;
239
240    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error> {
241        if R::CAN_READ_SLICE {
242            <&'a T>::decode_value(reader, header).map(Cow::Borrowed)
243        } else {
244            T::Owned::decode_value(reader, header).map(Cow::Owned)
245        }
246    }
247}