der/asn1/
any.rs

1//! ASN.1 `ANY` type.
2
3use crate::{
4    asn1::*, ByteSlice, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind,
5    FixedTag, Header, Length, Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
6};
7use core::cmp::Ordering;
8
9#[cfg(feature = "alloc")]
10use alloc::vec::Vec;
11
12#[cfg(feature = "oid")]
13use crate::asn1::ObjectIdentifier;
14
15/// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
16///
17/// This is a zero-copy reference type which borrows from the input data.
18///
19/// Technically `ANY` hasn't been a recommended part of ASN.1 since the X.209
20/// revision from 1988. It was deprecated and replaced by Information Object
21/// Classes in X.680 in 1994, and X.690 no longer refers to it whatsoever.
22///
23/// Nevertheless, this crate defines an `ANY` type as it remains a familiar
24/// and useful concept which is still extensively used in things like
25/// PKI-related RFCs.
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: ByteSlice<'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: ByteSlice::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 = ByteSlice::new(bytes).map_err(|_| ErrorKind::Length { tag })?;
45        Ok(Self { tag, value })
46    }
47
48    /// Infallible creation of an [`AnyRef`] from a [`ByteSlice`].
49    pub(crate) fn from_tag_and_value(tag: Tag, value: ByteSlice<'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_into<T>(self) -> Result<T>
60    where
61        T: DecodeValue<'a> + FixedTag,
62    {
63        self.tag.assert_eq(T::TAG)?;
64        let header = Header {
65            tag: self.tag,
66            length: self.value.len(),
67        };
68
69        let mut decoder = SliceReader::new(self.value())?;
70        let result = T::decode_value(&mut decoder, header)?;
71        decoder.finish(result)
72    }
73
74    /// Is this value an ASN.1 `NULL` value?
75    pub fn is_null(self) -> bool {
76        self == Self::NULL
77    }
78
79    /// Attempt to decode an ASN.1 `BIT STRING`.
80    pub fn bit_string(self) -> Result<BitStringRef<'a>> {
81        self.try_into()
82    }
83
84    /// Attempt to decode an ASN.1 `CONTEXT-SPECIFIC` field.
85    pub fn context_specific<T>(self) -> Result<ContextSpecific<T>>
86    where
87        T: Decode<'a>,
88    {
89        self.try_into()
90    }
91
92    /// Attempt to decode an ASN.1 `GeneralizedTime`.
93    pub fn generalized_time(self) -> Result<GeneralizedTime> {
94        self.try_into()
95    }
96
97    /// Attempt to decode an ASN.1 `IA5String`.
98    pub fn ia5_string(self) -> Result<Ia5StringRef<'a>> {
99        self.try_into()
100    }
101
102    /// Attempt to decode an ASN.1 `OCTET STRING`.
103    pub fn octet_string(self) -> Result<OctetStringRef<'a>> {
104        self.try_into()
105    }
106
107    /// Attempt to decode an ASN.1 `OBJECT IDENTIFIER`.
108    #[cfg(feature = "oid")]
109    #[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
110    pub fn oid(self) -> Result<ObjectIdentifier> {
111        self.try_into()
112    }
113
114    /// Attempt to decode an ASN.1 `OPTIONAL` value.
115    pub fn optional<T>(self) -> Result<Option<T>>
116    where
117        T: Choice<'a> + TryFrom<Self, Error = Error>,
118    {
119        if T::can_decode(self.tag) {
120            T::try_from(self).map(Some)
121        } else {
122            Ok(None)
123        }
124    }
125
126    /// Attempt to decode an ASN.1 `PrintableString`.
127    pub fn printable_string(self) -> Result<PrintableStringRef<'a>> {
128        self.try_into()
129    }
130
131    /// Attempt to decode an ASN.1 `TeletexString`.
132    pub fn teletex_string(self) -> Result<TeletexStringRef<'a>> {
133        self.try_into()
134    }
135
136    /// Attempt to decode an ASN.1 `VideotexString`.
137    pub fn videotex_string(self) -> Result<VideotexStringRef<'a>> {
138        self.try_into()
139    }
140
141    /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
142    /// nested reader and calling the provided argument with it.
143    pub fn sequence<F, T>(self, f: F) -> Result<T>
144    where
145        F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
146    {
147        self.tag.assert_eq(Tag::Sequence)?;
148        let mut reader = SliceReader::new(self.value.as_slice())?;
149        let result = f(&mut reader)?;
150        reader.finish(result)
151    }
152
153    /// Attempt to decode an ASN.1 `UTCTime`.
154    pub fn utc_time(self) -> Result<UtcTime> {
155        self.try_into()
156    }
157
158    /// Attempt to decode an ASN.1 `UTF8String`.
159    pub fn utf8_string(self) -> Result<Utf8StringRef<'a>> {
160        self.try_into()
161    }
162}
163
164impl<'a> Choice<'a> for AnyRef<'a> {
165    fn can_decode(_: Tag) -> bool {
166        true
167    }
168}
169
170impl<'a> Decode<'a> for AnyRef<'a> {
171    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<AnyRef<'a>> {
172        let header = Header::decode(reader)?;
173
174        Ok(Self {
175            tag: header.tag,
176            value: ByteSlice::decode_value(reader, header)?,
177        })
178    }
179}
180
181impl EncodeValue for AnyRef<'_> {
182    fn value_len(&self) -> Result<Length> {
183        Ok(self.value.len())
184    }
185
186    fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
187        writer.write(self.value())
188    }
189}
190
191impl Tagged for AnyRef<'_> {
192    fn tag(&self) -> Tag {
193        self.tag
194    }
195}
196
197impl ValueOrd for AnyRef<'_> {
198    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
199        self.value.der_cmp(&other.value)
200    }
201}
202
203impl<'a> From<AnyRef<'a>> for ByteSlice<'a> {
204    fn from(any: AnyRef<'a>) -> ByteSlice<'a> {
205        any.value
206    }
207}
208
209impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> {
210    type Error = Error;
211
212    fn try_from(bytes: &'a [u8]) -> Result<AnyRef<'a>> {
213        AnyRef::from_der(bytes)
214    }
215}
216
217/// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
218///
219/// This type provides the same functionality as [`AnyRef`] but owns the
220/// backing data.
221#[cfg(feature = "alloc")]
222#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
223#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
224pub struct Any {
225    /// Tag representing the type of the encoded value.
226    tag: Tag,
227
228    /// Inner value encoded as bytes.
229    value: Vec<u8>,
230}
231
232#[cfg(feature = "alloc")]
233impl Any {
234    /// Create a new [`Any`] from the provided [`Tag`] and DER bytes.
235    pub fn new(tag: Tag, bytes: impl Into<Vec<u8>>) -> Result<Self> {
236        let value = bytes.into();
237
238        // Ensure the tag and value are a valid `AnyRef`.
239        AnyRef::new(tag, &value)?;
240        Ok(Self { tag, value })
241    }
242}
243
244#[cfg(feature = "alloc")]
245impl Choice<'_> for Any {
246    fn can_decode(_: Tag) -> bool {
247        true
248    }
249}
250
251#[cfg(feature = "alloc")]
252impl<'a> Decode<'a> for Any {
253    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
254        let header = Header::decode(reader)?;
255        let value = reader.read_vec(header.length)?;
256        Self::new(header.tag, value)
257    }
258}
259
260#[cfg(feature = "alloc")]
261impl EncodeValue for Any {
262    fn value_len(&self) -> Result<Length> {
263        self.value.len().try_into()
264    }
265
266    fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
267        writer.write(&self.value)
268    }
269}
270
271#[cfg(feature = "alloc")]
272impl<'a> From<&'a Any> for AnyRef<'a> {
273    fn from(any: &'a Any) -> AnyRef<'a> {
274        // Ensured to parse successfully in constructor
275        AnyRef::new(any.tag, &any.value).expect("invalid ANY")
276    }
277}
278
279#[cfg(feature = "alloc")]
280impl Tagged for Any {
281    fn tag(&self) -> Tag {
282        self.tag
283    }
284}