From fb9410ddbaeb7e10343ff925bd505633e24c10c7 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 1 Mar 2015 16:05:58 -0600 Subject: add support for serialization of EC private keys --- tests/hazmat/primitives/test_ec.py | 164 ++++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) (limited to 'tests/hazmat/primitives/test_ec.py') diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index ea621ad6..f1c49cf7 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -10,8 +10,10 @@ import os import pytest from cryptography import exceptions, utils -from cryptography.hazmat.backends.interfaces import EllipticCurveBackend -from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.backends.interfaces import ( + EllipticCurveBackend, PEMSerializationBackend +) +from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric.utils import ( encode_rfc6979_signature @@ -31,6 +33,13 @@ _HASH_TYPES = { } +def _skip_if_no_serialization(key, backend): + if not isinstance(key, ec.EllipticCurvePrivateKeyWithSerialization): + pytest.skip( + "{0} does not support EC key serialization".format(backend) + ) + + def _skip_ecdsa_vector(backend, curve_type, hash_type): if not backend.elliptic_curve_signature_algorithm_supported( ec.ECDSA(hash_type()), @@ -63,12 +72,22 @@ class DummySignatureAlgorithm(object): algorithm = None +@utils.register_interface(serialization.KeySerializationEncryption) +class DummyKeyEncryption(object): + pass + + @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) def test_skip_curve_unsupported(backend): with pytest.raises(pytest.skip.Exception): _skip_curve_unsupported(backend, DummyCurve()) +def test_skip_no_serialization(): + with pytest.raises(pytest.skip.Exception): + _skip_if_no_serialization("fakebackend", "fakekey") + + def test_ec_numbers(): numbers = ec.EllipticCurvePrivateNumbers( 1, @@ -378,3 +397,144 @@ class TestECNumbersEquality(object): 1, ec.EllipticCurvePublicNumbers(1, 2, ec.SECP521R1()) ) assert priv != object() + + +@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) +@pytest.mark.requires_backend_interface(interface=PEMSerializationBackend) +class TestECSerialization(object): + @pytest.mark.parametrize( + ("fmt", "password"), + itertools.product( + [ + serialization.Format.TraditionalOpenSSL, + serialization.Format.PKCS8 + ], + [ + b"s", + b"longerpassword", + b"!*$&(@#$*&($T@%_somesymbols", + b"\x01" * 1000, + ] + ) + ) + def test_private_bytes_encrypted_pem(self, backend, fmt, password): + key_bytes = load_vectors_from_file( + os.path.join( + "asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: pemfile.read().encode() + ) + key = serialization.load_pem_private_key(key_bytes, None, backend) + _skip_if_no_serialization(key, backend) + serialized = key.private_bytes( + serialization.Encoding.PEM, + fmt, + serialization.BestAvailableEncryption(password) + ) + loaded_key = serialization.load_pem_private_key( + serialized, password, backend + ) + loaded_priv_num = loaded_key.private_numbers() + priv_num = key.private_numbers() + assert loaded_priv_num == priv_num + + @pytest.mark.parametrize( + "fmt", + [serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8], + ) + def test_private_bytes_unencrypted_pem(self, backend, fmt): + key_bytes = load_vectors_from_file( + os.path.join( + "asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: pemfile.read().encode() + ) + key = serialization.load_pem_private_key(key_bytes, None, backend) + _skip_if_no_serialization(key, backend) + serialized = key.private_bytes( + serialization.Encoding.PEM, + fmt, + serialization.NoEncryption() + ) + loaded_key = serialization.load_pem_private_key( + serialized, None, backend + ) + loaded_priv_num = loaded_key.private_numbers() + priv_num = key.private_numbers() + assert loaded_priv_num == priv_num + + def test_private_bytes_traditional_openssl_unencrypted_pem(self, backend): + key_bytes = load_vectors_from_file( + os.path.join( + "asymmetric", "PEM_Serialization", "ec_private_key.pem"), + lambda pemfile: pemfile.read().encode() + ) + key = serialization.load_pem_private_key(key_bytes, None, backend) + serialized = key.private_bytes( + serialization.Encoding.PEM, + serialization.Format.TraditionalOpenSSL, + serialization.NoEncryption() + ) + assert serialized == key_bytes + + def test_private_bytes_invalid_encoding(self, backend): + key = load_vectors_from_file( + os.path.join( + "asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: serialization.load_pem_private_key( + pemfile.read().encode(), None, backend + ) + ) + _skip_if_no_serialization(key, backend) + with pytest.raises(TypeError): + key.private_bytes( + "notencoding", + serialization.Format.PKCS8, + serialization.NoEncryption() + ) + + def test_private_bytes_invalid_format(self, backend): + key = load_vectors_from_file( + os.path.join( + "asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: serialization.load_pem_private_key( + pemfile.read().encode(), None, backend + ) + ) + _skip_if_no_serialization(key, backend) + with pytest.raises(TypeError): + key.private_bytes( + serialization.Encoding.PEM, + "invalidformat", + serialization.NoEncryption() + ) + + def test_private_bytes_invalid_encryption_algorithm(self, backend): + key = load_vectors_from_file( + os.path.join( + "asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: serialization.load_pem_private_key( + pemfile.read().encode(), None, backend + ) + ) + _skip_if_no_serialization(key, backend) + with pytest.raises(TypeError): + key.private_bytes( + serialization.Encoding.PEM, + serialization.Format.TraditionalOpenSSL, + "notanencalg" + ) + + def test_private_bytes_unsupported_encryption_type(self, backend): + key = load_vectors_from_file( + os.path.join( + "asymmetric", "PKCS8", "ec_private_key.pem"), + lambda pemfile: serialization.load_pem_private_key( + pemfile.read().encode(), None, backend + ) + ) + _skip_if_no_serialization(key, backend) + with pytest.raises(ValueError): + key.private_bytes( + serialization.Encoding.PEM, + serialization.Format.TraditionalOpenSSL, + DummyKeyEncryption() + ) -- cgit v1.2.3 From 61ecd279ac3247a925d614c55c1e73d2dd87ea94 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 1 Mar 2015 17:40:56 -0600 Subject: skip those tests if ec unsupported --- tests/hazmat/primitives/test_ec.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests/hazmat/primitives/test_ec.py') diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index f1c49cf7..e6cb6ce9 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -418,6 +418,7 @@ class TestECSerialization(object): ) ) def test_private_bytes_encrypted_pem(self, backend, fmt, password): + _skip_curve_unsupported(backend, ec.SECP256R1()) key_bytes = load_vectors_from_file( os.path.join( "asymmetric", "PKCS8", "ec_private_key.pem"), @@ -442,6 +443,7 @@ class TestECSerialization(object): [serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8], ) def test_private_bytes_unencrypted_pem(self, backend, fmt): + _skip_curve_unsupported(backend, ec.SECP256R1()) key_bytes = load_vectors_from_file( os.path.join( "asymmetric", "PKCS8", "ec_private_key.pem"), @@ -462,6 +464,7 @@ class TestECSerialization(object): assert loaded_priv_num == priv_num def test_private_bytes_traditional_openssl_unencrypted_pem(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) key_bytes = load_vectors_from_file( os.path.join( "asymmetric", "PEM_Serialization", "ec_private_key.pem"), @@ -476,6 +479,7 @@ class TestECSerialization(object): assert serialized == key_bytes def test_private_bytes_invalid_encoding(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) key = load_vectors_from_file( os.path.join( "asymmetric", "PKCS8", "ec_private_key.pem"), @@ -492,6 +496,7 @@ class TestECSerialization(object): ) def test_private_bytes_invalid_format(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) key = load_vectors_from_file( os.path.join( "asymmetric", "PKCS8", "ec_private_key.pem"), @@ -508,6 +513,7 @@ class TestECSerialization(object): ) def test_private_bytes_invalid_encryption_algorithm(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) key = load_vectors_from_file( os.path.join( "asymmetric", "PKCS8", "ec_private_key.pem"), @@ -524,6 +530,7 @@ class TestECSerialization(object): ) def test_private_bytes_unsupported_encryption_type(self, backend): + _skip_curve_unsupported(backend, ec.SECP256R1()) key = load_vectors_from_file( os.path.join( "asymmetric", "PKCS8", "ec_private_key.pem"), -- cgit v1.2.3 From f1c7b740324be18e0f67f095a81d6d8802498a2c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 1 Mar 2015 21:56:32 -0600 Subject: format to privateformat --- tests/hazmat/primitives/test_ec.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'tests/hazmat/primitives/test_ec.py') diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index e6cb6ce9..77ee38b4 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -406,8 +406,8 @@ class TestECSerialization(object): ("fmt", "password"), itertools.product( [ - serialization.Format.TraditionalOpenSSL, - serialization.Format.PKCS8 + serialization.PrivateFormat.TraditionalOpenSSL, + serialization.PrivateFormat.PKCS8 ], [ b"s", @@ -440,7 +440,10 @@ class TestECSerialization(object): @pytest.mark.parametrize( "fmt", - [serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8], + [ + serialization.PrivateFormat.TraditionalOpenSSL, + serialization.PrivateFormat.PKCS8 + ], ) def test_private_bytes_unencrypted_pem(self, backend, fmt): _skip_curve_unsupported(backend, ec.SECP256R1()) @@ -473,7 +476,7 @@ class TestECSerialization(object): key = serialization.load_pem_private_key(key_bytes, None, backend) serialized = key.private_bytes( serialization.Encoding.PEM, - serialization.Format.TraditionalOpenSSL, + serialization.PrivateFormat.TraditionalOpenSSL, serialization.NoEncryption() ) assert serialized == key_bytes @@ -491,7 +494,7 @@ class TestECSerialization(object): with pytest.raises(TypeError): key.private_bytes( "notencoding", - serialization.Format.PKCS8, + serialization.PrivateFormat.PKCS8, serialization.NoEncryption() ) @@ -525,7 +528,7 @@ class TestECSerialization(object): with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, - serialization.Format.TraditionalOpenSSL, + serialization.PrivateFormat.TraditionalOpenSSL, "notanencalg" ) @@ -542,6 +545,6 @@ class TestECSerialization(object): with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, - serialization.Format.TraditionalOpenSSL, + serialization.PrivateFormat.TraditionalOpenSSL, DummyKeyEncryption() ) -- cgit v1.2.3