python / python/cpython

SSLContext.load_verify_locations(cadata=<DER>) fails with [ASN1: NOT_ENOUGH_DATA] when linked against OpenSSL 3.0.21+

Đang mở
#151,504 16 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

3.11 extension-modules topic-SSL type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu trong Modules/_ssl.c tại _add_ca_certs(), đặc biệt là vòng lặp d2i_X509_bio() và cách xử lý ERR_peek_last_error(). Tái hiện lỗi cadata DER bằng ví dụ ssl được cung cấp, sau đó xác minh rằng chứng chỉ đơn lẻ được tải thành công và việc tải kho tin cậy của ngữ cảnh mặc định trên Windows hoạt động với cách xử lý EOF đã được cập nhật.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
security
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
74/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.