Repository navigation
SSLContext.load_verify_locations(cadata=<DER>) fails with [ASN1: NOT_ENOUGH_DATA] when linked against OpenSSL 3.0.21+ #151504
Description
Bug report
Bug description:
When CPython is linked against OpenSSL 3.0.21 (and likely any release carrying the CVE-2026-34180 ASN.1 hardening), SSLContext.load_verify_locations(cadata=) raises:
ssl.SSLError: [ASN1: NOT_ENOUGH_DATA] not enough data (_ssl.c:NNNN)
even for a single, perfectly valid DER certificate. On Windows this breaks ssl.create_default_context() outright, because SSLContext._load_windows_store_certs() loads the system trust store via cadata=. The practical effect is that all default-context HTTPS fails (e.g. importing aiohttp, which builds a default context at import time, crashes).
Reproducer (platform-independent)
import ssl
pem = ssl.get_server_certificate(("www.python.org", 443))
der = ssl.PEM_cert_to_DER_cert(pem)
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.load_verify_locations(cadata=der) # raises [ASN1: NOT_ENOUGH_DATA] on OpenSSL 3.0.21+
print("loaded OK")OpenSSL 3.0.15 (and earlier): prints loaded OK.
OpenSSL 3.0.21: raises ssl.SSLError: [ASN1: NOT_ENOUGH_DATA].
The certificate itself is fine — calling d2i_X509 directly against the same libcrypto-3.dll parses it successfully; only the path through _ssl fails.
Root cause
In Modules/_ssl.c, _add_ca_certs() reads certs in a loop until d2i_X509_bio() returns NULL, then inspects the leftover error to distinguish a clean end-of-buffer from a real failure. It only accepts ASN1_R_HEADER_TOO_LONG as the benign EOF marker:
} else if ((filetype == SSL_FILETYPE_ASN1) &&
(ERR_GET_LIB(err) == ERR_LIB_ASN1) &&
(ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) {
/* EOF ASN1 file, not an error */
ERR_clear_error();
retval = 0;
}OpenSSL 3.0.21 now reports end-of-buffer as ASN1_R_NOT_ENOUGH_DATA (reason 142) instead of ASN1_R_HEADER_TOO_LONG. That reason isn't whitelisted, so the function falls through to the generic error branch and raises, discarding the load. Confirmed by reading ERR_peek_last_error() after the final d2i_X509_bio() on a single-cert buffer: 0x0680008E = asn1 ... not enough data.
Proposed fix
Treat ASN1_R_NOT_ENOUGH_DATA as a clean EOF alongside ASN1_R_HEADER_TOO_LONG:
} else if ((filetype == SSL_FILETYPE_ASN1) &&
(ERR_GET_LIB(err) == ERR_LIB_ASN1) &&
((ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG) ||
(ERR_GET_REASON(err) == ASN1_R_NOT_ENOUGH_DATA))) {
/* EOF ASN1 buffer, not an error (OpenSSL 3.0.21+ reports the
end-of-data condition as ASN1_R_NOT_ENOUGH_DATA). */
ERR_clear_error();
retval = 0;
}With this change, load_verify_locations(cadata=...) succeeds, the Windows store loads fully, and TLS verification works again.
Environment
CPython 3.11.15 (self-built, Windows x64, MSVC), linked against self-compiled OpenSSL 3.0.21.
Windows 11.
Also expected to affect any build/version of CPython linked against OpenSSL ≥ 3.0.21 (or whichever release introduced the reason-code change), on any platform, for the DER cadata path.
CPython versions tested on:
3.11
Operating systems tested on:
Windows
Activity
vstinner commentedon Jun 15, 2026
Note: I cannot reproduce the issue on Fedora 44 with OpenSSL 3.5.5.
nkfilis commentedon Jun 17, 2026
likely to happen for you in 3.5.7
zooba commentedon Jun 22, 2026
This seems to be a 3.11-only issue that's already been resolved in 3.12. I recently started hitting it on my private Windows builds.
In 3.12, a
was_bio_eofflag was added and is assignedBIO_eof(biobuf). Then when we break out, the code snippet mentioned in the original report checks that flag rather than relying on specific error codes.@pablogsal How do you feel about fixing this in 3.11? It's not strictly a security issue in itself, but without it, it's not feasible to use newer OpenSSL (I haven't tested with newer than OpenSSL 3.0.21), at least on Windows, possibly other platforms too.
po1nt-1 commentedon Jun 23, 2026
Here are the test results for this issue across various Fedora images and Python versions
upd: added
ssl.OPENSSL_VERSIONzooba commentedon Jun 23, 2026
Can you include the OpenSSL versions? That's what is relevant here, though it does seem likely that it's the same issue.
We need RM agreement to treat this as a security fix, since it isn't really a security issue.
encukou commentedon Jun 30, 2026
It's now hitting 3.10 & 3.11 buildbots.
hroncok commentedon Jul 1, 2026
We might see this in Fedora for OpenSSL 3.5.7+
https://koschei.fedoraproject.org/package/python3.11?collection=f44
https://koschei.fedoraproject.org/package/python3.10?collection=f44
hroncok commentedon Jul 1, 2026
acfe02f looks like a change that could explain why this no longer impacts 3.12+
EDIT: Yes, I can confirm that backporting that to 3.11 makes it pass the tests.
zooba commentedon Jul 1, 2026
Yes, that's the change. I backported it to my own (private) fork of 3.11 and it's working fine so far (hasn't made it into production anywhere, but it's passing the tests that were failing without it).
00489: Use BIO_eof to detect EOF for SSL_FILETYPE_ASN1
00489: Use BIO_eof to detect EOF for SSL_FILETYPE_ASN1
8 remaining items
Mark centos9s jobs non-voting
Update git submodules
fix: download ansible collections using curl, not Python SSL
fix: download ansible collections using curl, not Python SSL
1rcjoy commentedon Jul 16, 2026
Ran into this issue on
Rocky Linux 9.8
Python 3.9.25
openssl-3.5.5-5.el9_8.x86_64
openssl-libs-3.5.5-5.el9_8.x86_64
Have been looking around, but not sure who is fixing this ? Python ? or openssl ?
Would help to know what package update to watch for.
hroncok commentedon Jul 16, 2026
In RHEL (and hence I assume also in Rocky) it should be both.
OSAC-2801: Scope validate_certs:false to k3s_controller's plain-HTTP …
OSAC-2801: Scope validate_certs:false to k3s_controller's plain-HTTP …
zooba commentedon Jul 20, 2026
That's an unnecessarily long way to say "me too".
What we need is the release manager to say whether we can backport our own fix or not. No number of paragraphs are going to help with that.
OSAC-2801: Work around ansible-galaxy TLS regression in tooling-check…
GitHub Release 다운로드에서 CVE-2026-34180 관련 SSL 검증 오류 임시 우회
core: openssl: fix python ptest errors
core: openssl: fix python ptest errors
cidermole commentedon Aug 14, 2026
Hit this on Windows 11 25H2 with Python 3.11.4
Solution is to upgrade Python or to avoid using pip-system-certs.
samatjain commentedon Sep 14, 2026
The RC appears to be an upstream OpenSSL fix for asn1_d2i_read_bio reads too many bytes · Issue #22704 · openssl/openssl / CVE-2026-34180 / CVE-2026-34180 - GitHub Advisory Database ; this broke the API contract for OpenSSL's ASN.1-based certificate parsing on Windows.
This faulty fix was backported to a bunch of OpenSSL releases, and also actually fixed in a following release by openssl/openssl#31807:
77f8454895430472298fecb386c0244007e39bbb27f8738688d7623687ff719503e734e38ab6eec366c60280445b06163b4360d537e8Per thread, it looks like Python 3.12+ is more defensive about this API change. Absent a fix for Python 3.11 and earlier, it looks like the best way forward: