aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-03-14 13:15:17 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-03-14 13:18:10 -0500
commit919a5b2af627a18c0298db8a4ac11d8b2b6da7b9 (patch)
tree25f45d4e19aaf8fd134329920e0063c6773abb4f
parent939af10558eccce22e72fafceb7eb4f32d8cea2f (diff)
downloadcryptography-919a5b2af627a18c0298db8a4ac11d8b2b6da7b9.tar.gz
cryptography-919a5b2af627a18c0298db8a4ac11d8b2b6da7b9.tar.bz2
cryptography-919a5b2af627a18c0298db8a4ac11d8b2b6da7b9.zip
DER serialization of DSA private keys
-rw-r--r--CHANGELOG.rst6
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py6
-rw-r--r--tests/hazmat/backends/test_openssl.py16
-rw-r--r--tests/hazmat/primitives/test_dsa.py110
4 files changed, 94 insertions, 44 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 9e19186a..e3352f57 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -12,6 +12,12 @@ Changelog
:class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKeyWithSerialization`,
and
:class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKeyWithSerialization`.
+* Support :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`
+ serialization of private keys using the ``private_bytes`` method of
+ :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization`,
+ :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKeyWithSerialization`,
+ and
+ :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKeyWithSerialization`.
0.8 - 2015-03-08
~~~~~~~~~~~~~~~~
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 13699558..59503bd9 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -1210,10 +1210,8 @@ class Backend(object):
elif (self._lib.Cryptography_HAS_EC == 1 and
type == self._lib.EVP_PKEY_EC):
write_bio = self._lib.i2d_ECPrivateKey_bio
- else:
- raise TypeError(
- "Only RSA & EC keys are supported for DER serialization"
- )
+ elif type == self._lib.EVP_PKEY_DSA:
+ write_bio = self._lib.i2d_DSAPrivateKey_bio
bio = self._create_mem_bio()
res = write_bio(bio, cdata)
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 410d3d2a..6ce89d65 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -507,19 +507,3 @@ class TestRSAPEMSerialization(object):
serialization.PrivateFormat.PKCS8,
serialization.BestAvailableEncryption(password)
)
-
-
-@pytest.mark.requires_backend_interface(interface=DSABackend)
-class TestDSADERSerialization(object):
- def test_unsupported_private_key_encoding(self):
- key_bytes = load_vectors_from_file(
- os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pem"),
- lambda pemfile: pemfile.read().encode()
- )
- key = serialization.load_pem_private_key(key_bytes, None, backend)
- with pytest.raises(TypeError):
- key.private_bytes(
- serialization.Encoding.DER,
- serialization.PrivateFormat.TraditionalOpenSSL,
- serialization.NoEncryption()
- )
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 5f53c36c..5c83d5c7 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -833,53 +833,115 @@ class TestDSASerialization(object):
assert loaded_priv_num == priv_num
@pytest.mark.parametrize(
- "fmt",
+ ("fmt", "password"),
[
- serialization.PrivateFormat.TraditionalOpenSSL,
- serialization.PrivateFormat.PKCS8
- ],
+ [serialization.PrivateFormat.PKCS8, b"s"],
+ [serialization.PrivateFormat.PKCS8, b"longerpassword"],
+ [serialization.PrivateFormat.PKCS8, b"!*$&(@#$*&($T@%_somesymbol"],
+ [serialization.PrivateFormat.PKCS8, b"\x01" * 1000]
+ ]
)
- def test_private_bytes_unencrypted_pem(self, backend, fmt):
+ def test_private_bytes_encrypted_der(self, backend, fmt, password):
key_bytes = load_vectors_from_file(
- os.path.join(
- "asymmetric",
- "Traditional_OpenSSL_Serialization",
- "dsa.1024.pem"
- ),
+ os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.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,
+ serialization.Encoding.DER,
fmt,
- serialization.NoEncryption()
+ serialization.BestAvailableEncryption(password)
)
- loaded_key = serialization.load_pem_private_key(
- serialized, None, backend
+ loaded_key = serialization.load_der_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(
+ ("encoding", "fmt", "loader_func"),
+ [
+ [
+ serialization.Encoding.PEM,
+ serialization.PrivateFormat.TraditionalOpenSSL,
+ serialization.load_pem_private_key
+ ],
+ [
+ serialization.Encoding.DER,
+ serialization.PrivateFormat.TraditionalOpenSSL,
+ serialization.load_der_private_key
+ ],
+ [
+ serialization.Encoding.PEM,
+ serialization.PrivateFormat.PKCS8,
+ serialization.load_pem_private_key
+ ],
+ [
+ serialization.Encoding.DER,
+ serialization.PrivateFormat.PKCS8,
+ serialization.load_der_private_key
+ ],
+ ]
+ )
+ def test_private_bytes_unencrypted(self, backend, encoding, fmt,
+ loader_func):
+ key = DSA_KEY_1024.private_key(backend)
+ _skip_if_no_serialization(key, backend)
+ serialized = key.private_bytes(
+ encoding, fmt, serialization.NoEncryption()
)
+ loaded_key = loader_func(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):
+ @pytest.mark.parametrize(
+ ("key_path", "encoding", "loader_func"),
+ [
+ [
+ os.path.join(
+ "asymmetric",
+ "Traditional_OpenSSL_Serialization",
+ "dsa.1024.pem"
+ ),
+ serialization.Encoding.PEM,
+ serialization.load_pem_private_key
+ ],
+ [
+ os.path.join(
+ "asymmetric", "DER_Serialization", "dsa.1024.der"
+ ),
+ serialization.Encoding.DER,
+ serialization.load_der_private_key
+ ],
+ ]
+ )
+ def test_private_bytes_traditional_openssl_unencrypted(
+ self, backend, key_path, encoding, loader_func
+ ):
key_bytes = load_vectors_from_file(
- os.path.join(
- "asymmetric",
- "Traditional_OpenSSL_Serialization",
- "dsa.1024.pem"
- ),
- lambda pemfile: pemfile.read().encode()
+ key_path, lambda pemfile: pemfile.read(), mode="rb"
)
- key = serialization.load_pem_private_key(key_bytes, None, backend)
- _skip_if_no_serialization(key, backend)
+ key = loader_func(key_bytes, None, backend)
serialized = key.private_bytes(
- serialization.Encoding.PEM,
+ encoding,
serialization.PrivateFormat.TraditionalOpenSSL,
serialization.NoEncryption()
)
assert serialized == key_bytes
+ def test_private_bytes_traditional_der_encrypted_invalid(self, backend):
+ key = DSA_KEY_1024.private_key(backend)
+ _skip_if_no_serialization(key, backend)
+ with pytest.raises(ValueError):
+ key.private_bytes(
+ serialization.Encoding.DER,
+ serialization.PrivateFormat.TraditionalOpenSSL,
+ serialization.BestAvailableEncryption(b"password")
+ )
+
def test_private_bytes_invalid_encoding(self, backend):
key = load_vectors_from_file(
os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pem"),