From 983b35e7b0b76e687889f755d62c3a95dd485944 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 29 Oct 2018 21:10:54 +0800 Subject: create & use _evp_md_from_algorithm and _evp_md_non_null_from_algorithm (#4542) * create & use _evp_md_from_algorithm and _evp_md_non_null_from_algorithm * remove unused import --- .../hazmat/backends/openssl/backend.py | 46 +++++++++------------- src/cryptography/hazmat/backends/openssl/hashes.py | 5 +-- src/cryptography/hazmat/backends/openssl/hmac.py | 6 +-- src/cryptography/hazmat/backends/openssl/rsa.py | 27 +++++++------ tests/hazmat/primitives/test_rsa.py | 18 +++++++++ 5 files changed, 55 insertions(+), 47 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index bd414fde..19734a54 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -181,7 +181,7 @@ class Backend(object): def create_hmac_ctx(self, key, algorithm): return _HMACContext(self, key, algorithm) - def _build_openssl_digest_name(self, algorithm): + def _evp_md_from_algorithm(self, algorithm): if algorithm.name == "blake2b" or algorithm.name == "blake2s": alg = "{0}{1}".format( algorithm.name, algorithm.digest_size * 8 @@ -189,12 +189,17 @@ class Backend(object): else: alg = algorithm.name.encode("ascii") - return alg + evp_md = self._lib.EVP_get_digestbyname(alg) + return evp_md + + def _evp_md_non_null_from_algorithm(self, algorithm): + evp_md = self._evp_md_from_algorithm(algorithm) + self.openssl_assert(evp_md != self._ffi.NULL) + return evp_md def hash_supported(self, algorithm): - name = self._build_openssl_digest_name(algorithm) - digest = self._lib.EVP_get_digestbyname(name) - return digest != self._ffi.NULL + evp_md = self._evp_md_from_algorithm(algorithm) + return evp_md != self._ffi.NULL def hmac_supported(self, algorithm): return self.hash_supported(algorithm) @@ -286,9 +291,7 @@ class Backend(object): def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, key_material): buf = self._ffi.new("unsigned char[]", length) - evp_md = self._lib.EVP_get_digestbyname( - algorithm.name.encode("ascii")) - self.openssl_assert(evp_md != self._ffi.NULL) + evp_md = self._evp_md_non_null_from_algorithm(algorithm) res = self._lib.PKCS5_PBKDF2_HMAC( key_material, len(key_material), @@ -685,10 +688,7 @@ class Backend(object): ) # Resolve the signature algorithm. - evp_md = self._lib.EVP_get_digestbyname( - algorithm.name.encode('ascii') - ) - self.openssl_assert(evp_md != self._ffi.NULL) + evp_md = self._evp_md_non_null_from_algorithm(algorithm) # Create an empty request. x509_req = self._lib.X509_REQ_new() @@ -767,10 +767,7 @@ class Backend(object): ) # Resolve the signature algorithm. - evp_md = self._lib.EVP_get_digestbyname( - algorithm.name.encode('ascii') - ) - self.openssl_assert(evp_md != self._ffi.NULL) + evp_md = self._evp_md_non_null_from_algorithm(algorithm) # Create an empty certificate. x509_cert = self._lib.X509_new() @@ -875,10 +872,7 @@ class Backend(object): "MD5 is not a supported hash algorithm for EC/DSA CRLs" ) - evp_md = self._lib.EVP_get_digestbyname( - algorithm.name.encode('ascii') - ) - self.openssl_assert(evp_md != self._ffi.NULL) + evp_md = self._evp_md_non_null_from_algorithm(algorithm) # Create an empty CRL. x509_crl = self._lib.X509_CRL_new() @@ -1452,9 +1446,7 @@ class Backend(object): self.openssl_assert(ocsp_req != self._ffi.NULL) ocsp_req = self._ffi.gc(ocsp_req, self._lib.OCSP_REQUEST_free) cert, issuer, algorithm = builder._request - evp_md = self._lib.EVP_get_digestbyname( - algorithm.name.encode("ascii")) - self.openssl_assert(evp_md != self._ffi.NULL) + evp_md = self._evp_md_non_null_from_algorithm(algorithm) certid = self._lib.OCSP_cert_to_id( evp_md, cert._x509, issuer._x509 ) @@ -1474,10 +1466,9 @@ class Backend(object): basic = self._lib.OCSP_BASICRESP_new() self.openssl_assert(basic != self._ffi.NULL) basic = self._ffi.gc(basic, self._lib.OCSP_BASICRESP_free) - evp_md = self._lib.EVP_get_digestbyname( - builder._response._algorithm.name.encode("ascii") + evp_md = self._evp_md_non_null_from_algorithm( + builder._response._algorithm ) - self.openssl_assert(evp_md != self._ffi.NULL) certid = self._lib.OCSP_cert_to_id( evp_md, builder._response._cert._x509, builder._response._issuer._x509 @@ -1516,8 +1507,7 @@ class Backend(object): ) self.openssl_assert(res != self._ffi.NULL) # okay, now sign the basic structure - evp_md = self._lib.EVP_get_digestbyname(algorithm.name.encode("ascii")) - self.openssl_assert(evp_md != self._ffi.NULL) + evp_md = self._evp_md_non_null_from_algorithm(algorithm) responder_cert, responder_encoding = builder._responder_id flags = self._lib.OCSP_NOCERTS if responder_encoding is ocsp.OCSPResponderEncoding.HASH: diff --git a/src/cryptography/hazmat/backends/openssl/hashes.py b/src/cryptography/hazmat/backends/openssl/hashes.py index 92ea53bb..c39f57dc 100644 --- a/src/cryptography/hazmat/backends/openssl/hashes.py +++ b/src/cryptography/hazmat/backends/openssl/hashes.py @@ -22,12 +22,11 @@ class _HashContext(object): ctx = self._backend._ffi.gc( ctx, self._backend._lib.Cryptography_EVP_MD_CTX_free ) - name = self._backend._build_openssl_digest_name(algorithm) - evp_md = self._backend._lib.EVP_get_digestbyname(name) + evp_md = self._backend._evp_md_from_algorithm(algorithm) if evp_md == self._backend._ffi.NULL: raise UnsupportedAlgorithm( "{0} is not a supported hash on this backend.".format( - name), + algorithm.name), _Reasons.UNSUPPORTED_HASH ) res = self._backend._lib.EVP_DigestInit_ex(ctx, evp_md, diff --git a/src/cryptography/hazmat/backends/openssl/hmac.py b/src/cryptography/hazmat/backends/openssl/hmac.py index 3577f477..99c43f2a 100644 --- a/src/cryptography/hazmat/backends/openssl/hmac.py +++ b/src/cryptography/hazmat/backends/openssl/hmac.py @@ -25,11 +25,11 @@ class _HMACContext(object): ctx = self._backend._ffi.gc( ctx, self._backend._lib.Cryptography_HMAC_CTX_free ) - name = self._backend._build_openssl_digest_name(algorithm) - evp_md = self._backend._lib.EVP_get_digestbyname(name) + evp_md = self._backend._evp_md_from_algorithm(algorithm) if evp_md == self._backend._ffi.NULL: raise UnsupportedAlgorithm( - "{0} is not a supported hash on this backend".format(name), + "{0} is not a supported hash on this backend".format( + algorithm.name), _Reasons.UNSUPPORTED_HASH ) res = self._backend._lib.HMAC_Init_ex( diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index 9a7bfaa5..00f5e377 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -92,14 +92,11 @@ def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding): isinstance(padding, OAEP) and backend._lib.Cryptography_HAS_RSA_OAEP_MD ): - mgf1_md = backend._lib.EVP_get_digestbyname( - padding._mgf._algorithm.name.encode("ascii")) - backend.openssl_assert(mgf1_md != backend._ffi.NULL) + mgf1_md = backend._evp_md_non_null_from_algorithm( + padding._mgf._algorithm) res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md) backend.openssl_assert(res > 0) - oaep_md = backend._lib.EVP_get_digestbyname( - padding._algorithm.name.encode("ascii")) - backend.openssl_assert(oaep_md != backend._ffi.NULL) + oaep_md = backend._evp_md_non_null_from_algorithm(padding._algorithm) res = backend._lib.EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, oaep_md) backend.openssl_assert(res > 0) @@ -189,15 +186,21 @@ def _rsa_sig_determine_padding(backend, key, padding, algorithm): def _rsa_sig_setup(backend, padding, algorithm, key, data, init_func): padding_enum = _rsa_sig_determine_padding(backend, key, padding, algorithm) - evp_md = backend._lib.EVP_get_digestbyname(algorithm.name.encode("ascii")) - backend.openssl_assert(evp_md != backend._ffi.NULL) + evp_md = backend._evp_md_non_null_from_algorithm(algorithm) pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL) backend.openssl_assert(pkey_ctx != backend._ffi.NULL) pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free) res = init_func(pkey_ctx) backend.openssl_assert(res == 1) res = backend._lib.EVP_PKEY_CTX_set_signature_md(pkey_ctx, evp_md) - backend.openssl_assert(res > 0) + if res == 0: + backend._consume_errors() + raise UnsupportedAlgorithm( + "{0} is not supported by this backend for RSA signing.".format( + algorithm.name + ), + _Reasons.UNSUPPORTED_HASH + ) res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum) backend.openssl_assert(res > 0) if isinstance(padding, PSS): @@ -206,10 +209,8 @@ def _rsa_sig_setup(backend, padding, algorithm, key, data, init_func): ) backend.openssl_assert(res > 0) - mgf1_md = backend._lib.EVP_get_digestbyname( - padding._mgf._algorithm.name.encode("ascii") - ) - backend.openssl_assert(mgf1_md != backend._ffi.NULL) + mgf1_md = backend._evp_md_non_null_from_algorithm( + padding._mgf._algorithm) res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md) backend.openssl_assert(res > 0) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 4d56bcd4..ffe62594 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -634,6 +634,24 @@ class TestRSASignature(object): public_key = private_key.public_key() public_key.verify(signature, message, pss, hashes.SHA1()) + @pytest.mark.supported( + only_if=lambda backend: backend.hash_supported( + hashes.BLAKE2s(digest_size=32)), + skip_message="Does not support BLAKE2s", + ) + @pytest.mark.supported( + only_if=lambda backend: backend.rsa_padding_supported( + padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0) + ), + skip_message="Does not support PSS." + ) + def test_unsupported_hash(self, backend): + private_key = RSA_KEY_512.private_key(backend) + message = b"one little message" + pss = padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=0) + with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH): + private_key.sign(message, pss, hashes.BLAKE2s(32)) + @pytest.mark.supported( only_if=lambda backend: backend.rsa_padding_supported( padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0) -- cgit v1.2.3