Skip to content

Commit 2cc0223

Browse files
authored
bpo-35925: Skip SSL tests that fail due to weak external certs. (pythonGH-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.
1 parent 7b3a028 commit 2cc0223

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

@@ -1619,14 +1620,30 @@ def test_networked_good_cert(self):
16191620
# We feed the server's cert as a validating cert
16201621
import ssl
16211622
support.requires('network')
1622-
with support.transient_internet('self-signed.pythontest.net'):
1623+
selfsigned_pythontestdotnet = 'self-signed.pythontest.net'
1624+
with support.transient_internet(selfsigned_pythontestdotnet):
16231625
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
16241626
self.assertEqual(context.verify_mode, ssl.CERT_REQUIRED)
16251627
self.assertEqual(context.check_hostname, True)
16261628
context.load_verify_locations(CERT_selfsigned_pythontestdotnet)
1627-
h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context)
1628-
h.request('GET', '/')
1629-
resp = h.getresponse()
1629+
try:
1630+
h = client.HTTPSConnection(selfsigned_pythontestdotnet, 443,
1631+
context=context)
1632+
h.request('GET', '/')
1633+
resp = h.getresponse()
1634+
except ssl.SSLError as ssl_err:
1635+
ssl_err_str = str(ssl_err)
1636+
# In the error message of [SSL: CERTIFICATE_VERIFY_FAILED] on
1637+
# modern Linux distros (Debian Buster, etc) default OpenSSL
1638+
# configurations it'll fail saying "key too weak" until we
1639+
# address https://bugs.python.org/issue36816 to use a proper
1640+
# key size on self-signed.pythontest.net.
1641+
if re.search(r'(?i)key.too.weak', ssl_err_str):
1642+
raise unittest.SkipTest(
1643+
f'Got {ssl_err_str} trying to connect '
1644+
f'to {selfsigned_pythontestdotnet}. '
1645+
'See https://bugs.python.org/issue36816.')
1646+
raise
16301647
server_string = resp.getheader('server')
16311648
resp.close()
16321649
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)