Skip to content

Commit ffa29b5

Browse files
bpo-35925: Skip SSL tests that fail due to weak external certs. (GH-13124)
Modern Linux distros such as Debian Buster have default OpenSSL system configurations that reject connections to servers with weak certificates by default. This causes our test suite run with external networking resources enabled to skip these tests when they encounter such a failure. Fixing the network servers is a separate issue. (cherry picked from commit 2cc0223) Co-authored-by: Gregory P. Smith <[email protected]>
1 parent b2d29bf commit ffa29b5

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

Lib/test/test_httplib.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import itertools
55
import os
66
import array
7+
import re
78
import socket
89
import threading
910

@@ -1622,14 +1623,30 @@ def test_networked_good_cert(self):
16221623
# We feed the server's cert as a validating cert
16231624
import ssl
16241625
support.requires('network')
1625-
with support.transient_internet('self-signed.pythontest.net'):
1626+
selfsigned_pythontestdotnet = 'self-signed.pythontest.net'
1627+
with support.transient_internet(selfsigned_pythontestdotnet):
16261628
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
16271629
self.assertEqual(context.verify_mode, ssl.CERT_REQUIRED)
16281630
self.assertEqual(context.check_hostname, True)
16291631
context.load_verify_locations(CERT_selfsigned_pythontestdotnet)
1630-
h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context)
1631-
h.request('GET', '/')
1632-
resp = h.getresponse()
1632+
try:
1633+
h = client.HTTPSConnection(selfsigned_pythontestdotnet, 443,
1634+
context=context)
1635+
h.request('GET', '/')
1636+
resp = h.getresponse()
1637+
except ssl.SSLError as ssl_err:
1638+
ssl_err_str = str(ssl_err)
1639+
# In the error message of [SSL: CERTIFICATE_VERIFY_FAILED] on
1640+
# modern Linux distros (Debian Buster, etc) default OpenSSL
1641+
# configurations it'll fail saying "key too weak" until we
1642+
# address https://bugs.python.org/issue36816 to use a proper
1643+
# key size on self-signed.pythontest.net.
1644+
if re.search(r'(?i)key.too.weak', ssl_err_str):
1645+
raise unittest.SkipTest(
1646+
f'Got {ssl_err_str} trying to connect '
1647+
f'to {selfsigned_pythontestdotnet}. '
1648+
'See https://bugs.python.org/issue36816.')
1649+
raise
16331650
server_string = resp.getheader('server')
16341651
resp.close()
16351652
h.close()

Lib/test/test_nntplib.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import functools
77
import contextlib
88
import os.path
9+
import re
910
import threading
1011

1112
from test import support
@@ -21,6 +22,13 @@
2122
TIMEOUT = 30
2223
certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem')
2324

25+
if ssl is not None:
26+
SSLError = ssl.SSLError
27+
else:
28+
class SSLError(Exception):
29+
"""Non-existent exception class when we lack SSL support."""
30+
reason = "This will never be raised."
31+
2432
# TODO:
2533
# - test the `file` arg to more commands
2634
# - test error conditions
@@ -261,14 +269,21 @@ def is_connected():
261269
return False
262270
return True
263271

264-
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
265-
self.assertTrue(is_connected())
266-
self.assertTrue(server.help())
267-
self.assertFalse(is_connected())
268-
269-
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
270-
server.quit()
271-
self.assertFalse(is_connected())
272+
try:
273+
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
274+
self.assertTrue(is_connected())
275+
self.assertTrue(server.help())
276+
self.assertFalse(is_connected())
277+
278+
with self.NNTP_CLASS(self.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) as server:
279+
server.quit()
280+
self.assertFalse(is_connected())
281+
except SSLError as ssl_err:
282+
# matches "[SSL: DH_KEY_TOO_SMALL] dh key too small"
283+
if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason):
284+
raise unittest.SkipTest(f"Got {ssl_err} connecting "
285+
f"to {self.NNTP_HOST!r}")
286+
raise
272287

273288

274289
NetworkedNNTPTestsMixin.wrap_methods()
@@ -294,6 +309,12 @@ def setUpClass(cls):
294309
try:
295310
cls.server = cls.NNTP_CLASS(cls.NNTP_HOST, timeout=TIMEOUT,
296311
usenetrc=False)
312+
except SSLError as ssl_err:
313+
# matches "[SSL: DH_KEY_TOO_SMALL] dh key too small"
314+
if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason):
315+
raise unittest.SkipTest(f"{cls} got {ssl_err} connecting "
316+
f"to {cls.NNTP_HOST!r}")
317+
raise
297318
except EOF_ERRORS:
298319
raise unittest.SkipTest(f"{cls} got EOF error on connecting "
299320
f"to {cls.NNTP_HOST!r}")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Skip httplib and nntplib networking tests when they would otherwise fail due to a modern OS or distro with a default OpenSSL policy of rejecting connections to servers with weak certificates.

0 commit comments

Comments
 (0)