Skip to content

Commit cc6870f

Browse files
committed
[3.6] 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.. (cherry picked from commit 2cc0223) Co-authored-by: Gregory P. Smith <[email protected]>
1 parent 2b9d7ab commit cc6870f

File tree

3 files changed

+54
-12
lines changed

3 files changed

+54
-12
lines changed

Lib/test/test_httplib.py

Lines changed: 23 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

910
import unittest
@@ -1597,13 +1598,31 @@ def test_networked_good_cert(self):
15971598
# We feed the server's cert as a validating cert
15981599
import ssl
15991600
support.requires('network')
1600-
with support.transient_internet('self-signed.pythontest.net'):
1601+
selfsigned_pythontestdotnet = 'self-signed.pythontest.net'
1602+
with support.transient_internet(selfsigned_pythontestdotnet):
16011603
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
16021604
context.verify_mode = ssl.CERT_REQUIRED
1605+
self.assertEqual(context.verify_mode, ssl.CERT_REQUIRED)
1606+
self.assertEqual(context.check_hostname, True)
16031607
context.load_verify_locations(CERT_selfsigned_pythontestdotnet)
1604-
h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context)
1605-
h.request('GET', '/')
1606-
resp = h.getresponse()
1608+
try:
1609+
h = client.HTTPSConnection(selfsigned_pythontestdotnet, 443,
1610+
context=context)
1611+
h.request('GET', '/')
1612+
resp = h.getresponse()
1613+
except ssl.SSLError as ssl_err:
1614+
ssl_err_str = str(ssl_err)
1615+
# In the error message of [SSL: CERTIFICATE_VERIFY_FAILED] on
1616+
# modern Linux distros (Debian Buster, etc) default OpenSSL
1617+
# configurations it'll fail saying "key too weak" until we
1618+
# address https://bugs.python.org/issue36816 to use a proper
1619+
# key size on self-signed.pythontest.net.
1620+
if re.search(r'(?i)key.too.weak', ssl_err_str):
1621+
raise unittest.SkipTest(
1622+
f'Got {ssl_err_str} trying to connect '
1623+
f'to {selfsigned_pythontestdotnet}. '
1624+
'See https://bugs.python.org/issue36816.')
1625+
raise
16071626
server_string = resp.getheader('server')
16081627
resp.close()
16091628
h.close()

Lib/test/test_nntplib.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import functools
77
import contextlib
88
import os.path
9+
import re
10+
911
from test import support
1012
from nntplib import NNTP, GroupInfo
1113
import nntplib
@@ -22,6 +24,13 @@
2224
TIMEOUT = 30
2325
certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem')
2426

27+
if ssl is not None:
28+
SSLError = ssl.SSLError
29+
else:
30+
class SSLError(Exception):
31+
"""Non-existent exception class when we lack SSL support."""
32+
reason = "This will never be raised."
33+
2534
# TODO:
2635
# - test the `file` arg to more commands
2736
# - test error conditions
@@ -262,14 +271,21 @@ def is_connected():
262271
return False
263272
return True
264273

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

274290

275291
NetworkedNNTPTestsMixin.wrap_methods()
@@ -290,6 +306,12 @@ def setUpClass(cls):
290306
try:
291307
cls.server = cls.NNTP_CLASS(cls.NNTP_HOST, timeout=TIMEOUT,
292308
usenetrc=False)
309+
except SSLError as ssl_err:
310+
# matches "[SSL: DH_KEY_TOO_SMALL] dh key too small"
311+
if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason):
312+
raise unittest.SkipTest(f"{cls} got {ssl_err} connecting "
313+
f"to {cls.NNTP_HOST!r}")
314+
raise
293315
except EOFError:
294316
raise unittest.SkipTest(f"{cls} got EOF error on connecting "
295317
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)