mirror of
https://github.com/saymrwulf/cryptography.git
synced 2026-05-14 20:37:55 +00:00
Drop OpenSSL 0.9.8 (#2978)
* Drop OpenSSL 0.9.8 * Drop this test, it's not relevant any longer * unused import * Remove CRYPTOGRAPHY_ALLOW_OPENSSL_098=1 from our tox * removed unused code for Cryptography_HAS_PKEY_CTX * return unused code for _AESCTRCipherContext * syntax :-( * remove some unused tests and skips * remove unused code for Cryptography_HAS_PBKDF2_HMAC * Revert "return unused code for _AESCTRCipherContext" This reverts commit 7d149729205aa4c9735eb322414b167a75b302df. * Remove unused RSA code * Remove unused test code for conditional bindings * Remove unused dsa code * unused import * Remove unused x509 extension code * Remove unused EC code * Attempt to remove unused DER key loading code * document this * grammar * Added back this paragraph * Update docs
This commit is contained in:
parent
a778fbc56c
commit
1252dec0c8
13 changed files with 44 additions and 394 deletions
12
.travis.yml
12
.travis.yml
|
|
@ -30,18 +30,6 @@ matrix:
|
|||
env: TOXENV=py27 OPENSSL=1.0.0
|
||||
- python: 3.5
|
||||
env: TOXENV=py35 OPENSSL=1.0.0
|
||||
- python: 2.6
|
||||
env: TOXENV=py26 OPENSSL=0.9.8
|
||||
- python: 2.7
|
||||
env: TOXENV=py27 OPENSSL=0.9.8
|
||||
- python: 3.3
|
||||
env: TOXENV=py33 OPENSSL=0.9.8
|
||||
- python: 3.4
|
||||
env: TOXENV=py34 OPENSSL=0.9.8
|
||||
- python: 3.5
|
||||
env: TOXENV=py35 OPENSSL=0.9.8
|
||||
- python: pypy
|
||||
env: TOXENV=pypy OPENSSL=0.9.8 PYPY_VERSION=5.1
|
||||
- python: 2.7
|
||||
env: TOXENV=docs
|
||||
addons:
|
||||
|
|
|
|||
10
docs/faq.rst
10
docs/faq.rst
|
|
@ -40,8 +40,8 @@ If you have no other libraries using OpenSSL in your process, or they do not
|
|||
appear to be at fault, it's possible that this is a bug in ``cryptography``.
|
||||
Please file an `issue`_ with instructions on how to reproduce it.
|
||||
|
||||
Importing cryptography causes a ``RuntimeError`` about OpenSSL 0.9.8
|
||||
--------------------------------------------------------------------
|
||||
Installing cryptography with OpenSSL 0.9.8 fails
|
||||
------------------------------------------------
|
||||
|
||||
The OpenSSL project has dropped support for the 0.9.8 release series. Since it
|
||||
is no longer receiving security patches from upstream, ``cryptography`` is also
|
||||
|
|
@ -49,9 +49,9 @@ dropping support for it. To fix this issue you should upgrade to a newer
|
|||
version of OpenSSL (1.0.1 or later). This may require you to upgrade to a newer
|
||||
operating system.
|
||||
|
||||
For the 1.4 release, you can set the ``CRYPTOGRAPHY_ALLOW_OPENSSL_098``
|
||||
environment variable. Please note that this is *temporary* and will be removed
|
||||
in ``cryptography`` 1.5.
|
||||
In ``cryptography`` 1.4, you can set the ``CRYPTOGRAPHY_ALLOW_OPENSSL_098``
|
||||
environment variable. Please note that this is *temporary* and is removed in
|
||||
``cryptography`` 1.5.
|
||||
|
||||
.. _`NaCl`: https://nacl.cr.yp.to/
|
||||
.. _`PyNaCl`: https://pynacl.readthedocs.io
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@
|
|||
OpenSSL backend
|
||||
===============
|
||||
|
||||
The `OpenSSL`_ C library. Cryptography supports version ``0.9.8e`` (present in
|
||||
Red Hat Enterprise Linux 5) and greater. Earlier versions may work but are
|
||||
**not tested or supported**.
|
||||
The `OpenSSL`_ C library. Cryptography supports OpenSSL version ``1.0.0`` and
|
||||
greater.
|
||||
|
||||
.. data:: cryptography.hazmat.backends.openssl.backend
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ OpenSSL binding
|
|||
.. currentmodule:: cryptography.hazmat.bindings.openssl.binding
|
||||
|
||||
These are `CFFI`_ bindings to the `OpenSSL`_ C library. Cryptography supports
|
||||
version ``0.9.8e`` (present in Red Hat Enterprise Linux 5) and greater. Earlier
|
||||
versions may work but are **not tested or supported**.
|
||||
OpenSSL version ``1.0.0`` and greater.
|
||||
|
||||
.. class:: cryptography.hazmat.bindings.openssl.binding.Binding()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Supported platforms
|
|||
Currently we test ``cryptography`` on Python 2.6, 2.7, 3.3, 3.4, 3.5, and PyPy
|
||||
2.6+ on these operating systems.
|
||||
|
||||
* x86-64 CentOS 7.x, 6.4 and CentOS 5.x
|
||||
* x86-64 CentOS 7.x, 6.4
|
||||
* x86-64 FreeBSD 10
|
||||
* OS X 10.11 El Capitan, 10.10 Yosemite, 10.9 Mavericks, 10.8 Mountain Lion,
|
||||
and 10.7 Lion
|
||||
|
|
@ -28,8 +28,6 @@ Currently we test ``cryptography`` on Python 2.6, 2.7, 3.3, 3.4, 3.5, and PyPy
|
|||
We test compiling with ``clang`` as well as ``gcc`` and use the following
|
||||
OpenSSL releases:
|
||||
|
||||
* ``OpenSSL 0.9.8e-fips-rhel5`` (``RHEL/CentOS 5``)
|
||||
* ``OpenSSL 0.9.8k``
|
||||
* ``OpenSSL 1.0.0-fips`` (``RHEL/CentOS 6.4``)
|
||||
* ``OpenSSL 1.0.1``
|
||||
* ``OpenSSL 1.0.1e-fips`` (``RHEL/CentOS 7``)
|
||||
|
|
@ -38,9 +36,8 @@ OpenSSL releases:
|
|||
* ``OpenSSL 1.0.2-latest``
|
||||
|
||||
.. warning::
|
||||
OpenSSL versions 0.9.8 and 1.0.0 are no longer supported by the OpenSSL
|
||||
project. Cryptography 1.4 has dropped support for OpenSSL 0.9.8, see the
|
||||
:doc:`FAQ </faq>` for more details.
|
||||
OpenSSL 1.0.0 is no longer supported by the OpenSSL project. Cryptography
|
||||
will drop support for it in a future release.
|
||||
|
||||
On Windows
|
||||
----------
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ const long EVP_CTRL_GCM_GET_TAG = -1;
|
|||
const long EVP_CTRL_GCM_SET_TAG = -1;
|
||||
const long EVP_CTRL_GCM_SET_IVLEN = -1;
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
|
||||
const long Cryptography_HAS_PBKDF2_HMAC = 1;
|
||||
const long Cryptography_HAS_PKEY_CTX = 1;
|
||||
|
||||
|
|
@ -198,31 +198,7 @@ int Cryptography_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
|
|||
size_t inlen) {
|
||||
return EVP_PKEY_decrypt(ctx, out, outlen, in, inlen);
|
||||
}
|
||||
#else
|
||||
const long Cryptography_HAS_PBKDF2_HMAC = 0;
|
||||
int (*PKCS5_PBKDF2_HMAC)(const char *, int, const unsigned char *, int, int,
|
||||
const EVP_MD *, int, unsigned char *) = NULL;
|
||||
const long Cryptography_HAS_PKEY_CTX = 0;
|
||||
typedef void EVP_PKEY_CTX;
|
||||
int (*EVP_PKEY_CTX_set_signature_md)(EVP_PKEY_CTX *, const EVP_MD *) = NULL;
|
||||
int (*EVP_PKEY_sign_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_sign)(EVP_PKEY_CTX *, unsigned char *, size_t *,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
int (*EVP_PKEY_verify_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_verify)(EVP_PKEY_CTX *, const unsigned char *, size_t,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
EVP_PKEY_CTX *(*EVP_PKEY_CTX_new)(EVP_PKEY *, ENGINE *) = NULL;
|
||||
EVP_PKEY_CTX *(*EVP_PKEY_CTX_new_id)(int, ENGINE *) = NULL;
|
||||
EVP_PKEY_CTX *(*EVP_PKEY_CTX_dup)(EVP_PKEY_CTX *) = NULL;
|
||||
void (*EVP_PKEY_CTX_free)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_encrypt_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_decrypt_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*Cryptography_EVP_PKEY_encrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
int (*Cryptography_EVP_PKEY_decrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
int (*EVP_PKEY_id)(const EVP_PKEY *) = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_EC
|
||||
int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL;
|
||||
EC_KEY *(*EVP_PKEY_get1_EC_KEY)(EVP_PKEY *) = NULL;
|
||||
|
|
|
|||
|
|
@ -290,50 +290,25 @@ class Backend(object):
|
|||
return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)
|
||||
|
||||
def pbkdf2_hmac_supported(self, algorithm):
|
||||
if self._lib.Cryptography_HAS_PBKDF2_HMAC:
|
||||
return self.hmac_supported(algorithm)
|
||||
else:
|
||||
# OpenSSL < 1.0.0 has an explicit PBKDF2-HMAC-SHA1 function,
|
||||
# so if the PBKDF2_HMAC function is missing we only support
|
||||
# SHA1 via PBKDF2_HMAC_SHA1.
|
||||
return isinstance(algorithm, hashes.SHA1)
|
||||
return self.hmac_supported(algorithm)
|
||||
|
||||
def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations,
|
||||
key_material):
|
||||
buf = self._ffi.new("char[]", length)
|
||||
if self._lib.Cryptography_HAS_PBKDF2_HMAC:
|
||||
evp_md = self._lib.EVP_get_digestbyname(
|
||||
algorithm.name.encode("ascii"))
|
||||
self.openssl_assert(evp_md != self._ffi.NULL)
|
||||
res = self._lib.PKCS5_PBKDF2_HMAC(
|
||||
key_material,
|
||||
len(key_material),
|
||||
salt,
|
||||
len(salt),
|
||||
iterations,
|
||||
evp_md,
|
||||
length,
|
||||
buf
|
||||
)
|
||||
self.openssl_assert(res == 1)
|
||||
else:
|
||||
if not isinstance(algorithm, hashes.SHA1):
|
||||
raise UnsupportedAlgorithm(
|
||||
"This version of OpenSSL only supports PBKDF2HMAC with "
|
||||
"SHA1.",
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
res = self._lib.PKCS5_PBKDF2_HMAC_SHA1(
|
||||
key_material,
|
||||
len(key_material),
|
||||
salt,
|
||||
len(salt),
|
||||
iterations,
|
||||
length,
|
||||
buf
|
||||
)
|
||||
self.openssl_assert(res == 1)
|
||||
|
||||
evp_md = self._lib.EVP_get_digestbyname(
|
||||
algorithm.name.encode("ascii"))
|
||||
self.openssl_assert(evp_md != self._ffi.NULL)
|
||||
res = self._lib.PKCS5_PBKDF2_HMAC(
|
||||
key_material,
|
||||
len(key_material),
|
||||
salt,
|
||||
len(salt),
|
||||
iterations,
|
||||
evp_md,
|
||||
length,
|
||||
buf
|
||||
)
|
||||
self.openssl_assert(res == 1)
|
||||
return self._ffi.buffer(buf)[:]
|
||||
|
||||
def _consume_errors(self):
|
||||
|
|
@ -617,12 +592,6 @@ class Backend(object):
|
|||
if key_size not in (1024, 2048, 3072):
|
||||
raise ValueError("Key size must be 1024 or 2048 or 3072 bits.")
|
||||
|
||||
if (self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f and
|
||||
key_size > 1024):
|
||||
raise ValueError(
|
||||
"Key size must be 1024 because OpenSSL < 1.0.0 doesn't "
|
||||
"support larger key sizes.")
|
||||
|
||||
ctx = self._lib.DSA_new()
|
||||
self.openssl_assert(ctx != self._ffi.NULL)
|
||||
ctx = self._ffi.gc(ctx, self._lib.DSA_free)
|
||||
|
|
@ -731,16 +700,10 @@ class Backend(object):
|
|||
return evp_pkey
|
||||
|
||||
def dsa_hash_supported(self, algorithm):
|
||||
if self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f:
|
||||
return isinstance(algorithm, hashes.SHA1)
|
||||
else:
|
||||
return self.hash_supported(algorithm)
|
||||
return self.hash_supported(algorithm)
|
||||
|
||||
def dsa_parameters_supported(self, p, q, g):
|
||||
if self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f:
|
||||
return utils.bit_length(p) <= 1024 and utils.bit_length(q) <= 160
|
||||
else:
|
||||
return True
|
||||
return True
|
||||
|
||||
def cmac_algorithm_supported(self, algorithm):
|
||||
return (
|
||||
|
|
@ -1049,32 +1012,9 @@ class Backend(object):
|
|||
extension.oid.dotted_string.encode("ascii")
|
||||
)
|
||||
backend.openssl_assert(nid != self._lib.NID_undef)
|
||||
x509_extension = self._lib.X509V3_EXT_i2d(
|
||||
return self._lib.X509V3_EXT_i2d(
|
||||
nid, 1 if extension.critical else 0, ext_struct
|
||||
)
|
||||
if (
|
||||
x509_extension == self._ffi.NULL and
|
||||
extension.oid == x509.OID_CERTIFICATE_ISSUER
|
||||
):
|
||||
# This path exists to support OpenSSL 0.9.8, which does not
|
||||
# know how to encode a CERTIFICATE_ISSUER for CRLs. Once we
|
||||
# drop 0.9.8 support we can remove this.
|
||||
self._consume_errors()
|
||||
pp = backend._ffi.new("unsigned char **")
|
||||
r = self._lib.i2d_GENERAL_NAMES(ext_struct, pp)
|
||||
backend.openssl_assert(r > 0)
|
||||
pp = backend._ffi.gc(
|
||||
pp,
|
||||
lambda pointer: backend._lib.OPENSSL_free(pointer[0])
|
||||
)
|
||||
obj = _txt2obj_gc(self, extension.oid.dotted_string)
|
||||
return self._lib.X509_EXTENSION_create_by_OBJ(
|
||||
self._ffi.NULL,
|
||||
obj,
|
||||
1 if extension.critical else 0,
|
||||
_encode_asn1_str_gc(self, pp[0], r)
|
||||
)
|
||||
return x509_extension
|
||||
|
||||
def create_x509_revoked_certificate(self, builder):
|
||||
if not isinstance(builder, x509.RevokedCertificateBuilder):
|
||||
|
|
@ -1142,19 +1082,10 @@ class Backend(object):
|
|||
def load_der_private_key(self, data, password):
|
||||
# OpenSSL has a function called d2i_AutoPrivateKey that can simplify
|
||||
# this. Unfortunately it doesn't properly support PKCS8 on OpenSSL
|
||||
# 0.9.8 so we can't use it. Instead we sequentially try to load it 3
|
||||
# 0.9.8 so we can't use it. Instead we sequentially try to load it 2
|
||||
# different ways. First we'll try to load it as a traditional key
|
||||
bio_data = self._bytes_to_bio(data)
|
||||
key = self._evp_pkey_from_der_traditional_key(bio_data, password)
|
||||
if not key:
|
||||
# Okay so it's not a traditional key. Let's try
|
||||
# PKCS8 unencrypted. OpenSSL 0.9.8 can't load unencrypted
|
||||
# PKCS8 keys using d2i_PKCS8PrivateKey_bio so we do this instead.
|
||||
# Reset the memory BIO so we can read the data again.
|
||||
res = self._lib.BIO_reset(bio_data.bio)
|
||||
self.openssl_assert(res == 1)
|
||||
key = self._evp_pkey_from_der_unencrypted_pkcs8(bio_data, password)
|
||||
|
||||
if key:
|
||||
return self._evp_pkey_to_private_key(key)
|
||||
else:
|
||||
|
|
@ -1181,24 +1112,6 @@ class Backend(object):
|
|||
self._consume_errors()
|
||||
return None
|
||||
|
||||
def _evp_pkey_from_der_unencrypted_pkcs8(self, bio_data, password):
|
||||
info = self._lib.d2i_PKCS8_PRIV_KEY_INFO_bio(
|
||||
bio_data.bio, self._ffi.NULL
|
||||
)
|
||||
info = self._ffi.gc(info, self._lib.PKCS8_PRIV_KEY_INFO_free)
|
||||
if info != self._ffi.NULL:
|
||||
key = self._lib.EVP_PKCS82PKEY(info)
|
||||
self.openssl_assert(key != self._ffi.NULL)
|
||||
key = self._ffi.gc(key, self._lib.EVP_PKEY_free)
|
||||
if password is not None:
|
||||
raise TypeError(
|
||||
"Password was given but private key is not encrypted."
|
||||
)
|
||||
return key
|
||||
else:
|
||||
self._consume_errors()
|
||||
return None
|
||||
|
||||
def load_der_public_key(self, data):
|
||||
mem_bio = self._bytes_to_bio(data)
|
||||
evp_pkey = self._lib.d2i_PUBKEY_bio(mem_bio.bio, self._ffi.NULL)
|
||||
|
|
@ -1418,13 +1331,6 @@ class Backend(object):
|
|||
if not isinstance(signature_algorithm, ec.ECDSA):
|
||||
return False
|
||||
|
||||
# Before 0.9.8m OpenSSL can't cope with digests longer than the curve.
|
||||
if (
|
||||
self._lib.OPENSSL_VERSION_NUMBER < 0x009080df and
|
||||
curve.key_size < signature_algorithm.algorithm.digest_size * 8
|
||||
):
|
||||
return False
|
||||
|
||||
return self.elliptic_curve_supported(curve)
|
||||
|
||||
def generate_elliptic_curve_private_key(self, curve):
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import math
|
|||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized, InvalidSignature, UnsupportedAlgorithm, _Reasons
|
||||
InvalidSignature, UnsupportedAlgorithm, _Reasons
|
||||
)
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import (
|
||||
|
|
@ -68,10 +68,7 @@ def _enc_dec_rsa(backend, key, data, padding):
|
|||
_Reasons.UNSUPPORTED_PADDING
|
||||
)
|
||||
|
||||
if backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
|
||||
else:
|
||||
return _enc_dec_rsa_098(backend, key, data, padding_enum)
|
||||
return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
|
||||
|
||||
|
||||
def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding):
|
||||
|
|
@ -118,22 +115,6 @@ def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding):
|
|||
return backend._ffi.buffer(buf)[:outlen[0]]
|
||||
|
||||
|
||||
def _enc_dec_rsa_098(backend, key, data, padding_enum):
|
||||
if isinstance(key, _RSAPublicKey):
|
||||
crypt = backend._lib.RSA_public_encrypt
|
||||
else:
|
||||
crypt = backend._lib.RSA_private_decrypt
|
||||
|
||||
key_size = backend._lib.RSA_size(key._rsa_cdata)
|
||||
backend.openssl_assert(key_size > 0)
|
||||
buf = backend._ffi.new("unsigned char[]", key_size)
|
||||
res = crypt(len(data), data, buf, key._rsa_cdata, padding_enum)
|
||||
if res < 0:
|
||||
_handle_rsa_enc_dec_error(backend, key)
|
||||
|
||||
return backend._ffi.buffer(buf)[:res]
|
||||
|
||||
|
||||
def _handle_rsa_enc_dec_error(backend, key):
|
||||
errors = backend._consume_errors()
|
||||
assert errors
|
||||
|
|
@ -177,11 +158,8 @@ class _RSASignatureContext(object):
|
|||
self._backend.openssl_assert(self._pkey_size > 0)
|
||||
|
||||
if isinstance(padding, PKCS1v15):
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._finalize_method = self._finalize_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING
|
||||
else:
|
||||
self._finalize_method = self._finalize_pkcs1
|
||||
self._finalize_method = self._finalize_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING
|
||||
elif isinstance(padding, PSS):
|
||||
if not isinstance(padding._mgf, MGF1):
|
||||
raise UnsupportedAlgorithm(
|
||||
|
|
@ -204,11 +182,8 @@ class _RSASignatureContext(object):
|
|||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._finalize_method = self._finalize_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING
|
||||
else:
|
||||
self._finalize_method = self._finalize_pss
|
||||
self._finalize_method = self._finalize_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING
|
||||
else:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not supported by this backend.".format(padding.name),
|
||||
|
|
@ -297,62 +272,6 @@ class _RSASignatureContext(object):
|
|||
|
||||
return self._backend._ffi.buffer(buf)[:]
|
||||
|
||||
def _finalize_pkcs1(self, evp_md):
|
||||
if self._hash_ctx._ctx is None:
|
||||
raise AlreadyFinalized("Context has already been finalized.")
|
||||
|
||||
sig_buf = self._backend._ffi.new("char[]", self._pkey_size)
|
||||
sig_len = self._backend._ffi.new("unsigned int *")
|
||||
res = self._backend._lib.EVP_SignFinal(
|
||||
self._hash_ctx._ctx._ctx,
|
||||
sig_buf,
|
||||
sig_len,
|
||||
self._private_key._evp_pkey
|
||||
)
|
||||
self._hash_ctx.finalize()
|
||||
if res == 0:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors[0].lib == self._backend._lib.ERR_LIB_RSA
|
||||
assert (errors[0].reason ==
|
||||
self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY)
|
||||
raise ValueError("Digest too large for key size. Use a larger "
|
||||
"key.")
|
||||
|
||||
return self._backend._ffi.buffer(sig_buf)[:sig_len[0]]
|
||||
|
||||
def _finalize_pss(self, evp_md):
|
||||
data_to_sign = self._hash_ctx.finalize()
|
||||
padded = self._backend._ffi.new("unsigned char[]", self._pkey_size)
|
||||
res = self._backend._lib.RSA_padding_add_PKCS1_PSS(
|
||||
self._private_key._rsa_cdata,
|
||||
padded,
|
||||
data_to_sign,
|
||||
evp_md,
|
||||
_get_rsa_pss_salt_length(
|
||||
self._padding,
|
||||
self._private_key.key_size,
|
||||
len(data_to_sign)
|
||||
)
|
||||
)
|
||||
if res != 1:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors[0].lib == self._backend._lib.ERR_LIB_RSA
|
||||
assert (errors[0].reason ==
|
||||
self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE)
|
||||
raise ValueError("Salt length too long for key size. Try using "
|
||||
"MAX_LENGTH instead.")
|
||||
|
||||
sig_buf = self._backend._ffi.new("char[]", self._pkey_size)
|
||||
sig_len = self._backend._lib.RSA_private_encrypt(
|
||||
self._pkey_size,
|
||||
padded,
|
||||
sig_buf,
|
||||
self._private_key._rsa_cdata,
|
||||
self._backend._lib.RSA_NO_PADDING
|
||||
)
|
||||
self._backend.openssl_assert(sig_len != -1)
|
||||
return self._backend._ffi.buffer(sig_buf)[:sig_len]
|
||||
|
||||
|
||||
@utils.register_interface(AsymmetricVerificationContext)
|
||||
class _RSAVerificationContext(object):
|
||||
|
|
@ -370,11 +289,8 @@ class _RSAVerificationContext(object):
|
|||
self._backend.openssl_assert(self._pkey_size > 0)
|
||||
|
||||
if isinstance(padding, PKCS1v15):
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._verify_method = self._verify_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING
|
||||
else:
|
||||
self._verify_method = self._verify_pkcs1
|
||||
self._verify_method = self._verify_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING
|
||||
elif isinstance(padding, PSS):
|
||||
if not isinstance(padding._mgf, MGF1):
|
||||
raise UnsupportedAlgorithm(
|
||||
|
|
@ -399,11 +315,8 @@ class _RSAVerificationContext(object):
|
|||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._verify_method = self._verify_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING
|
||||
else:
|
||||
self._verify_method = self._verify_pss
|
||||
self._verify_method = self._verify_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING
|
||||
else:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not supported by this backend.".format(padding.name),
|
||||
|
|
@ -479,57 +392,6 @@ class _RSAVerificationContext(object):
|
|||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
def _verify_pkcs1(self, evp_md):
|
||||
if self._hash_ctx._ctx is None:
|
||||
raise AlreadyFinalized("Context has already been finalized.")
|
||||
|
||||
res = self._backend._lib.EVP_VerifyFinal(
|
||||
self._hash_ctx._ctx._ctx,
|
||||
self._signature,
|
||||
len(self._signature),
|
||||
self._public_key._evp_pkey
|
||||
)
|
||||
self._hash_ctx.finalize()
|
||||
# The previous call can return negative numbers in the event of an
|
||||
# error. This is not a signature failure but we need to fail if it
|
||||
# occurs.
|
||||
self._backend.openssl_assert(res >= 0)
|
||||
if res == 0:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
def _verify_pss(self, evp_md):
|
||||
buf = self._backend._ffi.new("unsigned char[]", self._pkey_size)
|
||||
res = self._backend._lib.RSA_public_decrypt(
|
||||
len(self._signature),
|
||||
self._signature,
|
||||
buf,
|
||||
self._public_key._rsa_cdata,
|
||||
self._backend._lib.RSA_NO_PADDING
|
||||
)
|
||||
if res != self._pkey_size:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
data_to_verify = self._hash_ctx.finalize()
|
||||
res = self._backend._lib.RSA_verify_PKCS1_PSS(
|
||||
self._public_key._rsa_cdata,
|
||||
data_to_verify,
|
||||
evp_md,
|
||||
buf,
|
||||
_get_rsa_pss_salt_length(
|
||||
self._padding,
|
||||
self._public_key.key_size,
|
||||
len(data_to_verify)
|
||||
)
|
||||
)
|
||||
if res != 1:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
|
||||
@utils.register_interface(RSAPrivateKeyWithSerialization)
|
||||
class _RSAPrivateKey(object):
|
||||
|
|
|
|||
|
|
@ -215,27 +215,6 @@ CONDITIONAL_NAMES = {
|
|||
"EVP_CTRL_GCM_SET_TAG",
|
||||
"EVP_CTRL_GCM_SET_IVLEN",
|
||||
],
|
||||
"Cryptography_HAS_PBKDF2_HMAC": [
|
||||
"PKCS5_PBKDF2_HMAC"
|
||||
],
|
||||
"Cryptography_HAS_PKEY_CTX": [
|
||||
"EVP_PKEY_CTX_new",
|
||||
"EVP_PKEY_CTX_new_id",
|
||||
"EVP_PKEY_CTX_dup",
|
||||
"EVP_PKEY_CTX_free",
|
||||
"EVP_PKEY_sign",
|
||||
"EVP_PKEY_sign_init",
|
||||
"EVP_PKEY_verify",
|
||||
"EVP_PKEY_verify_init",
|
||||
"Cryptography_EVP_PKEY_encrypt",
|
||||
"EVP_PKEY_encrypt_init",
|
||||
"Cryptography_EVP_PKEY_decrypt",
|
||||
"EVP_PKEY_decrypt_init",
|
||||
"EVP_PKEY_CTX_set_signature_md",
|
||||
"EVP_PKEY_id",
|
||||
"EVP_PKEY_CTX_set_rsa_padding",
|
||||
"EVP_PKEY_CTX_set_rsa_pss_saltlen",
|
||||
],
|
||||
"Cryptography_HAS_ECDSA_SHA2_NIDS": [
|
||||
"NID_ecdsa_with_SHA224",
|
||||
"NID_ecdsa_with_SHA256",
|
||||
|
|
|
|||
|
|
@ -217,21 +217,7 @@ class Binding(object):
|
|||
|
||||
|
||||
def _verify_openssl_version(version):
|
||||
if version < 0x10000000:
|
||||
if os.environ.get("CRYPTOGRAPHY_ALLOW_OPENSSL_098"):
|
||||
warnings.warn(
|
||||
"OpenSSL version 0.9.8 is no longer supported by the OpenSSL "
|
||||
"project, please upgrade. The next version of cryptography "
|
||||
"will completely remove support for it.",
|
||||
DeprecationWarning
|
||||
)
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"You are linking against OpenSSL 0.9.8, which is no longer "
|
||||
"support by the OpenSSL project. You need to upgrade to a "
|
||||
"newer version of OpenSSL."
|
||||
)
|
||||
elif version < 0x10001000:
|
||||
if version < 0x10001000:
|
||||
warnings.warn(
|
||||
"OpenSSL versions less than 1.0.1 are no longer supported by the "
|
||||
"OpenSSL project, please upgrade. A future version of "
|
||||
|
|
|
|||
|
|
@ -142,27 +142,6 @@ class TestOpenSSL(object):
|
|||
with pytest.raises(InternalError):
|
||||
enc.finalize()
|
||||
|
||||
def test_derive_pbkdf2_raises_unsupported_on_old_openssl(self):
|
||||
if backend.pbkdf2_hmac_supported(hashes.SHA256()):
|
||||
pytest.skip("Requires an older OpenSSL")
|
||||
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):
|
||||
backend.derive_pbkdf2_hmac(hashes.SHA256(), 10, b"", 1000, b"")
|
||||
|
||||
@pytest.mark.skipif(
|
||||
backend._lib.OPENSSL_VERSION_NUMBER >= 0x1000000f,
|
||||
reason="Requires an older OpenSSL. Must be < 1.0.0"
|
||||
)
|
||||
def test_large_key_size_on_old_openssl(self):
|
||||
with pytest.raises(ValueError):
|
||||
dsa.generate_parameters(2048, backend=backend)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
dsa.generate_parameters(3072, backend=backend)
|
||||
|
||||
@pytest.mark.skipif(
|
||||
backend._lib.OPENSSL_VERSION_NUMBER < 0x1000000f,
|
||||
reason="Requires a newer OpenSSL. Must be >= 1.0.0"
|
||||
)
|
||||
def test_large_key_size_on_new_openssl(self):
|
||||
parameters = dsa.generate_parameters(2048, backend)
|
||||
param_num = parameters.parameter_numbers()
|
||||
|
|
@ -743,10 +722,6 @@ class TestRSAPEMSerialization(object):
|
|||
|
||||
|
||||
class TestGOSTCertificate(object):
|
||||
@pytest.mark.skipif(
|
||||
backend._lib.OPENSSL_VERSION_NUMBER < 0x1000000f,
|
||||
reason="Requires a newer OpenSSL. Must be >= 1.0.0"
|
||||
)
|
||||
def test_numeric_string_x509_name_entry(self):
|
||||
cert = _load_cert(
|
||||
os.path.join("x509", "e-trust.ru.der"),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import pytest
|
|||
|
||||
from cryptography.exceptions import InternalError
|
||||
from cryptography.hazmat.bindings.openssl.binding import (
|
||||
Binding, _OpenSSLErrorWithText, _openssl_assert, _verify_openssl_version
|
||||
Binding, _OpenSSLErrorWithText, _openssl_assert
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -137,15 +137,6 @@ class TestOpenSSL(object):
|
|||
|
||||
def test_conditional_removal(self):
|
||||
b = Binding()
|
||||
if b.lib.OPENSSL_VERSION_NUMBER >= 0x10000000:
|
||||
assert b.lib.X509_V_ERR_DIFFERENT_CRL_SCOPE
|
||||
assert b.lib.X509_V_ERR_CRL_PATH_VALIDATION_ERROR
|
||||
else:
|
||||
with pytest.raises(AttributeError):
|
||||
b.lib.X509_V_ERR_DIFFERENT_CRL_SCOPE
|
||||
|
||||
with pytest.raises(AttributeError):
|
||||
b.lib.X509_V_ERR_CRL_PATH_VALIDATION_ERROR
|
||||
|
||||
if b.lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
|
||||
assert b.lib.CMAC_Init
|
||||
|
|
@ -175,9 +166,3 @@ class TestOpenSSL(object):
|
|||
b'ex:data not multiple of block length'
|
||||
)
|
||||
)]
|
||||
|
||||
def test_verify_openssl_version(self, monkeypatch):
|
||||
monkeypatch.delenv("CRYPTOGRAPHY_ALLOW_OPENSSL_098", raising=False)
|
||||
with pytest.raises(RuntimeError):
|
||||
# OpenSSL 0.9.8zg
|
||||
_verify_openssl_version(0x9081DF)
|
||||
|
|
|
|||
2
tox.ini
2
tox.ini
|
|
@ -7,8 +7,6 @@ deps =
|
|||
.[test]
|
||||
./vectors
|
||||
passenv = ARCHFLAGS LDFLAGS CFLAGS INCLUDE LIB LD_LIBRARY_PATH USERNAME
|
||||
setenv =
|
||||
CRYPTOGRAPHY_ALLOW_OPENSSL_098=1
|
||||
commands =
|
||||
pip list
|
||||
# We use parallel mode and then combine here so that coverage.py will take
|
||||
|
|
|
|||
Loading…
Reference in a new issue