From d0ca682749be4364a92929cd238414ec413d8210 Mon Sep 17 00:00:00 2001 From: Syed Mohammed Nayyar Date: Sun, 25 Oct 2026 23:30:30 +0530 Subject: [PATCH] reject unsuccessful ocsp responses that carry response bytes --- CHANGELOG.rst | 5 +++++ src/rust/src/x509/ocsp_resp.rs | 10 +++++++++- tests/x509/test_ocsp.py | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2b33d8040ac5..2500fdaf6b5c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -26,6 +26,11 @@ Changelog empty ``GeneralNames`` sequence, matching the ``SIZE (1..MAX)`` constraint RFC 5280 4.2.1.6/4.2.1.7 places on the field and the strictness already applied to ``extendedKeyUsage``. +* :func:`~cryptography.x509.ocsp.load_der_ocsp_response` now raises + ``ValueError`` for a response whose ``responseStatus`` is not + ``successful`` but which still carries ``responseBytes``. Previously the + properties of such a response returned the embedded ``BasicOCSPResponse`` + data instead of raising, contrary to their documentation. .. _v50-0-2: diff --git a/src/rust/src/x509/ocsp_resp.rs b/src/rust/src/x509/ocsp_resp.rs index 0114e02065a4..baabea55782b 100644 --- a/src/rust/src/x509/ocsp_resp.rs +++ b/src/rust/src/x509/ocsp_resp.rs @@ -38,7 +38,15 @@ pub(crate) fn load_der_ocsp_response( | INTERNAL_ERROR_RESPONSE | TRY_LATER_RESPONSE | SIG_REQUIRED_RESPONSE - | UNAUTHORIZED_RESPONSE => {} + | UNAUTHORIZED_RESPONSE => { + if response.response_bytes.is_some() { + return Err(CryptographyError::from( + pyo3::exceptions::PyValueError::new_err( + "Unsuccessful OCSP response contains a BasicResponse", + ), + )); + } + } _ => { return Err(CryptographyError::from( pyo3::exceptions::PyValueError::new_err("OCSP response has an unknown status code"), diff --git a/tests/x509/test_ocsp.py b/tests/x509/test_ocsp.py index cc9283bb931b..2208161866f7 100644 --- a/tests/x509/test_ocsp.py +++ b/tests/x509/test_ocsp.py @@ -1642,6 +1642,21 @@ def test_response_bytes_absent(self): ocsp.load_der_ocsp_response, ) + def test_response_bytes_present_unsuccessful(self): + data = bytearray( + load_vectors_from_file( + os.path.join("x509", "ocsp", "resp-sha256.der"), + lambda f: f.read(), + mode="rb", + ) + ) + # Change the responseStatus from successful (0) to tryLater (3), + # leaving the BasicOCSPResponse in place. + assert data[4:7] == b"\x0a\x01\x00" + data[6] = 3 + with pytest.raises(ValueError): + ocsp.load_der_ocsp_response(bytes(data)) + def test_unknown_response_status(self): with pytest.raises(ValueError): _load_data(