From 66d1ae1cde1225b62d821f91482a34581285fcc4 Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Fri, 3 Oct 2025 16:12:00 +0200 Subject: [PATCH] der: wip: Cow<'a, OctetStringRef> traits --- der/src/referenced.rs | 96 +++++++++++++++++++++++++++++++++++++++++++ x509-cert/src/ext.rs | 14 +++++-- 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/der/src/referenced.rs b/der/src/referenced.rs index 22060b93b..124d93648 100644 --- a/der/src/referenced.rs +++ b/der/src/referenced.rs @@ -61,6 +61,12 @@ where #[cfg(feature = "alloc")] mod allocating { + use std::borrow::Cow; + + use crate::{ + DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Tag, Tagged, Writer, + }; + use super::{OwnedToRef, RefToOwned}; use alloc::boxed::Box; @@ -79,4 +85,94 @@ mod allocating { self.as_ref() } } + + impl<'a, T> FixedTag for Cow<'a, T> + where + T: Clone, + &'a T: FixedTag, + { + const TAG: Tag = <&'a T as FixedTag>::TAG; + } + + // impl<'a, T> Tagged for Cow<'a, T> + // where + // T: Clone, + // &'a T: Tagged, + // { + // fn tag(&self) -> Tag { + // match self { + // Cow::Borrowed(object) => object.tag(), + // Cow::Owned(object) => object.tag(), + // } + // } + // } + + // impl<'a, T> Decode<'a> for Cow<'a, T> + // where + // T: Clone, + // &'a T: Decode<'a>, + // { + // type Error = <&'a T as Decode<'a>>::Error; + + // fn decode>(reader: &mut R) -> Result { + // let object = <&'a T as Decode<'a>>::decode(reader)?; + // Ok(Self::Borrowed(object)) + // } + // } + + impl<'a, T> DecodeValue<'a> for Cow<'a, T> + where + T: Clone, + &'a T: DecodeValue<'a>, + { + type Error = <&'a T as DecodeValue<'a>>::Error; + + fn decode_value>( + reader: &mut R, + header: Header, + ) -> Result { + let value = <&'a T as DecodeValue<'a>>::decode_value(reader, header)?; + Ok(Self::Borrowed(value)) + } + } + + impl<'a, T> Encode for &'a Cow<'a, T> + where + T: Clone, + &'a T: Encode, + { + fn encoded_len(&self) -> crate::Result { + match self { + Cow::Borrowed(object) => object.encoded_len(), + Cow::Owned(object) => object.encoded_len(), + } + } + + fn encode(&self, encoder: &mut impl Writer) -> crate::Result<()> { + match self { + Cow::Borrowed(object) => object.encode(encoder), + Cow::Owned(object) => object.encode(encoder), + } + } + } + + impl<'a, T> EncodeValue for &'a Cow<'a, T> + where + T: Clone, + &'a T: EncodeValue, + { + fn value_len(&self) -> crate::Result { + match self { + Cow::Borrowed(value) => value.value_len(), + Cow::Owned(value) => value.value_len(), + } + } + + fn encode_value(&self, encoder: &mut impl Writer) -> crate::Result<()> { + match self { + Cow::Borrowed(value) => value.encode_value(encoder), + Cow::Owned(value) => value.encode_value(encoder), + } + } + } } diff --git a/x509-cert/src/ext.rs b/x509-cert/src/ext.rs index 71232fabc..b26184ec3 100644 --- a/x509-cert/src/ext.rs +++ b/x509-cert/src/ext.rs @@ -1,7 +1,12 @@ //! Standardized X.509 Certificate Extensions +use std::borrow::Cow; + use const_oid::AssociatedOid; -use der::{Sequence, ValueOrd, asn1::OctetString}; +use der::{ + Sequence, ValueOrd, + asn1::{OctetString, OctetStringRef}, +}; use spki::ObjectIdentifier; pub mod pkix; @@ -26,13 +31,14 @@ pub mod pkix; #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] #[allow(missing_docs)] -pub struct Extension { +pub struct Extension<'a> { pub extn_id: ObjectIdentifier, #[asn1(default = "Default::default")] pub critical: bool, - pub extn_value: OctetString, + // maybe #[asn1(type = "OCTET STRING", deref = "true")] + pub extn_value: Cow<'a, OctetStringRef>, } /// Extensions as defined in [RFC 5280 Section 4.1.2.9]. @@ -42,7 +48,7 @@ pub struct Extension { /// ``` /// /// [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9 -pub type Extensions = alloc::vec::Vec; +pub type Extensions = alloc::vec::Vec>; /// Trait to be implemented by extensions to allow them to be formatted as x509 v3 extensions by /// builder.