Skip to content

Fix OCSP status verify callback gaps and Zephyr responder lookup - #11977

Open
Frauschi wants to merge 3 commits into
wolfSSL:masterfrom
Frauschi:ocsp_fixes
Open

Frauschi wants to merge 3 commits into
wolfSSL:masterfrom
Frauschi:ocsp_fixes

Conversation

@Frauschi

@Frauschi Frauschi commented Nov 3, 2026

Copy link
Copy Markdown
Member

Closes three OCSP stapling gaps: the status verify callback was missing from client-only builds and never saw a staple that does not decode, and a Zephyr build with OCSP could not reach a responder.

Changes

  • Zephyr: define HAVE_SOCKADDR when the HTTP client is built, and HAVE_GETADDRINFO so responder lookups go through zsock_getaddrinfo
  • Guard wolfSSL_CTX_set_ocsp_status_verify_cb, its CTX fields and both call sites on status request support alone, so NO_WOLFSSL_SERVER builds define and use it
  • Run the status verify callback for a staple that fails to decode, as the status_request_v2 multi path already does
  • Clear the recorded producedAt when that decode fails, so a staple the callback accepts does not report an earlier date
  • Document when the callback runs and what its return value means (English and Japanese)

Testing

  • New test_ocsp_status_verify_cb_undecodable_staple: truncated staple over TLS 1.2 and 1.3, checking callback arguments, alert, override and produced date
  • New test_wolfSSL_CTX_set_ocsp_status_verify_cb: sets the callback on a client CTX, run by the all-no-server os-check leg
  • test_internal_status_whitebox now runs its CsrDoStatusVerifyCb sweep in client-only builds
  • New Zephyr 4.x CI build: native_sim wolfssl_tls_sock with OCSP and stapling, without DTLS

HAVE_OCSP makes wolfio.h define HAVE_HTTP_CLIENT, which compiles
wolfIO_TcpConnect() into a Zephyr build. Without HAVE_SOCKADDR its body
is the stub that always fails, and zephyr/user_settings.h defined
HAVE_SOCKADDR only for CONFIG_WOLFSSL_DTLS, so a Zephyr client with OCSP
but no DTLS could never reach a responder. With HAVE_SOCKADDR set, the
body took the gethostbyname() branch, because nothing defined
HAVE_GETADDRINFO for Zephyr. That fails with an implicit declaration and
an incomplete struct hostent: Zephyr has no gethostbyname() at all, only
gethostent() in its POSIX netdb.h. Name resolution goes through
zsock_getaddrinfo(), which this block already maps
getaddrinfo/freeaddrinfo/ADDRINFO onto; only the switch was missing.

Define HAVE_SOCKADDR in the Zephyr socket block whenever the HTTP client
is compiled in (HAVE_OCSP or HAVE_CRL_IO), and HAVE_GETADDRINFO for every
Zephyr build. The OCSP responder screen, wolfIO_OcspDestAllowed(), has the
same resolver fallback and now uses getaddrinfo too.

Nothing in CI built the HTTP client for Zephyr, so add an OCSP and
stapling build without DTLS to the Zephyr 4.x list. It compiles the
client in and runs the TLS socket sample, which does no OCSP lookup.
wolfSSL_CTX_set_ocsp_status_verify_cb() hooks the client's check of a
stapled OCSP response: ProcessCSR_ex() and the TLS 1.2 certificate_status
handler pass their result through it, so the application can record the
outcome or override an error. Its setter, the WOLFSSL_CTX fields and both
call sites were all under NO_WOLFSSL_SERVER, next to the server's own
stapling state, so a build with NO_WOLFSSL_SERVER declared the setter in
ssl.h but did not define it, and never consulted the callback.

Guard them on HAVE_CERTIFICATE_STATUS_REQUEST(_V2) alone, like the rest
of the status request code that runs on the client.

The new test sets the callback on a client CTX, so the client-only
os-check builds link and run the setter.
ProcessCSR_ex() decodes a stapled response twice, the first time only to
read producedAt, and called CsrDoStatusVerifyCb() only when that first
decode succeeded. A staple that is not a well-formed OCSPResponse
therefore failed the handshake with BAD_CERTIFICATE_STATUS_ERROR without
reaching the callback, so the application could neither see nor override
that error, although it can for a response that decodes and then fails
verification. ProcessCSR() handles a TLS 1.2 status_request through this
function, and TLS 1.3 reads each certificate's staple through it.

Call the callback after both decodes whatever their result, as the
status_request_v2 multi handler already does. A failed first decode now
also clears the recorded producedAt format, so a handshake the callback
lets through does not report an earlier staple's date from
wolfSSL_get_ocsp_producedDate(). The callback's documentation now says
when it runs and what its return value does, since a callback that
returns 0 for BAD_CERTIFICATE_STATUS_ERROR now also accepts a staple
that does not decode.

The new test staples a truncated response over TLS 1.2 and TLS 1.3,
checks that the callback runs once for index 0 with the staple's length
and BAD_CERTIFICATE_STATUS_ERROR, that the handshake fails with a
bad_certificate_status_response alert unless the callback overrides the
error, and that no produced date is reported.
@Frauschi Frauschi self-assigned this Nov 3, 2026
Copilot AI balanced review requested due to automatic review settings November 3, 2026 19:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues block approval of the OCSP callback and Zephyr responder lookup changes.

No open issues 🎉

What changed in this PR

This PR fixes OCSP stapling callback gaps in wolfSSL and enables OCSP responder lookup on Zephyr.

Changes:

  • Makes status verification callbacks available in client-only builds and invokes them for undecodable staples, clearing stale produced-date metadata.
  • Enables Zephyr socket address and resolver support, with a new OCSP-enabled CI build.
  • Adds regression tests and documents callback behavior in English and Japanese.
File Description
wolfssl/​wolfio.h Enables Zephyr socket address and responder lookup support.
wolfssl/​internal.h Exposes callback fields in client-only builds.
tests/​unit-mcdc/​test_internal_status_whitebox.c Enables callback checks in client-only builds.
tests/​api/​test_ssl_crl_ocsp.h Declares and registers the callback setter test.
tests/​api/​test_ssl_crl_ocsp.c Tests callback registration on a client context.
tests/​api/​test_ocsp.h Declares the undecodable-staple regression test.
tests/​api/​test_ocsp.c Tests malformed staples, callback overrides, alerts, and date clearing.
tests/​api.c Registers the undecodable-staple test.
src/​ssl_api_crl_ocsp.c Makes the callback setter available without server support.
src/​internal.c Invokes callbacks on decode failures and clears stale date metadata.
doc/​dox_comments/​header_files/​ssl.h Documents callback invocation and return values in English.
doc/​dox_comments/​header_files-ja/​ssl.h Documents callback invocation and return values in Japanese.
.github/​scripts/​zephyr-4.x/​ocsp.conf Adds OCSP and stapling configuration for CI.
.github/​scripts/​zephyr-4.x/​builds.txt Adds the OCSP-enabled Zephyr build.

Review effort: Balanced

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

@Frauschi Frauschi assigned wolfSSL-Bot and unassigned Frauschi Nov 5, 2026
@Frauschi

Frauschi commented Nov 5, 2026

Copy link
Copy Markdown
Member Author

@claude review

@Frauschi

Frauschi commented Nov 5, 2026

Copy link
Copy Markdown
Member Author

@wolfSSL-Fenrir-bot review balanced

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #11977

Scan targets checked: wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): .github/scripts/zephyr-4.x/builds.txt, .github/scripts/zephyr-4.x/ocsp.conf, doc/dox_comments/header_files-ja/ssl.h, doc/dox_comments/header_files/ssl.h, tests/api/test_ocsp.h, tests/api/test_ssl_crl_ocsp.h
Coverage: 6 of 8 in-scope changed file(s) opened by the reviewer; not opened: tests/api.c, tests/api/test_ssl_crl_ocsp.c

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Balanced

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this PR and didn't find any bugs. It changes how stapled OCSP responses are verified during the TLS handshake, and the status verify callback can now override a decode failure, so a human look would still be worthwhile.

What was reviewed:

  • CsrDoStatusVerifyCb and its two call sites in src/internal.c. The ProcessCSR_ex call now also runs for undecodable staples, which matches the existing DoCertificateStatus path, and a failed decode now clears ocspProducedDateFormat.
  • The ocspStatusVerifyCb/ocspStatusVerifyCbArg fields in WOLFSSL_CTX move out of the server-only block. Their guard now matches the setter in src/ssl_api_crl_ocsp.c and the call-site guards.
  • The wolfio.h additions apply only inside the WOLFSSL_ZEPHYR branch: HAVE_SOCKADDR when the HTTP client is built, and HAVE_GETADDRINFO.
Extended reasoning...

The change touches OCSP stapling verification in the TLS handshake (src/internal.c), the WOLFSSL_CTX struct layout across several build configurations, Zephyr socket macros, docs and tests. The security-relevant part is a semantics change. An existing callback that returns 0 no matter what err says will now also accept a staple that fails to decode, where before the handshake failed. That is consistent with the documented rule that the return value replaces err, but maintainers should confirm they want it. No bugs were found and no reviewer objections are outstanding. I deferred because the change is in security-sensitive certificate-status code and changes callback behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants