Fix x509.Name.build() to properly handle all fields (#270)
Previously it did not properly handle the following fields:
- unique_identifier
- tpm_manufacturer
- tpm_model
- tpm_version
- platform_manufacturer
- platform_model
- platform_version
Fixes #260
diff --git a/asn1crypto/x509.py b/asn1crypto/x509.py
index 8cfb2c7..a67ab1a 100644
--- a/asn1crypto/x509.py
+++ b/asn1crypto/x509.py
@@ -1015,15 +1015,27 @@
for attribute_name, attribute_value in name_dict.items():
attribute_name = NameType.map(attribute_name)
- if attribute_name == 'email_address':
- value = EmailAddress(attribute_value)
- elif attribute_name == 'domain_component':
- value = DNSName(attribute_value)
+ attribute_class = NameTypeAndValue._oid_specs.get(attribute_name)
+ if not attribute_class:
+ raise ValueError(unwrap(
+ '''
+ No encoding specification found for %s
+ ''',
+ attribute_name
+ ))
+
+ if isinstance(attribute_value, attribute_class):
+ value = attribute_value
+
+ elif attribute_class is not DirectoryString:
+ value = attribute_class(attribute_value)
+
elif attribute_name in set(['dn_qualifier', 'country_name', 'serial_number']):
value = DirectoryString(
name='printable_string',
value=PrintableString(attribute_value)
)
+
else:
value = DirectoryString(
name=encoding_name,
diff --git a/tests/test_x509.py b/tests/test_x509.py
index ece9252..c177fe6 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -466,6 +466,25 @@
self.assertIsInstance(printable_name.chosen[2][0]['value'].chosen, core.PrintableString)
self.assertEqual('common_name', printable_name.chosen[2][0]['type'].native)
+ def test_build_name_type_by_oid(self):
+ complex_name = x509.Name.build(
+ {
+ 'country_name': 'US',
+ 'tpm_manufacturer': 'Acme Co',
+ 'unique_identifier': b'\x04\x10\x03\x09',
+ 'email_address': 'will@codexns.io'
+ }
+ )
+ self.assertEqual("country_name", complex_name.chosen[0][0]['type'].native)
+ self.assertIsInstance(complex_name.chosen[0][0]['value'], x509.DirectoryString)
+ self.assertIsInstance(complex_name.chosen[0][0]['value'].chosen, core.PrintableString)
+ self.assertEqual("email_address", complex_name.chosen[1][0]['type'].native)
+ self.assertIsInstance(complex_name.chosen[1][0]['value'], x509.EmailAddress)
+ self.assertEqual("tpm_manufacturer", complex_name.chosen[2][0]['type'].native)
+ self.assertIsInstance(complex_name.chosen[2][0]['value'], core.UTF8String)
+ self.assertEqual("unique_identifier", complex_name.chosen[3][0]['type'].native)
+ self.assertIsInstance(complex_name.chosen[3][0]['value'], core.OctetBitString)
+
def test_v1_cert(self):
cert = self._load_cert('chromium/ndn.ca.crt')
tbs_cert = cert['tbs_certificate']