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 fn decode<R: Reader<'a>>(decoder: &mut R) -> Result<Self, Self::Error>;
61
62 /// Parse `Self` from the provided BER-encoded byte slice.
63 ///
64 /// Note that most usages should probably use [`Decode::from_der`]. This method allows some
65 /// BER productions which are not allowed under DER.
66 #[cfg(feature = "ber")]
67 fn from_ber(bytes: &'a [u8]) -> Result<Self, Self::Error> {
68 let mut reader = SliceReader::new_with_encoding_rules(bytes, EncodingRules::Ber)?;
69 let result = Self::decode(&mut reader)?;
70 reader.finish()?;
71 Ok(result)
72 }
73
74 /// Parse `Self` from the provided DER-encoded byte slice.
75 ///
76 /// Returns [`ErrorKind::TrailingData`] if message is incomplete.
77 fn from_der(bytes: &'a [u8]) -> Result<Self, Self::Error> {
78 let mut reader = SliceReader::new(bytes)?;
79 let result = Self::decode(&mut reader)?;
80 reader.finish()?;
81 Ok(result)
82 }
83
84 /// Parse `Self` from the provided DER-encoded byte slice.
85 ///
86 /// Returns remaining byte slice, without checking for incomplete message.
87 fn from_der_partial(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), Self::Error> {
88 let mut reader = SliceReader::new(bytes)?;
89 let result = Self::decode(&mut reader)?;
90
91 let remaining = reader.remaining()?;
92 Ok((result, remaining))
93 }
94}
95
96impl<'a, T> Decode<'a> for T
97where
98 T: DecodeValue<'a> + FixedTag + 'a,
99{
100 type Error = <T as DecodeValue<'a>>::Error;
101
102 fn decode<R: Reader<'a>>(reader: &mut R) -> Result<T, <T as DecodeValue<'a>>::Error> {
103 let header = Header::decode(reader)?;
104 header.tag().assert_eq(T::TAG)?;
105 read_value(reader, header, T::decode_value)
106 }
107}
108
109/// Dummy implementation for [`PhantomData`] which allows deriving
110/// implementations on structs with phantom fields.
111impl<'a, T> Decode<'a> for PhantomData<T>
112where
113 T: ?Sized + 'a,
114{
115 type Error = Error;
116
117 fn decode<R: Reader<'a>>(_reader: &mut R) -> Result<PhantomData<T>, Error> {
118 Ok(PhantomData)
119 }
120}
121
122/// Marker trait for data structures that can be decoded from DER without
123/// borrowing any data from the decoder.
124///
125/// This is primarily useful for trait bounds on functions which require that
126/// no data is borrowed from the decoder, for example a PEM decoder which needs
127/// to first decode data from Base64.
128///
129/// This trait is inspired by the [`DeserializeOwned` trait from `serde`](https://docs.rs/serde/latest/serde/de/trait.DeserializeOwned.html).
130#[diagnostic::on_unimplemented(
131 note = "`DecodeOwned` is auto-impl'd for all lifetime-free types which impl `Decode`"
132)]
133pub trait DecodeOwned: for<'a> Decode<'a> {}
134
135impl<T> DecodeOwned for T where T: for<'a> Decode<'a> {}
136
137/// PEM decoding trait.
138///
139/// This trait is automatically impl'd for any type which impls both
140/// [`DecodeOwned`] and [`PemLabel`].
141#[cfg(feature = "pem")]
142#[diagnostic::on_unimplemented(
143 note = "`DecodePem` is auto-impl'd for all lifetime-free types which impl both `Decode` and `PemLabel`"
144)]
145pub trait DecodePem: DecodeOwned + PemLabel {
146 /// Try to decode this type from PEM.
147 fn from_pem(pem: impl AsRef<[u8]>) -> Result<Self, <Self as Decode<'static>>::Error>;
148}
149
150#[cfg(feature = "pem")]
151impl<T: DecodeOwned<Error = Error> + PemLabel> DecodePem for T {
152 fn from_pem(pem: impl AsRef<[u8]>) -> Result<T, Error> {
153 let mut reader = PemReader::new(pem.as_ref())?;
154 Self::validate_pem_label(reader.type_label()).map_err(Error::from)?;
155 T::decode(&mut reader)
156 }
157}
158
159/// DecodeValue trait parses the value part of a Tag-Length-Value object,
160/// sans the [`Tag`] and [`Length`].
161///
162/// As opposed to [`Decode`], implementer is expected to read the inner content only,
163/// without the [`Header`], which was decoded beforehand.
164///
165/// ## Example
166/// ```
167/// use der::{Decode, DecodeValue, ErrorKind, FixedTag, Header, Reader, Tag};
168///
169/// /// 1-byte month
170/// struct MyByteMonth(u8);
171///
172/// impl<'a> DecodeValue<'a> for MyByteMonth {
173/// type Error = der::Error;
174///
175/// fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
176/// let month = reader.read_byte()?;
177///
178/// if (0..12).contains(&month) {
179/// Ok(Self(month))
180/// } else {
181/// Err(reader.error(ErrorKind::DateTime))
182/// }
183/// }
184/// }
185///
186/// impl FixedTag for MyByteMonth {
187/// const TAG: Tag = Tag::OctetString;
188/// }
189///
190/// let month = MyByteMonth::from_der(b"\x04\x01\x09").expect("month to decode");
191///
192/// assert_eq!(month.0, 9);
193/// ```
194pub trait DecodeValue<'a>: Sized {
195 /// Type returned in the event of a decoding error.
196 type Error: core::error::Error + From<Error> + 'static;
197
198 /// Attempt to decode this value using the provided [`Reader`].
199 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error>;
200}
201
202#[cfg(feature = "alloc")]
203impl<'a, T> DecodeValue<'a> for Box<T>
204where
205 T: DecodeValue<'a>,
206{
207 type Error = T::Error;
208
209 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error> {
210 Ok(Box::new(T::decode_value(reader, header)?))
211 }
212}
213
214#[cfg(feature = "alloc")]
215impl<'a, T, E> DecodeValue<'a> for Cow<'a, T>
216where
217 T: ToOwned + ?Sized,
218 &'a T: DecodeValue<'a, Error = E>,
219 T::Owned: for<'b> DecodeValue<'b, Error = E>,
220 E: core::error::Error + From<Error> + 'static,
221{
222 type Error = E;
223
224 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error> {
225 if R::CAN_READ_SLICE {
226 <&'a T>::decode_value(reader, header).map(Cow::Borrowed)
227 } else {
228 T::Owned::decode_value(reader, header).map(Cow::Owned)
229 }
230 }
231}