From 3be23b621cc4797667a79f483d19514a032c7e8f Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Fri, 24 Apr 2026 16:22:06 -0400
Subject: [PATCH] Prepare 26.1.0 release (#1495)

* Prepare 26.1.0 release

Fixes X509Name NUL-byte truncation (CVE-2026-40475), raises the
maximum supported cryptography version to 47.x, and bumps the
version to 26.1.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Use valid DER-encoded OCSPResponse in OCSP stapling tests

OpenSSL 4.0.0 reworked SSL_set_tlsext_status_ocsp_resp to parse the
input bytes via d2i_OCSP_RESPONSE and only staple the parsed form on
the wire. Arbitrary bytes (previously accepted) are now silently
dropped, so the test's fake "this is totally ocsp data" no longer
reaches the client. Use a minimal valid DER OCSPResponse instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 CHANGELOG.rst          | 15 +++++++++++++++
 setup.py               |  2 +-
 src/OpenSSL/crypto.py  |  2 +-
 src/OpenSSL/version.py |  2 +-
 tests/test_crypto.py   |  8 ++++++++
 tests/test_ssl.py      |  6 +++++-
 6 files changed, 31 insertions(+), 4 deletions(-)

Index: pyOpenSSL-24.0.0/src/OpenSSL/crypto.py
===================================================================
--- pyOpenSSL-24.0.0.orig/src/OpenSSL/crypto.py
+++ pyOpenSSL-24.0.0/src/OpenSSL/crypto.py
@@ -649,7 +649,7 @@ class X509Name:
             value = value.encode("utf-8")
 
         add_result = _lib.X509_NAME_add_entry_by_NID(
-            self._name, nid, _lib.MBSTRING_UTF8, value, -1, -1, 0
+            self._name, nid, _lib.MBSTRING_UTF8, value, len(value), -1, 0
         )
         if not add_result:
             _raise_current_error()
Index: pyOpenSSL-24.0.0/tests/test_crypto.py
===================================================================
--- pyOpenSSL-24.0.0.orig/tests/test_crypto.py
+++ pyOpenSSL-24.0.0/tests/test_crypto.py
@@ -1297,6 +1297,14 @@ class TestX509Name:
         name.emailAddress = "quux@example.com"
         assert copy.emailAddress == "bar@example.com"
 
+    def test_null_bytes_preserved(self) -> None:
+        """
+        Null bytes in X509Name field values are round-tripped correctly.
+        """
+        name = x509_name()
+        name.CN = "a\x00b"
+        assert name.CN == "a\x00b"
+
     def test_repr(self):
         """
         `repr` passed an `X509Name` instance should return a string containing
Index: pyOpenSSL-24.0.0/tests/test_ssl.py
===================================================================
--- pyOpenSSL-24.0.0.orig/tests/test_ssl.py
+++ pyOpenSSL-24.0.0/tests/test_ssl.py
@@ -4117,7 +4117,11 @@ class TestOCSP:
     Tests for PyOpenSSL's OCSP stapling support.
     """
 
-    sample_ocsp_data = b"this is totally ocsp data"
+    # Minimal valid DER-encoded OCSPResponse with status "unauthorized"
+    # (SEQUENCE { ENUMERATED 6 }). Required by OpenSSL 4.0+, which parses
+    # the bytes via d2i_OCSP_RESPONSE before stapling and silently drops
+    # unparseable input.
+    sample_ocsp_data = b"\x30\x03\x0a\x01\x06"
 
     def _client_connection(self, callback, data, request_ocsp=True):
         """
