Skip to content

Commit 4ddd5da

Browse files
authored
[3.9] bpo-40479: Fix hashlib's usedforsecurity for OpenSSL 3.0.0 (GH-30455) (GH-30574)
Co-authored-by: Christian Heimes <[email protected]>
1 parent d9101c4 commit 4ddd5da

File tree

9 files changed

+374
-236
lines changed

9 files changed

+374
-236
lines changed

Doc/library/hashlib.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ More condensed:
120120

121121
Using :func:`new` with an algorithm provided by OpenSSL:
122122

123-
>>> h = hashlib.new('sha512_256')
123+
>>> h = hashlib.new('sha256')
124124
>>> h.update(b"Nobody inspects the spammish repetition")
125125
>>> h.hexdigest()
126-
'19197dc4d03829df858011c6c87600f994a858103bbc19005f20987aa19a97e2'
126+
'031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'
127127

128128
Hashlib provides the following constant attributes:
129129

Lib/test/test_hashlib.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,15 @@
4545
builtin_hashlib = None
4646

4747
try:
48-
from _hashlib import HASH, HASHXOF, openssl_md_meth_names
48+
from _hashlib import HASH, HASHXOF, openssl_md_meth_names, get_fips_mode
4949
except ImportError:
5050
HASH = None
5151
HASHXOF = None
5252
openssl_md_meth_names = frozenset()
5353

54+
def get_fips_mode():
55+
return 0
56+
5457
try:
5558
import _blake2
5659
except ImportError:
@@ -196,10 +199,7 @@ def hash_constructors(self):
196199

197200
@property
198201
def is_fips_mode(self):
199-
if hasattr(self._hashlib, "get_fips_mode"):
200-
return self._hashlib.get_fips_mode()
201-
else:
202-
return None
202+
return get_fips_mode()
203203

204204
def test_hash_array(self):
205205
a = array.array("b", range(10))
@@ -1013,7 +1013,7 @@ def _test_pbkdf2_hmac(self, pbkdf2, supported):
10131013
self.assertEqual(out, expected,
10141014
(digest_name, password, salt, rounds))
10151015

1016-
with self.assertRaisesRegex(ValueError, 'unsupported hash type'):
1016+
with self.assertRaisesRegex(ValueError, '.*unsupported.*'):
10171017
pbkdf2('unknown', b'pass', b'salt', 1)
10181018

10191019
if 'sha1' in supported:
@@ -1050,6 +1050,7 @@ def test_pbkdf2_hmac_c(self):
10501050

10511051
@unittest.skipUnless(hasattr(hashlib, 'scrypt'),
10521052
' test requires OpenSSL > 1.1')
1053+
@unittest.skipIf(get_fips_mode(), reason="scrypt is blocked in FIPS mode")
10531054
def test_scrypt(self):
10541055
for password, salt, n, r, p, expected in self.scrypt_test_vectors:
10551056
result = hashlib.scrypt(password, salt=salt, n=n, r=r, p=p)

Lib/test/test_imaplib.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ def cmd_AUTHENTICATE(self, tag, args):
385385
self.assertEqual(code, 'OK')
386386
self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake'
387387

388-
@hashlib_helper.requires_hashdigest('md5')
388+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
389389
def test_login_cram_md5_bytes(self):
390390
class AuthHandler(SimpleIMAPHandler):
391391
capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'
@@ -403,7 +403,7 @@ def cmd_AUTHENTICATE(self, tag, args):
403403
ret, _ = client.login_cram_md5("tim", b"tanstaaftanstaaf")
404404
self.assertEqual(ret, "OK")
405405

406-
@hashlib_helper.requires_hashdigest('md5')
406+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
407407
def test_login_cram_md5_plain_text(self):
408408
class AuthHandler(SimpleIMAPHandler):
409409
capabilities = 'LOGINDISABLED AUTH=CRAM-MD5'
@@ -849,7 +849,7 @@ def cmd_AUTHENTICATE(self, tag, args):
849849
b'ZmFrZQ==\r\n') # b64 encoded 'fake'
850850

851851
@reap_threads
852-
@hashlib_helper.requires_hashdigest('md5')
852+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
853853
def test_login_cram_md5(self):
854854

855855
class AuthHandler(SimpleIMAPHandler):

Lib/test/test_poplib.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,11 @@ def test_noop(self):
313313
def test_rpop(self):
314314
self.assertOK(self.client.rpop('foo'))
315315

316-
@hashlib_helper.requires_hashdigest('md5')
316+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
317317
def test_apop_normal(self):
318318
self.assertOK(self.client.apop('foo', 'dummypassword'))
319319

320-
@hashlib_helper.requires_hashdigest('md5')
320+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
321321
def test_apop_REDOS(self):
322322
# Replace welcome with very long evil welcome.
323323
# NB The upper bound on welcome length is currently 2048.

Lib/test/test_smtplib.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,7 @@ def auth_buggy(challenge=None):
11671167
finally:
11681168
smtp.close()
11691169

1170-
@hashlib_helper.requires_hashdigest('md5')
1170+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
11711171
def testAUTH_CRAM_MD5(self):
11721172
self.serv.add_feature("AUTH CRAM-MD5")
11731173
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost',
@@ -1176,7 +1176,7 @@ def testAUTH_CRAM_MD5(self):
11761176
self.assertEqual(resp, (235, b'Authentication Succeeded'))
11771177
smtp.close()
11781178

1179-
@hashlib_helper.requires_hashdigest('md5')
1179+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
11801180
def testAUTH_multiple(self):
11811181
# Test that multiple authentication methods are tried.
11821182
self.serv.add_feature("AUTH BOGUS PLAIN LOGIN CRAM-MD5")

Lib/test/test_tools/test_md5sum.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
skip_if_missing()
1313

14-
@hashlib_helper.requires_hashdigest('md5')
14+
@hashlib_helper.requires_hashdigest('md5', openssl=True)
1515
class MD5SumTests(unittest.TestCase):
1616
@classmethod
1717
def setUpClass(cls):

Lib/test/test_urllib2_localnet.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def test_basic_auth_httperror(self):
316316
self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, self.server_url)
317317

318318

319-
@hashlib_helper.requires_hashdigest("md5")
319+
@hashlib_helper.requires_hashdigest("md5", openssl=True)
320320
class ProxyAuthTests(unittest.TestCase):
321321
URL = "http://localhost"
322322

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :mod:`hashlib` *usedforsecurity* option to work correctly with OpenSSL
2+
3.0.0 in FIPS mode.

0 commit comments

Comments
 (0)