summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2014-09-24 11:45:41 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2014-09-27 09:42:03 -0500
commitc6323f16014748bcda0cc755af7dd2a0e8cc457e (patch)
treec6f58dc45bed979ccdc7bb3856a5b87ef2edec76
parente025be284e1a1d19e761b0fff907d126f17b4fb0 (diff)
downloadcryptography-c6323f16014748bcda0cc755af7dd2a0e8cc457e.tar.gz
Support EC WithNumbers on OpenSSL backend + tests
-rw-r--r--cryptography/hazmat/backends/openssl/ec.py59
-rw-r--r--tests/hazmat/primitives/test_ec.py36
2 files changed, 93 insertions, 2 deletions
diff --git a/cryptography/hazmat/backends/openssl/ec.py b/cryptography/hazmat/backends/openssl/ec.py
index 611dba2ca..879d674a7 100644
--- a/cryptography/hazmat/backends/openssl/ec.py
+++ b/cryptography/hazmat/backends/openssl/ec.py
@@ -129,7 +129,7 @@ class _ECDSAVerificationContext(object):
return True
-@utils.register_interface(interfaces.EllipticCurvePrivateKey)
+@utils.register_interface(interfaces.EllipticCurvePrivateKeyWithNumbers)
class _EllipticCurvePrivateKey(object):
def __init__(self, backend, ec_key_cdata, curve):
self._backend = backend
@@ -172,8 +172,16 @@ class _EllipticCurvePrivateKey(object):
self._backend, public_ec_key, self._curve
)
+ def private_numbers(self):
+ bn = self._backend._lib.EC_KEY_get0_private_key(self._ec_key)
+ private_value = self._backend._bn_to_int(bn)
+ return ec.EllipticCurvePrivateNumbers(
+ private_value=private_value,
+ public_numbers=self.public_key().public_numbers()
+ )
+
-@utils.register_interface(interfaces.EllipticCurvePublicKey)
+@utils.register_interface(interfaces.EllipticCurvePublicKeyWithNumbers)
class _EllipticCurvePublicKey(object):
def __init__(self, backend, ec_key_cdata, curve):
self._backend = backend
@@ -193,3 +201,50 @@ class _EllipticCurvePublicKey(object):
raise UnsupportedAlgorithm(
"Unsupported elliptic curve signature algorithm.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
+ def public_numbers(self):
+ bn_ctx = self._backend._lib.BN_CTX_new()
+ assert bn_ctx != self._backend._ffi.NULL
+ bn_ctx = self._backend._ffi.gc(bn_ctx, self._backend._lib.BN_CTX_free)
+
+ group = self._backend._lib.EC_KEY_get0_group(self._ec_key)
+ assert group != self._backend._ffi.NULL
+
+ method = self._backend._lib.EC_GROUP_method_of(group)
+ assert method != self._backend._ffi.NULL
+
+ nid = self._backend._lib.EC_METHOD_get_field_type(method)
+ assert nid != self._backend._lib.NID_undef
+
+ nid_two_field = self._backend._lib.OBJ_sn2nid(
+ b"characteristic-two-field"
+ )
+ assert nid_two_field != self._backend._lib.NID_undef
+
+ if nid == nid_two_field and self._backend._lib.Cryptography_HAS_EC2M:
+ get_func = self._backend._lib.EC_POINT_get_affine_coordinates_GF2m
+ else:
+ get_func = self._backend._lib.EC_POINT_get_affine_coordinates_GFp
+
+ point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key)
+ assert point != self._backend._ffi.NULL
+
+ try:
+ self._backend._lib.BN_CTX_start(bn_ctx)
+
+ bn_x = self._backend._lib.BN_CTX_get(bn_ctx)
+ bn_y = self._backend._lib.BN_CTX_get(bn_ctx)
+
+ res = get_func(group, point, bn_x, bn_y, bn_ctx)
+ assert res == 1
+
+ x = self._backend._bn_to_int(bn_x)
+ y = self._backend._bn_to_int(bn_y)
+ finally:
+ self._backend._lib.BN_CTX_end(bn_ctx)
+
+ return ec.EllipticCurvePublicNumbers(
+ x=x,
+ y=y,
+ curve=self._curve
+ )
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 65461f705..a2613db83 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -129,6 +129,42 @@ def test_ec_numbers():
@pytest.mark.elliptic
+class TestECWithNumbers(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_with_numbers(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
+
+ if isinstance(key, interfaces.EllipticCurvePrivateKeyWithNumbers):
+ priv_num = key.private_numbers()
+ assert priv_num.private_value == vector['d']
+ assert priv_num.public_numbers.x == vector['x']
+ assert priv_num.public_numbers.y == vector['y']
+ assert curve_type().name == priv_num.public_numbers.curve.name
+
+
+@pytest.mark.elliptic
class TestECDSAVectors(object):
@pytest.mark.parametrize(
("vector", "hash_type"),