1 //! ASN.1 `ANY` type. 2 3 use crate::{ 4 asn1::*, ByteSlice, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, 5 FixedTag, Header, Length, Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer, 6 }; 7 use core::cmp::Ordering; 8 9 #[cfg(feature = "alloc")] 10 use alloc::vec::Vec; 11 12 #[cfg(feature = "oid")] 13 use 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)] 27 pub 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 35 impl<'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. new(tag: Tag, bytes: &'a [u8]) -> Result<Self>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`]. from_tag_and_value(tag: Tag, value: ByteSlice<'a>) -> Self49 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. value(self) -> &'a [u8]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. decode_into<T>(self) -> Result<T> where T: DecodeValue<'a> + FixedTag,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? is_null(self) -> bool75 pub fn is_null(self) -> bool { 76 self == Self::NULL 77 } 78 79 /// Attempt to decode an ASN.1 `BIT STRING`. bit_string(self) -> Result<BitStringRef<'a>>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. context_specific<T>(self) -> Result<ContextSpecific<T>> where T: Decode<'a>,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`. generalized_time(self) -> Result<GeneralizedTime>93 pub fn generalized_time(self) -> Result<GeneralizedTime> { 94 self.try_into() 95 } 96 97 /// Attempt to decode an ASN.1 `IA5String`. ia5_string(self) -> Result<Ia5StringRef<'a>>98 pub fn ia5_string(self) -> Result<Ia5StringRef<'a>> { 99 self.try_into() 100 } 101 102 /// Attempt to decode an ASN.1 `OCTET STRING`. octet_string(self) -> Result<OctetStringRef<'a>>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")))] oid(self) -> Result<ObjectIdentifier>110 pub fn oid(self) -> Result<ObjectIdentifier> { 111 self.try_into() 112 } 113 114 /// Attempt to decode an ASN.1 `OPTIONAL` value. optional<T>(self) -> Result<Option<T>> where T: Choice<'a> + TryFrom<Self, Error = Error>,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`. printable_string(self) -> Result<PrintableStringRef<'a>>127 pub fn printable_string(self) -> Result<PrintableStringRef<'a>> { 128 self.try_into() 129 } 130 131 /// Attempt to decode an ASN.1 `TeletexString`. teletex_string(self) -> Result<TeletexStringRef<'a>>132 pub fn teletex_string(self) -> Result<TeletexStringRef<'a>> { 133 self.try_into() 134 } 135 136 /// Attempt to decode an ASN.1 `VideotexString`. videotex_string(self) -> Result<VideotexStringRef<'a>>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. sequence<F, T>(self, f: F) -> Result<T> where F: FnOnce(&mut SliceReader<'a>) -> Result<T>,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`. utc_time(self) -> Result<UtcTime>154 pub fn utc_time(self) -> Result<UtcTime> { 155 self.try_into() 156 } 157 158 /// Attempt to decode an ASN.1 `UTF8String`. utf8_string(self) -> Result<Utf8StringRef<'a>>159 pub fn utf8_string(self) -> Result<Utf8StringRef<'a>> { 160 self.try_into() 161 } 162 } 163 164 impl<'a> Choice<'a> for AnyRef<'a> { can_decode(_: Tag) -> bool165 fn can_decode(_: Tag) -> bool { 166 true 167 } 168 } 169 170 impl<'a> Decode<'a> for AnyRef<'a> { decode<R: Reader<'a>>(reader: &mut R) -> Result<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 181 impl EncodeValue for AnyRef<'_> { value_len(&self) -> Result<Length>182 fn value_len(&self) -> Result<Length> { 183 Ok(self.value.len()) 184 } 185 encode_value(&self, writer: &mut dyn Writer) -> Result<()>186 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { 187 writer.write(self.value()) 188 } 189 } 190 191 impl Tagged for AnyRef<'_> { tag(&self) -> Tag192 fn tag(&self) -> Tag { 193 self.tag 194 } 195 } 196 197 impl ValueOrd for AnyRef<'_> { value_cmp(&self, other: &Self) -> Result<Ordering>198 fn value_cmp(&self, other: &Self) -> Result<Ordering> { 199 self.value.der_cmp(&other.value) 200 } 201 } 202 203 impl<'a> From<AnyRef<'a>> for ByteSlice<'a> { from(any: AnyRef<'a>) -> ByteSlice<'a>204 fn from(any: AnyRef<'a>) -> ByteSlice<'a> { 205 any.value 206 } 207 } 208 209 impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> { 210 type Error = Error; 211 try_from(bytes: &'a [u8]) -> Result<AnyRef<'a>>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)] 224 pub 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")] 233 impl Any { 234 /// Create a new [`Any`] from the provided [`Tag`] and DER bytes. new(tag: Tag, bytes: impl Into<Vec<u8>>) -> Result<Self>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")] 245 impl Choice<'_> for Any { can_decode(_: Tag) -> bool246 fn can_decode(_: Tag) -> bool { 247 true 248 } 249 } 250 251 #[cfg(feature = "alloc")] 252 impl<'a> Decode<'a> for Any { decode<R: Reader<'a>>(reader: &mut R) -> Result<Self>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")] 261 impl EncodeValue for Any { value_len(&self) -> Result<Length>262 fn value_len(&self) -> Result<Length> { 263 self.value.len().try_into() 264 } 265 encode_value(&self, writer: &mut dyn Writer) -> Result<()>266 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { 267 writer.write(&self.value) 268 } 269 } 270 271 #[cfg(feature = "alloc")] 272 impl<'a> From<&'a Any> for AnyRef<'a> { from(any: &'a Any) -> 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")] 280 impl Tagged for Any { tag(&self) -> Tag281 fn tag(&self) -> Tag { 282 self.tag 283 } 284 } 285