Skip to main content

der/asn1/
any.rs

1//! ASN.1 `ANY` type.
2
3#![cfg_attr(feature = "arbitrary", allow(clippy::arithmetic_side_effects))]
4
5use crate::{
6    BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, EncodingRules, Error, ErrorKind,
7    Header, Length, Reader, SliceReader, Tag, Tagged, ValueOrd, Writer,
8};
9use core::cmp::Ordering;
10
11/// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
12///
13/// This is a zero-copy reference type which borrows from the input data.
14///
15/// Technically `ANY` hasn't been a recommended part of ASN.1 since the X.209
16/// revision from 1988. It was deprecated and replaced by Information Object
17/// Classes in X.680 in 1994, and X.690 no longer refers to it whatsoever.
18///
19/// Nevertheless, this crate defines an `ANY` type as it remains a familiar
20/// and useful concept which is still extensively used in things like
21/// PKI-related RFCs.
22#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
23#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
24pub struct AnyRef<'a> {
25    /// Tag representing the type of the encoded value.
26    tag: Tag,
27
28    /// Inner value encoded as bytes.
29    value: &'a BytesRef,
30}
31
32impl<'a> AnyRef<'a> {
33    /// [`AnyRef`] representation of the ASN.1 `NULL` type.
34    pub const NULL: Self = Self {
35        tag: Tag::Null,
36        value: BytesRef::new_unchecked(&[]),
37    };
38
39    /// Create a new [`AnyRef`] from the provided [`Tag`] and DER bytes.
40    ///
41    /// # Errors
42    /// Returns [`Error`] with [`ErrorKind::Length`] if `bytes` is too long.
43    pub const fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self, Error> {
44        match BytesRef::new(bytes) {
45            Ok(value) => Ok(Self { tag, value }),
46            Err(_) => Err(Error::from_kind(ErrorKind::Length { tag })),
47        }
48    }
49
50    /// Infallible creation of an [`AnyRef`] from a [`BytesRef`].
51    pub(crate) fn from_tag_and_value(tag: Tag, value: &'a BytesRef) -> Self {
52        Self { tag, value }
53    }
54
55    /// Get the raw value for this [`AnyRef`] type as a byte slice.
56    #[must_use]
57    pub fn value(self) -> &'a [u8] {
58        self.value.as_slice()
59    }
60
61    /// Returns [`Tag`] and [`Length`] of self.
62    #[must_use]
63    pub fn header(&self) -> Header {
64        Header::new(self.tag, self.value.len())
65    }
66
67    /// Attempt to decode this [`AnyRef`] type into the inner value.
68    ///
69    /// # Errors
70    /// Returns `T::Error` if a decoding error occurred.
71    pub fn decode_as<T>(self) -> Result<T, <T as DecodeValue<'a>>::Error>
72    where
73        T: Choice<'a> + DecodeValue<'a>,
74    {
75        self.decode_as_encoding(EncodingRules::Der)
76    }
77
78    /// Attempt to decode this [`AnyRef`] type into the inner value.
79    ///
80    /// # Errors
81    /// Returns `T::Error` if a decoding error occurred.
82    pub fn decode_as_encoding<T>(
83        self,
84        encoding: EncodingRules,
85    ) -> Result<T, <T as DecodeValue<'a>>::Error>
86    where
87        T: Choice<'a> + DecodeValue<'a>,
88    {
89        if !T::can_decode(self.tag) {
90            return Err(self.tag.unexpected_error(None).to_error().into());
91        }
92
93        let mut decoder = SliceReader::new_with_encoding_rules(self.value(), encoding)?;
94        let result = T::decode_value(&mut decoder, self.header())?;
95        decoder.finish()?;
96        Ok(result)
97    }
98
99    /// Is this value an ASN.1 `NULL` value?
100    #[must_use]
101    pub fn is_null(self) -> bool {
102        self == Self::NULL
103    }
104
105    /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
106    /// nested reader and calling the provided argument with it.
107    ///
108    /// # Errors
109    /// Returns `E` in the event an error is returned from `F` or if a decoding error occurs.
110    pub fn sequence<F, T, E>(self, f: F) -> Result<T, E>
111    where
112        F: FnOnce(&mut SliceReader<'a>) -> Result<T, E>,
113        E: From<Error>,
114    {
115        self.tag.assert_eq(Tag::Sequence)?;
116        let mut reader = SliceReader::new(self.value.as_slice())?;
117        let result = f(&mut reader)?;
118        reader.finish()?;
119        Ok(result)
120    }
121}
122
123impl<'a> Choice<'a> for AnyRef<'a> {
124    fn can_decode(_: Tag) -> bool {
125        true
126    }
127}
128
129impl<'a> Decode<'a> for AnyRef<'a> {
130    type Error = Error;
131
132    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<AnyRef<'a>, Error> {
133        let header = Header::decode(reader)?;
134        Self::decode_value(reader, header)
135    }
136}
137
138impl<'a> DecodeValue<'a> for AnyRef<'a> {
139    type Error = Error;
140
141    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Error> {
142        Ok(Self {
143            tag: header.tag(),
144            value: <&'a BytesRef>::decode_value(reader, header)?,
145        })
146    }
147}
148
149impl EncodeValue for AnyRef<'_> {
150    fn value_len(&self) -> Result<Length, Error> {
151        Ok(self.value.len())
152    }
153
154    fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
155        writer.write(self.value())
156    }
157}
158
159impl Tagged for AnyRef<'_> {
160    fn tag(&self) -> Tag {
161        self.tag
162    }
163}
164
165impl ValueOrd for AnyRef<'_> {
166    fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
167        self.value.der_cmp(other.value)
168    }
169}
170
171impl<'a> From<AnyRef<'a>> for &'a BytesRef {
172    fn from(any: AnyRef<'a>) -> &'a BytesRef {
173        any.value
174    }
175}
176
177impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> {
178    type Error = Error;
179
180    fn try_from(bytes: &'a [u8]) -> Result<AnyRef<'a>, Error> {
181        AnyRef::from_der(bytes)
182    }
183}
184
185#[cfg(feature = "alloc")]
186pub use self::allocating::Any;
187
188#[cfg(feature = "alloc")]
189mod allocating {
190    use super::*;
191    use crate::{BytesOwned, encode::encode_value_to_slice, reader::read_value, referenced::*};
192    use alloc::boxed::Box;
193
194    /// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
195    ///
196    /// This type provides the same functionality as [`AnyRef`] but owns the
197    /// backing data.
198    #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
199    #[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
200    pub struct Any {
201        /// Tag representing the type of the encoded value.
202        tag: Tag,
203
204        /// Inner value encoded as bytes.
205        value: BytesOwned,
206    }
207
208    impl Any {
209        /// Create a new [`Any`] from the provided [`Tag`] and DER bytes.
210        ///
211        /// # Errors
212        /// If `bytes` is too long.
213        pub fn new(tag: Tag, bytes: impl Into<Box<[u8]>>) -> Result<Self, Error> {
214            let value = BytesOwned::new(bytes)?;
215            Ok(Self { tag, value })
216        }
217
218        /// Allow access to value
219        #[must_use]
220        pub fn value(&self) -> &[u8] {
221            self.value.as_slice()
222        }
223
224        /// Returns [`Tag`] and [`Length`] of self.
225        #[must_use]
226        pub fn header(&self) -> Header {
227            Header::new(self.tag, self.value.len())
228        }
229
230        /// Attempt to decode this [`Any`] type into the inner value.
231        ///
232        /// # Errors
233        /// Returns `T::Error` if a decoding error occurred.
234        pub fn decode_as<'a, T>(&'a self) -> Result<T, <T as DecodeValue<'a>>::Error>
235        where
236            T: Choice<'a> + DecodeValue<'a>,
237        {
238            self.decode_as_encoding(EncodingRules::Der)
239        }
240
241        /// Attempt to decode this [`Any`] type into the inner value with the given encoding rules.
242        ///
243        /// # Errors
244        /// Returns `T::Error` if a decoding error occurred.
245        pub fn decode_as_encoding<'a, T>(
246            &'a self,
247            encoding: EncodingRules,
248        ) -> Result<T, <T as DecodeValue<'a>>::Error>
249        where
250            T: Choice<'a> + DecodeValue<'a>,
251        {
252            self.to_ref().decode_as_encoding(encoding)
253        }
254
255        /// Encode the provided type as an [`Any`] value.
256        ///
257        /// # Errors
258        /// If an encoding error occurred.
259        pub fn encode_from<T>(msg: &T) -> Result<Self, Error>
260        where
261            T: Tagged + EncodeValue,
262        {
263            let encoded_len = usize::try_from(msg.value_len()?)?;
264            let mut buf = vec![0u8; encoded_len];
265            encode_value_to_slice(&mut buf, msg)?;
266            Any::new(msg.tag(), buf)
267        }
268
269        /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
270        /// nested reader and calling the provided argument with it.
271        ///
272        /// # Errors
273        /// If a decoding error occurred.
274        pub fn sequence<'a, F, T, E>(&'a self, f: F) -> Result<T, E>
275        where
276            F: FnOnce(&mut SliceReader<'a>) -> Result<T, E>,
277            E: From<Error>,
278        {
279            AnyRef::from(self).sequence(f)
280        }
281
282        /// [`Any`] representation of the ASN.1 `NULL` type.
283        #[must_use]
284        pub fn null() -> Self {
285            Self {
286                tag: Tag::Null,
287                value: BytesOwned::default(),
288            }
289        }
290
291        /// Create a new [`AnyRef`] from the provided [`Any`] owned tag and bytes.
292        #[must_use]
293        pub fn to_ref(&self) -> AnyRef<'_> {
294            AnyRef {
295                tag: self.tag,
296                value: self.value.as_ref(),
297            }
298        }
299    }
300
301    impl Choice<'_> for Any {
302        fn can_decode(_: Tag) -> bool {
303            true
304        }
305    }
306
307    impl<'a> Decode<'a> for Any {
308        type Error = Error;
309
310        fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self, Error> {
311            let header = Header::decode(reader)?;
312            read_value(reader, header, Self::decode_value)
313        }
314    }
315
316    impl<'a> DecodeValue<'a> for Any {
317        type Error = Error;
318
319        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Error> {
320            Ok(Self {
321                tag: header.tag(),
322                value: BytesOwned::decode_value(reader, header)?,
323            })
324        }
325    }
326
327    impl EncodeValue for Any {
328        fn value_len(&self) -> Result<Length, Error> {
329            Ok(self.value.len())
330        }
331
332        fn encode_value(&self, writer: &mut impl Writer) -> Result<(), Error> {
333            writer.write(self.value.as_slice())
334        }
335    }
336
337    impl<'a> From<&'a Any> for AnyRef<'a> {
338        fn from(any: &'a Any) -> AnyRef<'a> {
339            any.to_ref()
340        }
341    }
342
343    impl Tagged for Any {
344        fn tag(&self) -> Tag {
345            self.tag
346        }
347    }
348
349    impl ValueOrd for Any {
350        fn value_cmp(&self, other: &Self) -> Result<Ordering, Error> {
351            self.value.der_cmp(&other.value)
352        }
353    }
354
355    impl<'a, T> From<T> for Any
356    where
357        T: Into<AnyRef<'a>>,
358    {
359        fn from(input: T) -> Any {
360            let anyref: AnyRef<'a> = input.into();
361            Self {
362                tag: anyref.tag(),
363                value: BytesOwned::from(anyref.value),
364            }
365        }
366    }
367
368    impl<'a> RefToOwned<'a> for AnyRef<'a> {
369        type Owned = Any;
370        fn ref_to_owned(&self) -> Self::Owned {
371            Any {
372                tag: self.tag(),
373                value: BytesOwned::from(self.value),
374            }
375        }
376    }
377
378    impl OwnedToRef for Any {
379        type Borrowed<'a> = AnyRef<'a>;
380        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
381            self.into()
382        }
383    }
384
385    impl Any {
386        /// Is this value an ASN.1 `NULL` value?
387        #[must_use]
388        pub fn is_null(&self) -> bool {
389            self.owned_to_ref() == AnyRef::NULL
390        }
391    }
392}