//! ASN.1 `ANY` type. #![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))] use crate::{ BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, Header, Length, Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer, }; use core::cmp::Ordering; #[cfg(feature = "alloc")] use crate::SliceWriter; /// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value. /// /// This is a zero-copy reference type which borrows from the input data. /// /// Technically `ANY` hasn't been a recommended part of ASN.1 since the X.209 /// revision from 1988. It was deprecated and replaced by Information Object /// Classes in X.680 in 1994, and X.690 no longer refers to it whatsoever. /// /// Nevertheless, this crate defines an `ANY` type as it remains a familiar /// and useful concept which is still extensively used in things like /// PKI-related RFCs. #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct AnyRef<'a> { /// Tag representing the type of the encoded value. tag: Tag, /// Inner value encoded as bytes. value: BytesRef<'a>, } impl<'a> AnyRef<'a> { /// [`AnyRef`] representation of the ASN.1 `NULL` type. pub const NULL: Self = Self { tag: Tag::Null, value: BytesRef::EMPTY, }; /// Create a new [`AnyRef`] from the provided [`Tag`] and DER bytes. pub fn new(tag: Tag, bytes: &'a [u8]) -> Result { let value = BytesRef::new(bytes).map_err(|_| ErrorKind::Length { tag })?; Ok(Self { tag, value }) } /// Infallible creation of an [`AnyRef`] from a [`BytesRef`]. pub(crate) fn from_tag_and_value(tag: Tag, value: BytesRef<'a>) -> Self { Self { tag, value } } /// Get the raw value for this [`AnyRef`] type as a byte slice. pub fn value(self) -> &'a [u8] { self.value.as_slice() } /// Attempt to decode this [`AnyRef`] type into the inner value. pub fn decode_as(self) -> Result where T: Choice<'a> + DecodeValue<'a>, { if !T::can_decode(self.tag) { return Err(self.tag.unexpected_error(None)); } let header = Header { tag: self.tag, length: self.value.len(), }; let mut decoder = SliceReader::new(self.value())?; let result = T::decode_value(&mut decoder, header)?; decoder.finish(result) } /// Is this value an ASN.1 `NULL` value? pub fn is_null(self) -> bool { self == Self::NULL } /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new /// nested reader and calling the provided argument with it. pub fn sequence(self, f: F) -> Result where F: FnOnce(&mut SliceReader<'a>) -> Result, { self.tag.assert_eq(Tag::Sequence)?; let mut reader = SliceReader::new(self.value.as_slice())?; let result = f(&mut reader)?; reader.finish(result) } } impl<'a> Choice<'a> for AnyRef<'a> { fn can_decode(_: Tag) -> bool { true } } impl<'a> Decode<'a> for AnyRef<'a> { fn decode>(reader: &mut R) -> Result> { let header = Header::decode(reader)?; Self::decode_value(reader, header) } } impl<'a> DecodeValue<'a> for AnyRef<'a> { fn decode_value>(reader: &mut R, header: Header) -> Result { Ok(Self { tag: header.tag, value: BytesRef::decode_value(reader, header)?, }) } } impl EncodeValue for AnyRef<'_> { fn value_len(&self) -> Result { Ok(self.value.len()) } fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { writer.write(self.value()) } } impl Tagged for AnyRef<'_> { fn tag(&self) -> Tag { self.tag } } impl ValueOrd for AnyRef<'_> { fn value_cmp(&self, other: &Self) -> Result { self.value.der_cmp(&other.value) } } impl<'a> From> for BytesRef<'a> { fn from(any: AnyRef<'a>) -> BytesRef<'a> { any.value } } impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> { type Error = Error; fn try_from(bytes: &'a [u8]) -> Result> { AnyRef::from_der(bytes) } } #[cfg(feature = "alloc")] pub use self::allocating::Any; #[cfg(feature = "alloc")] mod allocating { use super::*; use crate::{referenced::*, BytesOwned}; use alloc::boxed::Box; /// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value. /// /// This type provides the same functionality as [`AnyRef`] but owns the /// backing data. #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct Any { /// Tag representing the type of the encoded value. tag: Tag, /// Inner value encoded as bytes. value: BytesOwned, } impl Any { /// Create a new [`Any`] from the provided [`Tag`] and DER bytes. pub fn new(tag: Tag, bytes: impl Into>) -> Result { let value = BytesOwned::new(bytes)?; // Ensure the tag and value are a valid `AnyRef`. AnyRef::new(tag, value.as_slice())?; Ok(Self { tag, value }) } /// Allow access to value pub fn value(&self) -> &[u8] { self.value.as_slice() } /// Attempt to decode this [`Any`] type into the inner value. pub fn decode_as<'a, T>(&'a self) -> Result where T: Choice<'a> + DecodeValue<'a>, { AnyRef::from(self).decode_as() } /// Encode the provided type as an [`Any`] value. pub fn encode_from(msg: &T) -> Result where T: Tagged + EncodeValue, { let encoded_len = usize::try_from(msg.value_len()?)?; let mut buf = vec![0u8; encoded_len]; let mut writer = SliceWriter::new(&mut buf); msg.encode_value(&mut writer)?; writer.finish()?; Any::new(msg.tag(), buf) } /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new /// nested reader and calling the provided argument with it. pub fn sequence<'a, F, T>(&'a self, f: F) -> Result where F: FnOnce(&mut SliceReader<'a>) -> Result, { AnyRef::from(self).sequence(f) } /// [`Any`] representation of the ASN.1 `NULL` type. pub fn null() -> Self { Self { tag: Tag::Null, value: BytesOwned::default(), } } } impl Choice<'_> for Any { fn can_decode(_: Tag) -> bool { true } } impl<'a> Decode<'a> for Any { fn decode>(reader: &mut R) -> Result { let header = Header::decode(reader)?; Self::decode_value(reader, header) } } impl<'a> DecodeValue<'a> for Any { fn decode_value>(reader: &mut R, header: Header) -> Result { let value = reader.read_vec(header.length)?; Self::new(header.tag, value) } } impl EncodeValue for Any { fn value_len(&self) -> Result { Ok(self.value.len()) } fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { writer.write(self.value.as_slice()) } } impl<'a> From<&'a Any> for AnyRef<'a> { fn from(any: &'a Any) -> AnyRef<'a> { // Ensured to parse successfully in constructor AnyRef::new(any.tag, any.value.as_slice()).expect("invalid ANY") } } impl Tagged for Any { fn tag(&self) -> Tag { self.tag } } impl ValueOrd for Any { fn value_cmp(&self, other: &Self) -> Result { self.value.der_cmp(&other.value) } } impl<'a, T> From for Any where T: Into>, { fn from(input: T) -> Any { let anyref: AnyRef<'a> = input.into(); Self { tag: anyref.tag(), value: BytesOwned::from(anyref.value), } } } impl<'a> RefToOwned<'a> for AnyRef<'a> { type Owned = Any; fn ref_to_owned(&self) -> Self::Owned { Any { tag: self.tag(), value: BytesOwned::from(self.value), } } } impl OwnedToRef for Any { type Borrowed<'a> = AnyRef<'a>; fn owned_to_ref(&self) -> Self::Borrowed<'_> { self.into() } } impl Any { /// Is this value an ASN.1 `NULL` value? pub fn is_null(&self) -> bool { self.owned_to_ref() == AnyRef::NULL } } }