diff options
Diffstat (limited to 'src/name.rs')
-rw-r--r-- | src/name.rs | 110 |
1 files changed, 68 insertions, 42 deletions
diff --git a/src/name.rs b/src/name.rs index 81ee4aa..ec62249 100644 --- a/src/name.rs +++ b/src/name.rs @@ -2,8 +2,8 @@ use crate::attr::AttributeTypeAndValue; use alloc::vec::Vec; -use core::fmt; -use der::{asn1::SetOfVec, Decode, Encode}; +use core::{fmt, str::FromStr}; +use der::{asn1::SetOfVec, Encode}; /// X.501 Name as defined in [RFC 5280 Section 4.1.2.4]. X.501 Name is used to represent distinguished names. /// @@ -12,7 +12,7 @@ use der::{asn1::SetOfVec, Decode, Encode}; /// ``` /// /// [RFC 5280 Section 4.1.2.4]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.4 -pub type Name<'a> = RdnSequence<'a>; +pub type Name = RdnSequence; /// X.501 RDNSequence as defined in [RFC 5280 Section 4.1.2.4]. /// @@ -21,35 +21,47 @@ pub type Name<'a> = RdnSequence<'a>; /// ``` /// /// [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 RdnSequence<'a>(pub Vec<RelativeDistinguishedName<'a>>); - -impl RdnSequence<'_> { - /// Converts an RDNSequence string into an encoded RDNSequence - /// - /// This function follows the rules in [RFC 4514]. - /// - /// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 +pub struct RdnSequence(pub Vec<RelativeDistinguishedName>); + +impl RdnSequence { + /// Converts an `RDNSequence` string into an encoded `RDNSequence`. + #[deprecated(since = "0.2.1", note = "use RdnSequence::from_str(...)?.to_der()")] pub fn encode_from_string(s: &str) -> Result<Vec<u8>, der::Error> { - let ders = split(s, b',') - .map(RelativeDistinguishedName::encode_from_string) - .collect::<Result<Vec<_>, der::Error>>()?; + Self::from_str(s)?.to_der() + } - let mut out = Vec::new(); - for der in ders.iter() { - out.push(RelativeDistinguishedName::from_der(der)?); - } + /// Is this [`RdnSequence`] empty? + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} - RdnSequence(out).to_vec() +/// Parse an [`RdnSequence`] string. +/// +/// Follows the rules in [RFC 4514]. +/// +/// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 +impl FromStr for RdnSequence { + type Err = der::Error; + + fn from_str(s: &str) -> der::Result<Self> { + let mut parts = split(s, b',') + .map(RelativeDistinguishedName::from_str) + .collect::<der::Result<Vec<_>>>()?; + parts.reverse(); + Ok(Self(parts)) } } /// Serializes the structure according to the rules in [RFC 4514]. /// /// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 -impl fmt::Display for RdnSequence<'_> { +impl fmt::Display for RdnSequence { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for (i, atv) in self.0.iter().enumerate() { + // As per RFC 4514 Section 2.1, the elements are reversed + for (i, atv) in self.0.iter().rev().enumerate() { match i { 0 => write!(f, "{}", atv)?, _ => write!(f, ",{}", atv)?, @@ -60,7 +72,7 @@ impl fmt::Display for RdnSequence<'_> { } } -impl_newtype!(RdnSequence<'a>, Vec<RelativeDistinguishedName<'a>>); +impl_newtype!(RdnSequence, Vec<RelativeDistinguishedName>); /// Find the indices of all non-escaped separators. fn find(s: &str, b: u8) -> impl '_ + Iterator<Item = usize> { @@ -98,7 +110,7 @@ fn split(s: &str, b: u8) -> impl '_ + Iterator<Item = &'_ str> { /// ``` /// /// [RFC 5280 Section 4.1.2.4]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.4 -pub type DistinguishedName<'a> = RdnSequence<'a>; +pub type DistinguishedName = RdnSequence; /// RelativeDistinguishedName as defined in [RFC 5280 Section 4.1.2.4]. /// @@ -124,33 +136,50 @@ pub type DistinguishedName<'a> = RdnSequence<'a>; /// ``` /// /// [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 RelativeDistinguishedName<'a>(pub SetOfVec<AttributeTypeAndValue<'a>>); +pub struct RelativeDistinguishedName(pub SetOfVec<AttributeTypeAndValue>); -impl RelativeDistinguishedName<'_> { +impl RelativeDistinguishedName { /// Converts an RelativeDistinguishedName string into an encoded RelativeDistinguishedName - /// - /// This function follows the rules in [RFC 4514]. - /// - /// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 + #[deprecated( + since = "0.2.1", + note = "use RelativeDistinguishedName::from_str(...)?.to_der()" + )] pub fn encode_from_string(s: &str) -> Result<Vec<u8>, der::Error> { - let ders = split(s, b'+') - .map(AttributeTypeAndValue::encode_from_string) - .collect::<Result<Vec<_>, der::Error>>()?; + Self::from_str(s)?.to_der() + } +} + +/// Parse a [`RelativeDistinguishedName`] string. +/// +/// This function follows the rules in [RFC 4514]. +/// +/// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 +impl FromStr for RelativeDistinguishedName { + type Err = der::Error; + + fn from_str(s: &str) -> der::Result<Self> { + split(s, b'+') + .map(AttributeTypeAndValue::from_str) + .collect::<der::Result<Vec<_>>>()? + .try_into() + .map(Self) + } +} - let atvs = ders - .iter() - .map(|der| AttributeTypeAndValue::from_der(der)) - .collect::<Result<Vec<_>, der::Error>>()?; +impl TryFrom<Vec<AttributeTypeAndValue>> for RelativeDistinguishedName { + type Error = der::Error; - RelativeDistinguishedName(atvs.try_into()?).to_vec() + fn try_from(vec: Vec<AttributeTypeAndValue>) -> der::Result<RelativeDistinguishedName> { + Ok(RelativeDistinguishedName(SetOfVec::try_from(vec)?)) } } /// Serializes the structure according to the rules in [RFC 4514]. /// /// [RFC 4514]: https://datatracker.ietf.org/doc/html/rfc4514 -impl fmt::Display for RelativeDistinguishedName<'_> { +impl fmt::Display for RelativeDistinguishedName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for (i, atv) in self.0.iter().enumerate() { match i { @@ -163,7 +192,4 @@ impl fmt::Display for RelativeDistinguishedName<'_> { } } -impl_newtype!( - RelativeDistinguishedName<'a>, - SetOfVec<AttributeTypeAndValue<'a>> -); +impl_newtype!(RelativeDistinguishedName, SetOfVec<AttributeTypeAndValue>); |