diff --git a/certomancer/_asn1crypto_patches.py b/certomancer/_asn1crypto_patches.py deleted file mode 100644 index d6b7d7b..0000000 --- a/certomancer/_asn1crypto_patches.py +++ /dev/null @@ -1,226 +0,0 @@ -# Shim module that makes asn1crypto aware of OIDs relevant for EdDSA support -# Will be removed once asn1crypto supports these OIDs natively - -from asn1crypto import algos, core, keys, cms, x509 -from asn1crypto._errors import unwrap - - -PRIVATE_KEY_SPECS = { - 'rsa': keys.RSAPrivateKey, - 'rsassa_pss': keys.RSAPrivateKey, - 'dsa': core.Integer, - 'ec': keys.ECPrivateKey, - 'ed25519': core.OctetString, - 'ed448': core.OctetString, -} - - -def _private_key_spec(self): - algorithm = self['private_key_algorithm']['algorithm'].native - return PRIVATE_KEY_SPECS[algorithm] - - -PUBLIC_KEY_SPECS = { - 'rsa': keys.RSAPublicKey, - 'rsaes_oaep': keys.RSAPublicKey, - 'rsassa_pss': keys.RSAPublicKey, - 'dsa': core.Integer, - # We override the field spec with ECPoint so that users can easily - # decompose the byte string into the constituent X and Y coords - 'ec': (keys.ECPointBitString, None), - 'ed25519': (core.OctetBitString, None), - 'ed448': (core.OctetBitString, None), - 'dh': core.Integer, -} - - -def _public_key_spec(self): - algorithm = self['algorithm']['algorithm'].native - return PUBLIC_KEY_SPECS[algorithm] - - -SIG_ALGO_MAP = { - 'md2_rsa': 'rsassa_pkcs1v15', - 'md5_rsa': 'rsassa_pkcs1v15', - 'sha1_rsa': 'rsassa_pkcs1v15', - 'sha224_rsa': 'rsassa_pkcs1v15', - 'sha256_rsa': 'rsassa_pkcs1v15', - 'sha384_rsa': 'rsassa_pkcs1v15', - 'sha512_rsa': 'rsassa_pkcs1v15', - 'rsassa_pkcs1v15': 'rsassa_pkcs1v15', - 'rsassa_pss': 'rsassa_pss', - 'sha1_dsa': 'dsa', - 'sha224_dsa': 'dsa', - 'sha256_dsa': 'dsa', - 'dsa': 'dsa', - 'sha1_ecdsa': 'ecdsa', - 'sha224_ecdsa': 'ecdsa', - 'sha256_ecdsa': 'ecdsa', - 'sha384_ecdsa': 'ecdsa', - 'sha512_ecdsa': 'ecdsa', - 'sha3_224_ecdsa': 'ecdsa', - 'sha3_256_ecdsa': 'ecdsa', - 'sha3_384_ecdsa': 'ecdsa', - 'sha3_512_ecdsa': 'ecdsa', - 'ecdsa': 'ecdsa', - 'ed448': 'ed448', - 'ed25519': 'ed25519' -} - - -def _signature_algo(self): - algorithm = self['algorithm'].native - - if algorithm in SIG_ALGO_MAP: - return SIG_ALGO_MAP[algorithm] - - raise ValueError(unwrap( - ''' - Signature algorithm not known for %s - ''', - algorithm - )) - - -HASH_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', - 'sha1_ecdsa': 'sha1', - 'sha224_ecdsa': 'sha224', - 'sha256_ecdsa': 'sha256', - 'sha384_ecdsa': 'sha384', - 'sha512_ecdsa': 'sha512', - # baked into the signing algorithm - 'ed25519': 'sha512', - # idem - 'ed448': 'shake256', -} - - -def _hash_algo(self): - """ - :return: - A unicode string of "md2", "md5", "sha1", "sha224", "sha256", - "sha384", "sha512", "sha512_224", "sha512_256" - """ - - algorithm = self['algorithm'].native - if algorithm in HASH_ALGO_MAP: - return HASH_ALGO_MAP[algorithm] - - if algorithm == 'rsassa_pss': - return self['parameters']['hash_algorithm']['algorithm'].native - - raise ValueError(unwrap( - ''' - Hash algorithm not known for %s - ''', - algorithm - )) - - -_eddsa_registered = False -_attr_cert_patches_registered = False - - -def _make_tag_explicit(field_decl): - tag_dict = field_decl[2] - if 'explicit' in tag_dict: - return - tag_dict['explicit'] = tag_dict['implicit'] - del tag_dict['implicit'] - - -def _make_tag_implicit(field_decl): - tag_dict = field_decl[2] - if 'implicit' in tag_dict: - return - tag_dict['implicit'] = tag_dict['explicit'] - del tag_dict['explicit'] - - -def register_attr_cert_patches(): - global _attr_cert_patches_registered - if _attr_cert_patches_registered: - return - - # Deal with wbond/asn1crypto#218 - _make_tag_explicit(cms.RoleSyntax._fields[1]) - _make_tag_explicit(cms.SecurityCategory._fields[1]) - # Deal with wbond/asn1crypto#220 - _make_tag_implicit(cms.AttCertIssuer._alternatives[1]) - - # patch in attribute certificate extensions - # Note: we only make these patches so that we can reliably produce the - # relevant values, and don't insist on supplying Certomancer's internal - # definitions at the Python level if some other library already supplied - # them - ext_map = x509.ExtensionId._map - ext_specs = x509.Extension._oid_specs - if '2.5.29.55' not in ext_map: - from ._asn1_types import SequenceOfTargets - ext_map['2.5.29.55'] = 'target_information' - ext_specs['target_information'] = SequenceOfTargets - if '2.5.29.56' not in ext_map: - ext_map['2.5.29.56'] = 'no_rev_avail' - ext_specs['no_rev_avail'] = core.Null - if '1.3.6.1.5.5.7.1.6' not in ext_map: - from ._asn1_types import AAControls - ext_map['1.3.6.1.5.5.7.1.6'] = 'aa_controls' - ext_specs['aa_controls'] = AAControls - - -def _defer_to_certvalidator(): - global _eddsa_registered - # try to import pyhanko_certvalidator (test dependency with a similar shim) - # if that succeeds, we delegate - try: - from pyhanko_certvalidator import _eddsa_oids - _eddsa_oids.register_eddsa_oids() - _eddsa_registered = True - return True - except ImportError: - return False - - -def register_eddsa_oids(): - global _eddsa_registered - if _eddsa_registered: - return - - if _defer_to_certvalidator(): - return - - ed25519_oid = '1.3.101.112' - ed448_oid = '1.3.101.113' - - algos.SignedDigestAlgorithmId._map[ed25519_oid] = 'ed25519' - algos.SignedDigestAlgorithmId._map[ed448_oid] = 'ed448' - algos.SignedDigestAlgorithmId._reverse_map = None - - # override the signature_algo and hash_algo properties - setattr(algos.SignedDigestAlgorithm, - 'signature_algo', property(_signature_algo)) - setattr(algos.SignedDigestAlgorithm, 'hash_algo', property(_hash_algo)) - - keys.PublicKeyAlgorithmId._map[ed25519_oid] = 'ed25519' - keys.PublicKeyAlgorithmId._map[ed448_oid] = 'ed448' - keys.PublicKeyAlgorithmId._reverse_map = None - - keys.PrivateKeyAlgorithmId._map[ed25519_oid] = 'ed25519' - keys.PrivateKeyAlgorithmId._map[ed448_oid] = 'ed448' - keys.PrivateKeyAlgorithmId._reverse_map = None - - # need to patch in these callback methods as well - keys.PrivateKeyInfo._spec_callbacks['private_key'] = _private_key_spec - keys.PublicKeyInfo._spec_callbacks['public_key'] = _public_key_spec - - _eddsa_registered = True diff --git a/certomancer/crypto_utils.py b/certomancer/crypto_utils.py index 3d8508d..aec1f8d 100644 --- a/certomancer/crypto_utils.py +++ b/certomancer/crypto_utils.py @@ -270,13 +270,8 @@ def _oscrypto_hacky_load_pss_exclusive_key(private: keys.PrivateKeyInfo): def _select_default_crypto_backend() -> CryptoBackend: - from ._asn1crypto_patches import register_attr_cert_patches - register_attr_cert_patches() # pyca/cryptography required for EdDSA certs if pyca_cryptography_present(): - # Patch EdDSA support into asn1crypto - from ._asn1crypto_patches import register_eddsa_oids - register_eddsa_oids() return PycaCryptographyBackend() else: return OscryptoBackend() diff --git a/requirements.txt b/requirements.txt index cda67c6..c011303 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -asn1crypto>=1.4.0 +asn1crypto>=1.5.0 click>=7.1.2 pyyaml>=5.4.1 oscrypto>=1.2.1 diff --git a/setup.py b/setup.py index ed69b47..3f1e75e 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ def get_version(): ] }, install_requires=[ - 'asn1crypto>=1.4.0', + 'asn1crypto>=1.5.0', 'click>=7.1.2', 'oscrypto>=1.2.1', 'pyyaml>=5.4.1',