Skip to content

Commit

Permalink
Remove .hash_algo for ECDSA-based signature algorithms (#265)
Browse files Browse the repository at this point in the history
Add .cms_hash_algo as a replacement. See discussion at
#230 for details.
  • Loading branch information
wbond authored Sep 27, 2023
1 parent 896166d commit 3c903c8
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 45 deletions.
127 changes: 83 additions & 44 deletions asn1crypto/algos.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,47 @@ class SignedDigestAlgorithm(_ForceNullParameters, Sequence):
'rsassa_pss': RSASSAPSSParams,
}

_algo_map = {
'md2_rsa': 'md2',
'md5_rsa': 'md5',
'sha1_rsa': 'sha1',
'sha224_rsa': 'sha224',
'sha256_rsa': 'sha256',
'sha384_rsa': 'sha384',
'sha512_rsa': 'sha512',
'sha1_dsa': 'sha1',
'sha224_dsa': 'sha224',
'sha256_dsa': 'sha256',
'sha384_dsa': 'sha384',
'sha512_dsa': 'sha512',
'sha1_ecdsa': 'sha1',
'sha1_ecdsa_plain': 'sha1',
'sha224_ecdsa': 'sha224',
'sha256_ecdsa': 'sha256',
'sha384_ecdsa': 'sha384',
'sha512_ecdsa': 'sha512',
'sha224_ecdsa_plain': 'sha224',
'sha256_ecdsa_plain': 'sha256',
'sha384_ecdsa_plain': 'sha384',
'sha512_ecdsa_plain': 'sha512',
'sha3_224_dsa': 'sha3_224',
'sha3_256_dsa': 'sha3_256',
'sha3_384_dsa': 'sha3_384',
'sha3_512_dsa': 'sha3_512',
'sha3_224_ecdsa': 'sha3_224',
'sha3_256_ecdsa': 'sha3_256',
'sha3_384_ecdsa': 'sha3_384',
'sha3_512_ecdsa': 'sha3_512',
'sha3_224_ecdsa_plain': 'sha3_224',
'sha3_256_ecdsa_plain': 'sha3_256',
'sha3_384_ecdsa_plain': 'sha3_384',
'sha3_512_ecdsa_plain': 'sha3_512',
'sha3_224_rsa': 'sha3_224',
'sha3_256_rsa': 'sha3_256',
'sha3_384_rsa': 'sha3_384',
'sha3_512_rsa': 'sha3_512',
}

@property
def signature_algo(self):
"""
Expand Down Expand Up @@ -422,55 +463,53 @@ def hash_algo(self):
"""

algorithm = self['algorithm'].native
if algorithm in self._algo_map:
return self._algo_map[algorithm]

algo_map = {
'md2_rsa': 'md2',
'md5_rsa': 'md5',
'sha1_rsa': 'sha1',
'sha224_rsa': 'sha224',
'sha256_rsa': 'sha256',
'sha384_rsa': 'sha384',
'sha512_rsa': 'sha512',
'sha1_dsa': 'sha1',
'sha224_dsa': 'sha224',
'sha256_dsa': 'sha256',
'sha384_dsa': 'sha384',
'sha512_dsa': 'sha512',
'sha1_ecdsa': 'sha1',
'sha1_ecdsa_plain': 'sha1',
'sha224_ecdsa': 'sha224',
'sha256_ecdsa': 'sha256',
'sha384_ecdsa': 'sha384',
'sha512_ecdsa': 'sha512',
'sha224_ecdsa_plain': 'sha224',
'sha256_ecdsa_plain': 'sha256',
'sha384_ecdsa_plain': 'sha384',
'sha512_ecdsa_plain': 'sha512',
'sha3_224_dsa': 'sha3_224',
'sha3_256_dsa': 'sha3_256',
'sha3_384_dsa': 'sha3_384',
'sha3_512_dsa': 'sha3_512',
'sha3_224_ecdsa': 'sha3_224',
'sha3_256_ecdsa': 'sha3_256',
'sha3_384_ecdsa': 'sha3_384',
'sha3_512_ecdsa': 'sha3_512',
'sha3_224_ecdsa_plain': 'sha3_224',
'sha3_256_ecdsa_plain': 'sha3_256',
'sha3_384_ecdsa_plain': 'sha3_384',
'sha3_512_ecdsa_plain': 'sha3_512',
'sha3_224_rsa': 'sha3_224',
'sha3_256_rsa': 'sha3_256',
'sha3_384_rsa': 'sha3_384',
'sha3_512_rsa': 'sha3_512',
'ed25519': 'sha512',
'ed448': 'shake256',
}
if algorithm in algo_map:
return algo_map[algorithm]
if algorithm == 'rsassa_pss':
return self['parameters']['hash_algorithm']['algorithm'].native

if algorithm == 'ed25519' or algorithm == 'ed448':
raise ValueError(unwrap(
'''
Hash algorithm not known for %s - use .cms_hash_algorithm for CMS purposes.
More info at https://github.com/wbond/asn1crypto/pull/230.
''',
algorithm
))

raise ValueError(unwrap(
'''
Hash algorithm not known for %s
''',
algorithm
))

@property
def cms_hash_algo(self):
"""
The hash algorithm for CMS hashing
:return:
A unicode string of "md2", "md5", "sha1", "sha224", "sha256",
"sha384", "sha512", "sha512_224", "sha512_256" or "shake256"
"""

algorithm = self['algorithm'].native

if algorithm in self._algo_map:
return self._algo_map[algorithm]

if algorithm == 'rsassa_pss':
return self['parameters']['hash_algorithm']['algorithm'].native

cms_algo_map = {
'ed25519': 'sha512',
'ed448': 'shake256',
}
if algorithm in cms_algo_map:
return cms_algo_map[algorithm]

raise ValueError(unwrap(
'''
Hash algorithm not known for %s
Expand Down
49 changes: 48 additions & 1 deletion tests/test_x509.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,13 +549,60 @@ def signature_algo_info():
'rsassa_pss',
'sha256'
),
(
'keys/test-ed448.crt',
'ed448',
ValueError
),
)

@data('signature_algo_info')
def signature_algo(self, relative_path, signature_algo, hash_algo):
cert = self._load_cert(relative_path)
self.assertEqual(signature_algo, cert['signature_algorithm'].signature_algo)
self.assertEqual(hash_algo, cert['signature_algorithm'].hash_algo)
if isinstance(hash_algo, type) and issubclass(hash_algo, Exception):
with self.assertRaises(hash_algo):
self.assertEqual(hash_algo, cert['signature_algorithm'].hash_algo)
else:
self.assertEqual(hash_algo, cert['signature_algorithm'].hash_algo)

@staticmethod
def cms_hash_algo_info():
return (
(
'keys/test-der.crt',
'sha256'
),
(
'keys/test-inter-der.crt',
'sha256'
),
(
'keys/test-dsa-der.crt',
'sha256'
),
(
'keys/test-third-der.crt',
'sha256'
),
(
'keys/test-ec-der.crt',
'sha256'
),
(
'keys/test-rsapss.crt',
'sha256'
),
(
'keys/test-ed448.crt',
'shake256'
),
)

@data('cms_hash_algo_info')
def cms_hash_algo(self, relative_path, hash_algo):
cert = self._load_cert(relative_path)
self.assertEqual(hash_algo, cert['signature_algorithm'].cms_hash_algo)

@staticmethod
def critical_extensions_info():
Expand Down

0 comments on commit 3c903c8

Please sign in to comment.