aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAviv Palivoda <palaviv@gmail.com>2017-02-07 15:24:56 +0200
committerPaul Kehrer <paul.l.kehrer@gmail.com>2017-02-07 21:24:56 +0800
commit6723a12712836cae4908f2918e88a3db9b12fe1c (patch)
tree0b8326a903d00138b48c0685dfbd9a47e17f2fe4 /src
parent523b132b27905e79f393d9999ff232ab61500a9d (diff)
downloadcryptography-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.py28
-rw-r--r--src/cryptography/hazmat/backends/openssl/dh.py39
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
+ )