https://github.com/python/cpython/commit/b2e2cd3912af3213ece29a22cebe774e21c6f62a
commit: b2e2cd3912af3213ece29a22cebe774e21c6f62a
branch: main
author: Robsdedude <[email protected]>
committer: vstinner <[email protected]>
date: 2026-06-09T16:37:38+02:00
summary:

gh-150898: Assume OpenSSL supports keylogging (#150870)

Since version 3.10, CPython requires OpenSSL 1.1.1 or higher.
Therefore, support for keylogging can be assumed.

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst
M Doc/library/ssl.rst
M Lib/ssl.py
M Lib/test/test_ssl.py

diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index 41a101e84ac4d7..66fe6c7aee4862 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -146,9 +146,9 @@ purposes.
    *cadata* is given) or uses :meth:`SSLContext.load_default_certs` to load
    default CA certificates.
 
-   When :attr:`~SSLContext.keylog_filename` is supported and the environment
-   variable :envvar:`SSLKEYLOGFILE` is set, :func:`create_default_context`
-   enables key logging.
+   When the environment variable :envvar:`!SSLKEYLOGFILE` is set,
+   :func:`create_default_context` enables key logging by setting
+   :attr:`~SSLContext.keylog_filename` to the variable's value.
 
    The default settings for this context include
    :data:`VERIFY_X509_PARTIAL_CHAIN` and :data:`VERIFY_X509_STRICT`.
diff --git a/Lib/ssl.py b/Lib/ssl.py
index f23bcbe75e7201..3c0361330d7e95 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -721,10 +721,9 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, 
cafile=None,
         # root CA certificates for the given purpose. This may fail silently.
         context.load_default_certs(purpose)
     # OpenSSL 1.1.1 keylog file
-    if hasattr(context, 'keylog_filename'):
-        keylogfile = os.environ.get('SSLKEYLOGFILE')
-        if keylogfile and not sys.flags.ignore_environment:
-            context.keylog_filename = keylogfile
+    keylogfile = os.environ.get('SSLKEYLOGFILE')
+    if keylogfile and not sys.flags.ignore_environment:
+        context.keylog_filename = keylogfile
     return context
 
 def _create_unverified_context(protocol=None, *, cert_reqs=CERT_NONE,
@@ -775,10 +774,9 @@ def _create_unverified_context(protocol=None, *, 
cert_reqs=CERT_NONE,
         # root CA certificates for the given purpose. This may fail silently.
         context.load_default_certs(purpose)
     # OpenSSL 1.1.1 keylog file
-    if hasattr(context, 'keylog_filename'):
-        keylogfile = os.environ.get('SSLKEYLOGFILE')
-        if keylogfile and not sys.flags.ignore_environment:
-            context.keylog_filename = keylogfile
+    keylogfile = os.environ.get('SSLKEYLOGFILE')
+    if keylogfile and not sys.flags.ignore_environment:
+        context.keylog_filename = keylogfile
     return context
 
 # Used by http.client if no context is explicitly passed.
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 4f998ef2b02a69..40111d41007795 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -59,10 +59,7 @@
 CAN_GET_SELECTED_OPENSSL_SIGALG = ssl.OPENSSL_VERSION_INFO >= (3, 5)
 PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS')
 
-HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename')
-requires_keylog = unittest.skipUnless(
-    HAS_KEYLOG, 'test requires OpenSSL 1.1.1 with keylog callback')
-CAN_SET_KEYLOG = HAS_KEYLOG and os.name != "nt"
+CAN_SET_KEYLOG = (os.name != "nt")
 requires_keylog_setter = unittest.skipUnless(
     CAN_SET_KEYLOG,
     "cannot set 'keylog_filename' on Windows"
@@ -5453,7 +5450,6 @@ def keylog_lines(self, fname=os_helper.TESTFN):
         with open(fname) as f:
             return len(list(f))
 
-    @requires_keylog
     def test_keylog_defaults(self):
         self.addCleanup(os_helper.unlink, os_helper.TESTFN)
         ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
@@ -5481,7 +5477,6 @@ def test_keylog_defaults(self):
         with self.assertRaises(TypeError):
             ctx.keylog_filename = 1
 
-    @requires_keylog
     def test_keylog_filename(self):
         self.addCleanup(os_helper.unlink, os_helper.TESTFN)
         client_context, server_context, hostname = testing_context()
@@ -5522,7 +5517,6 @@ def test_keylog_filename(self):
         client_context.keylog_filename = None
         server_context.keylog_filename = None
 
-    @requires_keylog
     @unittest.skipIf(sys.flags.ignore_environment,
                      "test is not compatible with ignore_environment")
     def test_keylog_env(self):
diff --git 
a/Misc/NEWS.d/next/Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst 
b/Misc/NEWS.d/next/Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst
new file mode 100644
index 00000000000000..85328c43368e19
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst
@@ -0,0 +1 @@
+Unconditionally assume :attr:`ssl.SSLContext.keylog_filename` exists.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to