diff options
4 files changed, 37 insertions, 9 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index dd50fd3b..0b129d1a 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -501,6 +501,12 @@ class Backend(object): assert dsa_cdata != self._ffi.NULL dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) return _DSAPublicKey(self, dsa_cdata) + elif self._lib.Cryptography_HAS_EC == 1 \ + and type == self._lib.EVP_PKEY_EC: + ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) + assert ec_cdata != self._ffi.NULL + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + return _EllipticCurvePublicKey(self, ec_cdata, None) else: raise UnsupportedAlgorithm("Unsupported key type.") diff --git a/cryptography/hazmat/backends/openssl/ec.py b/cryptography/hazmat/backends/openssl/ec.py index b7cd9802..51fc8f4b 100644 --- a/cryptography/hazmat/backends/openssl/ec.py +++ b/cryptography/hazmat/backends/openssl/ec.py @@ -24,6 +24,13 @@ from cryptography.hazmat.primitives.asymmetric import ec def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend): + """ + This function truncates digests that are longer than a given elliptic + curve key's length so they can be signed. Since elliptic curve keys are + much shorter than RSA keys many digests (e.g. SHA-512) may require + truncation. + """ + _lib = backend._lib _ffi = backend._ffi @@ -31,17 +38,14 @@ def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend): 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 + with backend._bn_ctx_manager() as bn_ctx: + order = _lib.BN_CTX_get(bn_ctx) + assert order != _ffi.NULL - res = _lib.EC_GROUP_get_order(group, order, bn_ctx) - assert res == 1 + res = _lib.EC_GROUP_get_order(group, order, bn_ctx) + assert res == 1 - order_bits = _lib.BN_num_bits(order) + order_bits = _lib.BN_num_bits(order) if 8 * digest_len > order_bits: digest_len = (order_bits + 7) // 8 diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 7cbd3f71..8405f4b2 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -122,6 +122,20 @@ class TestPEMSerialization(object): assert key assert isinstance(key, interfaces.DSAPublicKey) + @pytest.mark.elliptic + def test_load_ec_public_key(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) + key = load_vectors_from_file( + os.path.join( + "asymmetric", "PEM_Serialization", + "ec_public_key.pem"), + lambda pemfile: load_pem_public_key( + pemfile.read().encode(), backend + ) + ) + assert key + assert isinstance(key, interfaces.EllipticCurvePublicKey) + @pytest.mark.traditional_openssl_serialization class TestTraditionalOpenSSLSerialization(object): diff --git a/vectors/cryptography_vectors/asymmetric/PEM_Serialization/ec_public_key.pem b/vectors/cryptography_vectors/asymmetric/PEM_Serialization/ec_public_key.pem new file mode 100644 index 00000000..6be3d673 --- /dev/null +++ b/vectors/cryptography_vectors/asymmetric/PEM_Serialization/ec_public_key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJLzzbuz2tRnLFlOL+6bTX6giVavA +sc6NDFFT0IMCd2ibTTNUDDkFGsgq0cH5JYPg/6xUlMBFKrWYe3yQ4has9w== +-----END PUBLIC KEY----- |