diff options
-rw-r--r-- | cryptography/exceptions.py | 1 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 395 | ||||
-rw-r--r-- | cryptography/hazmat/bindings/openssl/ssl.py | 45 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/asymmetric/ec.py | 186 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/interfaces.py | 94 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/serialization.py | 8 | ||||
-rw-r--r-- | docs/hazmat/primitives/asymmetric/ec.rst | 182 | ||||
-rw-r--r-- | docs/hazmat/primitives/asymmetric/serialization.rst | 38 | ||||
-rw-r--r-- | docs/hazmat/primitives/interfaces.rst | 98 | ||||
-rw-r--r-- | docs/spelling_wordlist.txt | 1 | ||||
-rw-r--r-- | pytest.ini | 1 | ||||
-rw-r--r-- | tests/conftest.py | 11 | ||||
-rw-r--r-- | tests/hazmat/backends/test_openssl.py | 23 | ||||
-rw-r--r-- | tests/hazmat/primitives/fixtures_rsa.py | 492 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_ec.py | 294 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_rsa.py | 63 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_serialization.py | 18 |
17 files changed, 1453 insertions, 497 deletions
diff --git a/cryptography/exceptions.py b/cryptography/exceptions.py index b4ee8feb..c64b67f4 100644 --- a/cryptography/exceptions.py +++ b/cryptography/exceptions.py @@ -21,6 +21,7 @@ class _Reasons(object): UNSUPPORTED_PADDING = object() UNSUPPORTED_MGF = object() UNSUPPORTED_PUBLIC_KEY_ALGORITHM = object() + UNSUPPORTED_ELLIPTIC_CURVE = object() class UnsupportedAlgorithm(Exception): diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index ffe09663..7746dafb 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -25,13 +25,13 @@ from cryptography.exceptions import ( UnsupportedAlgorithm, _Reasons ) from cryptography.hazmat.backends.interfaces import ( - CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend, - PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend, + CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend, + HashBackend, PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend, TraditionalOpenSSLSerializationBackend ) from cryptography.hazmat.bindings.openssl.binding import Binding from cryptography.hazmat.primitives import hashes, interfaces -from cryptography.hazmat.primitives.asymmetric import dsa, rsa +from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa from cryptography.hazmat.primitives.asymmetric.padding import ( MGF1, OAEP, PKCS1v15, PSS ) @@ -51,12 +51,13 @@ _OpenSSLError = collections.namedtuple("_OpenSSLError", @utils.register_interface(CipherBackend) @utils.register_interface(CMACBackend) @utils.register_interface(DSABackend) +@utils.register_interface(EllipticCurveBackend) @utils.register_interface(HashBackend) @utils.register_interface(HMACBackend) @utils.register_interface(PBKDF2HMACBackend) +@utils.register_interface(PKCS8SerializationBackend) @utils.register_interface(RSABackend) @utils.register_interface(TraditionalOpenSSLSerializationBackend) -@utils.register_interface(PKCS8SerializationBackend) class Backend(object): """ OpenSSL API binding interfaces. @@ -425,8 +426,8 @@ class Backend(object): The char* is the storage for the BIO and it must stay alive until the BIO is finished with. """ - data_char_p = backend._ffi.new("char[]", data) - bio = backend._lib.BIO_new_mem_buf( + data_char_p = self._ffi.new("char[]", data) + bio = self._lib.BIO_new_mem_buf( data_char_p, len(data) ) assert bio != self._ffi.NULL @@ -890,6 +891,236 @@ class Backend(object): return self._evp_pkey_to_private_key(evp_pkey) + def elliptic_curve_supported(self, curve): + if self._lib.Cryptography_HAS_EC != 1: + return False + + curves = self._supported_curves() + return curve.name.encode("ascii") in curves + + def elliptic_curve_signature_algorithm_supported( + self, signature_algorithm, curve + ): + if self._lib.Cryptography_HAS_EC != 1: + return False + + # We only support ECDSA right now. + if isinstance(signature_algorithm, ec.ECDSA) is False: + return False + + # Before 0.9.8m OpenSSL can't cope with digests longer than the curve. + if ( + self._lib.OPENSSL_VERSION_NUMBER < 0x009080df and + curve.key_size < signature_algorithm.algorithm.digest_size * 8 + ): + return False + + return self.elliptic_curve_supported(curve) + + def _supported_curves(self): + if self._lib.Cryptography_HAS_EC != 1: + return [] + + num_curves = self._lib.EC_get_builtin_curves(self._ffi.NULL, 0) + curve_array = self._ffi.new("EC_builtin_curve[]", num_curves) + num_curves_assigned = self._lib.EC_get_builtin_curves( + curve_array, num_curves) + assert num_curves == num_curves_assigned + + curves = [ + self._ffi.string(self._lib.OBJ_nid2sn(curve.nid)).decode() + for curve in curve_array + ] + + curve_aliases = { + "prime192v1": "secp192r1", + "prime256v1": "secp256r1" + } + return [ + curve_aliases.get(curve, curve) + for curve in curves + ] + + def _create_ecdsa_signature_ctx(self, private_key, ecdsa): + return _ECDSASignatureContext(self, private_key, ecdsa.algorithm) + + def _create_ecdsa_verification_ctx(self, public_key, signature, ecdsa): + return _ECDSAVerificationContext(self, public_key, signature, + ecdsa.algorithm) + + def generate_elliptic_curve_private_key(self, curve): + """ + Generate a new private key on the named curve. + """ + + curve_nid = self._elliptic_curve_to_nid(curve) + + ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid) + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free) + + res = self._lib.EC_KEY_generate_key(ctx) + assert res == 1 + + res = self._lib.EC_KEY_check_key(ctx) + assert res == 1 + + return _EllipticCurvePrivateKey(self, ctx, curve) + + def elliptic_curve_private_key_from_numbers(self, numbers): + ec_key = self._ec_key_cdata_from_private_numbers(numbers) + return _EllipticCurvePrivateKey(self, ec_key, + numbers.public_numbers.curve) + + def elliptic_curve_public_key_from_numbers(self, numbers): + ec_key = self._ec_key_cdata_from_public_numbers(numbers) + return _EllipticCurvePublicKey(self, ec_key, numbers.curve) + + def _elliptic_curve_to_nid(self, curve): + """ + Get the NID for a curve name. + """ + + curve_aliases = { + "secp192r1": "prime192v1", + "secp256r1": "prime256v1" + } + + curve_name = curve_aliases.get(curve.name, curve.name) + + curve_nid = self._lib.OBJ_sn2nid(curve_name.encode()) + if curve_nid == self._lib.NID_undef: + raise UnsupportedAlgorithm( + "{0} is not a supported elliptic curve".format(curve.name), + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + return curve_nid + + def _ec_key_cdata_from_private_numbers(self, numbers): + """ + Build an EC_KEY from a private key object. + """ + + public = numbers.public_numbers + + curve_nid = self._elliptic_curve_to_nid(public.curve) + + ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid) + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free) + + ctx = self._ec_key_set_public_key_affine_coordinates( + ctx, public.x, public.y) + + res = self._lib.EC_KEY_set_private_key( + ctx, self._int_to_bn(numbers.private_value)) + assert res == 1 + + return ctx + + def _ec_key_cdata_from_public_numbers(self, numbers): + """ + Build an EC_KEY from a public key object. + """ + + curve_nid = self._elliptic_curve_to_nid(numbers.curve) + + ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid) + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free) + + ctx = self._ec_key_set_public_key_affine_coordinates( + ctx, numbers.x, numbers.y) + + return ctx + + def _public_ec_key_from_private_ec_key(self, private_key_cdata): + """ + Copy the public portions out of one EC key into a new one. + """ + + group = self._lib.EC_KEY_get0_group(private_key_cdata) + assert group != self._ffi.NULL + + curve_nid = self._lib.EC_GROUP_get_curve_name(group) + + ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid) + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free) + + point = self._lib.EC_KEY_get0_public_key(private_key_cdata) + assert point != self._ffi.NULL + + res = self._lib.EC_KEY_set_public_key(ctx, point) + assert res == 1 + + return ctx + + def _ec_key_set_public_key_affine_coordinates(self, ctx, x, y): + """ + This is a port of EC_KEY_set_public_key_affine_coordinates that was + added in 1.0.1. + + Sets the public key point in the EC_KEY context to the affine x and y + values. + """ + + assert ctx != self._ffi.NULL + + bn_x = self._int_to_bn(x) + bn_y = self._int_to_bn(y) + + nid_two_field = self._lib.OBJ_sn2nid(b"characteristic-two-field") + assert nid_two_field != self._lib.NID_undef + + bn_ctx = self._lib.BN_CTX_new() + assert bn_ctx != self._ffi.NULL + bn_ctx = self._ffi.gc(bn_ctx, self._lib.BN_CTX_free) + + group = self._lib.EC_KEY_get0_group(ctx) + assert group != self._ffi.NULL + + point = self._lib.EC_POINT_new(group) + assert point != self._ffi.NULL + point = self._ffi.gc(point, self._lib.EC_POINT_free) + + method = self._lib.EC_GROUP_method_of(group) + assert method != self._ffi.NULL + + nid = self._lib.EC_METHOD_get_field_type(method) + assert nid != self._lib.NID_undef + + check_x = self._lib.BN_CTX_get(bn_ctx) + check_y = self._lib.BN_CTX_get(bn_ctx) + + if nid == nid_two_field and self._lib.Cryptography_HAS_EC2M: + set_func = self._lib.EC_POINT_set_affine_coordinates_GF2m + get_func = self._lib.EC_POINT_get_affine_coordinates_GF2m + else: + set_func = self._lib.EC_POINT_set_affine_coordinates_GFp + get_func = self._lib.EC_POINT_get_affine_coordinates_GFp + + assert set_func and get_func + + res = set_func(group, point, bn_x, bn_y, bn_ctx) + assert res == 1 + + res = get_func(group, point, check_x, check_y, bn_ctx) + assert res == 1 + + assert ( + self._lib.BN_cmp(bn_x, check_x) == 0 and + self._lib.BN_cmp(bn_y, check_y) == 0 + ) + + res = self._lib.EC_KEY_set_public_key(ctx, point) + assert res == 1 + + res = self._lib.EC_KEY_check_key(ctx) + assert res == 1 + + return ctx + class GetCipherByName(object): def __init__(self, fmt): @@ -1727,4 +1958,156 @@ class _CMACContext(object): ) +def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend): + _lib = backend._lib + _ffi = backend._ffi + + digest_len = len(digest) + + group = _lib.EC_KEY_get0_group(ec_key_cdata) + + bn_ctx = _lib.BN_CTX_new() + assert bn_ctx != _ffi.NULL + bn_ctx = _ffi.gc(bn_ctx, _lib.BN_CTX_free) + + order = _lib.BN_CTX_get(bn_ctx) + assert order != _ffi.NULL + + res = _lib.EC_GROUP_get_order(group, order, bn_ctx) + assert res == 1 + + order_bits = _lib.BN_num_bits(order) + + if 8 * digest_len > order_bits: + digest_len = (order_bits + 7) // 8 + digest = digest[:digest_len] + + if 8 * digest_len > order_bits: + rshift = 8 - (order_bits & 0x7) + assert rshift > 0 and rshift < 8 + + mask = 0xFF >> rshift << rshift + + # Set the bottom rshift bits to 0 + digest = digest[:-1] + six.int2byte(six.byte2int(digest[-1]) & mask) + + return digest + + +@utils.register_interface(interfaces.AsymmetricSignatureContext) +class _ECDSASignatureContext(object): + def __init__(self, backend, private_key, algorithm): + self._backend = backend + self._private_key = private_key + self._digest = hashes.Hash(algorithm, backend) + + def update(self, data): + self._digest.update(data) + + def finalize(self): + ec_key = self._private_key._ec_key + + digest = self._digest.finalize() + + digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend) + + max_size = self._backend._lib.ECDSA_size(ec_key) + assert max_size > 0 + + sigbuf = self._backend._ffi.new("char[]", max_size) + siglen_ptr = self._backend._ffi.new("unsigned int[]", 1) + res = self._backend._lib.ECDSA_sign( + 0, + digest, + len(digest), + sigbuf, + siglen_ptr, + ec_key + ) + assert res == 1 + return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]] + + +@utils.register_interface(interfaces.AsymmetricVerificationContext) +class _ECDSAVerificationContext(object): + def __init__(self, backend, public_key, signature, algorithm): + self._backend = backend + self._public_key = public_key + self._signature = signature + self._digest = hashes.Hash(algorithm, backend) + + def update(self, data): + self._digest.update(data) + + def verify(self): + ec_key = self._public_key._ec_key + + digest = self._digest.finalize() + + digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend) + + res = self._backend._lib.ECDSA_verify( + 0, + digest, + len(digest), + self._signature, + len(self._signature), + ec_key + ) + if res != 1: + self._backend._consume_errors() + raise InvalidSignature + return True + + +@utils.register_interface(interfaces.EllipticCurvePrivateKey) +class _EllipticCurvePrivateKey(object): + def __init__(self, backend, ec_key_cdata, curve): + self._backend = backend + self._ec_key = ec_key_cdata + self._curve = curve + + @property + def curve(self): + return self._curve + + def signer(self, signature_algorithm): + if isinstance(signature_algorithm, ec.ECDSA): + return self._backend._create_ecdsa_signature_ctx( + self, signature_algorithm) + else: + raise UnsupportedAlgorithm( + "Unsupported elliptic curve signature algorithm.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def public_key(self): + public_ec_key = self._backend._public_ec_key_from_private_ec_key( + self._ec_key + ) + + return _EllipticCurvePublicKey( + self._backend, public_ec_key, self._curve) + + +@utils.register_interface(interfaces.EllipticCurvePublicKey) +class _EllipticCurvePublicKey(object): + def __init__(self, backend, ec_key_cdata, curve): + self._backend = backend + self._ec_key = ec_key_cdata + self._curve = curve + + @property + def curve(self): + return self._curve + + def verifier(self, signature, signature_algorithm): + if isinstance(signature_algorithm, ec.ECDSA): + return self._backend._create_ecdsa_verification_ctx( + self, signature, signature_algorithm) + else: + raise UnsupportedAlgorithm( + "Unsupported elliptic curve signature algorithm.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + backend = Backend() diff --git a/cryptography/hazmat/bindings/openssl/ssl.py b/cryptography/hazmat/bindings/openssl/ssl.py index 94b96d98..165bc7a1 100644 --- a/cryptography/hazmat/bindings/openssl/ssl.py +++ b/cryptography/hazmat/bindings/openssl/ssl.py @@ -46,6 +46,7 @@ static const long Cryptography_HAS_SSL_SET_SSL_CTX; static const long Cryptography_HAS_SSL_OP_NO_TICKET; static const long Cryptography_HAS_NETBSD_D1_METH; static const long Cryptography_HAS_NEXTPROTONEG; +static const long Cryptography_HAS_ALPN; static const long SSL_FILETYPE_PEM; static const long SSL_FILETYPE_ASN1; @@ -367,6 +368,21 @@ void SSL_get0_next_proto_negotiated(const SSL *, int sk_SSL_CIPHER_num(Cryptography_STACK_OF_SSL_CIPHER *); SSL_CIPHER *sk_SSL_CIPHER_value(Cryptography_STACK_OF_SSL_CIPHER *, int); + +/* ALPN APIs were introduced in OpenSSL 1.0.2. To continue to support earlier + * versions some special handling of these is necessary. + */ +int SSL_CTX_set_alpn_protos(SSL_CTX *, const unsigned char*, unsigned); +int SSL_set_alpn_protos(SSL *, const unsigned char*, unsigned); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *, + int (*) (SSL *, + const unsigned char **, + unsigned char *, + const unsigned char *, + unsigned int, + void *), + void *); +void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *); """ CUSTOMIZATIONS = """ @@ -515,6 +531,28 @@ void (*SSL_get0_next_proto_negotiated)(const SSL *, #else static const long Cryptography_HAS_NEXTPROTONEG = 1; #endif + +// ALPN was added in OpenSSL 1.0.2. +#if OPENSSL_VERSION_NUMBER < 0x10002001L +int (*SSL_CTX_set_alpn_protos)(SSL_CTX *, + const unsigned char*, + unsigned) = NULL; +int (*SSL_set_alpn_protos)(SSL *, const unsigned char*, unsigned) = NULL; +void (*SSL_CTX_set_alpn_select_cb)(SSL_CTX *, + int (*) (SSL *, + const unsigned char **, + unsigned char *, + const unsigned char *, + unsigned int, + void *), + void *) = NULL; +void (*SSL_get0_alpn_selected)(const SSL *, + const unsigned char **, + unsigned *) = NULL; +static const long Cryptography_HAS_ALPN = 0; +#else +static const long Cryptography_HAS_ALPN = 1; +#endif """ CONDITIONAL_NAMES = { @@ -585,4 +623,11 @@ CONDITIONAL_NAMES = { "SSL_OP_LEGACY_SERVER_CONNECT", "SSL_get_secure_renegotiation_support", ], + + "Cryptography_HAS_ALPN": [ + "SSL_CTX_set_alpn_protos", + "SSL_set_alpn_protos", + "SSL_CTX_set_alpn_select_cb", + "SSL_get0_alpn_selected", + ] } diff --git a/cryptography/hazmat/primitives/asymmetric/ec.py b/cryptography/hazmat/primitives/asymmetric/ec.py index 1e49ad7b..220a419c 100644 --- a/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/cryptography/hazmat/primitives/asymmetric/ec.py @@ -15,9 +15,189 @@ from __future__ import absolute_import, division, print_function import six +from cryptography import utils from cryptography.hazmat.primitives import interfaces +@utils.register_interface(interfaces.EllipticCurve) +class SECT571R1(object): + @property + def name(self): + return "sect571r1" + + @property + def key_size(self): + return 571 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT409R1(object): + @property + def name(self): + return "sect409r1" + + @property + def key_size(self): + return 409 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT283R1(object): + @property + def name(self): + return "sect283r1" + + @property + def key_size(self): + return 283 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT233R1(object): + @property + def name(self): + return "sect233r1" + + @property + def key_size(self): + return 233 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT163R2(object): + @property + def name(self): + return "sect163r2" + + @property + def key_size(self): + return 163 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT571K1(object): + @property + def name(self): + return "sect571k1" + + @property + def key_size(self): + return 571 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT409K1(object): + @property + def name(self): + return "sect409k1" + + @property + def key_size(self): + return 409 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT283K1(object): + @property + def name(self): + return "sect283k1" + + @property + def key_size(self): + return 283 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT233K1(object): + @property + def name(self): + return "sect233k1" + + @property + def key_size(self): + return 233 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT163K1(object): + @property + def name(self): + return "sect163k1" + + @property + def key_size(self): + return 163 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP521R1(object): + @property + def name(self): + return "secp521r1" + + @property + def key_size(self): + return 521 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP384R1(object): + @property + def name(self): + return "secp384r1" + + @property + def key_size(self): + return 384 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP256R1(object): + @property + def name(self): + return "secp256r1" + + @property + def key_size(self): + return 256 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP224R1(object): + @property + def name(self): + return "secp224r1" + + @property + def key_size(self): + return 224 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP192R1(object): + @property + def name(self): + return "secp192r1" + + @property + def key_size(self): + return 192 + + +@utils.register_interface(interfaces.EllipticCurveSignatureAlgorithm) +class ECDSA(object): + def __init__(self, algorithm): + self._algorithm = algorithm + + @property + def algorithm(self): + return self._algorithm + + +def generate_private_key(curve, backend): + return backend.generate_elliptic_curve_private_key(curve) + + class EllipticCurvePublicNumbers(object): def __init__(self, x, y, curve): if ( @@ -33,6 +213,9 @@ class EllipticCurvePublicNumbers(object): self._x = x self._curve = curve + def public_key(self, backend): + return backend.elliptic_curve_public_key_from_numbers(self) + @property def curve(self): return self._curve @@ -60,6 +243,9 @@ class EllipticCurvePrivateNumbers(object): self._private_value = private_value self._public_numbers = public_numbers + def private_key(self, backend): + return backend.elliptic_curve_private_key_from_numbers(self) + @property def private_value(self): return self._private_value diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py index 0dd1d01a..d805bd1a 100644 --- a/cryptography/hazmat/primitives/interfaces.py +++ b/cryptography/hazmat/primitives/interfaces.py @@ -192,24 +192,6 @@ class RSAPrivateKey(object): """ @abc.abstractproperty - def modulus(self): - """ - The public modulus of the RSA key. - """ - - @abc.abstractproperty - def public_exponent(self): - """ - The public exponent of the RSA key. - """ - - @abc.abstractproperty - def private_exponent(self): - """ - The private exponent of the RSA key. - """ - - @abc.abstractproperty def key_size(self): """ The bit length of the public modulus. @@ -221,58 +203,6 @@ class RSAPrivateKey(object): The RSAPublicKey associated with this private key. """ - @abc.abstractproperty - def n(self): - """ - The public modulus of the RSA key. Alias for modulus. - """ - - @abc.abstractproperty - def p(self): - """ - One of the two primes used to generate d. - """ - - @abc.abstractproperty - def q(self): - """ - One of the two primes used to generate d. - """ - - @abc.abstractproperty - def d(self): - """ - The private exponent. This can be calculated using p and q. Alias for - private_exponent. - """ - - @abc.abstractproperty - def dmp1(self): - """ - A Chinese remainder theorem coefficient used to speed up RSA - calculations. Calculated as: d mod (p-1) - """ - - @abc.abstractproperty - def dmq1(self): - """ - A Chinese remainder theorem coefficient used to speed up RSA - calculations. Calculated as: d mod (q-1) - """ - - @abc.abstractproperty - def iqmp(self): - """ - A Chinese remainder theorem coefficient used to speed up RSA - calculations. The modular inverse of q modulo p - """ - - @abc.abstractproperty - def e(self): - """ - The public exponent of the RSA key. Alias for public_exponent. - """ - @six.add_metaclass(abc.ABCMeta) class RSAPublicKey(object): @@ -283,35 +213,11 @@ class RSAPublicKey(object): """ @abc.abstractproperty - def modulus(self): - """ - The public modulus of the RSA key. - """ - - @abc.abstractproperty - def public_exponent(self): - """ - The public exponent of the RSA key. - """ - - @abc.abstractproperty def key_size(self): """ The bit length of the public modulus. """ - @abc.abstractproperty - def n(self): - """ - The public modulus of the RSA key. Alias for modulus. - """ - - @abc.abstractproperty - def e(self): - """ - The public exponent of the RSA key. Alias for public_exponent. - """ - @six.add_metaclass(abc.ABCMeta) class DSAParameters(object): diff --git a/cryptography/hazmat/primitives/serialization.py b/cryptography/hazmat/primitives/serialization.py index ed73c4c4..056d4a06 100644 --- a/cryptography/hazmat/primitives/serialization.py +++ b/cryptography/hazmat/primitives/serialization.py @@ -24,3 +24,11 @@ def load_pem_pkcs8_private_key(data, password, backend): return backend.load_pkcs8_pem_private_key( data, password ) + + +def load_rsa_private_numbers(numbers, backend): + return backend.load_rsa_private_numbers(numbers) + + +def load_rsa_public_numbers(numbers, backend): + return backend.load_rsa_public_numbers(numbers) diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst index f88b965a..84911cba 100644 --- a/docs/hazmat/primitives/asymmetric/ec.rst +++ b/docs/hazmat/primitives/asymmetric/ec.rst @@ -1,11 +1,30 @@ .. hazmat:: -Elliptic Curve -============== +Elliptic Curve Cryptography +=========================== .. currentmodule:: cryptography.hazmat.primitives.asymmetric.ec +.. method:: generate_private_key(curve, backend): + + .. versionadded:: 0.5 + + Generate a new private key on ``curve`` for use with ``backend``. + + :param backend: A + :class:`~cryptography.hazmat.primtives.interfaces.EllipticCurve` + provider. + + :param backend: A + :class:`~cryptography.hazmat.backends.interfaces.EllipticCurveBackend` + provider. + + :returns: A new instance of a + :class:`~cryptography.hazmat.primtivies.interfaces.EllipticCurvePrivateKey` + provider. + + .. class:: EllipticCurvePrivateNumbers(private_value, public_numbers) .. versionadded:: 0.5 @@ -25,6 +44,19 @@ Elliptic Curve The private value. + .. method:: private_key(backend) + + Convert a collection of numbers into a private key suitable for doing + actual cryptographic operations. + + :param backend: A + :class:`~cryptography.hazmat.backends.interfaces.EllipticCurveBackend` + provider. + + :returns: A new instance of a + :class:`~cryptography.hazmat.primtivies.interfaces.EllipticCurvePrivateKey` + provider. + .. class:: EllipticCurvePublicNumbers(x, y, curve) @@ -49,3 +81,149 @@ Elliptic Curve :type: int The affine y component of the public point used for verifying. + + .. method:: public_key(backend) + + Convert a collection of numbers into a public key suitable for doing + actual cryptographic operations. + + :param backend: A + :class:`~cryptography.hazmat.backends.interfaces.EllipticCurveBackend` + provider. + + :returns: A new instance of a + :class:`~cryptography.hazmat.primtivies.interfaces.EllipticCurvePublicKey` + provider. + + +Elliptic Curve Signature Algorithms +----------------------------------- + +.. class:: ECDSA(algorithm) + .. versionadded:: 0.5 + + The ECDSA signature algorithm first standardized in NIST publication + `FIPS 186-3`_, and later in `FIPS 186-4`_. + + :param algorithm: An instance of a + :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm` + provider. + + .. code-block:: pycon + + >>> from cryptography.hazmat.backends import default_backend + >>> from cryptography.hazmat.primitives import hashes + >>> from cryptography.hazmat.primitives.asymmetric import ec + >>> private_key = ec.generate_private_key( + ... ec.SECT283K1(), default_backend() + ... ) + >>> signer = private_key.signer(ec.ECDSA(hashes.SHA256())) + >>> signer.update(b"this is some data I'd like") + >>> signer.update(b" to sign") + >>> signature = signer.finalize() + +Elliptic Curves +--------------- + +All named curves are providers of +:class:`~cryptography.hazmat.primtives.interfaces.EllipticCurve`. + +There is `some concern`_ that the non-Koblitz NIST curves (identified by names +that start with "B" or "P") may have been intentionally weakened by their +generation process. + + +.. class:: SECT571K1 + .. versionadded:: 0.5 + + SECG curve ``sect571k1``. Also called NIST K-571. + + +.. class:: SECT409K1 + .. versionadded:: 0.5 + + SECG curve ``sect409k1``. Also called NIST K-409. + + +.. class:: SECT283K1 + .. versionadded:: 0.5 + + SECG curve ``sect283k1``. Also called NIST K-283. + + +.. class:: SECT233K1 + .. versionadded:: 0.5 + + SECG curve ``sect233k1``. Also called NIST K-233. + + +.. class:: SECT163K1 + .. versionadded:: 0.5 + + SECG curve ``sect163k1``. Also called NIST K-163. + + +.. class:: SECT571R1 + .. versionadded:: 0.5 + + SECG curve ``sect571r1``. Also called NIST B-571. + + +.. class:: SECT409R1 + .. versionadded:: 0.5 + + SECG curve ``sect409r1``. Also called NIST B-409. + + +.. class:: SECT283R1 + .. versionadded:: 0.5 + + SECG curve ``sect283r1``. Also called NIST B-283. + + +.. class:: SECT233R1 + .. versionadded:: 0.5 + + SECG curve ``sect233r1``. Also called NIST B-233. + + +.. class:: SECT163R2 + .. versionadded:: 0.5 + + SECG curve ``sect163r2``. Also called NIST B-163. + + +.. class:: SECP521R1 + .. versionadded:: 0.5 + + SECG curve ``secp521r1``. Also called NIST P-521. + + +.. class:: SECP384R1 + .. versionadded:: 0.5 + + SECG curve ``secp384r1``. Also called NIST P-384. + + +.. class:: SECP256R1 + .. versionadded:: 0.5 + + SECG curve ``secp256r1``. Also called NIST P-256. + + +.. class:: SECT224R1 + .. versionadded:: 0.5 + + SECG curve ``secp224r1``. Also called NIST P-224. + + +.. class:: SECP192R1 + .. versionadded:: 0.5 + + SECG curve ``secp192r1``. Also called NIST P-192. + + + +.. _`FIPS 186-3`: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf +.. _`FIPS 186-4`: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf +.. _`some concern`: https://crypto.stackexchange.com/questions/10263/should-we-trust-the-nist-recommended-ecc-parameters diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 2b3eb511..e53d0d1f 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -98,3 +98,41 @@ header that mentions the type of the serialized key. e.g. :raises UnsupportedAlgorithm: If the serialized key is of a type that is not supported by the backend or if the key is encrypted with a symmetric cipher that is not supported by the backend. + + +RSA Numbers +~~~~~~~~~~~ + +.. function:: load_rsa_private_numbers(numbers, backend) + + .. versionadded:: 0.5 + + Create a private key instance using the given backend and numbers. + + :param numbers: An instance of + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers`. + + :param backend: A + :class:`~cryptography.hazmat.backends.interfaces.RSABackend` provider. + + :returns: A new instance of a private key. + + :raises UnsupportedAlgorithm: If the given backend does not support loading + numbers. + +.. function:: load_rsa_public_numbers(numbers, backend) + + .. versionadded:: 0.5 + + Create a public key instance using the given backend and numbers. + + :param numbers: An instance of + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers`. + + :param backend: A + :class:`~cryptography.hazmat.backends.interfaces.RSABackend` provider. + + :returns: A new instance of a public key. + + :raises UnsupportedAlgorithm: If the given backend does not support loading + numbers. diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst index b2857f58..d5ca59ab 100644 --- a/docs/hazmat/primitives/interfaces.rst +++ b/docs/hazmat/primitives/interfaces.rst @@ -157,81 +157,12 @@ Asymmetric interfaces An RSA public key object corresponding to the values of the private key. - .. attribute:: modulus - - :type: int - - The public modulus. - - .. attribute:: public_exponent - - :type: int - - The public exponent. - - .. attribute:: private_exponent - - :type: int - - The private exponent. - .. attribute:: key_size :type: int The bit length of the modulus. - .. attribute:: p - - :type: int - - ``p``, one of the two primes composing the :attr:`modulus`. - - .. attribute:: q - - :type: int - - ``q``, one of the two primes composing the :attr:`modulus`. - - .. attribute:: d - - :type: int - - The private exponent. Alias for :attr:`private_exponent`. - - .. attribute:: dmp1 - - :type: int - - A `Chinese remainder theorem`_ coefficient used to speed up RSA - operations. Calculated as: d mod (p-1) - - .. attribute:: dmq1 - - :type: int - - A `Chinese remainder theorem`_ coefficient used to speed up RSA - operations. Calculated as: d mod (q-1) - - .. attribute:: iqmp - - :type: int - - A `Chinese remainder theorem`_ coefficient used to speed up RSA - operations. Calculated as: q\ :sup:`-1` mod p - - .. attribute:: n - - :type: int - - The public modulus. Alias for :attr:`modulus`. - - .. attribute:: e - - :type: int - - The public exponent. Alias for :attr:`public_exponent`. - .. class:: RSAPublicKey @@ -281,36 +212,12 @@ Asymmetric interfaces :return bytes: Encrypted data. - .. attribute:: modulus - - :type: int - - The public modulus. - .. attribute:: key_size :type: int The bit length of the modulus. - .. attribute:: public_exponent - - :type: int - - The public exponent. - - .. attribute:: n - - :type: int - - The public modulus. Alias for :attr:`modulus`. - - .. attribute:: e - - :type: int - - The public exponent. Alias for :attr:`public_exponent`. - .. class:: DSAParameters @@ -504,7 +411,6 @@ Asymmetric interfaces `EdDSA`_. .. classmethod:: signer(signature_algorithm) - Sign data which can be verified later by others using the public key. :param signature_algorithm: An instance of a @@ -514,7 +420,6 @@ Asymmetric interfaces :returns: :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricSignatureContext` - .. attribute:: curve :type: :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurve` @@ -533,8 +438,7 @@ Asymmetric interfaces An elliptic curve public key. - .. classmethod:: verifier(signer, signature_algorithm) - + .. classmethod:: verifier(signature, signature_algorithm) Verify data was signed by the private key associated with this public key. diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 9baf0822..d5a2bee3 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -27,6 +27,7 @@ interoperable introspectability invariants iOS +Koblitz metadata pickleable plaintext @@ -11,3 +11,4 @@ markers = traditional_openssl_serialization: this test requires a backend providing TraditionalOpenSSLSerializationBackend pkcs8_serialization: this test requires a backend providing PKCS8SerializationBackend supported: parametrized test requiring only_if and skip_message + elliptic: this test requires a backend providing EllipticCurveBackend diff --git a/tests/conftest.py b/tests/conftest.py index b1326dc8..af146386 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,8 +17,8 @@ import pytest from cryptography.hazmat.backends import _available_backends from cryptography.hazmat.backends.interfaces import ( - CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend, - PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend, + CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend, + HashBackend, PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend, TraditionalOpenSSLSerializationBackend ) from .utils import check_backend_support, check_for_iface, select_backends @@ -46,11 +46,8 @@ def pytest_runtest_setup(item): TraditionalOpenSSLSerializationBackend, item ) - check_for_iface( - "pkcs8_serialization", - PKCS8SerializationBackend, - item - ) + check_for_iface("pkcs8_serialization", PKCS8SerializationBackend, item) + check_for_iface("elliptic", EllipticCurveBackend, item) check_backend_support(item) diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index bfcdf14a..aa2122fb 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -19,7 +19,9 @@ import pytest from cryptography import utils from cryptography.exceptions import InternalError, _Reasons -from cryptography.hazmat.backends.openssl.backend import Backend, backend +from cryptography.hazmat.backends.openssl.backend import ( + Backend, backend +) from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import dsa, padding, rsa from cryptography.hazmat.primitives.ciphers import Cipher @@ -445,3 +447,22 @@ class TestOpenSSLSerialisationWithOpenSSL(object): key = pretend.stub(type="unsupported") with raises_unsupported_algorithm(None): backend._evp_pkey_to_private_key(key) + + +class TestOpenSSLNoEllipticCurve(object): + def test_elliptic_curve_supported(self, monkeypatch): + monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0) + + assert backend.elliptic_curve_supported(None) is False + + def test_elliptic_curve_signature_algorithm_supported(self, monkeypatch): + monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0) + + assert backend.elliptic_curve_signature_algorithm_supported( + None, None + ) is False + + def test_supported_curves(self, monkeypatch): + monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0) + + assert backend._supported_curves() == [] diff --git a/tests/hazmat/primitives/fixtures_rsa.py b/tests/hazmat/primitives/fixtures_rsa.py index 494b9942..f0eb5a54 100644 --- a/tests/hazmat/primitives/fixtures_rsa.py +++ b/tests/hazmat/primitives/fixtures_rsa.py @@ -14,449 +14,495 @@ from __future__ import absolute_import, division, print_function +from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateNumbers, RSAPublicNumbers +) -RSA_KEY_512 = { - "p": int( + +RSA_KEY_512 = RSAPrivateNumbers( + p=int( "d57846898d5c0de249c08467586cb458fa9bc417cdf297f73cfc52281b787cd9", 16 ), - "q": int( + q=int( "d10f71229e87e010eb363db6a85fd07df72d985b73c42786191f2ce9134afb2d", 16 ), - "private_exponent": int( + d=int( "272869352cacf9c866c4e107acc95d4c608ca91460a93d28588d51cfccc07f449" "18bbe7660f9f16adc2b4ed36ca310ef3d63b79bd447456e3505736a45a6ed21", 16 ), - "dmp1": int( + dmp1=int( "addff2ec7564c6b64bc670d250b6f24b0b8db6b2810099813b7e7658cecf5c39", 16 ), - "dmq1": int( + dmq1=int( "463ae9c6b77aedcac1397781e50e4afc060d4b216dc2778494ebe42a6850c81", 16 ), - "iqmp": int( + iqmp=int( "54deef8548f65cad1d411527a32dcb8e712d3e128e4e0ff118663fae82a758f4", 16 ), - "public_exponent": 65537, - "modulus": int( - "ae5411f963c50e3267fafcf76381c8b1e5f7b741fdb2a544bcf48bd607b10c991" - "90caeb8011dc22cf83d921da55ec32bd05cac3ee02ca5e1dbef93952850b525", 16 - ), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "ae5411f963c50e3267fafcf76381c8b1e5f7b741fdb2a544bcf48bd607b10c991" + "90caeb8011dc22cf83d921da55ec32bd05cac3ee02ca5e1dbef93952850b525", + 16 + ), + ) +) -RSA_KEY_512_ALT = { - "p": int( +RSA_KEY_512_ALT = RSAPrivateNumbers( + p=int( "febe19c29a0b50fefa4f7b1832f84df1caf9be8242da25c9d689e18226e67ce5", 16), - "q": int( + q=int( "eb616c639dd999feda26517e1c77b6878f363fe828c4e6670ec1787f28b1e731", 16), - "private_exponent": int( + d=int( "80edecfde704a806445a4cc782b85d3f36f17558f385654ea767f006470fdfcbda5e2" "206839289d3f419b4e4fb8e1acee1b4fb9c591f69b64ec83937f5829241", 16), - "dmp1": int( + dmp1=int( "7f4fa06e2a3077a54691cc5216bf13ad40a4b9fa3dd0ea4bca259487484baea5", 16), - "dmq1": int( + dmq1=int( "35eaa70d5a8711c352ed1c15ab27b0e3f46614d575214535ae279b166597fac1", 16), - "iqmp": int( + iqmp=int( "cc1f272de6846851ec80cb89a02dbac78f44b47bc08f53b67b4651a3acde8b19", 16), - "public_exponent": 65537, - "modulus": int( - "ea397388b999ef0f7e7416fa000367efd9a0ba0deddd3f8160d1c36d62267f210fbd9" - "c97abeb6654450ff03e7601b8caa6c6f4cba18f0b52c179d17e8f258ad5", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "ea397388b999ef0f7e7416fa000367efd9a0ba0deddd3f8160d1c36d62267f210" + "fbd9c97abeb6654450ff03e7601b8caa6c6f4cba18f0b52c179d17e8f258ad5", + 16), + ) +) -RSA_KEY_522 = { - "p": int( +RSA_KEY_522 = RSAPrivateNumbers( + p=int( "1a8aab9a069f92b52fdf05824f2846223dc27adfc806716a247a77d4c36885e4bf", 16), - "q": int( + q=int( "19e8d620d177ec54cdb733bb1915e72ef644b1202b889ceb524613efa49c07eb4f", 16), - "private_exponent": int( + d=int( "10b8a7c0a92c1ae2d678097d69db3bfa966b541fb857468291d48d1b52397ea2bac0d" "4370c159015c7219e3806a01bbafaffdd46f86e3da1e2d1fe80a0369ccd745", 16), - "dmp1": int( + dmp1=int( "3eb6277f66e6e2dcf89f1b8529431f730839dbd9a3e49555159bc8470eee886e5", 16), - "dmq1": int( + dmq1=int( "184b4d74aa54c361e51eb23fee4eae5e4786b37b11b6e0447af9c0b9c4e4953c5b", 16), - "iqmp": int( + iqmp=int( "f80e9ab4fa7b35d0d232ef51c4736d1f2dcf2c7b1dd8716211b1bf1337e74f8ae", 16), - "public_exponent": 65537, - "modulus": int( - "2afaea0e0bb6fca037da7d190b5270a6c665bc18e7a456f7e69beaac4433db748ba99" - "acdd14697e453bca596eb35b47f2d48f1f85ef08ce5109dad557a9cf85ebf1", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "2afaea0e0bb6fca037da7d190b5270a6c665bc18e7a456f7e69beaac4433db748" + "ba99acdd14697e453bca596eb35b47f2d48f1f85ef08ce5109dad557a9cf85ebf" + "1", 16), + ), +) -RSA_KEY_599 = { - "p": int( +RSA_KEY_599 = RSAPrivateNumbers( + p=int( "cf95d20be0c7af69f4b3d909f65d858c26d1a7ef34da8e3977f4fa230580e58814b54" "24be99", 16), - "q": int( + q=int( "6052be4b28debd4265fe12ace5aa4a0c4eb8d63ff8853c66824b35622161eb48a3bc8" "c3ada5", 16), - "private_exponent": int( + d=int( "69d9adc465e61585d3142d7cc8dd30605e8d1cbbf31009bc2cd5538dc40528d5d68ee" "fe6a42d23674b6ec76e192351bf368c8968f0392110bf1c2825dbcff071270b80adcc" "fa1d19d00a1", 16), - "dmp1": int( + dmp1=int( "a86d10edde456687fba968b1f298d2e07226adb1221b2a466a93f3d83280f0bb46c20" "2b6811", 16), - "dmq1": int( + dmq1=int( "40d570e08611e6b1da94b95d46f8e7fe80be48f7a5ff8838375b08039514a399b11c2" "80735", 16), - "iqmp": int( + iqmp=int( "cd051cb0ea68b88765c041262ace2ec4db11dab14afd192742e34d5da3328637fabdf" "bae26e", 16), - "public_exponent": 65537, - "modulus": int( - "4e1b470fe00642426f3808e74c959632dd67855a4c503c5b7876ccf4dc7f6a1a49107" - "b90d26daf0a7879a6858218345fbc6e59f01cd095ca5647c27c25265e6c474fea8953" - "7191c7073d9d", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "4e1b470fe00642426f3808e74c959632dd67855a4c503c5b7876ccf4dc7f6a1a4" + "9107b90d26daf0a7879a6858218345fbc6e59f01cd095ca5647c27c25265e6c47" + "4fea89537191c7073d9d", 16), + ) +) -RSA_KEY_745 = { - "p": int( +RSA_KEY_745 = RSAPrivateNumbers( + p=int( "1c5a0cfe9a86debd19eca33ba961f15bc598aa7983a545ce775b933afc89eb51bcf90" "836257fdd060d4b383240241d", 16 ), - "q": int( + q=int( "fb2634f657f82ee6b70553382c4e2ed26b947c97ce2f0016f1b282cf2998184ad0527" "a9eead826dd95fe06b57a025", 16 ), - "private_exponent": int( + d=int( "402f30f976bc07d15ff0779abff127b20a8b6b1d0024cc2ad8b6762d38f174f81e792" "3b49d80bdbdd80d9675cbc7b2793ec199a0430eb5c84604dacfdb29259ae6a1a44676" "22f0b23d4cb0f5cb1db4b8173c8d9d3e57a74dbd200d2141", 16), - "dmp1": int( + dmp1=int( "e5e95b7751a6649f199be21bef7a51c9e49821d945b6fc5f538b4a670d8762c375b00" "8e70f31d52b3ea2bd14c3101", 16), - "dmq1": int( + dmq1=int( "12b85d5843645f72990fcf8d2f58408b34b3a3b9d9078dd527fceb5d2fb7839008092" "dd4aca2a1fb00542801dcef5", 16), - "iqmp": int( + iqmp=int( "5672740d947f621fc7969e3a44ec26736f3f819863d330e63e9409e139d20753551ac" "c16544dd2bdadb9dee917440", 16), - "public_exponent": 65537, - "modulus": int( - "1bd085f92237774d34013b477ceebbb2f2feca71118db9b7429341477947e7b1d04e8" - "c43ede3c52bb25781af58d4ff81289f301eac62dc3bcd7dafd7a4d5304e9f308e7669" - "52fbf2b62373e66611fa53189987dbef9f7243dcbbeb25831", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "1bd085f92237774d34013b477ceebbb2f2feca71118db9b7429341477947e7b1d" + "04e8c43ede3c52bb25781af58d4ff81289f301eac62dc3bcd7dafd7a4d5304e9f" + "308e766952fbf2b62373e66611fa53189987dbef9f7243dcbbeb25831", 16), + ) +) -RSA_KEY_768 = { - "p": int( +RSA_KEY_768 = RSAPrivateNumbers( + p=int( "f80c0061b607f93206b68e208906498d68c6e396faf457150cf975c8f849848465869" "7ecd402313397088044c4c2071b", 16), - "q": int( + q=int( "e5b5dbecc93c6d306fc14e6aa9737f9be2728bc1a326a8713d2849b34c1cb54c63468" "3a68abb1d345dbf15a3c492cf55", 16), - "private_exponent": int( + d=int( "d44601442255ffa331212c60385b5e898555c75c0272632ff42d57c4b16ca97dbca9f" "d6d99cd2c9fd298df155ed5141b4be06c651934076133331d4564d73faed7ce98e283" "2f7ce3949bc183be7e7ca34f6dd04a9098b6c73649394b0a76c541", 16), - "dmp1": int( + dmp1=int( "a5763406fa0b65929661ce7b2b8c73220e43a5ebbfe99ff15ddf464fd238105ad4f2a" "c83818518d70627d8908703bb03", 16), - "dmq1": int( + dmq1=int( "cb467a9ef899a39a685aecd4d0ad27b0bfdc53b68075363c373d8eb2bed8eccaf3533" "42f4db735a9e087b7539c21ba9d", 16), - "iqmp": int( + iqmp=int( "5fe86bd3aee0c4d09ef11e0530a78a4534c9b833422813b5c934a450c8e564d8097a0" "6fd74f1ebe2d5573782093f587a", 16), - "public_exponent": 65537, - "modulus": int( - "de92f1eb5f4abf426b6cac9dd1e9bf57132a4988b4ed3f8aecc15e251028bd6df46eb" - "97c711624af7db15e6430894d1b640c13929329241ee094f5a4fe1a20bc9b75232320" - "a72bc567207ec54d6b48dccb19737cf63acc1021abb337f19130f7", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "de92f1eb5f4abf426b6cac9dd1e9bf57132a4988b4ed3f8aecc15e251028bd6df" + "46eb97c711624af7db15e6430894d1b640c13929329241ee094f5a4fe1a20bc9b" + "75232320a72bc567207ec54d6b48dccb19737cf63acc1021abb337f19130f7", + 16), + ) +) -RSA_KEY_1024 = { - "p": int( +RSA_KEY_1024 = RSAPrivateNumbers( + p=int( "ea4d9d9a1a068be44b9a5f8f6de0512b2c5ba1fb804a4655babba688e6e890b347c1a" "7426685a929337f513ae4256f0b7e5022d642237f960c5b24b96bee8e51", 16), - "q": int( + q=int( "cffb33e400d6f08b410d69deb18a85cf0ed88fcca9f32d6f2f66c62143d49aff92c11" "4de937d4f1f62d4635ee89af99ce86d38a2b05310f3857c7b5d586ac8f9", 16), - "private_exponent": int( + d=int( "3d12d46d04ce942fb99be7bf30587b8cd3e21d75a2720e7bda1b867f1d418d91d8b9f" "e1c00181fdde94f2faf33b4e6f800a1b3ae3b972ccb6d5079dcb6c794070ac8306d59" "c00b58b7a9a81122a6b055832de7c72334a07494d8e7c9fbeed2cc37e011d9e6bfc6e" "9bcddbef7f0f5771d9cf82cd4b268c97ec684575c24b6c881", 16), - "dmp1": int( + dmp1=int( "470f2b11257b7ec9ca34136f487f939e6861920ad8a9ae132a02e74af5dceaa5b4c98" "2949ccb44b67e2bcad2f58674db237fe250e0d62b47b28fa1dfaa603b41", 16), - "dmq1": int( + dmq1=int( "c616e8317d6b3ae8272973709b80e8397256697ff14ea03389de454f619f99915a617" "45319fefbe154ec1d49441a772c2f63f7d15c478199afc60469bfd0d561", 16), - "iqmp": int( + iqmp=int( "d15e7c9ad357dfcd5dbdc8427680daf1006761bcfba93a7f86589ad88832a8d564b1c" "d4291a658c96fbaea7ca588795820902d85caebd49c2d731e3fe0243130", 16), - "public_exponent": 65537, - "modulus": int( - "be5aac07456d990133ebce69c06b48845b972ab1ad9f134bc5683c6b5489b5119ede0" - "7be3bed0e355d48e0dfab1e4fb5187adf42d7d3fb0401c082acb8481bf17f0e871f88" - "77be04c3a1197d40aa260e2e0c48ed3fd2b93dc3fc0867591f67f3cd60a77adee1d68" - "a8c3730a5702485f6ac9ede7f0fd2918e037ee4cc1fc1b4c9", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "be5aac07456d990133ebce69c06b48845b972ab1ad9f134bc5683c6b5489b5119" + "ede07be3bed0e355d48e0dfab1e4fb5187adf42d7d3fb0401c082acb8481bf17f" + "0e871f8877be04c3a1197d40aa260e2e0c48ed3fd2b93dc3fc0867591f67f3cd6" + "0a77adee1d68a8c3730a5702485f6ac9ede7f0fd2918e037ee4cc1fc1b4c9", + 16), + ) +) -RSA_KEY_1025 = { - "p": int( +RSA_KEY_1025 = RSAPrivateNumbers( + p=int( "18e9bfb7071725da04d31c103fa3563648c69def43a204989214eb57b0c8b299f9ef3" "5dda79a62d8d67fd2a9b69fbd8d0490aa2edc1e111a2b8eb7c737bb691a5", 16), - "q": int( + q=int( "d8eccaeeb95815f3079d13685f3f72ca2bf2550b349518049421375df88ca9bbb4ba8" "cb0e3502203c9eeae174112509153445d251313e4711a102818c66fcbb7", 16), - "private_exponent": int( + d=int( "fe9ac54910b8b1bc948a03511c54cab206a1d36d50d591124109a48abb7480977ccb0" "47b4d4f1ce7b0805df2d4fa3fe425f49b78535a11f4b87a4eba0638b3340c23d4e6b2" "1ecebe9d5364ea6ead2d47b27836019e6ecb407000a50dc95a8614c9d0031a6e3a524" "d2345cfb76e15c1f69d5ba35bdfb6ec63bcb115a757ef79d9", 16), - "dmp1": int( + dmp1=int( "18537e81006a68ea76d590cc88e73bd26bc38d09c977959748e5265c0ce21c0b5fd26" "53d975f97ef759b809f791487a8fff1264bf561627fb4527a3f0bbb72c85", 16), - "dmq1": int( + dmq1=int( "c807eac5a1f1e1239f04b04dd16eff9a00565127a91046fa89e1eb5d6301cace85447" "4d1f47b0332bd35b4214b66e9166953241538f761f30d969272ee214f17", 16), - "iqmp": int( + iqmp=int( "133aa74dd41fe70fa244f07d0c4091a22f8c8f0134fe6aea9ec8b55383b758fefe358" "2beec36eca91715eee7d21931f24fa9e97e8e3a50f9cd0f731574a5eafcc", 16), - "public_exponent": 65537, - "modulus": int( - "151c44fed756370fb2d4a0e6ec7dcac84068ca459b6aaf22daf902dca72c77563bf27" - "6fe3523f38f5ddaf3ea9aa88486a9d8760ff732489075862bee0e599de5c5f509b451" - "9f4f446521bad15cd279a498fe1e89107ce0d237e3103d7c5eb80166642e2924b152a" - "ebff97b71fdd2d68ebb45034cc784e2e822ff6d1edf98af3f3", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "151c44fed756370fb2d4a0e6ec7dcac84068ca459b6aaf22daf902dca72c77563" + "bf276fe3523f38f5ddaf3ea9aa88486a9d8760ff732489075862bee0e599de5c5" + "f509b4519f4f446521bad15cd279a498fe1e89107ce0d237e3103d7c5eb801666" + "42e2924b152aebff97b71fdd2d68ebb45034cc784e2e822ff6d1edf98af3f3", + 16), + ) +) -RSA_KEY_1026 = { - "p": int( +RSA_KEY_1026 = RSAPrivateNumbers( + p=int( "1fcbfb8719c5bdb5fe3eb0937c76bb096e750b9442dfe31d6a877a13aed2a6a4e9f79" "40f815f1c307dd6bc2b4b207bb6fe5be3a15bd2875a957492ce197cdedb1", 16), - "q": int( + q=int( "1f704a0f6b8966dd52582fdc08227dd3dbaeaa781918b41144b692711091b4ca4eb62" "985c3513853828ce8739001dfba9a9a7f1a23cbcaf74280be925e2e7b50d", 16), - "private_exponent": int( + d=int( "c67975e35a1d0d0b3ebfca736262cf91990cb31cf4ac473c0c816f3bc2720bcba2475" "e8d0de8535d257816c0fc53afc1b597eada8b229069d6ef2792fc23f59ffb4dc6c3d9" "0a3c462082025a4cba7561296dd3d8870c4440d779406f00879afe2c681e7f5ee055e" "ff829e6e55883ec20830c72300762e6e3a333d94b4dbe4501", 16), - "dmp1": int( + dmp1=int( "314730ca7066c55d086a9fbdf3670ef7cef816b9efea8b514b882ae9d647217cf41d7" "e9989269dc9893d02e315cb81f058c49043c2cac47adea58bdf5e20e841", 16), - "dmq1": int( + dmq1=int( "1da28a9d687ff7cfeebc2439240de7505a8796376968c8ec723a2b669af8ce53d9c88" "af18540bd78b2da429014923fa435f22697ac60812d7ca9c17a557f394cd", 16), - "iqmp": int( + iqmp=int( "727947b57b8a36acd85180522f1b381bce5fdbd962743b3b14af98a36771a80f58ddd" "62675d72a5935190da9ddc6fd6d6d5e9e9f805a2e92ab8d56b820493cdf", 16), - "public_exponent": 65537, - "modulus": int( - "3e7a5e6483e55eb8b723f9c46732d21b0af9e06a4a1099962d67a35ee3f62e3129cfa" - "e6ab0446da18e26f33e1d753bc1cc03585c100cf0ab5ef056695706fc8b0c9c710cd7" - "3fe6e5beda70f515a96fabd3cc5ac49efcb2594b220ff3b603fcd927f6a0838ef04bf" - "52f3ed9eab801f09e5aed1613ddeb946ed0fbb02060b3a36fd", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "3e7a5e6483e55eb8b723f9c46732d21b0af9e06a4a1099962d67a35ee3f62e312" + "9cfae6ab0446da18e26f33e1d753bc1cc03585c100cf0ab5ef056695706fc8b0c" + "9c710cd73fe6e5beda70f515a96fabd3cc5ac49efcb2594b220ff3b603fcd927f" + "6a0838ef04bf52f3ed9eab801f09e5aed1613ddeb946ed0fbb02060b3a36fd", + 16), + ) +) -RSA_KEY_1027 = { - "p": int( +RSA_KEY_1027 = RSAPrivateNumbers( + p=int( "30135e54cfb072c3d3eaf2000f3ed92ceafc85efc867b9d4bf5612f2978c432040093" "4829f741c0f002b54af2a4433ff872b6321ef00ff1e72cba4e0ced937c7d", 16), - "q": int( + q=int( "1d01a8aead6f86b78c875f18edd74214e06535d65da054aeb8e1851d6f3319b4fb6d8" "6b01e07d19f8261a1ded7dc08116345509ab9790e3f13e65c037e5bb7e27", 16), - "private_exponent": int( + d=int( "21cf4477df79561c7818731da9b9c88cd793f1b4b8e175bd0bfb9c0941a4dc648ecf1" "6d96b35166c9ea116f4c2eb33ce1c231e641a37c25e54c17027bdec08ddafcb83642e" "795a0dd133155ccc5eed03b6e745930d9ac7cfe91f9045149f33295af03a2198c660f" "08d8150d13ce0e2eb02f21ac75d63b55822f77bd5be8d07619", 16), - "dmp1": int( + dmp1=int( "173fb695931e845179511c18b546b265cb79b517c135902377281bdf9f34205e1f399" "4603ad63e9f6e7885ea73a929f03fa0d6bed943051ce76cddde2d89d434d", 16), - "dmq1": int( + dmq1=int( "10956b387b2621327da0c3c8ffea2af8be967ee25163222746c28115a406e632a7f12" "5a9397224f1fa5c116cd3a313e5c508d31db2deb83b6e082d213e33f7fcf", 16), - "iqmp": int( + iqmp=int( "234f833949f2c0d797bc6a0e906331e17394fa8fbc8449395766d3a8d222cf6167c48" "8e7fe1fe9721d3e3b699a595c8e6f063d92bd840dbc84d763b2b37002109", 16), - "public_exponent": 65537, - "modulus": int( - "57281707d7f9b1369c117911758980e32c05b133ac52c225bcf68b79157ff47ea0a5a" - "e9f579ef1fd7e42937f921eb3123c4a045cc47a2159fbbf904783e654954c42294c30" - "a95c15db7c7b91f136244e548f62474b137087346c5522e54f226f49d6c93bc58cb39" - "972e41bde452bb3ae9d60eb93e5e1ce91d222138d9890c7d0b", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "57281707d7f9b1369c117911758980e32c05b133ac52c225bcf68b79157ff47ea" + "0a5ae9f579ef1fd7e42937f921eb3123c4a045cc47a2159fbbf904783e654954c" + "42294c30a95c15db7c7b91f136244e548f62474b137087346c5522e54f226f49d" + "6c93bc58cb39972e41bde452bb3ae9d60eb93e5e1ce91d222138d9890c7d0b", + 16), + ) +) -RSA_KEY_1028 = { - "p": int( +RSA_KEY_1028 = RSAPrivateNumbers( + p=int( "359d17378fae8e9160097daee78a206bd52efe1b757c12a6da8026cc4fc4bb2620f12" "b8254f4db6aed8228be8ee3e5a27ec7d31048602f01edb00befd209e8c75", 16), - "q": int( + q=int( "33a2e70b93d397c46e63b273dcd3dcfa64291342a6ce896e1ec8f1c0edc44106550f3" "c06e7d3ca6ea29eccf3f6ab5ac6235c265313d6ea8e8767e6a343f616581", 16), - "private_exponent": int( + d=int( "880640088d331aa5c0f4cf2887809a420a2bc086e671e6ffe4e47a8c80792c038a314" "9a8e45ef9a72816ab45b36e3af6800351067a6b2751843d4232413146bb575491463a" "8addd06ce3d1bcf7028ec6c5d938c545a20f0a40214b5c574ca7e840062b2b5f8ed49" "4b144bb2113677c4b10519177fee1d4f5fb8a1c159b0b47c01", 16), - "dmp1": int( + dmp1=int( "75f8c52dad2c1cea26b8bba63236ee4059489e3d2db766136098bcc6b67fde8f77cd3" "640035107bfb1ffc6480983cfb84fe0c3be008424ebc968a7db7e01f005", 16), - "dmq1": int( + dmq1=int( "3893c59469e4ede5cd0e6ff9837ca023ba9b46ff40c60ccf1bec10f7d38db5b1ba817" "6c41a3f750ec4203b711455aca06d1e0adffc5cffa42bb92c7cb77a6c01", 16), - "iqmp": int( + iqmp=int( "ad32aafae3c962ac25459856dc8ef1f733c3df697eced29773677f435d186cf759d1a" "5563dd421ec47b4d7e7f12f29647c615166d9c43fc49001b29089344f65", 16), - "public_exponent": 65537, - "modulus": int( - "ad0696bef71597eb3a88e135d83c596930cac73868fbd7e6b2d64f34eea5c28cce351" - "0c68073954d3ba4deb38643e7a820a4cf06e75f7f82eca545d412bd63781945c28d40" - "6e95a6cced5ae924a8bfa4f3def3e0250d91246c269ec40c89c93a85acd3770ba4d2e" - "774732f43abe94394de43fb57f93ca25f7a59d75d400a3eff5", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "ad0696bef71597eb3a88e135d83c596930cac73868fbd7e6b2d64f34eea5c28cc" + "e3510c68073954d3ba4deb38643e7a820a4cf06e75f7f82eca545d412bd637819" + "45c28d406e95a6cced5ae924a8bfa4f3def3e0250d91246c269ec40c89c93a85a" + "cd3770ba4d2e774732f43abe94394de43fb57f93ca25f7a59d75d400a3eff5", + 16), + ) +) -RSA_KEY_1029 = { - "p": int( +RSA_KEY_1029 = RSAPrivateNumbers( + p=int( "66f33e513c0b6b6adbf041d037d9b1f0ebf8de52812a3ac397a963d3f71ba64b3ad04" "e4d4b5e377e6fa22febcac292c907dc8dcfe64c807fd9a7e3a698850d983", 16), - "q": int( + q=int( "3b47a89a19022461dcc2d3c05b501ee76955e8ce3cf821beb4afa85a21a26fd7203db" "deb8941f1c60ada39fd6799f6c07eb8554113f1020460ec40e93cd5f6b21", 16), - "private_exponent": int( + d=int( "280c42af8b1c719821f2f6e2bf5f3dd53c81b1f3e1e7cc4fce6e2f830132da0665bde" "bc1e307106b112b52ad5754867dddd028116cf4471bc14a58696b99524b1ad8f05b31" "cf47256e54ab4399b6a073b2c0452441438dfddf47f3334c13c5ec86ece4d33409056" "139328fafa992fb5f5156f25f9b21d3e1c37f156d963d97e41", 16), - "dmp1": int( + dmp1=int( "198c7402a4ec10944c50ab8488d7b5991c767e75eb2817bd427dff10335ae141fa2e8" "7c016dc22d975cac229b9ffdf7d943ddfd3a04b8bf82e83c3b32c5698b11", 16), - "dmq1": int( + dmq1=int( "15fd30c7687b68ef7c2a30cdeb913ec56c4757c218cf9a04d995470797ee5f3a17558" "fbb6d00af245d2631d893b382da48a72bc8a613024289895952ab245b0c1", 16), - "iqmp": int( + iqmp=int( "4f8fde17e84557a3f4e242d889e898545ab55a1a8e075c9bb0220173ccffe84659abe" "a235104f82e32750309389d4a52af57dbb6e48d831917b6efeb190176570", 16), - "public_exponent": 65537, - "modulus": int( - "17d6e0a09aa5b2d003e51f43b9c37ffde74688f5e3b709fd02ef375cb6b8d15e299a9" - "f74981c3eeaaf947d5c2d64a1a80f5c5108a49a715c3f7be95a016b8d3300965ead4a" - "4df76e642d761526803e9434d4ec61b10cb50526d4dcaef02593085ded8c331c1b27b" - "200a45628403065efcb2c0a0ca1f75d648d40a007fbfbf2cae3", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "17d6e0a09aa5b2d003e51f43b9c37ffde74688f5e3b709fd02ef375cb6b8d15e2" + "99a9f74981c3eeaaf947d5c2d64a1a80f5c5108a49a715c3f7be95a016b8d3300" + "965ead4a4df76e642d761526803e9434d4ec61b10cb50526d4dcaef02593085de" + "d8c331c1b27b200a45628403065efcb2c0a0ca1f75d648d40a007fbfbf2cae3", + 16), + ) +) -RSA_KEY_1030 = { - "p": int( +RSA_KEY_1030 = RSAPrivateNumbers( + p=int( "6f4ac8a8172ef1154cf7f80b5e91de723c35a4c512860bfdbafcc3b994a2384bf7796" "3a2dd0480c7e04d5d418629651a0de8979add6f47b23da14c27a682b69c9", 16), - "q": int( + q=int( "65a9f83e07dea5b633e036a9dccfb32c46bf53c81040a19c574c3680838fc6d28bde9" "55c0ff18b30481d4ab52a9f5e9f835459b1348bbb563ad90b15a682fadb3", 16), - "private_exponent": int( + d=int( "290db707b3e1a96445ae8ea93af55a9f211a54ebe52995c2eb28085d1e3f09c986e73" "a00010c8e4785786eaaa5c85b98444bd93b585d0c24363ccc22c482e150a3fd900176" "86968e4fa20423ae72823b0049defceccb39bb34aa4ef64e6b14463b76d6a871c859e" "37285455b94b8e1527d1525b1682ac6f7c8fd79d576c55318c1", 16), - "dmp1": int( + dmp1=int( "23f7fa84010225dea98297032dac5d45745a2e07976605681acfe87e0920a8ab3caf5" "9d9602f3d63dc0584f75161fd8fff20c626c21c5e02a85282276a74628a9", 16), - "dmq1": int( + dmq1=int( "18ebb657765464a8aa44bf019a882b72a2110a77934c54915f70e6375088b10331982" "962bce1c7edd8ef9d3d95aa2566d2a99da6ebab890b95375919408d00f33", 16), - "iqmp": int( + iqmp=int( "3d59d208743c74054151002d77dcdfc55af3d41357e89af88d7eef2767be54c290255" "9258d85cf2a1083c035a33e65a1ca46dc8b706847c1c6434cef7b71a9dae", 16), - "public_exponent": 65537, - "modulus": int( - "2c326574320818a6a8cb6b3328e2d6c1ba2a3f09b6eb2bc543c03ab18eb5efdaa8fcd" - "bb6b4e12168304f587999f9d96a421fc80cb933a490df85d25883e6a88750d6bd8b3d" - "4117251eee8f45e70e6daac7dbbd92a9103c623a09355cf00e3f16168e38b9c4cb5b3" - "68deabbed8df466bc6835eaba959bc1c2f4ec32a09840becc8b", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "2c326574320818a6a8cb6b3328e2d6c1ba2a3f09b6eb2bc543c03ab18eb5efdaa" + "8fcdbb6b4e12168304f587999f9d96a421fc80cb933a490df85d25883e6a88750" + "d6bd8b3d4117251eee8f45e70e6daac7dbbd92a9103c623a09355cf00e3f16168" + "e38b9c4cb5b368deabbed8df466bc6835eaba959bc1c2f4ec32a09840becc8b", + 16), + ) +) -RSA_KEY_1031 = { - "p": int( +RSA_KEY_1031 = RSAPrivateNumbers( + p=int( "c0958c08e50137db989fb7cc93abf1984543e2f955d4f43fb2967f40105e79274c852" "293fa06ce63ca8436155e475ed6d1f73fea4c8e2516cc79153e3dc83e897", 16), - "q": int( + q=int( "78cae354ea5d6862e5d71d20273b7cddb8cdfab25478fe865180676b04250685c4d03" "30c216574f7876a7b12dfe69f1661d3b0cea6c2c0dcfb84050f817afc28d", 16), - "private_exponent": int( + d=int( "1d55cc02b17a5d25bfb39f2bc58389004d0d7255051507f75ef347cdf5519d1a00f4b" "d235ce4171bfab7bdb7a6dcfae1cf41433fb7da5923cc84f15a675c0b83492c95dd99" "a9fc157aea352ffdcbb5d59dbc3662171d5838d69f130678ee27841a79ef64f679ce9" "3821fa69c03f502244c04b737edad8967def8022a144feaab29", 16), - "dmp1": int( + dmp1=int( "5b1c2504ec3a984f86b4414342b5bcf59a0754f13adf25b2a0edbc43f5ba8c3cc061d" "80b03e5866d059968f0d10a98deaeb4f7830436d76b22cf41f2914e13eff", 16), - "dmq1": int( + dmq1=int( "6c361e1819691ab5d67fb2a8f65c958d301cdf24d90617c68ec7005edfb4a7b638cde" "79d4b61cfba5c86e8c0ccf296bc7f611cb8d4ae0e072a0f68552ec2d5995", 16), - "iqmp": int( + iqmp=int( "b7d61945fdc8b92e075b15554bab507fa8a18edd0a18da373ec6c766c71eece61136a" "84b90b6d01741d40458bfad17a9bee9d4a8ed2f6e270782dc3bf5d58b56e", 16), - "public_exponent": 65537, - "modulus": int( - "5adebaa926ea11fb635879487fdd53dcfbb391a11ac7279bb3b4877c9b811370a9f73" - "da0690581691626d8a7cf5d972cced9c2091ccf999024b23b4e6dc6d99f80a454737d" - "ec0caffaebe4a3fac250ed02079267c8f39620b5ae3e125ca35338522dc9353ecac19" - "cb2fe3b9e3a9291619dbb1ea3a7c388e9ee6469fbf5fb22892b", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "5adebaa926ea11fb635879487fdd53dcfbb391a11ac7279bb3b4877c9b811370a" + "9f73da0690581691626d8a7cf5d972cced9c2091ccf999024b23b4e6dc6d99f80" + "a454737dec0caffaebe4a3fac250ed02079267c8f39620b5ae3e125ca35338522" + "dc9353ecac19cb2fe3b9e3a9291619dbb1ea3a7c388e9ee6469fbf5fb22892b", + 16), + ) +) -RSA_KEY_1536 = { - "p": int( +RSA_KEY_1536 = RSAPrivateNumbers( + p=int( "f1a65fa4e2aa6e7e2b560251e8a4cd65b625ad9f04f6571785782d1c213d91c961637" "0c572f2783caf2899f7fb690cf99a0184257fbd4b071b212c88fb348279a5387e61f1" "17e9c62980c45ea863fa9292087c0f66ecdcde6443d5a37268bf71", 16), - "q": int( + q=int( "e54c2cbc3839b1da6ae6fea45038d986d6f523a3ae76051ba20583aab711ea5965cf5" "3cf54128cc9573f7460bba0fd6758a57aaf240c391790fb38ab473d83ef735510c53d" "1d10c31782e8fd7da42615e33565745c30a5e6ceb2a3ae0666cc35", 16), - "private_exponent": int( + d=int( "7bcad87e23da2cb2a8c328883fabce06e1f8e9b776c8bf253ad9884e6200e3bd9bd3b" "a2cbe87d3854527bf005ba5d878c5b0fa20cfb0a2a42884ae95ca12bf7304285e9214" "5e992f7006c7c0ae839ad550da495b143bec0f4806c7f44caed45f3ccc6dc44cfaf30" "7abdb757e3d28e41c2d21366835c0a41e50a95af490ac03af061d2feb36ac0afb87be" "a13fb0f0c5a410727ebedb286c77f9469473fae27ef2c836da6071ef7efc1647f1233" "4009a89eecb09a8287abc8c2afd1ddd9a1b0641", 16), - "dmp1": int( + dmp1=int( "a845366cd6f9df1f34861bef7594ed025aa83a12759e245f58adaa9bdff9c3befb760" "75d3701e90038e888eec9bf092df63400152cb25fc07effc6c74c45f0654ccbde15cd" "90dd5504298a946fa5cf22a956072da27a6602e6c6e5c97f2db9c1", 16), - "dmq1": int( + dmq1=int( "28b0c1e78cdac03310717992d321a3888830ec6829978c048156152d805b4f8919c61" "70b5dd204e5ddf3c6c53bc6aff15d0bd09faff7f351b94abb9db980b31f150a6d7573" "08eb66938f89a5225cb4dd817a824c89e7a0293b58fc2eefb7e259", 16), - "iqmp": int( + iqmp=int( "6c1536c0e16e42a094b6caaf50231ba81916871497d73dcbbbd4bdeb9e60cae0413b3" "8143b5d680275b29ed7769fe5577e4f9b3647ddb064941120914526d64d80016d2eb7" "dc362da7c569623157f3d7cff8347f11494bf5c048d77e28d3f515", 16), - "public_exponent": 65537, - "modulus": int( - "d871bb2d27672e54fc62c4680148cbdf848438da804e2c48b5a9c9f9daf6cc6e8ea7d" - "2296f25064537a9a542aef3dd449ea75774238d4da02c353d1bee70013dccc248ceef" - "4050160705c188043c8559bf6dbfb6c4bb382eda4e9547575a8227d5b3c0a70883913" - "64cf9f018d8bea053b226ec65e8cdbeaf48a071d0074860a734b1cb7d2146d43014b2" - "0776dea42f7853a54690e6cbbf3331a9f43763cfe2a51c3293bea3b2eebec0d8e43eb" - "317a443afe541107d886e5243c096091543ae65", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "d871bb2d27672e54fc62c4680148cbdf848438da804e2c48b5a9c9f9daf6cc6e8" + "ea7d2296f25064537a9a542aef3dd449ea75774238d4da02c353d1bee70013dcc" + "c248ceef4050160705c188043c8559bf6dbfb6c4bb382eda4e9547575a8227d5b" + "3c0a7088391364cf9f018d8bea053b226ec65e8cdbeaf48a071d0074860a734b1" + "cb7d2146d43014b20776dea42f7853a54690e6cbbf3331a9f43763cfe2a51c329" + "3bea3b2eebec0d8e43eb317a443afe541107d886e5243c096091543ae65", 16), + ) +) -RSA_KEY_2048 = { - "p": int( +RSA_KEY_2048 = RSAPrivateNumbers( + p=int( "e14202e58c5f7446648d75e5dc465781f661f6b73000c080368afcfb21377f4ef19da" "845d4ef9bc6b151f6d9f34629103f2e57615f9ba0a3a2fbb035069e1d63b4bb0e78ad" "dad1ec3c6f87e25c877a1c4c1972098e09158ef7b9bc163852a18d44a70b7b31a03dc" "2614fd9ab7bf002cba79054544af3bfbdb6aed06c7b24e6ab", 16), - "q": int( + q=int( "dbe2bea1ff92599bd19f9d045d6ce62250c05cfeac5117f3cf3e626cb696e3d886379" "557d5a57b7476f9cf886accfd40508a805fe3b45a78e1a8a125e516cda91640ee6398" "ec5a39d3e6b177ef12ab00d07907a17640e4ca454fd8487da3c4ffa0d5c2a5edb1221" "1c8e33c7ee9fa6753771fd111ec04b8317f86693eb2928c89", 16), - "private_exponent": int( + d=int( "aef17f80f2653bc30539f26dd4c82ed6abc1d1b53bc0abcdbee47e9a8ab433abde865" "9fcfae1244d22de6ad333c95aee7d47f30b6815065ac3322744d3ea75058002cd1b29" "3141ee2a6dc682342432707080071bd2131d6262cab07871c28aa5238b87173fb78c3" @@ -465,29 +511,31 @@ RSA_KEY_2048 = { "8dddee611d5205392d8e8dd61a15bf44680972a87f040a611a149271eeb2573f8bf6f" "627dfa70e77def2ee6584914fa0290e041349ea0999cdff3e493365885b906cbcf195" "843345809a85098cca90fea014a21", 16), - "dmp1": int( + dmp1=int( "9ba56522ffcfa5244eae805c87cc0303461f82be29691b9a7c15a5a050df6c143c575" "7c288d3d7ab7f32c782e9d9fcddc10a604e6425c0e5d0e46069035d95a923646d276d" "d9d95b8696fa29ab0de18e53f6f119310f8dd9efca62f0679291166fed8cbd5f18fe1" "3a5f1ead1d71d8c90f40382818c18c8d069be793dbc094f69", 16), - "dmq1": int( + dmq1=int( "a8d4a0aaa2212ccc875796a81353da1fdf00d46676c88d2b96a4bfcdd924622d8e607" "f3ac1c01dda7ebfb0a97dd7875c2a7b2db6728fb827b89c519f5716fb3228f4121647" "04b30253c17de2289e9cce3343baa82eb404f789e094a094577a9b0c5314f1725fdf5" "8e87611ad20da331bd30b8aebc7dc97d0e9a9ba8579772c9", 16), - "iqmp": int( + iqmp=int( "17bd5ef638c49440d1853acb3fa63a5aca28cb7f94ed350db7001c8445da8943866a7" "0936e1ee2716c98b484e357cc054d82fbbd98d42f880695d38a1dd4eb096f629b9417" "aca47e6de5da9f34e60e8a0ffd7e35be74deeef67298d94b3e0db73fc4b7a4cb360c8" "9d2117a0bfd9434d37dc7c027d6b01e5295c875015510917d", 16), - "public_exponent": 65537, - "modulus": int( - "c17afc7e77474caa5aa83036158a3ffbf7b5216851ba2230e5d6abfcc1c6cfef59e92" - "3ea1330bc593b73802ab608a6e4a3306523a3116ba5aa3966145174e13b6c49e9b780" - "62e449d72efb10fd49e91fa08b96d051e782e9f5abc5b5a6f7984827adb8e73da00f2" - "2b2efdcdb76eab46edad98ed65662743fdc6c0e336a5d0cdbaa7dc29e53635e24c87a" - "5b2c4215968063cdeb68a972babbc1e3cff00fb9a80e372a4d0c2c920d1e8cee333ce" - "470dc2e8145adb05bf29aee1d24f141e8cc784989c587fc6fbacd979f3f2163c1d729" - "9b365bc72ffe2848e967aed1e48dcc515b3a50ed4de04fd053846ca10a223b10cc841" - "cc80fdebee44f3114c13e886af583", 16), -} + public_numbers=RSAPublicNumbers( + e=65537, + n=int( + "c17afc7e77474caa5aa83036158a3ffbf7b5216851ba2230e5d6abfcc1c6cfef5" + "9e923ea1330bc593b73802ab608a6e4a3306523a3116ba5aa3966145174e13b6c" + "49e9b78062e449d72efb10fd49e91fa08b96d051e782e9f5abc5b5a6f7984827a" + "db8e73da00f22b2efdcdb76eab46edad98ed65662743fdc6c0e336a5d0cdbaa7d" + "c29e53635e24c87a5b2c4215968063cdeb68a972babbc1e3cff00fb9a80e372a4" + "d0c2c920d1e8cee333ce470dc2e8145adb05bf29aee1d24f141e8cc784989c587" + "fc6fbacd979f3f2163c1d7299b365bc72ffe2848e967aed1e48dcc515b3a50ed4" + "de04fd053846ca10a223b10cc841cc80fdebee44f3114c13e886af583", 16), + ) +) diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index 53985fe2..1879f4fc 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -14,66 +14,286 @@ from __future__ import absolute_import, division, print_function +import itertools +import os + import pytest -from cryptography import utils -from cryptography.hazmat.primitives import interfaces +from cryptography import exceptions, utils +from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import ec +from ...utils import ( + der_encode_dsa_signature, load_fips_ecdsa_key_pair_vectors, + load_fips_ecdsa_signing_vectors, load_vectors_from_file, + raises_unsupported_algorithm +) + +_CURVE_TYPES = { + "secp192r1": ec.SECP192R1, + "secp224r1": ec.SECP224R1, + "secp256r1": ec.SECP256R1, + "secp384r1": ec.SECP384R1, + "secp521r1": ec.SECP521R1, + + "sect163k1": ec.SECT163K1, + "sect233k1": ec.SECT233K1, + "sect283k1": ec.SECT283K1, + "sect409k1": ec.SECT409K1, + "sect571k1": ec.SECT571K1, + + "sect163r2": ec.SECT163R2, + "sect233r1": ec.SECT233R1, + "sect283r1": ec.SECT283R1, + "sect409r1": ec.SECT409R1, + "sect571r1": ec.SECT571R1, +} + +_HASH_TYPES = { + "SHA-1": hashes.SHA1, + "SHA-224": hashes.SHA224, + "SHA-256": hashes.SHA256, + "SHA-384": hashes.SHA384, + "SHA-512": hashes.SHA512, +} + + +def _skip_ecdsa_vector(backend, curve_type, hash_type): + if not backend.elliptic_curve_signature_algorithm_supported( + ec.ECDSA(hash_type()), + curve_type() + ): + pytest.skip( + "ECDSA not supported with this hash {0} and curve {1}".format( + hash_type().name, curve_type().name + ) + ) + @utils.register_interface(interfaces.EllipticCurve) class DummyCurve(object): name = "dummy-curve" + key_size = 1 -class TestECC(object): - def test_ec_numbers(self): - numbers = ec.EllipticCurvePrivateNumbers( - 1, +@utils.register_interface(interfaces.EllipticCurveSignatureAlgorithm) +class DummySignatureAlgorithm(object): + pass + + +def test_ec_numbers(): + numbers = ec.EllipticCurvePrivateNumbers( + 1, + ec.EllipticCurvePublicNumbers( + 2, 3, DummyCurve() + ) + ) + + assert numbers.private_value == 1 + assert numbers.public_numbers.x == 2 + assert numbers.public_numbers.y == 3 + assert isinstance(numbers.public_numbers.curve, DummyCurve) + + with pytest.raises(TypeError): + ec.EllipticCurvePrivateNumbers( + None, ec.EllipticCurvePublicNumbers( 2, 3, DummyCurve() ) ) - assert numbers.private_value == 1 - assert numbers.public_numbers.x == 2 - assert numbers.public_numbers.y == 3 - assert isinstance(numbers.public_numbers.curve, DummyCurve) + with pytest.raises(TypeError): + ec.EllipticCurvePrivateNumbers( + 1, + ec.EllipticCurvePublicNumbers( + None, 3, DummyCurve() + ) + ) - with pytest.raises(TypeError): - ec.EllipticCurvePrivateNumbers( - None, - ec.EllipticCurvePublicNumbers( - 2, 3, DummyCurve() - ) + with pytest.raises(TypeError): + ec.EllipticCurvePrivateNumbers( + 1, + ec.EllipticCurvePublicNumbers( + 2, None, DummyCurve() ) + ) - with pytest.raises(TypeError): - ec.EllipticCurvePrivateNumbers( - 1, - ec.EllipticCurvePublicNumbers( - None, 3, DummyCurve() - ) + with pytest.raises(TypeError): + ec.EllipticCurvePrivateNumbers( + 1, + ec.EllipticCurvePublicNumbers( + 2, 3, None ) + ) - with pytest.raises(TypeError): - ec.EllipticCurvePrivateNumbers( - 1, - ec.EllipticCurvePublicNumbers( - 2, None, DummyCurve() - ) + with pytest.raises(TypeError): + ec.EllipticCurvePrivateNumbers( + 1, + None + ) + + +@pytest.mark.elliptic +class TestECDSAVectors(object): + @pytest.mark.parametrize( + ("vector", "hash_type"), + list(itertools.product( + load_vectors_from_file( + os.path.join( + "asymmetric", "ECDSA", "FIPS_186-3", "KeyPair.rsp"), + load_fips_ecdsa_key_pair_vectors + ), + _HASH_TYPES.values() + )) + ) + def test_signing_with_example_keys(self, backend, vector, hash_type): + curve_type = _CURVE_TYPES[vector['curve']] + + _skip_ecdsa_vector(backend, curve_type, hash_type) + + key = ec.EllipticCurvePrivateNumbers( + vector['d'], + ec.EllipticCurvePublicNumbers( + vector['x'], + vector['y'], + curve_type() ) + ).private_key(backend) + assert key + + pkey = key.public_key() + assert pkey - with pytest.raises(TypeError): - ec.EllipticCurvePrivateNumbers( - 1, - ec.EllipticCurvePublicNumbers( - 2, 3, None + signer = key.signer(ec.ECDSA(hash_type())) + signer.update(b"YELLOW SUBMARINE") + signature = signer.finalize() + + verifier = pkey.verifier(signature, ec.ECDSA(hash_type())) + verifier.update(b"YELLOW SUBMARINE") + verifier.verify() + + @pytest.mark.parametrize( + "curve", _CURVE_TYPES.values() + ) + def test_generate_vector_curves(self, backend, curve): + if not backend.elliptic_curve_supported(curve()): + pytest.skip( + "Curve {0} is not supported by this backend {1}".format( + curve().name, backend ) ) - with pytest.raises(TypeError): - ec.EllipticCurvePrivateNumbers( - 1, - None + key = ec.generate_private_key(curve(), backend) + assert key + assert isinstance(key.curve, curve) + assert key.curve.key_size + + pkey = key.public_key() + assert pkey + assert isinstance(pkey.curve, curve) + assert key.curve.key_size == pkey.curve.key_size + + def test_generate_unknown_curve(self, backend): + with raises_unsupported_algorithm( + exceptions._Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ): + ec.generate_private_key(DummyCurve(), backend) + + assert backend.elliptic_curve_signature_algorithm_supported( + ec.ECDSA(hashes.SHA256()), + DummyCurve() + ) is False + + def test_unknown_signature_algoritm(self, backend): + if not backend.elliptic_curve_supported(ec.SECP192R1()): + pytest.skip( + "Curve secp192r1 is not supported by this backend {0}".format( + backend + ) ) + + key = ec.generate_private_key(ec.SECP192R1(), backend) + + with raises_unsupported_algorithm( + exceptions._Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM + ): + key.signer(DummySignatureAlgorithm()) + + with raises_unsupported_algorithm( + exceptions._Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM + ): + key.public_key().verifier(b"", DummySignatureAlgorithm()) + + assert backend.elliptic_curve_signature_algorithm_supported( + DummySignatureAlgorithm(), + ec.SECP192R1() + ) is False + + @pytest.mark.parametrize( + "vector", + load_vectors_from_file( + os.path.join( + "asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt"), + load_fips_ecdsa_signing_vectors + ) + ) + def test_signatures(self, backend, vector): + hash_type = _HASH_TYPES[vector['digest_algorithm']] + curve_type = _CURVE_TYPES[vector['curve']] + + _skip_ecdsa_vector(backend, curve_type, hash_type) + + key = ec.EllipticCurvePublicNumbers( + vector['x'], + vector['y'], + curve_type() + ).public_key(backend) + + signature = der_encode_dsa_signature( + vector['r'], + vector['s'] + ) + + verifier = key.verifier( + signature, + ec.ECDSA(hash_type()) + ) + verifier.update(vector['message']) + assert verifier.verify() + + @pytest.mark.parametrize( + "vector", + load_vectors_from_file( + os.path.join( + "asymmetric", "ECDSA", "FIPS_186-3", "SigVer.rsp"), + load_fips_ecdsa_signing_vectors + ) + ) + def test_signature_failures(self, backend, vector): + hash_type = _HASH_TYPES[vector['digest_algorithm']] + curve_type = _CURVE_TYPES[vector['curve']] + + _skip_ecdsa_vector(backend, curve_type, hash_type) + + key = ec.EllipticCurvePublicNumbers( + vector['x'], + vector['y'], + curve_type() + ).public_key(backend) + + signature = der_encode_dsa_signature( + vector['r'], + vector['s'] + ) + + verifier = key.verifier( + signature, + ec.ECDSA(hash_type()) + ) + verifier.update(vector['message']) + + if vector["fail"] is True: + with pytest.raises(exceptions.InvalidSignature): + verifier.verify() + else: + verifier.verify() diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 4f917d66..8f10fb10 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -27,6 +27,9 @@ from cryptography.exceptions import ( ) from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import padding, rsa +from cryptography.hazmat.primitives.serialization import ( + load_rsa_private_numbers +) from .fixtures_rsa import ( RSA_KEY_1024, RSA_KEY_1025, RSA_KEY_1026, RSA_KEY_1027, RSA_KEY_1028, @@ -491,7 +494,7 @@ class TestRSASignature(object): skip_message="Does not support PSS." ) def test_deprecated_pss_mgf1_salt_length(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) signer = private_key.signer( pytest.deprecated_call( padding.PSS, @@ -537,7 +540,7 @@ class TestRSASignature(object): pytest.skip( "Does not support {0} in MGF1 using PSS.".format(hash_alg.name) ) - private_key = rsa.RSAPrivateKey(**RSA_KEY_768) + private_key = load_rsa_private_numbers(RSA_KEY_768, backend) public_key = private_key.public_key() pss = padding.PSS( mgf=padding.MGF1(hash_alg), @@ -572,7 +575,7 @@ class TestRSASignature(object): skip_message="Does not support SHA512." ) def test_pss_minimum_key_size_for_digest(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_522) + private_key = load_rsa_private_numbers(RSA_KEY_522, backend) signer = private_key.signer( padding.PSS( mgf=padding.MGF1(hashes.SHA1()), @@ -598,7 +601,7 @@ class TestRSASignature(object): skip_message="Does not support SHA512." ) def test_pss_signing_digest_too_large_for_key_size(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with pytest.raises(ValueError): private_key.signer( padding.PSS( @@ -619,7 +622,7 @@ class TestRSASignature(object): skip_message="Does not support PSS." ) def test_pss_signing_salt_length_too_long(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) signer = private_key.signer( padding.PSS( mgf=padding.MGF1(hashes.SHA1()), @@ -639,7 +642,7 @@ class TestRSASignature(object): skip_message="Does not support PKCS1v1.5." ) def test_use_after_finalize(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend) signer.update(b"sign me") signer.finalize() @@ -649,18 +652,18 @@ class TestRSASignature(object): signer.update(b"more data") def test_unsupported_padding(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): private_key.signer(DummyPadding(), hashes.SHA1(), backend) def test_padding_incorrect_type(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with pytest.raises(TypeError): private_key.signer("notpadding", hashes.SHA1(), backend) def test_rsa_signer_invalid_backend(self, backend): pretend_backend = object() - private_key = rsa.RSAPrivateKey(**RSA_KEY_2048) + private_key = load_rsa_private_numbers(RSA_KEY_2048, backend) with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE): private_key.signer( @@ -673,7 +676,7 @@ class TestRSASignature(object): skip_message="Does not support PSS." ) def test_unsupported_pss_mgf(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): private_key.signer(padding.PSS(mgf=DummyMGF()), hashes.SHA1(), backend) @@ -685,7 +688,7 @@ class TestRSASignature(object): skip_message="Does not support PKCS1v1.5." ) def test_pkcs1_digest_too_large_for_key_size(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_599) + private_key = load_rsa_private_numbers(RSA_KEY_599, backend) signer = private_key.signer( padding.PKCS1v15(), hashes.SHA512(), @@ -702,7 +705,7 @@ class TestRSASignature(object): skip_message="Does not support PKCS1v1.5." ) def test_pkcs1_minimum_key_size(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_745) + private_key = load_rsa_private_numbers(RSA_KEY_745, backend) signer = private_key.signer( padding.PKCS1v15(), hashes.SHA512(), @@ -750,7 +753,7 @@ class TestRSAVerification(object): skip_message="Does not support PKCS1v1.5." ) def test_invalid_pkcs1v15_signature_wrong_data(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) public_key = private_key.public_key() signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend) signer.update(b"sign me") @@ -772,8 +775,8 @@ class TestRSAVerification(object): skip_message="Does not support PKCS1v1.5." ) def test_invalid_pkcs1v15_signature_wrong_key(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) - private_key2 = rsa.RSAPrivateKey(**RSA_KEY_512_ALT) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) + private_key2 = load_rsa_private_numbers(RSA_KEY_512_ALT, backend) public_key = private_key2.public_key() signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend) signer.update(b"sign me") @@ -939,7 +942,7 @@ class TestRSAVerification(object): skip_message="Does not support PKCS1v1.5." ) def test_use_after_finalize(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) public_key = private_key.public_key() signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend) signer.update(b"sign me") @@ -959,13 +962,13 @@ class TestRSAVerification(object): verifier.update(b"more data") def test_unsupported_padding(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): public_key.verifier(b"sig", DummyPadding(), hashes.SHA1(), backend) def test_padding_incorrect_type(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) public_key = private_key.public_key() with pytest.raises(TypeError): public_key.verifier(b"sig", "notpadding", hashes.SHA1(), backend) @@ -986,7 +989,7 @@ class TestRSAVerification(object): skip_message="Does not support PSS." ) def test_unsupported_pss_mgf(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): public_key.verifier(b"sig", padding.PSS(mgf=DummyMGF()), @@ -1006,7 +1009,7 @@ class TestRSAVerification(object): skip_message="Does not support SHA512." ) def test_pss_verify_digest_too_large_for_key_size(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) signature = binascii.unhexlify( b"8b9a3ae9fb3b64158f3476dd8d8a1f1425444e98940e0926378baa9944d219d8" b"534c050ef6b19b1bdc6eb4da422e89161106a6f5b5cc16135b11eb6439b646bd" @@ -1408,7 +1411,7 @@ class TestRSADecryption(object): assert message == binascii.unhexlify(example["message"]) def test_unsupported_padding(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): private_key.decrypt(b"0" * 64, DummyPadding(), backend) @@ -1419,7 +1422,7 @@ class TestRSADecryption(object): skip_message="Does not support PKCS1v1.5." ) def test_decrypt_invalid_decrypt(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with pytest.raises(ValueError): private_key.decrypt( b"\x00" * 64, @@ -1434,7 +1437,7 @@ class TestRSADecryption(object): skip_message="Does not support PKCS1v1.5." ) def test_decrypt_ciphertext_too_large(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with pytest.raises(ValueError): private_key.decrypt( b"\x00" * 65, @@ -1449,7 +1452,7 @@ class TestRSADecryption(object): skip_message="Does not support PKCS1v1.5." ) def test_decrypt_ciphertext_too_small(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) ct = binascii.unhexlify( b"50b4c14136bd198c2f3c3ed243fce036e168d56517984a263cd66492b80804f1" b"69d210f2b9bdfb48b12f9ea05009c77da257cc600ccefe3a6283789d8ea0" @@ -1514,7 +1517,7 @@ class TestRSADecryption(object): assert message == binascii.unhexlify(example["message"]) def test_unsupported_oaep_mgf(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): private_key.decrypt( b"0" * 64, @@ -1555,7 +1558,7 @@ class TestRSAEncryption(object): ) ) def test_rsa_encrypt_oaep(self, key_data, pad, backend): - private_key = rsa.RSAPrivateKey(**key_data) + private_key = load_rsa_private_numbers(key_data, backend) pt = b"encrypt me!" public_key = private_key.public_key() ct = public_key.encrypt( @@ -1588,7 +1591,7 @@ class TestRSAEncryption(object): ) ) def test_rsa_encrypt_pkcs1v15(self, key_data, pad, backend): - private_key = rsa.RSAPrivateKey(**key_data) + private_key = load_rsa_private_numbers(key_data, backend) pt = b"encrypt me!" public_key = private_key.public_key() ct = public_key.encrypt( @@ -1622,7 +1625,7 @@ class TestRSAEncryption(object): ) ) def test_rsa_encrypt_key_too_small(self, key_data, pad, backend): - private_key = rsa.RSAPrivateKey(**key_data) + private_key = load_rsa_private_numbers(key_data, backend) public_key = private_key.public_key() # Slightly smaller than the key size but not enough for padding. with pytest.raises(ValueError): @@ -1653,14 +1656,14 @@ class TestRSAEncryption(object): ) def test_unsupported_padding(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING): public_key.encrypt(b"somedata", DummyPadding(), backend) def test_unsupported_oaep_mgf(self, backend): - private_key = rsa.RSAPrivateKey(**RSA_KEY_512) + private_key = load_rsa_private_numbers(RSA_KEY_512, backend) public_key = private_key.public_key() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF): diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index b19990e0..4aa9707f 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -23,9 +23,12 @@ from cryptography.exceptions import _Reasons from cryptography.hazmat.primitives.asymmetric import dsa, rsa from cryptography.hazmat.primitives.serialization import ( load_pem_pkcs8_private_key, - load_pem_traditional_openssl_private_key + load_pem_traditional_openssl_private_key, + load_rsa_private_numbers, + load_rsa_public_numbers ) +from .fixtures_rsa import RSA_KEY_1024 from .utils import _check_rsa_private_key, load_vectors_from_file from ...utils import raises_unsupported_algorithm @@ -544,3 +547,16 @@ class TestPKCS8Serialisation(object): pemfile.read().encode(), password, backend ) ) + + +@pytest.mark.rsa +class TestLoadRSANumbers(object): + def test_load_private_numbers(self, backend): + private_key = load_rsa_private_numbers(RSA_KEY_1024, backend) + assert private_key + + def test_load_public_numbers(self, backend): + public_key = load_rsa_public_numbers( + RSA_KEY_1024.public_numbers, backend + ) + assert public_key |