Fixed failing cert verification with nonblocking-OCSP and low MFL#9957
Fixed failing cert verification with nonblocking-OCSP and low MFL#9957MatanRad wants to merge 1 commit intowolfSSL:masterfrom
Conversation
|
Can one of the admins verify this patch? |
There was a problem hiding this comment.
Pull request overview
Fixes a TLS 1.3 handshake bug where, under nonblocking OCSP with a small Max Fragment Length (MFL), a fragmented Certificate handshake message can complete assembly but then return OCSP_WANT_READ; the current fragment handling would ignore that and move past the assembled pendingMsg.
Changes:
- Treat
OCSP_WANT_READlikeWC_PENDING_Ewhen processing a fully reassembled fragmented handshake message, rewinding state to retry the fragment. - Expand the preprocessor guard around the retry/rewind logic to include nonblocking OCSP builds.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP) | ||
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) || ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) { |
There was a problem hiding this comment.
The rollback for OCSP_WANT_READ is currently compiled only when WOLFSSL_NONBLOCK_OCSP or WOLFSSL_ASYNC_CRYPT is defined. OCSP_WANT_READ can also be returned from CRL I/O paths (HAVE_CRL_IO) during cert verification, and this fragment-buffer code would still free pendingMsg and advance *inOutIdx in that case, reintroducing the same “skip pendingMsg” behavior. Consider keying this block off WOLFSSL_ASYNC_IO (or additionally HAVE_CRL_IO) to ensure any nonblocking I/O path returning OCSP_WANT_READ preserves pendingMsg for retry.
| #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP) | |
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) || ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) { | |
| #if defined(WOLFSSL_ASYNC_IO) || defined(HAVE_CRL_IO) || \ | |
| defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP) | |
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) || | |
| ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) { |
| #ifdef WOLFSSL_ASYNC_CRYPT | ||
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) { | ||
| #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP) | ||
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) || ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) { |
There was a problem hiding this comment.
The combined condition ret == ...WC_PENDING_E || ret == ...OCSP_WANT_READ is written on a single long line, whereas nearby code in this file typically wraps multi-term conditions across lines for readability/consistency. Please reformat this if to match the surrounding style (e.g., split across lines like other WC_PENDING_E/OCSP_WANT_READ checks).
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) || ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) { | |
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) || | |
| ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) { |
| #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP) | ||
| if (ret == WC_NO_ERR_TRACE(WC_PENDING_E) || ret == WC_NO_ERR_TRACE(OCSP_WANT_READ)) { | ||
| /* setup to process fragment again */ | ||
| ssl->arrays->pendingMsgOffset -= inputLength; | ||
| *inOutIdx -= inputLength + ssl->keys.padSz; |
There was a problem hiding this comment.
This change adds special handling for OCSP_WANT_READ when completing a fragmented TLS 1.3 handshake message. There doesn’t appear to be an automated regression test exercising TLS 1.3 fragmentation together with a nonblocking OCSP callback that returns WANT_READ (e.g., similar to the existing TLS1.3 fragment test in tests/test-tls13.conf, but with WOLFSSL_NONBLOCK_OCSP/OCSP callback configured). Adding such a test would help prevent regressions in this retry/rewind logic.
Description
Fixes a bug that happens when using nonblocking OCSP and having a low MFL configured.
This is caused by the Certificate handshake message being fragmented and the
OCSP_WANT_READerror being ignored, causing the library to skip over the currentpendingMsg.Testing
Ran locally with a nonblocking OCSP setup and a configured MFL of 1024