der/asn1/
any.rs

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