diff options
author | Aviv Palivoda <palaviv@gmail.com> | 2017-02-07 15:24:56 +0200 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2017-02-07 21:24:56 +0800 |
commit | 6723a12712836cae4908f2918e88a3db9b12fe1c (patch) | |
tree | 0b8326a903d00138b48c0685dfbd9a47e17f2fe4 /src | |
parent | 523b132b27905e79f393d9999ff232ab61500a9d (diff) | |
download | cryptography-6723a12712836cae4908f2918e88a3db9b12fe1c.tar.gz cryptography-6723a12712836cae4908f2918e88a3db9b12fe1c.tar.bz2 cryptography-6723a12712836cae4908f2918e88a3db9b12fe1c.zip |
DH serialization (#3297)
* DH keys support serialization
* Add DH serialization documentation
* Add tests for DH keys serialization in DER encoding
* update version to 1.8
* Allow only SubjectPublicKeyInfo serialization
* Remove support in TraditionalOpenSSL format
* Fix pep8
* Refactor dh serialization tests
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 28 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/dh.py | 39 |
2 files changed, 60 insertions, 7 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 3f44d7f8..e460ab51 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -522,6 +522,11 @@ class Backend(object): self.openssl_assert(ec_cdata != self._ffi.NULL) ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) + elif key_type == self._lib.EVP_PKEY_DH: + dh_cdata = self._lib.EVP_PKEY_get1_DH(evp_pkey) + self.openssl_assert(dh_cdata != self._ffi.NULL) + dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) + return _DHPrivateKey(self, dh_cdata, evp_pkey) else: raise UnsupportedAlgorithm("Unsupported key type.") @@ -549,6 +554,11 @@ class Backend(object): self.openssl_assert(ec_cdata != self._ffi.NULL) ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) + elif key_type == self._lib.EVP_PKEY_DH: + dh_cdata = self._lib.EVP_PKEY_get1_DH(evp_pkey) + self.openssl_assert(dh_cdata != self._ffi.NULL) + dh_cdata = self._ffi.gc(dh_cdata, self._lib.DH_free) + return _DHPublicKey(self, dh_cdata, evp_pkey) else: raise UnsupportedAlgorithm("Unsupported key type.") @@ -1730,6 +1740,12 @@ class Backend(object): return _DHParameters(self, dh_param_cdata) + def _dh_cdata_to_evp_pkey(self, dh_cdata): + evp_pkey = self._create_evp_pkey_gc() + res = self._lib.EVP_PKEY_set1_DH(evp_pkey, dh_cdata) + self.openssl_assert(res == 1) + return evp_pkey + def generate_dh_private_key(self, parameters): dh_key_cdata = self._lib.DHparams_dup(parameters._dh_cdata) self.openssl_assert(dh_key_cdata != self._ffi.NULL) @@ -1738,7 +1754,9 @@ class Backend(object): res = self._lib.DH_generate_key(dh_key_cdata) self.openssl_assert(res == 1) - return _DHPrivateKey(self, dh_key_cdata) + evp_pkey = self._dh_cdata_to_evp_pkey(dh_key_cdata) + + return _DHPrivateKey(self, dh_key_cdata, evp_pkey) def generate_dh_private_key_and_parameters(self, generator, key_size): return self.generate_dh_private_key( @@ -1769,7 +1787,9 @@ class Backend(object): if codes[0] != 0: raise ValueError("DH private numbers did not pass safety checks.") - return _DHPrivateKey(self, dh_cdata) + evp_pkey = self._dh_cdata_to_evp_pkey(dh_cdata) + + return _DHPrivateKey(self, dh_cdata, evp_pkey) def load_dh_public_numbers(self, numbers): dh_cdata = self._lib.DH_new() @@ -1788,7 +1808,9 @@ class Backend(object): res = self._lib.DH_set0_key(dh_cdata, pub_key, self._ffi.NULL) self.openssl_assert(res == 1) - return _DHPublicKey(self, dh_cdata) + evp_pkey = self._dh_cdata_to_evp_pkey(dh_cdata) + + return _DHPublicKey(self, dh_cdata, evp_pkey) def load_dh_parameter_numbers(self, numbers): dh_cdata = self._lib.DH_new() diff --git a/src/cryptography/hazmat/backends/openssl/dh.py b/src/cryptography/hazmat/backends/openssl/dh.py index 666429f2..b594d411 100644 --- a/src/cryptography/hazmat/backends/openssl/dh.py +++ b/src/cryptography/hazmat/backends/openssl/dh.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function from cryptography import utils +from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import dh @@ -64,9 +65,10 @@ def _get_dh_num_bits(backend, dh_cdata): @utils.register_interface(dh.DHPrivateKeyWithSerialization) class _DHPrivateKey(object): - def __init__(self, backend, dh_cdata): + def __init__(self, backend, dh_cdata, evp_pkey): self._backend = backend self._dh_cdata = dh_cdata + self._evp_pkey = evp_pkey self._key_size_bytes = self._backend._lib.DH_size(dh_cdata) @property @@ -141,18 +143,32 @@ class _DHPrivateKey(object): pub_key_dup, self._backend._ffi.NULL) self._backend.openssl_assert(res == 1) - - return _DHPublicKey(self._backend, dh_cdata) + evp_pkey = self._backend._dh_cdata_to_evp_pkey(dh_cdata) + return _DHPublicKey(self._backend, dh_cdata, evp_pkey) def parameters(self): return _dh_cdata_to_parameters(self._dh_cdata, self._backend) + def private_bytes(self, encoding, format, encryption_algorithm): + if format is not serialization.PrivateFormat.PKCS8: + raise ValueError( + "DH private keys support only PKCS8 serialization" + ) + return self._backend._private_key_bytes( + encoding, + format, + encryption_algorithm, + self._evp_pkey, + self._dh_cdata + ) + @utils.register_interface(dh.DHPublicKeyWithSerialization) class _DHPublicKey(object): - def __init__(self, backend, dh_cdata): + def __init__(self, backend, dh_cdata, evp_pkey): self._backend = backend self._dh_cdata = dh_cdata + self._evp_pkey = evp_pkey self._key_size_bits = _get_dh_num_bits(self._backend, self._dh_cdata) @property @@ -180,3 +196,18 @@ class _DHPublicKey(object): def parameters(self): return _dh_cdata_to_parameters(self._dh_cdata, self._backend) + + def public_bytes(self, encoding, format): + if format is not serialization.PublicFormat.SubjectPublicKeyInfo: + raise ValueError( + "DH public keys support only " + "SubjectPublicKeyInfo serialization" + ) + + return self._backend._public_key_bytes( + encoding, + format, + self, + self._evp_pkey, + None + ) |