Skip to content

Commit 2bb97f6

Browse files
authored
x509-cert: add DirectoryString::BmpString (#1794)
* x509-cert: add `DirectoryString::BmpString` x509-cert: use alloc instead of std x509-cert: apply clippy Cow<'_, str> x509-cert: fix test decode_cert_bmpstring * x509-cert: remove `DirectoryString::as_ref` * x509-cert: add deprecated `as_ref` and `From<DirectoryString> for String`
1 parent 14a53d7 commit 2bb97f6

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use alloc::borrow::Cow;
12
use alloc::string::String;
3+
use alloc::string::ToString;
24
use der::{
35
Choice, FixedTag, Header, Reader, ValueOrd,
4-
asn1::{Any, PrintableString, TeletexString},
6+
asn1::{Any, BmpString, PrintableString, TeletexString},
57
};
68

79
/// DirectoryString as defined in [RFC 5280 Section 4.2.1.4].
@@ -52,6 +54,9 @@ pub enum DirectoryString {
5254

5355
#[asn1(type = "UTF8String")]
5456
Utf8String(String),
57+
58+
#[asn1(type = "BMPString")]
59+
BmpString(BmpString),
5560
}
5661

5762
impl<'a> TryFrom<&'a Any> for DirectoryString {
@@ -73,6 +78,7 @@ impl<'a> der::DecodeValue<'a> for DirectoryString {
7378
TeletexString::decode_value(reader, header).map(Self::TeletexString)
7479
}
7580
String::TAG => String::decode_value(reader, header).map(Self::Utf8String),
81+
BmpString::TAG => BmpString::decode_value(reader, header).map(Self::BmpString),
7682
actual => Err(der::ErrorKind::TagUnexpected {
7783
expected: None,
7884
actual,
@@ -81,13 +87,36 @@ impl<'a> der::DecodeValue<'a> for DirectoryString {
8187
}
8288
}
8389
}
90+
impl DirectoryString {
91+
/// Returns `Borrowed` variant for UTF-8 compatible strings
92+
/// and `Owned` variant otherwise.
93+
pub fn value(&self) -> Cow<'_, str> {
94+
match self {
95+
Self::PrintableString(s) => Cow::Borrowed(s.as_ref()),
96+
Self::TeletexString(s) => Cow::Borrowed(s.as_ref()),
97+
Self::Utf8String(s) => Cow::Borrowed(s.as_ref()),
98+
Self::BmpString(s) => Cow::Owned(s.to_string()),
99+
}
100+
}
84101

85-
impl AsRef<str> for DirectoryString {
86-
fn as_ref(&self) -> &str {
102+
/// Returns `&str` for `PrintableString`, `TeletexString` and `Utf8String`
103+
///
104+
/// Warning: Returns `""` empty string for [`DirectoryString::BmpString`] variant
105+
#[deprecated(since = "0.3.0-pre.0", note = "use `DirectoryString::value` instead")]
106+
#[allow(clippy::should_implement_trait)]
107+
pub fn as_ref(&self) -> &str {
87108
match self {
88109
Self::PrintableString(s) => s.as_ref(),
89110
Self::TeletexString(s) => s.as_ref(),
90111
Self::Utf8String(s) => s.as_ref(),
112+
// BMPString is not str-compatible
113+
Self::BmpString(_s) => "",
91114
}
92115
}
93116
}
117+
118+
impl From<DirectoryString> for String {
119+
fn from(value: DirectoryString) -> Self {
120+
value.value().into_owned()
121+
}
122+
}

x509-cert/tests/certificate.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,3 +468,18 @@ fn certificate_arbitrary() {
468468
check_arbitrary(certificate);
469469
}
470470
}
471+
472+
#[cfg(feature = "pem")]
473+
#[test]
474+
fn decode_cert_bmpstring() {
475+
let der_encoded_cert = include_bytes!("examples/windows_bmpstring.pem");
476+
let result = Certificate::from_pem(der_encoded_cert);
477+
let cert: Certificate = result.unwrap();
478+
479+
let common_name = cert.tbs_certificate().issuer().common_name().unwrap();
480+
481+
assert_eq!(
482+
common_name.unwrap().value(),
483+
"WDKTestCert 混沌,133906716390833193"
484+
);
485+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDSDCCAjCgAwIBAgIQKPABcjfrcIpG1K6NEhSpIjANBgkqhkiG9w0BAQUFADBN
3+
MUswSQYDVQQDHkIAVwBEAEsAVABlAHMAdABDAGUAcgB0ACBt92yMACwAMQAzADMA
4+
OQAwADYANwAxADYAMwA5ADAAOAAzADMAMQA5ADMwHhcNMjUwNTAyMTUwMDM5WhcN
5+
MzUwNTAyMDAwMDAwWjBNMUswSQYDVQQDHkIAVwBEAEsAVABlAHMAdABDAGUAcgB0
6+
ACBt92yMACwAMQAzADMAOQAwADYANwAxADYAMwA5ADAAOAAzADMAMQA5ADMwggEi
7+
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDlgz7PDdlf6UzTtcWMRpaGGCdg
8+
KYQOBOJWg6lnTQMxALfWD2bzVrbLM8N2HlMUi1AhDmr3EX6xgFi3gdXB9DgZKwEB
9+
C1yq9CtU3QEyb/BKdsSaBasZPwfNEak8shAacvi0ssDhd05CIPYpvAlyO1RP1+m9
10+
g3LaHaTYnlPM1PYGr3yJ8qMprGsMepgrLf1AlHQRhWyEml5C0s/1WaflYo/NJnBy
11+
thyxksCEM2+AeO8A6CtwkL1yL47i6WImqk68NbeDiYalGwFt1Nb1Yd8PVbE7FT36
12+
4vdMJ7jdQxzsCDiIq+KORZGSF/nVVpDeWRy8W0YtcfQ0LRbpIdEpRJOpK2UZAgMB
13+
AAGjJDAiMAsGA1UdDwQEAwIEMDATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG
14+
9w0BAQUFAAOCAQEAycUVQ5SKUGsdQL5hkvJchs5I43/zEfEHRaT75lYlMn2lAMsa
15+
qX4vDBanWs0no9+0/7j0hPRBamNZGFThE6MswXcYdJrxhfp0ZjHntK0IMWO8riVO
16+
Y6O/4xHF8rUPQkOBFIcRBF19Ads2Qdfgtjzc+288YRCLiZ4TmWjYlg9TVst7x/Fo
17+
Hl1xH2Nbvm8AYPX9iPoqEzbq9aPy2MWi9Pf+R0lfqAjsdvj85A4dZKD2ovjOYzPX
18+
PBSJQizmCHjovucot2iB5MumoSGloHbIFZl2fe/2jqDjPwX4wDoYO94kenlhxedo
19+
lX4Tf6VRXWA0hVpJiE7NQMaVtO6rO/5P0pE1Pg==
20+
-----END CERTIFICATE-----

x509-cert/tests/name.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ fn access_attributes() {
381381
let name = Name::from_str("[email protected],UID=identity:ds.group.3891111,OU=management:ds.group.3891111,CN=OQFAvDNDWs.google.com,O=Google LLC,L=Mountain View,ST=California,C=US").unwrap();
382382

383383
assert_eq!(
384-
<_ as AsRef<str>>::as_ref(&name.common_name().unwrap().unwrap()),
384+
name.common_name().unwrap().unwrap().value(),
385385
"OQFAvDNDWs.google.com"
386386
);
387387

@@ -391,22 +391,16 @@ fn access_attributes() {
391391
);
392392

393393
assert_eq!(
394-
<_ as AsRef<str>>::as_ref(&name.state_or_province().unwrap().unwrap()),
394+
name.state_or_province().unwrap().unwrap().value(),
395395
"California"
396396
);
397397

398-
assert_eq!(
399-
<_ as AsRef<str>>::as_ref(&name.locality().unwrap().unwrap()),
400-
"Mountain View"
401-
);
398+
assert_eq!(name.locality().unwrap().unwrap().value(), "Mountain View");
402399

403-
assert_eq!(
404-
<_ as AsRef<str>>::as_ref(&name.organization().unwrap().unwrap()),
405-
"Google LLC"
406-
);
400+
assert_eq!(name.organization().unwrap().unwrap().value(), "Google LLC");
407401

408402
assert_eq!(
409-
<_ as AsRef<str>>::as_ref(&name.organization_unit().unwrap().unwrap()),
403+
name.organization_unit().unwrap().unwrap().value(),
410404
"management:ds.group.3891111"
411405
);
412406

0 commit comments

Comments
 (0)