asn1_rs/
traits.rs

1use crate::debug::{trace, trace_generic};
2use crate::error::*;
3use crate::{parse_der_any, Any, Class, Explicit, Implicit, Tag, TaggedParser};
4use core::convert::{TryFrom, TryInto};
5use core::fmt::{Debug, Display};
6#[cfg(feature = "std")]
7use std::io::Write;
8
9/// Phantom type representing a BER parser
10#[doc(hidden)]
11#[derive(Debug)]
12pub enum BerParser {}
13
14/// Phantom type representing a DER parser
15#[doc(hidden)]
16#[derive(Debug)]
17pub enum DerParser {}
18
19#[doc(hidden)]
20pub trait ASN1Parser {}
21
22impl ASN1Parser for BerParser {}
23impl ASN1Parser for DerParser {}
24
25pub trait Tagged {
26    const TAG: Tag;
27}
28
29impl<T> Tagged for &'_ T
30where
31    T: Tagged,
32{
33    const TAG: Tag = T::TAG;
34}
35
36pub trait DynTagged {
37    fn tag(&self) -> Tag;
38}
39
40impl<T> DynTagged for T
41where
42    T: Tagged,
43{
44    fn tag(&self) -> Tag {
45        T::TAG
46    }
47}
48
49/// Base trait for BER object parsers
50///
51/// Library authors should usually not directly implement this trait, but should prefer implementing the
52/// [`TryFrom<Any>`] trait,
53/// which offers greater flexibility and provides an equivalent `FromBer` implementation for free.
54///
55/// # Examples
56///
57/// ```
58/// use asn1_rs::{Any, Result, Tag};
59/// use std::convert::TryFrom;
60///
61/// // The type to be decoded
62/// #[derive(Clone, Copy, Debug, PartialEq, Eq)]
63/// pub struct MyType(pub u32);
64///
65/// impl<'a> TryFrom<Any<'a>> for MyType {
66///     type Error = asn1_rs::Error;
67///
68///     fn try_from(any: Any<'a>) -> Result<MyType> {
69///         any.tag().assert_eq(Tag::Integer)?;
70///         // for this fictive example, the type contains the number of characters
71///         let n = any.data.len() as u32;
72///         Ok(MyType(n))
73///     }
74/// }
75///
76/// // The above code provides a `FromBer` implementation for free.
77///
78/// // Example of parsing code:
79/// use asn1_rs::FromBer;
80///
81/// let input = &[2, 1, 2];
82/// // Objects can be parsed using `from_ber`, which returns the remaining bytes
83/// // and the parsed object:
84/// let (rem, my_type) = MyType::from_ber(input).expect("parsing failed");
85/// ```
86pub trait FromBer<'a, E = Error>: Sized {
87    /// Attempt to parse input bytes into a BER object
88    fn from_ber(bytes: &'a [u8]) -> ParseResult<Self, E>;
89}
90
91impl<'a, T, E> FromBer<'a, E> for T
92where
93    T: TryFrom<Any<'a>, Error = E>,
94    E: From<Error>,
95{
96    fn from_ber(bytes: &'a [u8]) -> ParseResult<T, E> {
97        let (i, any) = Any::from_ber(bytes).map_err(nom::Err::convert)?;
98        let result = any.try_into().map_err(nom::Err::Error)?;
99        Ok((i, result))
100    }
101}
102
103/// Base trait for DER object parsers
104///
105/// Library authors should usually not directly implement this trait, but should prefer implementing the
106/// [`TryFrom<Any>`] + [`CheckDerConstraints`] traits,
107/// which offers greater flexibility and provides an equivalent `FromDer` implementation for free
108/// (in fact, it provides both [`FromBer`] and `FromDer`).
109///
110/// Note: if you already implemented [`TryFrom<Any>`] and [`CheckDerConstraints`],
111/// you can get a free [`FromDer`] implementation by implementing the
112/// [`DerAutoDerive`] trait. This is not automatic, so it is also possible to manually
113/// implement [`FromDer`] if preferred.
114///
115/// # Examples
116///
117/// ```
118/// use asn1_rs::{Any, CheckDerConstraints, DerAutoDerive, Result, Tag};
119/// use std::convert::TryFrom;
120///
121/// // The type to be decoded
122/// #[derive(Clone, Copy, Debug, PartialEq, Eq)]
123/// pub struct MyType(pub u32);
124///
125/// impl<'a> TryFrom<Any<'a>> for MyType {
126///     type Error = asn1_rs::Error;
127///
128///     fn try_from(any: Any<'a>) -> Result<MyType> {
129///         any.tag().assert_eq(Tag::Integer)?;
130///         // for this fictive example, the type contains the number of characters
131///         let n = any.data.len() as u32;
132///         Ok(MyType(n))
133///     }
134/// }
135///
136/// impl CheckDerConstraints for MyType {
137///     fn check_constraints(any: &Any) -> Result<()> {
138///         any.header.assert_primitive()?;
139///         Ok(())
140///     }
141/// }
142///
143/// impl DerAutoDerive for MyType {}
144///
145/// // The above code provides a `FromDer` implementation for free.
146///
147/// // Example of parsing code:
148/// use asn1_rs::FromDer;
149///
150/// let input = &[2, 1, 2];
151/// // Objects can be parsed using `from_der`, which returns the remaining bytes
152/// // and the parsed object:
153/// let (rem, my_type) = MyType::from_der(input).expect("parsing failed");
154/// ```
155pub trait FromDer<'a, E = Error>: Sized {
156    /// Attempt to parse input bytes into a DER object (enforcing constraints)
157    fn from_der(bytes: &'a [u8]) -> ParseResult<Self, E>;
158}
159
160/// Trait to automatically derive `FromDer`
161///
162/// This trait is only a marker to control if a DER parser should be automatically derived. It is
163/// empty.
164///
165/// This trait is used in combination with others:
166/// after implementing [`TryFrom<Any>`] and [`CheckDerConstraints`] for a type,
167/// a free [`FromDer`] implementation is provided by implementing the
168/// [`DerAutoDerive`] trait. This is the most common case.
169///
170/// However, this is not automatic so it is also possible to manually
171/// implement [`FromDer`] if preferred.
172/// Manual implementation is generally only needed for generic containers (for ex. `Vec<T>`),
173/// because the default implementation adds a constraint on `T` to implement also `TryFrom<Any>`
174/// and `CheckDerConstraints`. This is problematic when `T` only provides `FromDer`, and can be
175/// solved by providing a manual implementation of [`FromDer`].
176pub trait DerAutoDerive {}
177
178impl<'a, T, E> FromDer<'a, E> for T
179where
180    T: TryFrom<Any<'a>, Error = E>,
181    T: CheckDerConstraints,
182    T: DerAutoDerive,
183    E: From<Error> + Display + Debug,
184{
185    fn from_der(bytes: &'a [u8]) -> ParseResult<T, E> {
186        trace_generic(
187            core::any::type_name::<T>(),
188            "T::from_der",
189            |bytes| {
190                let (i, any) = trace(core::any::type_name::<T>(), parse_der_any, bytes)
191                    .map_err(nom::Err::convert)?;
192                <T as CheckDerConstraints>::check_constraints(&any)
193                    .map_err(|e| nom::Err::Error(e.into()))?;
194                let result = any.try_into().map_err(nom::Err::Error)?;
195                Ok((i, result))
196            },
197            bytes,
198        )
199    }
200}
201
202/// Verification of DER constraints
203pub trait CheckDerConstraints {
204    fn check_constraints(any: &Any) -> Result<()>;
205}
206
207/// Common trait for all objects that can be encoded using the DER representation
208///
209/// # Examples
210///
211/// Objects from this crate can be encoded as DER:
212///
213/// ```
214/// use asn1_rs::{Integer, ToDer};
215///
216/// let int = Integer::from(4u32);
217/// let mut writer = Vec::new();
218/// let sz = int.write_der(&mut writer).expect("serialization failed");
219///
220/// assert_eq!(&writer, &[0x02, 0x01, 0x04]);
221/// # assert_eq!(sz, 3);
222/// ```
223///
224/// Many of the primitive types can also directly be encoded as DER:
225///
226/// ```
227/// use asn1_rs::ToDer;
228///
229/// let mut writer = Vec::new();
230/// let sz = 4.write_der(&mut writer).expect("serialization failed");
231///
232/// assert_eq!(&writer, &[0x02, 0x01, 0x04]);
233/// # assert_eq!(sz, 3);
234/// ```
235#[cfg(feature = "std")]
236pub trait ToDer
237where
238    Self: DynTagged,
239{
240    /// Get the length of the object (including the header), when encoded
241    ///
242    // Since we are using DER, length cannot be Indefinite, so we can use `usize`.
243    // XXX can this function fail?
244    fn to_der_len(&self) -> Result<usize>;
245
246    /// Write the DER encoded representation to a newly allocated `Vec<u8>`.
247    fn to_der_vec(&self) -> SerializeResult<Vec<u8>> {
248        let mut v = Vec::new();
249        let _ = self.write_der(&mut v)?;
250        Ok(v)
251    }
252
253    /// Similar to using `to_vec`, but uses provided values without changes.
254    /// This can generate an invalid encoding for a DER object.
255    fn to_der_vec_raw(&self) -> SerializeResult<Vec<u8>> {
256        let mut v = Vec::new();
257        let _ = self.write_der_raw(&mut v)?;
258        Ok(v)
259    }
260
261    /// Attempt to write the DER encoded representation (header and content) into this writer.
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// use asn1_rs::{Integer, ToDer};
267    ///
268    /// let int = Integer::from(4u32);
269    /// let mut writer = Vec::new();
270    /// let sz = int.write_der(&mut writer).expect("serialization failed");
271    ///
272    /// assert_eq!(&writer, &[0x02, 0x01, 0x04]);
273    /// # assert_eq!(sz, 3);
274    /// ```
275    fn write_der(&self, writer: &mut dyn Write) -> SerializeResult<usize> {
276        let sz = self.write_der_header(writer)?;
277        let sz = sz + self.write_der_content(writer)?;
278        Ok(sz)
279    }
280
281    /// Attempt to write the DER header to this writer.
282    fn write_der_header(&self, writer: &mut dyn Write) -> SerializeResult<usize>;
283
284    /// Attempt to write the DER content (all except header) to this writer.
285    fn write_der_content(&self, writer: &mut dyn Write) -> SerializeResult<usize>;
286
287    /// Similar to using `to_der`, but uses provided values without changes.
288    /// This can generate an invalid encoding for a DER object.
289    fn write_der_raw(&self, writer: &mut dyn Write) -> SerializeResult<usize> {
290        self.write_der(writer)
291    }
292}
293
294#[cfg(feature = "std")]
295impl<'a, T> ToDer for &'a T
296where
297    T: ToDer,
298    &'a T: DynTagged,
299{
300    fn to_der_len(&self) -> Result<usize> {
301        (*self).to_der_len()
302    }
303
304    fn write_der_header(&self, writer: &mut dyn Write) -> SerializeResult<usize> {
305        (*self).write_der_header(writer)
306    }
307
308    fn write_der_content(&self, writer: &mut dyn Write) -> SerializeResult<usize> {
309        (*self).write_der_content(writer)
310    }
311}
312
313/// Helper trait for creating tagged EXPLICIT values
314///
315/// # Examples
316///
317/// ```
318/// use asn1_rs::{AsTaggedExplicit, Class, Error, TaggedParser};
319///
320/// // create a `[1] EXPLICIT INTEGER` value
321/// let tagged: TaggedParser<_, _, Error> = 4u32.explicit(Class::ContextSpecific, 1);
322/// ```
323pub trait AsTaggedExplicit<'a, E = Error>: Sized {
324    fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E> {
325        TaggedParser::new_explicit(class, tag, self)
326    }
327}
328
329impl<'a, T, E> AsTaggedExplicit<'a, E> for T where T: Sized + 'a {}
330
331/// Helper trait for creating tagged IMPLICIT values
332///
333/// # Examples
334///
335/// ```
336/// use asn1_rs::{AsTaggedImplicit, Class, Error, TaggedParser};
337///
338/// // create a `[1] IMPLICIT INTEGER` value, not constructed
339/// let tagged: TaggedParser<_, _, Error> = 4u32.implicit(Class::ContextSpecific, false, 1);
340/// ```
341pub trait AsTaggedImplicit<'a, E = Error>: Sized {
342    fn implicit(
343        self,
344        class: Class,
345        constructed: bool,
346        tag: u32,
347    ) -> TaggedParser<'a, Implicit, Self, E> {
348        TaggedParser::new_implicit(class, constructed, tag, self)
349    }
350}
351
352impl<'a, T, E> AsTaggedImplicit<'a, E> for T where T: Sized + 'a {}
353
354pub trait ToStatic {
355    type Owned: 'static;
356    fn to_static(&self) -> Self::Owned;
357}