From 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:41:41 +0200 Subject: Merging upstream version 1.70.0+dfsg2. Signed-off-by: Daniel Baumann --- vendor/der/src/asn1/octet_string.rs | 182 ++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 vendor/der/src/asn1/octet_string.rs (limited to 'vendor/der/src/asn1/octet_string.rs') diff --git a/vendor/der/src/asn1/octet_string.rs b/vendor/der/src/asn1/octet_string.rs new file mode 100644 index 000000000..6f5b91a3d --- /dev/null +++ b/vendor/der/src/asn1/octet_string.rs @@ -0,0 +1,182 @@ +//! ASN.1 `OCTET STRING` support. + +use crate::{ + asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind, + FixedTag, Header, Length, Reader, Result, Tag, Writer, +}; + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +/// ASN.1 `OCTET STRING` type: borrowed form. +/// +/// Octet strings represent contiguous sequences of octets, a.k.a. bytes. +/// +/// This is a zero-copy reference type which borrows from the input data. +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct OctetStringRef<'a> { + /// Inner value + inner: ByteSlice<'a>, +} + +impl<'a> OctetStringRef<'a> { + /// Create a new ASN.1 `OCTET STRING` from a byte slice. + pub fn new(slice: &'a [u8]) -> Result { + ByteSlice::new(slice) + .map(|inner| Self { inner }) + .map_err(|_| ErrorKind::Length { tag: Self::TAG }.into()) + } + + /// Borrow the inner byte slice. + pub fn as_bytes(&self) -> &'a [u8] { + self.inner.as_slice() + } + + /// Get the length of the inner byte slice. + pub fn len(&self) -> Length { + self.inner.len() + } + + /// Is the inner byte slice empty? + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } +} + +impl AsRef<[u8]> for OctetStringRef<'_> { + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl<'a> DecodeValue<'a> for OctetStringRef<'a> { + fn decode_value>(reader: &mut R, header: Header) -> Result { + let inner = ByteSlice::decode_value(reader, header)?; + Ok(Self { inner }) + } +} + +impl EncodeValue for OctetStringRef<'_> { + fn value_len(&self) -> Result { + self.inner.value_len() + } + + fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { + self.inner.encode_value(writer) + } +} + +impl FixedTag for OctetStringRef<'_> { + const TAG: Tag = Tag::OctetString; +} + +impl OrdIsValueOrd for OctetStringRef<'_> {} + +impl<'a> From<&OctetStringRef<'a>> for OctetStringRef<'a> { + fn from(value: &OctetStringRef<'a>) -> OctetStringRef<'a> { + *value + } +} + +impl<'a> TryFrom> for OctetStringRef<'a> { + type Error = Error; + + fn try_from(any: AnyRef<'a>) -> Result> { + any.decode_into() + } +} + +impl<'a> From> for AnyRef<'a> { + fn from(octet_string: OctetStringRef<'a>) -> AnyRef<'a> { + AnyRef::from_tag_and_value(Tag::OctetString, octet_string.inner) + } +} + +impl<'a> From> for &'a [u8] { + fn from(octet_string: OctetStringRef<'a>) -> &'a [u8] { + octet_string.as_bytes() + } +} + +/// ASN.1 `OCTET STRING` type: owned form.. +/// +/// Octet strings represent contiguous sequences of octets, a.k.a. bytes. +/// +/// This type provides the same functionality as [`OctetStringRef`] but owns +/// the backing data. +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct OctetString { + /// Bitstring represented as a slice of bytes. + inner: Vec, +} + +#[cfg(feature = "alloc")] +impl OctetString { + /// Create a new ASN.1 `OCTET STRING`. + pub fn new(bytes: impl Into>) -> Result { + let inner = bytes.into(); + + // Ensure the bytes parse successfully as an `OctetStringRef` + OctetStringRef::new(&inner)?; + + Ok(Self { inner }) + } + + /// Borrow the inner byte slice. + pub fn as_bytes(&self) -> &[u8] { + self.inner.as_slice() + } + + /// Get the length of the inner byte slice. + pub fn len(&self) -> Length { + self.value_len().expect("invalid OCTET STRING length") + } + + /// Is the inner byte slice empty? + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } +} + +#[cfg(feature = "alloc")] +impl AsRef<[u8]> for OctetString { + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +#[cfg(feature = "alloc")] +impl<'a> DecodeValue<'a> for OctetString { + fn decode_value>(reader: &mut R, header: Header) -> Result { + Self::new(reader.read_vec(header.length)?) + } +} + +#[cfg(feature = "alloc")] +impl EncodeValue for OctetString { + fn value_len(&self) -> Result { + self.inner.len().try_into() + } + + fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { + writer.write(&self.inner) + } +} + +#[cfg(feature = "alloc")] +impl FixedTag for OctetString { + const TAG: Tag = Tag::OctetString; +} + +#[cfg(feature = "alloc")] +impl<'a> From<&'a OctetString> for OctetStringRef<'a> { + fn from(octet_string: &'a OctetString) -> OctetStringRef<'a> { + // Ensured to parse successfully in constructor + OctetStringRef::new(&octet_string.inner).expect("invalid OCTET STRING") + } +} + +#[cfg(feature = "alloc")] +impl OrdIsValueOrd for OctetString {} -- cgit v1.2.3