Skip to content

Implement OCSP client and responder with HTTP and SCGI transport#200

Open
julek-wolfssl wants to merge 4 commits intowolfSSL:mainfrom
julek-wolfssl:ocsp-responder
Open

Implement OCSP client and responder with HTTP and SCGI transport#200
julek-wolfssl wants to merge 4 commits intowolfSSL:mainfrom
julek-wolfssl:ocsp-responder

Conversation

@julek-wolfssl
Copy link
Member

@julek-wolfssl julek-wolfssl commented Feb 19, 2026

Depends on wolfSSL/wolfssl#9761

Core OCSP implementation:

  • Register the new WOLFCLU_OCSP mode enum value
  • The responder main loop accepts connections and handles the request in a transport-agnostic way.
  • Add the OCSP mode to the help text in src/tools/clu_funcs.c.

New HTTP utilities (src/tools/clu_http.c):

  • Move the static kHttpGetMsg from src/client/client.c and the static kHttpServerMsg from src/server/server.c into shared accessor functions
  • Add HTTP builder and server helpers

New SCGI protocol implementation (src/tools/clu_scgi.c):

Certificate and config additions (certs/):

  • Add ocsp-responder-cert.pem which is an authorized responder for ca-cert.pem

Test suites:

  • tests/ocsp/ocsp-test.sh: top-level test runner with four interop combinations (wolfssl↔openssl, wolfssl↔wolfssl, openssl↔wolfssl, openssl↔openssl) sequentially
  • tests/ocsp/ocsp-interop-test.sh: test script taking in $OCSP_CLIENT and $OCSP_RESPONDER. Written to take in the same commands when run with wolfssl or openssl on either side
  • tests/ocsp-scgi/ocsp-scgi-test.sh: SCGI integration test using nginx for HTTP termination

Removed git hooks as they interfere with dev work

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a comprehensive OCSP (Online Certificate Status Protocol) client and responder for wolfCLU, enabling certificate revocation checking with both HTTP and SCGI transport protocols.

Changes:

  • Added OCSP client and responder implementation with transport-agnostic design
  • Implemented HTTP utilities by refactoring existing code and adding server-side helpers
  • Added SCGI protocol support for nginx reverse proxy integration
  • Included comprehensive test suites for interoperability testing (wolfSSL ↔ OpenSSL)

Reviewed changes

Copilot reviewed 29 out of 30 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/ocsp/clu_ocsp.c Core OCSP client and responder implementation with index file parsing
src/tools/clu_http.c HTTP utilities including request/response building and server helpers
src/tools/clu_scgi.c SCGI protocol implementation following spec at python.ca/scgi/protocol.txt
src/tools/clu_pem_der.c Certificate and key loading utilities with PEM to DER conversion
wolfclu/clu_header_main.h Function declarations for OCSP, HTTP, and SCGI APIs
wolfclu/clu_optargs.h Added WOLFCLU_OCSP enum value
wolfclu/client.h Removed unnecessary WOLFSSL_THREAD define
src/clu_main.c Integrated OCSP mode into main command dispatcher
src/tools/clu_funcs.c Added OCSP to help text
src/client/client.c Refactored to use shared HTTP GET message
src/server/server.c Refactored to use shared HTTP response message
tests/ocsp/ocsp-test.sh Top-level test runner for four interop combinations
tests/ocsp/ocsp-interop-test.sh Detailed interop test script with 11 test cases
tests/ocsp-scgi/ocsp-scgi-test.sh SCGI integration test with nginx
tests/ocsp-scgi/scgi_params nginx SCGI parameter configuration
src/include.am Added new source files to build system
Makefile.am Added test directories to make check
wolfCLU.vcxproj Added source files for Windows build
certs/renew.sh Added OCSP responder certificate generation
certs/ocsp.cnf OpenSSL configuration for OCSP signing extension
certs/ocsp-responder-*.pem OCSP responder certificate and key
README.md Added deployment documentation for SCGI mode with nginx
.gitignore Added development artifacts
.github/workflows/*.yml Added nginx and openssl to CI dependencies
autogen.sh Removed Git hooks setup
tests/x509/x509-req-test.sh Added cleanup of tmp.csr file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Depends on wolfSSL/wolfssl#9761

Core OCSP implementation:
- Register the new WOLFCLU_OCSP mode enum value
- The responder main loop accepts connections and handles the request in a transport-agnostic way.
- Add the OCSP mode to the help text in src/tools/clu_funcs.c.

New HTTP utilities (src/tools/clu_http.c):
- Move the static `kHttpGetMsg` from src/client/client.c and the static `kHttpServerMsg` from src/server/server.c into shared accessor functions
- Add HTTP builder and server helpers

New SCGI protocol implementation (src/tools/clu_scgi.c):
- Implement the SCGI wire protocol per https://python.ca/scgi/protocol.txt

Certificate and config additions (certs/):
- Add ocsp-responder-cert.pem which is an authorized responder for ca-cert.pem

Test suites:
- tests/ocsp/ocsp-test.sh: top-level test runner with four interop combinations (wolfssl↔openssl, wolfssl↔wolfssl, openssl↔wolfssl, openssl↔openssl) sequentially
- tests/ocsp/ocsp-interop-test.sh: test script taking in $OCSP_CLIENT and $OCSP_RESPONDER. Written to take in the same commands when run with wolfssl or openssl on either side
- tests/ocsp-scgi/ocsp-scgi-test.sh: SCGI integration test using nginx for HTTP termination
Copilot AI review requested due to automatic review settings March 17, 2026 11:14
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 30 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

…ing logic; add wolfCLU_SendAll function for reliable socket writes
@dgarske
Copy link
Contributor

dgarske commented Mar 18, 2026

PR Review & Testing — OCSP Client and Responder

Test Results

All existing test suites pass:

  • ✅ wolfssl client ↔ openssl responder: 11/11 passed
  • ✅ openssl client ↔ wolfssl responder: 11/11 passed
  • ✅ wolfssl client ↔ wolfssl responder: 11/11 passed
  • ✅ openssl client ↔ openssl responder: 11/11 passed
  • ✅ Graceful shutdown messages verified for all wolfssl responder tests

Additional manual/edge case testing:

  • ✅ Good cert, revoked cert, delegated responder (ocsp-responder-cert.pem with OCSPSigning EKU)
  • -no_nonce option
  • -nrequest N auto-exit after N requests (N+1 correctly refused)
  • ✅ SIGTERM graceful shutdown (no crash, clean exit)
  • ✅ Empty index file → returns "unknown" status, no crash
  • ✅ Missing parameters (-cert, -issuer, -port, -CA, -rsigner, -rkey): clear error messages
  • ✅ Invalid/corrupt certificate files: proper error with wolfcrypt error code
  • ✅ Malformed HTTP input (garbage data, GET instead of POST, empty POST body): 400 Bad Request, responder stays alive
  • ✅ Oversized payload (20KB exceeding 16KB buffer): 400 Bad Request, no buffer overflow
  • ✅ SCGI mode — malformed netstring (no colon, missing comma): error logged, responder survives

Build Notes

wolfSSL must be built with --enable-ocsp --enable-ocsp-responder (note: the --enable-all flag also works). The wolfSSL --enable-ocsp-responder flag (with hyphens) is the correct form. SCGI tests require nginx which may not be available on all systems — the test correctly skips when nginx is not found.

Code Review Findings

Security — all look good:

  • Buffer management: 16KB static buffers with proper bounds checks throughout wolfCLU_HttpServerRecv(), wolfCLU_ScgiReadRequest(), and wolfCLU_HttpServerParseRequest()
  • XSNPRINTF used consistently with overflow detection (sz < 0 || sz >= bufferSz)
  • wolfCLU_SendAll() properly handles partial writes and EINTR
  • Signal handler is async-signal-safe (only sets volatile sig_atomic_t flag, preserves errno)
  • No SA_RESTART allows accept() to be interrupted for responsive shutdown
  • Index file: time field validated for length ≥ 12 before parsing (line 453), serial bounded by XSTRNCPY with sizeof(entry->serial) - 1
  • All memory freed via goto cleanup pattern on all error paths
  • Delegated vs CA signer auto-detection via DER comparison is clean

Minor issues / suggestions:

  1. clu_http.c:437contentLen may be NULL when searching for body: If Content-Length header is not found, contentLen is NULL, and then XSTRSTR((char*)contentLen, "\r\n\r\n") is called with NULL pointer. This is a potential NULL dereference for POST requests without Content-Length header.

    Suggested fix: search for \r\n\r\n from httpReq instead of contentLen when contentLen is NULL, or return error early.

  2. clu_http.c:382wolfCLU_HttpServerSendError uses raw send() instead of wolfCLU_SendAll(): Other send paths use wolfCLU_SendAll() for reliable delivery, but error responses use a single send() call. This is inconsistent — though unlikely to matter for small error responses, it would be more correct to use wolfCLU_SendAll().

  3. clu_ocsp.c:516sig_atomic_t shutdownRequested declared outside #ifndef _WIN32 guard: The variable is at file scope but the signal handler is behind #ifndef _WIN32. On Windows, shutdownRequested is declared but sig_atomic_t may not be available (depends on includes). Consider moving the declaration inside the guard or providing a Windows-compatible type.

  4. clu_ocsp.c:871requestsProcessed++ not reached on error paths: When transportReadRequest or transportSendResponse fails, execution jumps to continue_loop without incrementing requestsProcessed. This means failed requests don't count toward -nrequest limit. This seems intentional but worth documenting — a client sending malformed requests can't exhaust the nrequest budget.

  5. Copyright year inconsistency: clu_ocsp.c has 2006-2025, while clu_http.c and clu_scgi.c have 2006-2026.

Architecture

The transport abstraction pattern (transportReadRequest/transportSendResponse/transportSendError) is clean and well-designed. The error response chain (OCSP error → OCSP error response → fallback to HTTP/SCGI error) handles edge cases properly. The code follows existing wolfCLU patterns well (option parsing, config structs, cleanup via goto).

Overall this is production-quality work. Nice job!

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.

5 participants