bpo-43998: Default to TLS 1.2 and increase cipher suite security (GH-25778)
The ssl module now has more secure default settings. Ciphers without forward
secrecy or SHA-1 MAC are disabled by default. Security level 2 prohibits
weak RSA, DH, and ECC keys with less than 112 bits of security.
:class:`~ssl.SSLContext` defaults to minimum protocol version TLS 1.2.
Settings are based on Hynek Schlawack's research.
```
$ openssl version
OpenSSL 1.1.1k FIPS 25 Mar 2021
$ openssl ciphers -v '@SECLEVEL=2:ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES:DHE+AES:!aNULL:!eNULL:!aDSS:!SHA1:!AESCCM'
TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD
TLS_AES_128_CCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESCCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256
DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256
```
Signed-off-by: Christian Heimes <christian@python.org>
diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py
index 230a444..1950946 100644
--- a/Lib/test/test_nntplib.py
+++ b/Lib/test/test_nntplib.py
@@ -37,6 +37,8 @@ class SSLError(Exception):
class NetworkedNNTPTestsMixin:
+ ssl_context = None
+
def test_welcome(self):
welcome = self.server.getwelcome()
self.assertEqual(str, type(welcome))
@@ -273,18 +275,21 @@ def is_connected():
return False
return True
+ kwargs = dict(
+ timeout=support.INTERNET_TIMEOUT,
+ usenetrc=False
+ )
+ if self.ssl_context is not None:
+ kwargs["ssl_context"] = self.ssl_context
+
try:
- server = self.NNTP_CLASS(self.NNTP_HOST,
- timeout=support.INTERNET_TIMEOUT,
- usenetrc=False)
+ server = self.NNTP_CLASS(self.NNTP_HOST, **kwargs)
with server:
self.assertTrue(is_connected())
self.assertTrue(server.help())
self.assertFalse(is_connected())
- server = self.NNTP_CLASS(self.NNTP_HOST,
- timeout=support.INTERNET_TIMEOUT,
- usenetrc=False)
+ server = self.NNTP_CLASS(self.NNTP_HOST, **kwargs)
with server:
server.quit()
self.assertFalse(is_connected())
@@ -316,16 +321,21 @@ class NetworkedNNTPTests(NetworkedNNTPTestsMixin, unittest.TestCase):
@classmethod
def setUpClass(cls):
support.requires("network")
+ kwargs = dict(
+ timeout=support.INTERNET_TIMEOUT,
+ usenetrc=False
+ )
+ if cls.ssl_context is not None:
+ kwargs["ssl_context"] = cls.ssl_context
with socket_helper.transient_internet(cls.NNTP_HOST):
try:
- cls.server = cls.NNTP_CLASS(cls.NNTP_HOST,
- timeout=support.INTERNET_TIMEOUT,
- usenetrc=False)
+ cls.server = cls.NNTP_CLASS(cls.NNTP_HOST, **kwargs)
except SSLError as ssl_err:
# matches "[SSL: DH_KEY_TOO_SMALL] dh key too small"
if re.search(r'(?i)KEY.TOO.SMALL', ssl_err.reason):
raise unittest.SkipTest(f"{cls} got {ssl_err} connecting "
f"to {cls.NNTP_HOST!r}")
+ print(cls.NNTP_HOST)
raise
except EOF_ERRORS:
raise unittest.SkipTest(f"{cls} got EOF error on connecting "
@@ -358,6 +368,9 @@ class NetworkedNNTP_SSLTests(NetworkedNNTPTests):
# Disabled as the connection will already be encrypted.
test_starttls = None
+ ssl_context = ssl._create_unverified_context()
+ ssl_context.set_ciphers("DEFAULT")
+ ssl_context.maximum_version = ssl.TLSVersion.TLSv1_2
#
# Non-networked tests using a local server (or something mocking it).