Handle DSA certificates without parameters in keys.PublicKeyInfo.hash_algo
diff --git a/asn1crypto/keys.py b/asn1crypto/keys.py
index 81ab0aa..2f79fad 100644
--- a/asn1crypto/keys.py
+++ b/asn1crypto/keys.py
@@ -1052,7 +1052,8 @@
ValueError - when the key is not a DSA key
:return:
- A unicode string of "sha1" or "sha2"
+ A unicode string of "sha1" or "sha2" or None if no parameters are
+ present
"""
if self.algorithm != 'dsa':
@@ -1064,7 +1065,11 @@
self.algorithm.upper()
))
- byte_len = math.log(self['algorithm']['parameters']['q'].native, 2) / 8
+ parameters = self['algorithm']['parameters']
+ if parameters.native is None:
+ return None
+
+ byte_len = math.log(parameters['q'].native, 2) / 8
return 'sha1' if byte_len <= 20 else 'sha2'
diff --git a/tests/fixtures/DSAParametersInheritedCACert.crt b/tests/fixtures/DSAParametersInheritedCACert.crt
new file mode 100644
index 0000000..5e2fa5b
--- /dev/null
+++ b/tests/fixtures/DSAParametersInheritedCACert.crt
Binary files differ
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 4a5586b..d3539b4 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -2813,6 +2813,74 @@
extensions.native
)
+ def test_parse_dsa_certificate_inheritance(self):
+ cert = self._load_cert('DSAParametersInheritedCACert.crt')
+
+ tbs_certificate = cert['tbs_certificate']
+ signature = tbs_certificate['signature']
+ issuer = tbs_certificate['issuer']
+ validity = tbs_certificate['validity']
+ subject = tbs_certificate['subject']
+ subject_public_key_info = tbs_certificate['subject_public_key_info']
+ subject_public_key_algorithm = subject_public_key_info['algorithm']
+
+ self.assertEqual(
+ 'v3',
+ tbs_certificate['version'].native
+ )
+ self.assertEqual(
+ 2,
+ tbs_certificate['serial_number'].native
+ )
+ self.assertEqual(
+ 'sha1_dsa',
+ signature['algorithm'].native
+ )
+ self.assertEqual(
+ None,
+ signature['parameters'].native
+ )
+ self.assertEqual(
+ util.OrderedDict([
+ ('country_name', 'US'),
+ ('organization_name', 'Test Certificates 2011'),
+ ('common_name', 'DSA CA'),
+ ]),
+ issuer.native
+ )
+ self.assertEqual(
+ datetime(2010, 1, 1, 8, 30, tzinfo=util.timezone.utc),
+ validity['not_before'].native
+ )
+ self.assertEqual(
+ datetime(2030, 12, 31, 8, 30, tzinfo=util.timezone.utc),
+ validity['not_after'].native
+ )
+ self.assertEqual(
+ util.OrderedDict([
+ ('country_name', 'US'),
+ ('organization_name', 'Test Certificates 2011'),
+ ('common_name', 'DSA Parameters Inherited CA'),
+ ]),
+ subject.native
+ )
+ self.assertEqual(
+ 'dsa',
+ subject_public_key_algorithm['algorithm'].native
+ )
+ self.assertEqual(
+ None,
+ subject_public_key_algorithm['parameters'].native
+ )
+ self.assertEqual(
+ 'dsa',
+ subject_public_key_info.algorithm
+ )
+ self.assertEqual(
+ None,
+ subject_public_key_info.hash_algo
+ )
+
def test_parse_ec_certificate(self):
cert = self._load_cert('keys/test-ec-der.crt')