Skip to content

x509-cert: add DirectoryString::BmpString #1794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions x509-cert/src/ext/pkix/name/dirstr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use alloc::borrow::Cow;
use alloc::string::String;
use alloc::string::ToString;
use der::{
Choice, FixedTag, Header, Reader, ValueOrd,
asn1::{Any, PrintableString, TeletexString},
asn1::{Any, BmpString, PrintableString, TeletexString},
};

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

#[asn1(type = "UTF8String")]
Utf8String(String),

#[asn1(type = "BMPString")]
BmpString(BmpString),
}

impl<'a> TryFrom<&'a Any> for DirectoryString {
Expand All @@ -73,6 +78,7 @@ impl<'a> der::DecodeValue<'a> for DirectoryString {
TeletexString::decode_value(reader, header).map(Self::TeletexString)
}
String::TAG => String::decode_value(reader, header).map(Self::Utf8String),
BmpString::TAG => BmpString::decode_value(reader, header).map(Self::BmpString),
actual => Err(der::ErrorKind::TagUnexpected {
expected: None,
actual,
Expand All @@ -81,13 +87,36 @@ impl<'a> der::DecodeValue<'a> for DirectoryString {
}
}
}
impl DirectoryString {
/// Returns `Borrowed` variant for UTF-8 compatible strings
/// and `Owned` variant otherwise.
pub fn value(&self) -> Cow<'_, str> {
match self {
Self::PrintableString(s) => Cow::Borrowed(s.as_ref()),
Self::TeletexString(s) => Cow::Borrowed(s.as_ref()),
Self::Utf8String(s) => Cow::Borrowed(s.as_ref()),
Self::BmpString(s) => Cow::Owned(s.to_string()),
}
}

impl AsRef<str> for DirectoryString {
fn as_ref(&self) -> &str {
/// Returns `&str` for `PrintableString`, `TeletexString` and `Utf8String`
///
/// Warning: Returns `""` empty string for [`DirectoryString::BmpString`] variant
#[deprecated(since = "0.3.0-pre.0", note = "use `DirectoryString::value` instead")]
#[allow(clippy::should_implement_trait)]
pub fn as_ref(&self) -> &str {
match self {
Self::PrintableString(s) => s.as_ref(),
Self::TeletexString(s) => s.as_ref(),
Self::Utf8String(s) => s.as_ref(),
// BMPString is not str-compatible
Self::BmpString(_s) => "",
}
}
}

impl From<DirectoryString> for String {
fn from(value: DirectoryString) -> Self {
value.value().into_owned()
}
}
15 changes: 15 additions & 0 deletions x509-cert/tests/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,18 @@ fn certificate_arbitrary() {
check_arbitrary(certificate);
}
}

#[cfg(feature = "pem")]
#[test]
fn decode_cert_bmpstring() {
let der_encoded_cert = include_bytes!("examples/windows_bmpstring.pem");
let result = Certificate::from_pem(der_encoded_cert);
let cert: Certificate = result.unwrap();

let common_name = cert.tbs_certificate().issuer().common_name().unwrap();

assert_eq!(
common_name.unwrap().value(),
"WDKTestCert 混沌,133906716390833193"
);
}
20 changes: 20 additions & 0 deletions x509-cert/tests/examples/windows_bmpstring.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDSDCCAjCgAwIBAgIQKPABcjfrcIpG1K6NEhSpIjANBgkqhkiG9w0BAQUFADBN
MUswSQYDVQQDHkIAVwBEAEsAVABlAHMAdABDAGUAcgB0ACBt92yMACwAMQAzADMA
OQAwADYANwAxADYAMwA5ADAAOAAzADMAMQA5ADMwHhcNMjUwNTAyMTUwMDM5WhcN
MzUwNTAyMDAwMDAwWjBNMUswSQYDVQQDHkIAVwBEAEsAVABlAHMAdABDAGUAcgB0
ACBt92yMACwAMQAzADMAOQAwADYANwAxADYAMwA5ADAAOAAzADMAMQA5ADMwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDlgz7PDdlf6UzTtcWMRpaGGCdg
KYQOBOJWg6lnTQMxALfWD2bzVrbLM8N2HlMUi1AhDmr3EX6xgFi3gdXB9DgZKwEB
C1yq9CtU3QEyb/BKdsSaBasZPwfNEak8shAacvi0ssDhd05CIPYpvAlyO1RP1+m9
g3LaHaTYnlPM1PYGr3yJ8qMprGsMepgrLf1AlHQRhWyEml5C0s/1WaflYo/NJnBy
thyxksCEM2+AeO8A6CtwkL1yL47i6WImqk68NbeDiYalGwFt1Nb1Yd8PVbE7FT36
4vdMJ7jdQxzsCDiIq+KORZGSF/nVVpDeWRy8W0YtcfQ0LRbpIdEpRJOpK2UZAgMB
AAGjJDAiMAsGA1UdDwQEAwIEMDATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG
9w0BAQUFAAOCAQEAycUVQ5SKUGsdQL5hkvJchs5I43/zEfEHRaT75lYlMn2lAMsa
qX4vDBanWs0no9+0/7j0hPRBamNZGFThE6MswXcYdJrxhfp0ZjHntK0IMWO8riVO
Y6O/4xHF8rUPQkOBFIcRBF19Ads2Qdfgtjzc+288YRCLiZ4TmWjYlg9TVst7x/Fo
Hl1xH2Nbvm8AYPX9iPoqEzbq9aPy2MWi9Pf+R0lfqAjsdvj85A4dZKD2ovjOYzPX
PBSJQizmCHjovucot2iB5MumoSGloHbIFZl2fe/2jqDjPwX4wDoYO94kenlhxedo
lX4Tf6VRXWA0hVpJiE7NQMaVtO6rO/5P0pE1Pg==
-----END CERTIFICATE-----
16 changes: 5 additions & 11 deletions x509-cert/tests/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ fn access_attributes() {
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();

assert_eq!(
<_ as AsRef<str>>::as_ref(&name.common_name().unwrap().unwrap()),
name.common_name().unwrap().unwrap().value(),
"OQFAvDNDWs.google.com"
);

Expand All @@ -391,22 +391,16 @@ fn access_attributes() {
);

assert_eq!(
<_ as AsRef<str>>::as_ref(&name.state_or_province().unwrap().unwrap()),
name.state_or_province().unwrap().unwrap().value(),
"California"
);

assert_eq!(
<_ as AsRef<str>>::as_ref(&name.locality().unwrap().unwrap()),
"Mountain View"
);
assert_eq!(name.locality().unwrap().unwrap().value(), "Mountain View");

assert_eq!(
<_ as AsRef<str>>::as_ref(&name.organization().unwrap().unwrap()),
"Google LLC"
);
assert_eq!(name.organization().unwrap().unwrap().value(), "Google LLC");

assert_eq!(
<_ as AsRef<str>>::as_ref(&name.organization_unit().unwrap().unwrap()),
name.organization_unit().unwrap().unwrap().value(),
"management:ds.group.3891111"
);

Expand Down