diff options
-rw-r--r-- | src/_cffi_src/openssl/evp.py | 16 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 41 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/x509.py | 8 | ||||
-rw-r--r-- | tests/hazmat/backends/test_openssl.py | 4 |
4 files changed, 38 insertions, 31 deletions
diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py index 6d17cb7c..1d37b814 100644 --- a/src/_cffi_src/openssl/evp.py +++ b/src/_cffi_src/openssl/evp.py @@ -21,10 +21,7 @@ typedef struct env_md_ctx_st { ...; } EVP_MD_CTX; -typedef struct evp_pkey_st { - int type; - ...; -} EVP_PKEY; +typedef ... EVP_PKEY; typedef ... EVP_PKEY_CTX; static const int EVP_PKEY_RSA; static const int EVP_PKEY_DSA; @@ -122,6 +119,8 @@ int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *, const char *, int, int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *); EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *); + +int Cryptography_EVP_PKEY_id(const EVP_PKEY *); """ MACROS = """ @@ -230,4 +229,13 @@ int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL; EC_KEY *(*EVP_PKEY_get1_EC_KEY)(EVP_PKEY *) = NULL; int (*EVP_PKEY_set1_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL; #endif +/* EVP_PKEY_id is not available on 0.9.8 so we'll define our own. This can + be removed when we remove 0.9.8 support. */ +int Cryptography_EVP_PKEY_id(const EVP_PKEY *key) { + #if OPENSSL_VERSION_NUMBER >= 0x10000000L + return EVP_PKEY_id(key); + #else + return key->type; + #endif +} """ diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 9dfe2d4f..c21d5427 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1036,10 +1036,14 @@ class Backend(object): return _RSAPublicKey(self, rsa_cdata, evp_pkey) - def _rsa_cdata_to_evp_pkey(self, rsa_cdata): + def _create_evp_pkey_gc(self): evp_pkey = self._lib.EVP_PKEY_new() self.openssl_assert(evp_pkey != self._ffi.NULL) evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + return evp_pkey + + def _rsa_cdata_to_evp_pkey(self, rsa_cdata): + evp_pkey = self._create_evp_pkey_gc() res = self._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata) self.openssl_assert(res == 1) return evp_pkey @@ -1059,7 +1063,7 @@ class Backend(object): return _MemoryBIO(self._ffi.gc(bio, self._lib.BIO_free), data_char_p) - def _create_mem_bio(self): + def _create_mem_bio_gc(self): """ Creates an empty memory BIO. """ @@ -1087,7 +1091,7 @@ class Backend(object): pointer. """ - key_type = evp_pkey.type + key_type = self._lib.Cryptography_EVP_PKEY_id(evp_pkey) if key_type == self._lib.EVP_PKEY_RSA: rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) @@ -1114,7 +1118,7 @@ class Backend(object): pointer. """ - key_type = evp_pkey.type + key_type = self._lib.Cryptography_EVP_PKEY_id(evp_pkey) if key_type == self._lib.EVP_PKEY_RSA: rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) @@ -1257,9 +1261,7 @@ class Backend(object): return _DSAParameters(self, dsa_cdata) def _dsa_cdata_to_evp_pkey(self, dsa_cdata): - evp_pkey = self._lib.EVP_PKEY_new() - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + evp_pkey = self._create_evp_pkey_gc() res = self._lib.EVP_PKEY_set1_DSA(evp_pkey, dsa_cdata) self.openssl_assert(res == 1) return evp_pkey @@ -1984,9 +1986,7 @@ class Backend(object): ) def _ec_cdata_to_evp_pkey(self, ec_cdata): - evp_pkey = self._lib.EVP_PKEY_new() - self.openssl_assert(evp_pkey != self._ffi.NULL) - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + evp_pkey = self._create_evp_pkey_gc() res = self._lib.EVP_PKEY_set1_EC_KEY(evp_pkey, ec_cdata) self.openssl_assert(res == 1) return evp_pkey @@ -2140,19 +2140,20 @@ class Backend(object): else: raise ValueError("Unsupported encryption type") + key_type = self._lib.Cryptography_EVP_PKEY_id(evp_pkey) if encoding is serialization.Encoding.PEM: if format is serialization.PrivateFormat.PKCS8: write_bio = self._lib.PEM_write_bio_PKCS8PrivateKey key = evp_pkey else: assert format is serialization.PrivateFormat.TraditionalOpenSSL - if evp_pkey.type == self._lib.EVP_PKEY_RSA: + if key_type == self._lib.EVP_PKEY_RSA: write_bio = self._lib.PEM_write_bio_RSAPrivateKey - elif evp_pkey.type == self._lib.EVP_PKEY_DSA: + elif key_type == self._lib.EVP_PKEY_DSA: write_bio = self._lib.PEM_write_bio_DSAPrivateKey else: assert self._lib.Cryptography_HAS_EC == 1 - assert evp_pkey.type == self._lib.EVP_PKEY_EC + assert key_type == self._lib.EVP_PKEY_EC write_bio = self._lib.PEM_write_bio_ECPrivateKey key = cdata @@ -2166,9 +2167,7 @@ class Backend(object): "traditional OpenSSL keys" ) - return self._private_key_bytes_traditional_der( - evp_pkey.type, cdata - ) + return self._private_key_bytes_traditional_der(key_type, cdata) else: assert format is serialization.PrivateFormat.PKCS8 write_bio = self._lib.i2d_PKCS8PrivateKey_bio @@ -2176,7 +2175,7 @@ class Backend(object): else: raise TypeError("encoding must be an item from the Encoding enum") - bio = self._create_mem_bio() + bio = self._create_mem_bio_gc() res = write_bio( bio, key, @@ -2199,7 +2198,7 @@ class Backend(object): self.openssl_assert(key_type == self._lib.EVP_PKEY_DSA) write_bio = self._lib.i2d_DSAPrivateKey_bio - bio = self._create_mem_bio() + bio = self._create_mem_bio_gc() res = write_bio(bio, cdata) self.openssl_assert(res == 1) return self._read_mem_bio(bio) @@ -2218,7 +2217,9 @@ class Backend(object): key = evp_pkey elif format is serialization.PublicFormat.PKCS1: # Only RSA is supported here. - assert evp_pkey.type == self._lib.EVP_PKEY_RSA + assert self._lib.Cryptography_EVP_PKEY_id( + evp_pkey + ) == self._lib.EVP_PKEY_RSA if encoding is serialization.Encoding.PEM: write_bio = self._lib.PEM_write_bio_RSAPublicKey else: @@ -2231,7 +2232,7 @@ class Backend(object): "format must be an item from the PublicFormat enum" ) - bio = self._create_mem_bio() + bio = self._create_mem_bio_gc() res = write_bio(bio, key) self.openssl_assert(res == 1) return self._read_mem_bio(bio) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index b8614e0b..76920867 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -353,7 +353,7 @@ class _Certificate(object): return self._backend._ffi.buffer(pp[0], res)[:] def public_bytes(self, encoding): - bio = self._backend._create_mem_bio() + bio = self._backend._create_mem_bio_gc() if encoding is serialization.Encoding.PEM: res = self._backend._lib.PEM_write_bio_X509(bio, self._x509) elif encoding is serialization.Encoding.DER: @@ -827,7 +827,7 @@ class _CertificateRevocationList(object): def fingerprint(self, algorithm): h = hashes.Hash(algorithm, self._backend) - bio = self._backend._create_mem_bio() + bio = self._backend._create_mem_bio_gc() res = self._backend._lib.i2d_X509_CRL_bio( bio, self._x509_crl ) @@ -880,7 +880,7 @@ class _CertificateRevocationList(object): return self._backend._ffi.buffer(pp[0], res)[:] def public_bytes(self, encoding): - bio = self._backend._create_mem_bio() + bio = self._backend._create_mem_bio_gc() if encoding is serialization.Encoding.PEM: res = self._backend._lib.PEM_write_bio_X509_CRL( bio, self._x509_crl @@ -975,7 +975,7 @@ class _CertificateSigningRequest(object): return _CSR_EXTENSION_PARSER.parse(self._backend, x509_exts) def public_bytes(self, encoding): - bio = self._backend._create_mem_bio() + bio = self._backend._create_mem_bio_gc() if encoding is serialization.Encoding.PEM: res = self._backend._lib.PEM_write_bio_X509_REQ( bio, self._x509_req diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index ad2daf7d..e0555686 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -10,8 +10,6 @@ import subprocess import sys import textwrap -import pretend - import pytest from cryptography import utils, x509 @@ -621,7 +619,7 @@ class TestOpenSSLSerializationWithOpenSSL(object): assert backend._ffi.string(buf, len(password)) == password def test_unsupported_evp_pkey_type(self): - key = pretend.stub(type="unsupported") + key = backend._create_evp_pkey_gc() with raises_unsupported_algorithm(None): backend._evp_pkey_to_private_key(key) with raises_unsupported_algorithm(None): |