From 2de58539f8dfab9de4451685228fe4dde2ae7fbc Mon Sep 17 00:00:00 2001 From: wbond Date: Thu, 2 Nov 2023 19:20:13 -0400 Subject: [PATCH] Fix x509.Name.build() to properly handle all fields 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 --- asn1crypto/x509.py | 20 ++++++++++++++++---- tests/test_x509.py | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/asn1crypto/x509.py b/asn1crypto/x509.py index 8cfb2c78..a67ab1a3 100644 --- a/asn1crypto/x509.py +++ b/asn1crypto/x509.py @@ -1015,15 +1015,27 @@ def build(cls, name_dict, use_printable=False): 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 ece92520..c177fe63 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -466,6 +466,25 @@ def test_build_name_printable(self): 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']