Skip to content

Use wolfSSL's EmbedOcspLookup in non-blocking async OCSP example - #604

Open
night1rider wants to merge 1 commit into
wolfSSL:masterfrom
night1rider:fenrir-issue-2904
Open

Use wolfSSL's EmbedOcspLookup in non-blocking async OCSP example#604
night1rider wants to merge 1 commit into
wolfSSL:masterfrom
night1rider:fenrir-issue-2904

Conversation

@night1rider

@night1rider night1rider commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Replace the system("curl ... ") OCSP fetch in the async example with wolfSSL's EmbedOcspLookup, so the certificate-supplied URL is fetched as data over a socket instead of executed.

Both examples now target www.digicert.com (Google dropped OCSP): ocsp_nonblock
fetches the leaf live over TLS rather than a bundled cert that expires, and the async example uses wolfSSL's native async API. Bundle the DigiCert CAs and drop the expired google.pem and stale GTS certs.

@night1rider night1rider self-assigned this Jul 17, 2026

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread ocsp/ocsp_nonblock/ocsp_nonblock_async.c Outdated
Comment thread ocsp/ocsp_nonblock/ocsp_nonblock_async.c Outdated

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

@philljj
philljj self-requested a review July 29, 2026 19:41
@philljj philljj self-assigned this Jul 29, 2026
@philljj
philljj requested a review from Copilot July 30, 2026 02:10

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.

Pull request overview

This PR hardens the non-blocking async OCSP example by removing execution of an untrusted OCSP responder URL via system()/curl, instead using wolfSSL’s built-in OCSP HTTP fetch API, and updates server connection setup to resolve the hostname dynamically via getaddrinfo().

Changes:

  • Replace system("curl ... <untrusted-url>") OCSP fetching with EmbedOcspLookup() + EmbedOcspRespFree().
  • Resolve SERVER_NAME via getaddrinfo() instead of using a hard-coded IP address.
  • Update README sample output to remove the printed curl command flow.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
ocsp/ocsp_nonblock/ocsp_nonblock_async.c Switch OCSP callback to EmbedOcspLookup() and resolve server address via getaddrinfo().
ocsp/ocsp_nonblock/README.md Remove curl-command/temporary-file output lines from the example run log.

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

Comment thread ocsp/ocsp_nonblock/ocsp_nonblock_async.c Outdated
Comment thread ocsp/ocsp_nonblock/ocsp_nonblock_async.c Outdated

@philljj philljj 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.

Overall this looks good and an improvement over the original system(3) based example.

Two requested changes:

  1. While you're updating the README.md we should remove this outdated section:

NOTE: Before building this example the asynchronous support must be obtained from (https://github.com/wolfSSL/wolfAsyncCrypt) and installed into wolfSSL by following the instructions in the README file contained in the wolfAsyncCrypt repository.

The wolfAsyncCrypt repo is deprecated, and the async code is upstreamed into wolfssl now.

  1. It would be nice to just include a cert to use for this ocsp_nonblock_async example.

note: the google.pem used by ocsp_nonblock.c example is expired, but that's outside scope of this PR.

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Fenrir result: Approved ✅

No new issues found in the changed files.

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

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 3
3 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

night1rider added a commit to night1rider/wolfssl-examples that referenced this pull request Sep 8, 2026
Set SO_RCVTIMEO/SO_SNDTIMEO to the fetch timeout before wolfSSL_connect so a peer that accepts TCP but stalls TLS fails instead of blocking forever, and treat SSL_ERROR_WANT_WRITE as retryable in the async client's handshake loop, per PR wolfSSL#604 review.

@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 #604

Scan targets checked: wolfssl-examples-bugs, wolfssl-examples-src

Findings: 4
4 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

@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 #604

Scan targets checked: wolfssl-examples-src, wolfssl-examples-bugs
Findings: 2
1 finding(s) posted as inline comments (see file-level comments below)

Required changes (1)

Responder screening is bypassed by the custom OCSP callback

File: ocsp/ocsp_nonblock/ocsp_nonblock.c:107
Function: OcspLookupNonBlockCb
Category: Unsafe defaults

OcspLookupNonBlockCb() connects to the certificate URL without responder screening, so WOLFSSL_OCSP_SCREEN_RESPONDER does not block private or loopback targets. Unlike known #2904, this is SSRF, not shell injection.

Suggested fix: Call wolfIO_OcspDestAllowed() on domainName before wolfIO_TcpConnect() when responder screening is enabled.
Basis: wolfSSL wolfio.h exposes wolfIO_OcspDestAllowed() under WOLFSSL_OCSP_SCREEN_RESPONDER for OCSP destination screening.


This review was generated automatically by Fenrir. Reported findings require changes before merge.

night1rider added a commit to night1rider/wolfssl-examples that referenced this pull request Sep 9, 2026
Set SO_RCVTIMEO/SO_SNDTIMEO to the fetch timeout before wolfSSL_connect so a peer that accepts TCP but stalls TLS fails instead of blocking forever, and treat SSL_ERROR_WANT_WRITE as retryable in the async client's handshake loop, per PR wolfSSL#604 review.

@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 #604

Scan targets checked: wolfssl-examples-src, wolfssl-examples-bugs
Findings: 3

Required changes (3)

Responder screening is vulnerable to DNS rebinding

File: ocsp/ocsp_nonblock/ocsp_nonblock.c:92
Function: OcspLookupNonBlockCb
Category: Logic errors

wolfIO_OcspDestAllowed() screens one DNS result, then wolfIO_TcpConnect() resolves again, letting DNS rebinding bypass private-address blocking and permit SSRF. Unlike known #2904, this is address-validation TOCTOU.

Suggested fix: Resolve once, screen every returned address, and connect directly to an accepted sockaddr without resolving the hostname again.
Basis: Linux getaddrinfo(3): returned ai_addr and ai_addrlen values are suitable for connect(2) and remain valid until freeaddrinfo().


Embedded OCSP lookup permits DNS-rebinding SSRF

File: ocsp/ocsp_nonblock/ocsp_nonblock_async.c:133
Function: lookup_with_deadline
Category: Logic errors

EmbedOcspLookup() screens the responder through one DNS lookup and connects after another, letting DNS rebinding bypass private-address blocking and permit SSRF. Unlike known #2904, no shell execution is involved.

Related known finding #2904 (similar but distinct): Both arise from attacker-controlled OCSP responder URLs in the async callback path, but #2904 passes the URL to system() and has shell-quoting injection as its cause. This candidate validates then re-resolves before TCP connect; its direct-address connection patch cannot fix #2904.

Suggested fix: Use a lookup callback that screens resolved addresses and connects directly to an accepted address without a second DNS lookup.
Basis: Linux getaddrinfo(3): returned ai_addr and ai_addrlen values are suitable for connect(2) and remain valid until freeaddrinfo().


Uncanceled resolver retains expired stack pointers

File: ocsp/ocsp_nonblock/ocsp_nonblock_async.c:186
Function: resolve_with_deadline
Category: Memory management bugs

EAI_NOTCANCELED leaves the resolver running while req references open_socket()'s stack portStr and hints, causing invalid reads after return. Known #12584 concerns socket cleanup; this is resolver-input lifetime.

Related known finding #12584 (similar but distinct): Both are error-path lifetime/cleanup defects in the async OCSP client, but #12584 leaks a TCP socket after connect failure in test_connect. This candidate leaves an asynchronous resolver using stack-backed request inputs after failed cancellation in resolve_with_deadline, requiring independent request-lifetime handling.

Suggested fix: Keep the request and all referenced inputs alive until gai_error() no longer returns EAI_INPROGRESS, including after failed cancellation.
Basis: Linux getaddrinfo_a(3): EAI_NOTCANCELED means the request was not canceled, and an in-progress request proceeds as if gai_cancel() was never called.

Referenced code: ocsp/ocsp_nonblock/ocsp_nonblock_async.c:186-188 (3 lines)


This review was generated automatically by Fenrir. Reported findings require changes before merge.

@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 #604

Scan targets checked: wolfssl-examples-src, wolfssl-examples-bugs

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

@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 #604

Scan targets checked: wolfssl-examples-src, wolfssl-examples-bugs

Fenrir result: Approved ✅

No new issues found in the changed files.

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

@wolfSSL-Fenrir-bot
wolfSSL-Fenrir-bot dismissed stale reviews from themself September 9, 2026 23:20

Fenrir's latest completed scan found no issues; clearing the prior automated change request.

The plain client fetches the live www.digicert.com certificate itself and runs the non-blocking OCSP check with wolfSSL's own HTTP helpers, so no URL from a certificate ever reaches a shell. Both clients resolve the responder once, refuse loopback, private and link-local addresses, and connect to the address they checked. The cert fetch, the TCP connect, the handshake and the OCSP lookup each run non-blocking against a deadline so a stalled peer fails instead of hanging. The async client reads the OCSP reply in one parser call through a receive callback that waits against that deadline. The README and CI manifest gain a dedicated ocsp-nonblock build profile with the responder screening flag.
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