Skip to content

Commit 6634eed

Browse files
tiranstratakis
authored andcommitted
[3.8] bpo-38270: More fixes for strict crypto policy (pythonGH-16418) (python#16437)
test_hmac and test_hashlib test built-in hashing implementations and OpenSSL-based hashing implementations. Add more checks to skip OpenSSL implementations when a strict crypto policy is active. Use EVP_DigestInit_ex() instead of EVP_DigestInit() to initialize the EVP context. The EVP_DigestInit() function clears alls flags and breaks usedforsecurity flag again. Signed-off-by: Christian Heimes <[email protected]> https://bugs.python.org/issue38270. (cherry picked from commit 9055815) Co-authored-by: Christian Heimes <[email protected]>
1 parent edf2fde commit 6634eed

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

Lib/test/support/__init__.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@
7171
except ImportError:
7272
resource = None
7373

74+
try:
75+
import _hashlib
76+
except ImportError:
77+
_hashlib = None
78+
7479
__all__ = [
7580
# globals
7681
"PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast",
@@ -88,7 +93,8 @@
8893
"create_empty_file", "can_symlink", "fs_is_case_insensitive",
8994
# unittest
9095
"is_resource_enabled", "requires", "requires_freebsd_version",
91-
"requires_linux_version", "requires_mac_ver", "check_syntax_error",
96+
"requires_linux_version", "requires_mac_ver", "requires_hashdigest",
97+
"check_syntax_error",
9298
"TransientResource", "time_out", "socket_peer_reset", "ioerror_peer_reset",
9399
"transient_internet", "BasicTestRunner", "run_unittest", "run_doctest",
94100
"skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma",
@@ -628,20 +634,27 @@ def wrapper(*args, **kw):
628634
return wrapper
629635
return decorator
630636

631-
def requires_hashdigest(digestname):
637+
def requires_hashdigest(digestname, openssl=None):
632638
"""Decorator raising SkipTest if a hashing algorithm is not available
633639
634640
The hashing algorithm could be missing or blocked by a strict crypto
635641
policy.
636642
643+
If 'openssl' is True, then the decorator checks that OpenSSL provides
644+
the algorithm. Otherwise the check falls back to built-in
645+
implementations.
646+
637647
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS
638648
ValueError: unsupported hash type md4
639649
"""
640650
def decorator(func):
641651
@functools.wraps(func)
642652
def wrapper(*args, **kwargs):
643653
try:
644-
hashlib.new(digestname)
654+
if openssl and _hashlib is not None:
655+
_hashlib.new(digestname)
656+
else:
657+
hashlib.new(digestname)
645658
except ValueError:
646659
raise unittest.SkipTest(
647660
f"hash digest '{digestname}' is not available."

Lib/test/test_hashlib.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import array
1010
from binascii import unhexlify
11+
import functools
1112
import hashlib
1213
import importlib
1314
import itertools
@@ -21,6 +22,7 @@
2122
import warnings
2223
from test import support
2324
from test.support import _4G, bigmemtest, import_fresh_module
25+
from test.support import requires_hashdigest
2426
from http.client import HTTPException
2527

2628
# Were we compiled --with-pydebug or with #define Py_DEBUG?
@@ -143,6 +145,7 @@ def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm, usedforsecurity=T
143145
constructors.add(_test_algorithm_via_hashlib_new)
144146

145147
_hashlib = self._conditional_import_module('_hashlib')
148+
self._hashlib = _hashlib
146149
if _hashlib:
147150
# These two algorithms should always be present when this module
148151
# is compiled. If not, something was compiled wrong.

Lib/test/test_hmac.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def wrapper(*args, **kwargs):
1919

2020
class TestVectorsTestCase(unittest.TestCase):
2121

22-
@requires_hashdigest('md5')
22+
@requires_hashdigest('md5', openssl=True)
2323
def test_md5_vectors(self):
2424
# Test the HMAC module against test vectors from the RFC.
2525

@@ -66,7 +66,7 @@ def md5test(key, data, digest):
6666
b"and Larger Than One Block-Size Data"),
6767
"6f630fad67cda0ee1fb1f562db3aa53e")
6868

69-
@requires_hashdigest('sha1')
69+
@requires_hashdigest('sha1', openssl=True)
7070
def test_sha_vectors(self):
7171
def shatest(key, data, digest):
7272
h = hmac.HMAC(key, data, digestmod=hashlib.sha1)
@@ -234,19 +234,19 @@ def hmactest(key, data, hexdigests):
234234
'134676fb6de0446065c97440fa8c6a58',
235235
})
236236

237-
@requires_hashdigest('sha224')
237+
@requires_hashdigest('sha224', openssl=True)
238238
def test_sha224_rfc4231(self):
239239
self._rfc4231_test_cases(hashlib.sha224, 'sha224', 28, 64)
240240

241-
@requires_hashdigest('sha256')
241+
@requires_hashdigest('sha256', openssl=True)
242242
def test_sha256_rfc4231(self):
243243
self._rfc4231_test_cases(hashlib.sha256, 'sha256', 32, 64)
244244

245-
@requires_hashdigest('sha384')
245+
@requires_hashdigest('sha384', openssl=True)
246246
def test_sha384_rfc4231(self):
247247
self._rfc4231_test_cases(hashlib.sha384, 'sha384', 48, 128)
248248

249-
@requires_hashdigest('sha512')
249+
@requires_hashdigest('sha512', openssl=True)
250250
def test_sha512_rfc4231(self):
251251
self._rfc4231_test_cases(hashlib.sha512, 'sha512', 64, 128)
252252

0 commit comments

Comments
 (0)