From cb27b48024fa0bff80a795117c9daa073803ec84 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Fri, 6 Sep 2024 08:18:52 -0700 Subject: [PATCH] x509-cert: remove From for Name --- x509-cert/src/builder/profile/cabf/tls.rs | 5 +- x509-cert/src/name.rs | 83 +++++++++++++++++++---- 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/x509-cert/src/builder/profile/cabf/tls.rs b/x509-cert/src/builder/profile/cabf/tls.rs index 13f885419..76800cb69 100644 --- a/x509-cert/src/builder/profile/cabf/tls.rs +++ b/x509-cert/src/builder/profile/cabf/tls.rs @@ -22,7 +22,7 @@ use crate::{ }, AsExtension, Extension, }, - name::{Name, RdnSequence, RelativeDistinguishedName}, + name::{Name, RelativeDistinguishedName}, }; use spki::SubjectPublicKeyInfoRef; @@ -160,8 +160,7 @@ impl CertificateType { .filter(|rdn| !rdn.0.is_empty()) .collect(); - let subject: RdnSequence = rdns.into(); - let subject: Name = subject.into(); + let subject: Name = Name(rdns.into()); Ok(Self::DomainValidated(DomainValidated { subject, names })) } diff --git a/x509-cert/src/name.rs b/x509-cert/src/name.rs index 9f551a1f9..ec75a3798 100644 --- a/x509-cert/src/name.rs +++ b/x509-cert/src/name.rs @@ -6,10 +6,10 @@ use const_oid::{ db::{rfc3280, rfc4519}, ObjectIdentifier, }; -use core::{fmt, str::FromStr}; +use core::{cmp::Ordering, fmt, str::FromStr}; use der::{ asn1::{Any, Ia5StringRef, PrintableStringRef, SetOfVec}, - Encode, + DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Tag, ValueOrd, Writer, }; /// X.501 Name as defined in [RFC 5280 Section 4.1.2.4]. X.501 Name is used to represent distinguished names. @@ -58,17 +58,74 @@ use der::{ /// [RFC 5280 Section 4.1.2.4]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.4 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Default, PartialEq, Eq)] -pub struct Name(RdnSequence); - -// This will implement `From` which is provided as an escape hatch to build names -// from `bmpString`, `TeletexString`, or `UniversalString`: -// ``` -// When CAs have previously issued certificates with issuer fields with -// attributes encoded using TeletexString, BMPString, or -// UniversalString, then the CA MAY continue to use these encodings of -// the DirectoryString to preserve backward compatibility. -// ``` -impl_newtype!(Name, RdnSequence); +pub struct Name(pub(crate) RdnSequence); + +impl Name { + /// Build a name from an [`RdnSequence`]. + /// + /// + /// This is provided as an escape hatch (see [RFC 5280 Section 4.1.2.4]) to build + /// names from `bmpString`, `TeletexString`, or `UniversalString`: + /// ```text + /// When CAs have previously issued certificates with issuer fields with + /// attributes encoded using TeletexString, BMPString, or + /// UniversalString, then the CA MAY continue to use these encodings of + /// the DirectoryString to preserve backward compatibility. + /// ``` + /// + /// # Safety + /// + /// As the name implies, this is a dangerous helper. You are responsible for ensuring the + /// [`RdnSequence`] complies with the RFC. + /// + /// [RFC 5280 Section 4.1.2.4]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.4 + #[cfg(feature = "hazmat")] + pub fn hazmat_from_rdn_sequence(value: RdnSequence) -> Self { + Self(value) + } +} + +impl From for RdnSequence { + #[inline] + fn from(value: Name) -> Self { + value.0 + } +} + +impl AsRef for Name { + #[inline] + fn as_ref(&self) -> &RdnSequence { + &self.0 + } +} + +impl FixedTag for Name { + const TAG: Tag = ::TAG; +} + +impl<'a> DecodeValue<'a> for Name { + type Error = der::Error; + + fn decode_value>(decoder: &mut R, header: Header) -> der::Result { + Ok(Self(RdnSequence::decode_value(decoder, header)?)) + } +} + +impl EncodeValue for Name { + fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> { + self.0.encode_value(encoder) + } + + fn value_len(&self) -> der::Result { + self.0.value_len() + } +} + +impl ValueOrd for Name { + fn value_cmp(&self, other: &Self) -> der::Result { + self.0.value_cmp(&other.0) + } +} impl Name { /// Is this [`Name`] empty?