From 266b700efec1463cd16871d34b0efc2516364f42 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Wed, 3 Jun 2026 18:10:25 +0200 Subject: [PATCH 1/3] Assume OpenSSL supports keylogging Since version 3.10, CPython requires OpenSSL 1.1.1 or higher. Therefore, support for keylogging can be assumed. --- Doc/library/ssl.rst | 6 +++--- Lib/ssl.py | 14 ++++++-------- Lib/test/test_ssl.py | 8 +------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 41a101e84ac4d75..c96f400e3452283 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 f23bcbe75e7201f..3c0361330d7e951 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 4f998ef2b02a69a..250f581cef97520 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): From 8f4538c938c3278d3d33d0ed801e924d09fd0f86 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 06:50:08 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst 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 000000000000000..d252458226dbe14 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst @@ -0,0 +1,2 @@ +Avoid unnecessary presence checks for :attr:`ssl.SSLContext.keylog_filename`, +which since Python 3.10 always exists. From 7776cf165f33877a69cc665a60d5d790b3b9b297 Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Thu, 4 Jun 2026 09:18:55 +0200 Subject: [PATCH 3/3] Rephrase news entry --- .../Library/2026-06-04-06-50-06.gh-issue-150898.1LkLA3.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 index d252458226dbe14..85328c43368e198 100644 --- 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 @@ -1,2 +1 @@ -Avoid unnecessary presence checks for :attr:`ssl.SSLContext.keylog_filename`, -which since Python 3.10 always exists. +Unconditionally assume :attr:`ssl.SSLContext.keylog_filename` exists.