From 848a2eb63a9c7b9e9e0ac09ac208dc3af7869ca7 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 27 Jun 2023 19:40:37 -0700 Subject: [PATCH] x509-cert: use the shortest name when looking attr OID Before this commit, the string serialization will format some attributes with the longer name when the same OID was provided by two RFC. For example this would use `STATEORPROVINCENAME` instead of `ST` for oid 2.5.4.8 --- x509-cert/Cargo.toml | 2 +- x509-cert/src/attr.rs | 27 +++++++++++++++++++++++++-- x509-cert/tests/name.rs | 2 +- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 01bdc0d31..8a78260cf 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.65" [dependencies] -const-oid = { version = "0.9.2", features = ["db"] } # TODO: path = "../const-oid" +const-oid = { version = "0.9.3", features = ["db"] } der = { version = "0.7.6", features = ["alloc", "derive", "flagset", "oid"] } spki = { version = "0.7.2", features = ["alloc"] } diff --git a/x509-cert/src/attr.rs b/x509-cert/src/attr.rs index 732792fa8..d4cccc30e 100644 --- a/x509-cert/src/attr.rs +++ b/x509-cert/src/attr.rs @@ -3,7 +3,7 @@ use alloc::vec::Vec; use const_oid::db::{ rfc4519::{COUNTRY_NAME, DOMAIN_COMPONENT, SERIAL_NUMBER}, - DB, + Database, DB, }; use core::{ fmt::{self, Write}, @@ -260,7 +260,7 @@ impl fmt::Display for AttributeTypeAndValue { _ => None, }; - if let (Some(key), Some(val)) = (DB.by_oid(&self.oid), val) { + if let (Some(key), Some(val)) = (DB.shortest_name_by_oid(&self.oid), val) { write!(f, "{}=", key.to_ascii_uppercase())?; let mut iter = val.char_indices().peekable(); @@ -285,3 +285,26 @@ impl fmt::Display for AttributeTypeAndValue { Ok(()) } } + +/// Helper trait to bring shortest name by oid lookups to Database +trait ShortestName { + fn shortest_name_by_oid(&self, oid: &ObjectIdentifier) -> Option<&str>; +} + +impl<'a> ShortestName for Database<'a> { + fn shortest_name_by_oid(&self, oid: &ObjectIdentifier) -> Option<&'a str> { + let mut best_match: Option<&'a str> = None; + + for m in self.find_names_for_oid(*oid) { + if let Some(previous) = best_match { + if m.len() < previous.len() { + best_match = Some(m); + } + } else { + best_match = Some(m); + } + } + + best_match + } +} diff --git a/x509-cert/tests/name.rs b/x509-cert/tests/name.rs index ea8757500..27af2b563 100644 --- a/x509-cert/tests/name.rs +++ b/x509-cert/tests/name.rs @@ -85,7 +85,7 @@ fn decode_name() { let rdn1 = Name::from_der(&hex!("3081c0310b30090603550406130255533113301106035504080c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e205669657731133011060355040a0c0a476f6f676c65204c4c43311e301c06035504030c154f51464176444e4457732e676f6f676c652e636f6d31243022060355040b0c1b6d616e6167656d656e743a64732e67726f75702e3338393131313131293027060a0992268993f22c6401010c196964656e746974793a64732e67726f75702e33383931313131")[..]); let rdn1a = rdn1.unwrap(); let name = rdn1a.to_string(); - assert_eq!(name, "UID=identity:ds.group.3891111,OU=management:ds.group.3891111,CN=OQFAvDNDWs.google.com,O=Google LLC,L=Mountain View,STATEORPROVINCENAME=California,C=US"); + assert_eq!(name, "UID=identity:ds.group.3891111,OU=management:ds.group.3891111,CN=OQFAvDNDWs.google.com,O=Google LLC,L=Mountain View,ST=California,C=US"); } }