Skip to content

[3.11] gh-160040: Distrust compromised eMudhra intermediate CA keys (CVE-2026-115557) (GH-160042) - #160572

Merged
ambv merged 2 commits into
python:3.11from
gpshead:backport-7dd8b47-3.11
Oct 24, 2026
Merged

ambv merged 2 commits into
python:3.11from
gpshead:backport-7dd8b47-3.11

Conversation

@gpshead

@gpshead gpshead commented Oct 24, 2026

Copy link
Copy Markdown
Member

(cherry picked from commit 7dd8b47)

Co-authored-by: Christian Heimes christian@python.org

Manual backport notes (3.11):

  • Modules/_ssl.c: 3.11 predates _ssl.c calls SSL_CTX_get_verify_callback unnecessarily #113332, so _set_verify_mode() still fetched and re-installed the current ctx verify callback. It now installs _ssl_verify_callback directly, as on main (the unused verify_cb local is dropped; CPython never installs a callback of its own). newPySSLSocket()'s post-handshake-auth path already passes SSL_get_verify_callback() through, which inherits the ctx callback, so only main's comment is added there.
  • Lib/test/test_ssl.py: 3.11 lacks main's LEAF_MISSING_AKI_* constants; the DISTRUSTED_SPKI_* block is placed after SIGNED_CERTFILE_ECC_HOSTNAME. The test itself is unchanged.
  • Lib/test/certdata/make_ssl_certs.py: 3.11 predates the argparse cmdlineargs refactor, so make_distrusted_spki_cert() takes no arguments and uses the module-level enddate and literal '7000' days like the rest of the 3.11 script.
  • Makefile.pre.in / PCbuild/_ssl.vcxproj{,.filters}: add only Modules/_ssl/distrusted_spki.h (main's _openssl_mem.h is main-only), plus the Header Files filter definition.

distrusted_spki.h, distrusted.zip and the NEWS entry are identical to main. test_ssl and test_asyncio pass (along with the other ssl-using stdlib tests), including test_distrusted_spki; _ssl.c compiles warning-free with -Wall -Wextra.

…keys (CVE-2026-115557) (pythonGH-160042)

The ssl module now rejects TLS certificate chains that contain any of a set of
compromised eMudhra intermediate CA keys.  This is an extraordinary measure and
a last line of defense: removing trust is primarily the job of the platform root
store, and the built-in denylist only blocks connections while that update has
not yet reached the OS, a container image, or a bundled trust store in various
Python packages.  Entries are added to the denylist only under a very high
threshold.

The denylist matches on the public key (the SHA-256 digest of the RFC-5280
SubjectPublicKeyInfo), so it also covers the cross-signed certificates that
reuse one of the distrusted keys.

---------

Signed-off-by: Christian Heimes <christian@python.org>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

(cherry picked from commit 7dd8b47)

Co-authored-by: Christian Heimes <christian@python.org>
@ambv

ambv commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

The Windows failure is because the NuGet host Python is now 3.15.1, which dropped Loader.load_module(), but 3.11's makeopcodetargets.py still relies on it. This is an infra failure unrelated to this backport and can be dealt with separately.

@ambv

ambv commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Land #160621 first, then merge 3.11 into this PR.

@ambv
ambv merged commit af52b41 into python:3.11 Oct 24, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Development

Successfully merging this pull request may close these issues.

4 participants