Skip to content

Commit 6ed9934

Browse files
authored
x509-cert: make Name a new type over RdnSequence (#1499)
This make `FromStr` documented way to build a name. This also exposes a set of getter methods to get elements from the name (CN, Org, ...).
1 parent 94b00b7 commit 6ed9934

File tree

10 files changed

+713
-426
lines changed

10 files changed

+713
-426
lines changed

cms/tests/builder.rs

+6-19
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use cms::enveloped_data::RecipientInfo::Ktri;
1313
use cms::enveloped_data::{EnvelopedData, RecipientIdentifier, RecipientInfo};
1414
use cms::signed_data::{EncapsulatedContentInfo, SignedData, SignerIdentifier};
1515
use const_oid::ObjectIdentifier;
16-
use der::asn1::{OctetString, PrintableString, SetOfVec, Utf8StringRef};
16+
use der::asn1::{OctetString, PrintableString, SetOfVec};
1717
use der::{Any, AnyRef, Decode, DecodePem, Encode, Tag, Tagged};
1818
use p256::{pkcs8::DecodePrivateKey, NistP256};
1919
use pem_rfc7468::LineEnding;
@@ -24,8 +24,7 @@ use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
2424
use sha2::Sha256;
2525
use signature::Verifier;
2626
use spki::AlgorithmIdentifierOwned;
27-
use x509_cert::attr::{Attribute, AttributeTypeAndValue, AttributeValue};
28-
use x509_cert::name::{RdnSequence, RelativeDistinguishedName};
27+
use x509_cert::attr::{Attribute, AttributeValue};
2928
use x509_cert::serial_number::SerialNumber;
3029

3130
// TODO bk replace this by const_oid definitions as soon as released
@@ -50,30 +49,18 @@ fn ecdsa_signer() -> ecdsa::SigningKey<NistP256> {
5049
}
5150

5251
fn signer_identifier(id: i32) -> SignerIdentifier {
53-
let mut rdn_sequence = RdnSequence::default();
54-
let rdn = &[AttributeTypeAndValue {
55-
oid: const_oid::db::rfc4519::CN,
56-
value: Any::from(Utf8StringRef::new(&format!("test client {id}")).unwrap()),
57-
}];
58-
let set_of_vector = SetOfVec::try_from(rdn.to_vec()).unwrap();
59-
rdn_sequence.push(RelativeDistinguishedName::from(set_of_vector));
52+
let issuer = format!("CN=test client {id}").parse().unwrap();
6053
SignerIdentifier::IssuerAndSerialNumber(IssuerAndSerialNumber {
61-
issuer: rdn_sequence,
54+
issuer,
6255
serial_number: SerialNumber::new(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06])
6356
.expect("failed to create a serial number"),
6457
})
6558
}
6659

6760
fn recipient_identifier(id: i32) -> RecipientIdentifier {
68-
let mut rdn_sequence = RdnSequence::default();
69-
let rdn = &[AttributeTypeAndValue {
70-
oid: const_oid::db::rfc4519::CN,
71-
value: Any::from(Utf8StringRef::new(&format!("test client {id}")).unwrap()),
72-
}];
73-
let set_of_vector = SetOfVec::try_from(rdn.to_vec()).unwrap();
74-
rdn_sequence.push(RelativeDistinguishedName::from(set_of_vector));
61+
let issuer = format!("CN=test client {id}").parse().unwrap();
7562
RecipientIdentifier::IssuerAndSerialNumber(IssuerAndSerialNumber {
76-
issuer: rdn_sequence,
63+
issuer,
7764
serial_number: SerialNumber::new(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06])
7865
.expect("failed to create a serial number"),
7966
})

x509-cert/src/builder/profile/cabf.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn check_names_encoding(name: &Name, multiple_allowed: bool) -> Result<()> {
4343

4444
let mut seen = HashSet::new();
4545

46-
for rdn in name.iter() {
46+
for rdn in name.iter_rdn() {
4747
if rdn.len() != 1 {
4848
return Err(Error::NonUniqueRdn);
4949
}
@@ -87,13 +87,11 @@ pub fn ca_certificate_naming(subject: &Name) -> Result<()> {
8787

8888
check_names_encoding(subject, false)?;
8989

90-
for rdn in subject.iter() {
91-
for atv in rdn.iter() {
92-
if !allowed.remove(&atv.oid) {
93-
return Err(Error::InvalidAttribute { oid: atv.oid });
94-
}
95-
required.remove(&atv.oid);
90+
for atv in subject.iter() {
91+
if !allowed.remove(&atv.oid) {
92+
return Err(Error::InvalidAttribute { oid: atv.oid });
9693
}
94+
required.remove(&atv.oid);
9795
}
9896

9997
if !required.is_empty() {

x509-cert/src/builder/profile/cabf/tls.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ impl CertificateType {
145145
// TODO(baloo): not very happy with all that, might as well throw that in a helper
146146
// or something.
147147
let rdns: vec::Vec<RelativeDistinguishedName> = subject
148-
.iter()
148+
.iter_rdn()
149149
.filter_map(|rdn| {
150150
let out = SetOfVec::<AttributeTypeAndValue>::from_iter(
151151
rdn.iter()
@@ -159,7 +159,7 @@ impl CertificateType {
159159
.filter(|rdn| !rdn.is_empty())
160160
.collect();
161161

162-
let subject: Name = rdns.into();
162+
let subject: Name = Name(rdns.into());
163163

164164
Ok(Self::DomainValidated(DomainValidated { subject, names }))
165165
}

x509-cert/src/ext/pkix/name/dirstr.rs

+42-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use alloc::string::String;
2-
use der::asn1::{PrintableString, TeletexString};
3-
use der::{Choice, ValueOrd};
2+
use der::{
3+
asn1::{Any, PrintableString, TeletexString},
4+
Choice, FixedTag, Header, Reader, ValueOrd,
5+
};
46

57
/// DirectoryString as defined in [RFC 5280 Section 4.2.1.4].
68
///
@@ -51,3 +53,41 @@ pub enum DirectoryString {
5153
#[asn1(type = "UTF8String")]
5254
Utf8String(String),
5355
}
56+
57+
impl<'a> TryFrom<&'a Any> for DirectoryString {
58+
type Error = der::Error;
59+
fn try_from(any: &'a Any) -> der::Result<Self> {
60+
any.decode_as()
61+
}
62+
}
63+
64+
impl<'a> der::DecodeValue<'a> for DirectoryString {
65+
type Error = der::Error;
66+
67+
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error> {
68+
match header.tag {
69+
PrintableString::TAG => {
70+
PrintableString::decode_value(reader, header).map(Self::PrintableString)
71+
}
72+
TeletexString::TAG => {
73+
TeletexString::decode_value(reader, header).map(Self::TeletexString)
74+
}
75+
String::TAG => String::decode_value(reader, header).map(Self::Utf8String),
76+
actual => Err(der::ErrorKind::TagUnexpected {
77+
expected: None,
78+
actual,
79+
}
80+
.into()),
81+
}
82+
}
83+
}
84+
85+
impl AsRef<str> for DirectoryString {
86+
fn as_ref(&self) -> &str {
87+
match self {
88+
Self::PrintableString(s) => s.as_ref(),
89+
Self::TeletexString(s) => s.as_ref(),
90+
Self::Utf8String(s) => s.as_ref(),
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)