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/oid.rs | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 vendor/der/src/asn1/oid.rs (limited to 'vendor/der/src/asn1/oid.rs') diff --git a/vendor/der/src/asn1/oid.rs b/vendor/der/src/asn1/oid.rs new file mode 100644 index 000000000..8b287183d --- /dev/null +++ b/vendor/der/src/asn1/oid.rs @@ -0,0 +1,90 @@ +//! ASN.1 `OBJECT IDENTIFIER` + +use crate::{ + asn1::AnyRef, ord::OrdIsValueOrd, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, + Reader, Result, Tag, Tagged, Writer, +}; +use const_oid::ObjectIdentifier; + +impl<'a> DecodeValue<'a> for ObjectIdentifier { + fn decode_value>(reader: &mut R, header: Header) -> Result { + let mut buf = [0u8; ObjectIdentifier::MAX_SIZE]; + let slice = buf + .get_mut(..header.length.try_into()?) + .ok_or_else(|| Self::TAG.length_error())?; + + let actual_len = reader.read_into(slice)?.len(); + debug_assert_eq!(actual_len, header.length.try_into()?); + Ok(Self::from_bytes(slice)?) + } +} + +impl EncodeValue for ObjectIdentifier { + fn value_len(&self) -> Result { + Length::try_from(self.as_bytes().len()) + } + + fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { + writer.write(self.as_bytes()) + } +} + +impl FixedTag for ObjectIdentifier { + const TAG: Tag = Tag::ObjectIdentifier; +} + +impl OrdIsValueOrd for ObjectIdentifier {} + +impl<'a> From<&'a ObjectIdentifier> for AnyRef<'a> { + fn from(oid: &'a ObjectIdentifier) -> AnyRef<'a> { + // Note: ensuring an infallible conversion is possible relies on the + // invariant that `const_oid::MAX_LEN <= Length::max()`. + // + // The `length()` test below ensures this is the case. + let value = oid + .as_bytes() + .try_into() + .expect("OID length invariant violated"); + + AnyRef::from_tag_and_value(Tag::ObjectIdentifier, value) + } +} + +impl TryFrom> for ObjectIdentifier { + type Error = Error; + + fn try_from(any: AnyRef<'_>) -> Result { + any.tag().assert_eq(Tag::ObjectIdentifier)?; + Ok(ObjectIdentifier::from_bytes(any.value())?) + } +} + +#[cfg(test)] +mod tests { + use super::ObjectIdentifier; + use crate::{Decode, Encode, Length}; + + const EXAMPLE_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549"); + const EXAMPLE_OID_BYTES: &[u8; 8] = &[0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d]; + + #[test] + fn decode() { + let oid = ObjectIdentifier::from_der(EXAMPLE_OID_BYTES).unwrap(); + assert_eq!(EXAMPLE_OID, oid); + } + + #[test] + fn encode() { + let mut buffer = [0u8; 8]; + assert_eq!( + EXAMPLE_OID_BYTES, + EXAMPLE_OID.encode_to_slice(&mut buffer).unwrap() + ); + } + + #[test] + fn length() { + // Ensure an infallible `From` conversion to `Any` will never panic + assert!(ObjectIdentifier::MAX_SIZE <= Length::MAX.try_into().unwrap()); + } +} -- cgit v1.2.3