What Is CVE-2026-94417?
CVE-2026-94417 represents a critical vulnerability in the wolfSSL embedded SSL/TLS library that allows attackers to bypass certificate revocation checking entirely. When applications configure both OCSP (Online Certificate Status Protocol) and CRL (Certificate Revocation List) validation on the same context, wolfSSL fails to enforce revocation checks for certificates lacking an Authority Information Access (AIA) OCSP responder URL.
The core issue: wolfSSL’s soft-fail mechanism treats a missing OCSP responder URL as a successful validation result, then skips the CRL fallback check. This means revoked certificates explicitly listed in loaded CRLs are accepted as valid.
The Core Vulnerability
The vulnerability exists in the ProcessPeerCerts() function within wolfSSL’s certificate validation logic. When processing a peer certificate during TLS handshake:
- Missing URL Collapse: If a certificate lacks an AIA OCSP responder URL, wolfSSL’s soft-fail policy marks the OCSP check as successful
- Fallback Suppression: The CRL fallback decision relies on OCSP result status. Since “no responder” was collapsed into “success,” the engine skips CRL evaluation
- Revoked Certificate Acceptance: Certificates listed as revoked in loaded CRLs are accepted because the CRL check never executes
Why Revocation Checking Matters
Certificate revocation is a critical security control. When a certificate is compromised, stolen, or issued in error, certificate authorities (CAs) publish revocation information through OCSP or CRL mechanisms. Applications must check this information before trusting a certificate.
Without proper revocation checking:
- Compromised certificates remain trusted indefinitely
- Attackers can impersonate legitimate services using revoked credentials
- Malicious actors can establish unauthorized connections to critical infrastructure
Scope: Which Applications Are at Risk
Vulnerable configurations require ALL of the following:
- wolfSSL library compiled with both
HAVE_OCSPandHAVE_CRLflags enabled - Application explicitly enables OCSP via
wolfSSL_CTX_EnableOCSP()or equivalent - Application simultaneously enables CRL checking via
wolfSSL_CTX_EnableCRL()with loaded CRLs - Peer certificate lacks an AIA OCSP responder URL
Not affected:
- Applications using OCSP stapling exclusively (
wolfSSL_CTX_EnableOCSPStapling()) - Applications using only OCSP or only CRL (not both)
- Applications with neither OCSP nor CRL enabled
Affected Products and Versions
wolfSSL Library Versions
All versions up to and including 5.9.2 are affected.
The vulnerability has existed across all wolfSSL releases that support dual OCSP/CRL validation. No patched version has been released at the time of this analysis.
Build Configurations That Enable the Flaw
The vulnerability is triggered when wolfSSL is compiled with both OCSP and CRL support enabled. This occurs through:
Direct flags:
./configure --enable-ocsp --enable-crl
Implicit composite configurations:
--enable-all--enable-distro--enable-curl--enable-nginx--enable-haproxy--enable-stunnel--enable-lighty--enable-wpas--enable-strongswan--enable-mosquitto--enable-jni--enable-openvpn--enable-krb
Organizations using pre-built wolfSSL packages from distributions or embedded in third-party software should verify build flags.
Runtime Prerequisites for Exploitation
Even if wolfSSL is compiled with both OCSP and CRL support, the vulnerability only manifests at runtime when:
- The application calls
wolfSSL_CTX_EnableOCSP(),wolfSSL_EnableOCSP(), orwolfSSL_CertManagerEnableOCSP() - The application calls
wolfSSL_CTX_EnableCRL()or equivalent with at least one CRL loaded - A peer certificate in the handshake lacks an AIA OCSP responder URL
- That certificate is listed as revoked in the loaded CRL
How the Vulnerability Works
The Logic Flaw in ProcessPeerCerts()
The vulnerability stems from a decision-tree flaw in wolfSSL’s peer certificate processing function. The logic assumes that if OCSP validation completes (regardless of outcome), CRL fallback is unnecessary.
Vulnerable code flow:
IF certificate has AIA OCSP URL:
Attempt OCSP check
IF OCSP check succeeds:
Mark certificate as valid
SKIP CRL check
ELSE:
CRL fallback check
ELSE:
// Missing AIA URL case
Mark OCSP as "soft-fail success"
SKIP CRL check // <-- VULNERABILITY: Should fall back to CRL
The problem: “soft-fail success” (missing responder) is treated identically to “actual success” (responder confirmed certificate is good).
Soft-Fail Mechanism and Result Collapse
OCSP soft-fail is a legitimate security pattern used when OCSP responders are unavailable. The intent is to allow connections to proceed rather than blocking all traffic during responder outages.
However, wolfSSL’s implementation conflates two distinct scenarios:
| Scenario | Current Behavior | Correct Behavior |
|---|---|---|
| OCSP responder unavailable | Mark as success, skip CRL | Mark as soft-fail, check CRL |
| No OCSP URL in certificate | Mark as success, skip CRL | Mark as soft-fail, check CRL |
| OCSP responder confirms good | Mark as success, skip CRL | Mark as success, skip CRL ✓ |
| OCSP responder confirms revoked | Mark as revoked, reject | Mark as revoked, reject ✓ |
The vulnerability exists because cases 1 and 2 are not properly distinguished from case 3.
Why CRL Fallback Is Skipped
The decision logic for CRL fallback is:
if (ocsp_result == OCSP_GOOD) {
// Skip CRL check
} else {
// Perform CRL check
}
When a certificate lacks an AIA URL, wolfSSL sets ocsp_result = OCSP_GOOD (soft-fail), causing the condition to evaluate true and CRL fallback to be skipped.
The correct logic should be:
if (ocsp_result == OCSP_GOOD && ocsp_was_actually_checked) {
// Skip CRL check
} else if (ocsp_result == OCSP_SOFT_FAIL || ocsp_not_attempted) {
// Perform CRL check
}
Context Poisoning: Intermediate Certificate Caching
A secondary impact occurs when the vulnerable certificate is an intermediate authority rather than a leaf certificate.
When wolfSSL processes a multi-tier certificate chain:
- Leaf certificate → validated (revocation check bypassed)
- Intermediate certificate → validated (revocation check bypassed)
- Intermediate is promoted into
WOLFSSL_CTXcertificate manager as a trusted signer
Persistence problem: The promoted intermediate remains in the context’s certificate store for all subsequent connections. If that intermediate is revoked, it continues to be trusted indefinitely until the context is destroyed.
This creates a “trust store poisoning” scenario where a single malicious handshake can compromise all future connections using that context.

Real-World Attack Scenarios
Client-Side: Connecting to Malicious Servers
Scenario: A client application using wolfSSL connects to remote TLS servers.
Attack execution:
- Attacker compromises or spoofs a server certificate
- Certificate is revoked by the CA and added to CRL
- Attacker ensures the certificate lacks an AIA OCSP responder URL (or uses a certificate from a CA that doesn’t include AIA URLs)
- Attacker presents this certificate during TLS handshake
Outcome:
- Client’s wolfSSL library skips OCSP check (no URL)
- Client’s wolfSSL library skips CRL check (soft-fail success)
- Client accepts the revoked certificate as valid
- Attacker establishes encrypted session with client
- Client sends sensitive data to attacker-controlled server
Real-world impact: IoT devices, embedded systems, and client applications connecting to cloud services could be redirected to attacker infrastructure.
Server-Side: Accepting Revoked Client Certificates
Scenario: A server using wolfSSL for mutual TLS (mTLS) authentication.
Attack execution:
- Attacker obtains a client certificate (through theft, compromise, or social engineering)
- Certificate owner requests revocation; CA adds it to CRL
- Attacker attempts to authenticate using the revoked certificate
- Certificate lacks AIA OCSP URL
Outcome:
- Server’s wolfSSL library skips OCSP check
- Server’s wolfSSL library skips CRL check
- Server accepts revoked client credential
- Attacker gains unauthorized access to protected resources
Real-world impact: Microservices, API gateways, and internal service-to-service authentication could be compromised.
Trust Store Poisoning via Intermediate Certificates
Scenario: A long-running service (e.g., API server, load balancer) processes multiple client connections.
Attack execution:
- Attacker crafts a certificate chain with a revoked intermediate authority
- Intermediate certificate lacks AIA OCSP URL
- Attacker initiates a connection presenting this chain
- Intermediate bypasses revocation check and is cached in the service’s
WOLFSSL_CTX
Outcome:
- Intermediate remains trusted in the context indefinitely
- All subsequent connections can use certificates signed by this revoked intermediate
- Service restart is required to purge the poisoned context
- Attacker can impersonate any entity signed by the revoked intermediate
Real-world impact: Long-running services (web servers, API gateways, load balancers) become permanently compromised until restarted.
Threat Assessment
Affected Protocols and Authentication Methods
| Protocol | Status | Notes |
|---|---|---|
| TLS 1.0 | Affected | Legacy but still in use |
| TLS 1.1 | Affected | Deprecated but supported |
| TLS 1.2 | Affected | Most common |
| TLS 1.3 | Affected | Modern deployments |
| DTLS 1.0/1.2 | Affected | IoT and real-time applications |
| Server certificate validation | Affected | Client verifying server identity |
| Client certificate validation | Affected | Server verifying client identity (mTLS) |
| Post-handshake auth | Affected | TLS 1.3 post-handshake client auth |
Exploitation Prerequisites
An attacker must satisfy ALL of these conditions:
- Target uses vulnerable wolfSSL configuration (OCSP + CRL enabled)
- Peer certificate lacks AIA OCSP URL (attacker controls certificate or uses CA without AIA)
- Certificate is revoked and in loaded CRL (attacker coordinates with CA or uses previously revoked cert)
- Attacker can present certificate during handshake (network position, DNS hijacking, or certificate compromise)
The third condition is the most restrictive—the certificate must be both revoked AND in the specific CRL loaded by the target application.
Impact Severity and Business Risk
Technical Impact: HIGH
- Complete bypass of certificate revocation enforcement
- Potential for persistent trust establishment via intermediate poisoning
- Affects both client and server authentication
- No user-visible warnings or error messages
Business Impact: CRITICAL
| Scenario | Risk Level | Example |
|---|---|---|
| Client connecting to untrusted servers | Critical | Banking apps, payment processors, healthcare portals |
| Server accepting unauthorized clients | Critical | API authentication, microservice communication, VPN |
| Intermediate poisoning in long-running services | Critical | Web servers, load balancers, API gateways |
| IoT device compromise | High | Connected devices, industrial control systems |
| Supply chain attacks | High | Compromised embedded libraries in products |
How to Detect CVE-2026-94417
Auditing Build Configurations
Step 1: Identify wolfSSL usage
Search your codebase and dependencies for wolfSSL:
# Check for wolfSSL in dependencies
grep -r "wolfSSL\|wolf_ssl" package.json requirements.txt pom.xml build.gradle
find . -name "*wolfssl*" -o -name "*wolf_ssl*"
# Check compiled binaries
strings /path/to/binary | grep -i "wolfssl"
ldd /path/to/binary | grep -i "wolfssl"
Step 2: Verify build flags
Examine how wolfSSL was compiled:
# Check build logs
cat build.log | grep -E "HAVE_OCSP|HAVE_CRL|enable-ocsp|enable-crl"
# Inspect configure script
./configure --help | grep -E "ocsp|crl"
# Check compiled library
nm /path/to/libwolfssl.a | grep -i "ocsp\|crl"
Step 3: Identify vulnerable configurations
Look for evidence of both OCSP and CRL being enabled:
# In Makefile or build output
grep -E "HAVE_OCSP.*HAVE_CRL|HAVE_CRL.*HAVE_OCSP" Makefile config.h
# In Docker images
docker inspect <image> | grep -i "wolfssl\|ocsp\|crl"
Inspecting Application Source Code
Search for concurrent OCSP and CRL enablement:
# Find OCSP enablement calls
grep -r "EnableOCSP\|OCSP_Enable" src/ --include="*.c" --include="*.cpp"
# Find CRL enablement calls
grep -r "EnableCRL\|CRL_Enable" src/ --include="*.c" --include="*.cpp"
# Check if both appear in same context initialization
grep -B5 -A5 "EnableOCSP" src/ | grep -E "EnableCRL|WOLFSSL_CTX"
Example vulnerable code pattern:
// Vulnerable pattern
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(TLSv1_2_client_method());
wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL);
wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL);
wolfSSL_CTX_LoadCRL(ctx, "revoked.crl", WOLFSSL_FILETYPE_PEM, 0);
Monitoring Network and Certificate Handshakes
Capture and analyze TLS handshakes:
# Capture TLS handshakes
tcpdump -i any -s 0 'tcp port 443' -w capture.pcap
# Analyze with tshark
tshark -r capture.pcap -Y "ssl.handshake.certificate" -V | grep -E "Subject:|Authority Info"
Look for suspicious patterns:
- Certificates lacking AIA extension
- Certificates in your CRL appearing in successful handshakes
- Intermediate certificates without AIA URLs being accepted
Log analysis:
# Search application logs for certificate validation
grep -i "certificate\|revocation\|ocsp\|crl" app.log | grep -i "accepted\|valid\|success"
# Look for missing OCSP URL warnings (should appear but don't)
grep -i "ocsp.*url\|missing.*responder" app.log
Remediation and Mitigation
Primary Fix: Upgrade wolfSSL
Immediate action:
- Monitor wolfSSL security advisories at https://www.wolfssl.com/
- Wait for patched version (expected to be > 5.9.2)
- Test patch in staging environment before production deployment
- Upgrade all affected systems to patched version
Upgrade procedure:
# Download patched wolfSSL
wget https://github.com/wolfSSL/wolfssl/releases/download/v5.9.3/wolfssl-5.9.3.tar.gz
# Compile with same flags as original
./configure --enable-ocsp --enable-crl [other flags]
make
make install
# Verify installation
wolfssl-config --version
Critical: Context Teardown for Long-Running Services
This step is essential and often overlooked.
Simply upgrading the library binary is insufficient for long-running processes. If a vulnerable service previously processed a revoked intermediate certificate without an AIA URL, that intermediate was cached in the WOLFSSL_CTX certificate manager. Upgrading the library without restarting leaves the poisoned context in memory.
Required actions:
// Before upgrade: vulnerable code
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(...);
wolfSSL_CTX_EnableOCSP(ctx, ...);
wolfSSL_CTX_EnableCRL(ctx, ...);
// Context persists for lifetime of process
// After upgrade: MUST restart process
// Option 1: Graceful shutdown and restart
kill -TERM <pid> // Triggers graceful shutdown
systemctl restart myservice
// Option 2: Implement context refresh (if restart not possible)
void refresh_wolfssl_context() {
wolfSSL_CTX_free(old_ctx);
old_ctx = wolfSSL_CTX_new(TLSv1_2_client_method());
wolfSSL_CTX_EnableOCSP(old_ctx, ...);
wolfSSL_CTX_EnableCRL(old_ctx, ...);
// Reload CRLs
}
Verification:
# Confirm service has restarted
ps aux | grep myservice | grep -v grep
# Check process start time
stat /proc/<pid> | grep Access
# Verify new wolfSSL version is loaded
ldd /proc/<pid>/exe | grep wolfssl
Temporary Workarounds
If immediate patching is not possible:
Option 1: Disable dual checking
// Instead of enabling both OCSP and CRL:
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(...);
// Choose ONE revocation method:
wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL);
// DO NOT also enable CRL
// OR
wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL);
// DO NOT also enable OCSP
Tradeoff: Reduces revocation coverage but eliminates the bypass vulnerability.
Option 2: Use OCSP stapling instead
// OCSP stapling uses separate OCSP instance (not vulnerable)
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(...);
wolfSSL_CTX_EnableOCSPStapling(ctx);
// Server must provide OCSP staple in handshake
// Client validates staple instead of querying responder
Advantage: Better performance and privacy than traditional OCSP.
Option 3: Implement application-level revocation checking
// Query revocation status outside wolfSSL
int check_certificate_revocation(X509* cert) {
// Query OCSP responder directly
// Check CRL from trusted source
// Return revocation status
return REVOKED or VALID;
}
// Disable wolfSSL revocation checking
// Perform checks in application code
Switching to OCSP Stapling
OCSP stapling is a superior approach that avoids this vulnerability entirely:
How it works:
- Server queries OCSP responder and obtains signed response
- Server includes OCSP response (“staple”) in TLS handshake
- Client validates the staple without contacting responder
- No missing URL problem—staple is provided by server
Implementation:
// Server side
WOLFSSL_CTX* server_ctx = wolfSSL_CTX_new(TLSv1_2_server_method());
wolfSSL_CTX_EnableOCSPStapling(server_ctx);
// Client side
WOLFSSL_CTX* client_ctx = wolfSSL_CTX_new(TLSv1_2_client_method());
// No special configuration needed—client validates staple automatically
Benefits:
- Eliminates missing OCSP URL problem
- Better privacy (client doesn’t contact responder)
- Better performance (cached responses)
- Not affected by CVE-2026-94417
Key Takeaways for Security Teams
Immediate Action Items
Week 1:
- [ ] Identify all applications using wolfSSL
- [ ] Determine which are compiled with OCSP and CRL support
- [ ] Audit source code for concurrent OCSP/CRL enablement
- [ ] Document affected systems and their criticality
Week 2:
- [ ] Monitor wolfSSL security advisories for patched version
- [ ] Establish testing environment with vulnerable configuration
- [ ] Develop upgrade and restart procedures
- [ ] Plan maintenance windows for production systems
Week 3:
- [ ] Deploy patches to non-critical systems first
- [ ] Verify patches in staging environment
- [ ] Implement monitoring for revocation check failures
- [ ] Document lessons learned
Long-Term Hardening Strategies
1. Dependency Management
# Maintain inventory of all cryptographic libraries
# Include version, build flags, and update status
# Automate detection of vulnerable versions
# Example: SBOM (Software Bill of Materials)
{
"component": "wolfSSL",
"version": "5.9.2",
"vulnerable": true,
"build_flags": ["--enable-ocsp", "--enable-crl"],
"status": "REQUIRES_UPDATE"
}
2. Build Configuration Hardening
# Disable unnecessary features at compile time
./configure \
--enable-ocsp \
--enable-crl \
--disable-shared \
--enable-static \
--enable-all-static \
--with-libz=/usr/local
3. Runtime Monitoring
# Monitor for revocation check failures
# Alert on certificates lacking AIA URLs
# Track context creation/destruction
# Example: Application instrumentation
void log_certificate_validation(X509* cert, int result) {
if (result == REVOKED) {
log_alert("REVOKED_CERT_DETECTED", cert_subject);
}
if (!has_aia_ocsp_url(cert)) {
log_warning("MISSING_AIA_URL", cert_subject);
}
}
4. Testing and Validation
# Create test suite for revocation checking
# Include certificates with/without AIA URLs
# Test both OCSP and CRL paths
# Verify intermediate caching behavior
# Example test case
test_revoked_cert_without_aia_url() {
// Load revoked certificate without AIA URL
// Attempt connection
// Assert: connection REJECTED (not accepted)
}
5. Incident Response Preparation
# Develop response playbook for revocation bypass
# Include:
# - Detection procedures
# - Containment steps
# - Eradication procedures
# - Recovery timeline
# - Communication plan
# Example: Automated response
if (revocation_bypass_detected) {
kill_affected_processes();
restart_with_patched_library();
audit_recent_connections();
notify_security_team();
}
Frequently Asked Questions
Is my application vulnerable if it only uses OCSP Stapling?
No. OCSP stapling uses a separate OCSP handling path that is not affected by this vulnerability. Stapling works by having the server provide a signed OCSP response in the handshake, eliminating the need for the client to contact an OCSP responder.
If your application uses wolfSSL_CTX_EnableOCSPStapling() exclusively, you are not vulnerable to CVE-2026-94417.
Why is upgrading the library alone insufficient for long-running services?
When a vulnerable service processes a certificate chain containing a revoked intermediate without an AIA OCSP URL, that intermediate is promoted into the active WOLFSSL_CTX certificate manager. This cached intermediate persists in memory as a trusted signer.
Simply upgrading the library binary does not clear this cached state. The WOLFSSL_CTX instance must be destroyed and recreated. For long-running services (web servers, API gateways), this requires a process restart.
Example:
Time 0: Service starts with vulnerable wolfSSL 5.9.2
Time 1: Malicious handshake with revoked intermediate → cached in context
Time 2: Upgrade to wolfSSL 5.9.3 (patched)
Time 3: Service still running with old context → revoked intermediate still trusted
Time 4: Service restarts → new context created → revoked intermediate purged
How does WOLFSSLOCSPCHECKALL behave on versions 5.9.1 and 5.9.2?
When compiled with WOLFSSL_OCSP_CHECKALL, versions 5.9.1 and 5.9.2 fail closed with OCSP_NEED_URL when a certificate lacks an AIA OCSP responder URL. This means the certificate is rejected rather than accepted.
However, the vulnerable configuration on version 5.9.2 is wolfSSL_CTX_EnableOCSP() called without CHECKALL. In this mode, missing OCSP URLs are soft-failed and CRL fallback is skipped, allowing revoked certificates to be accepted.
What is the difference between OCSP and CRL validation?
| Aspect | OCSP | CRL |
|---|---|---|
| Method | Real-time query to responder | Pre-downloaded list |
| Freshness | Current status | Periodic updates |
| Privacy | Responder knows which certs you check | No responder contact |
| Performance | Slower (network request) | Faster (local check) |
| Reliability | Depends on responder availability | Works offline |
| Scalability | Responder load | CRL size grows |
OCSP is preferred for real-time validation but requires responder availability. CRL is preferred for offline validation but requires periodic updates.
How can I verify if my build includes both OCSP and CRL support?
# Method 1: Check compiled library symbols
nm /path/to/libwolfssl.a | grep -i "ocsp\|crl"
# Method 2: Check header files
grep -E "HAVE_OCSP|HAVE_CRL" /usr/include/wolfssl/options.h
# Method 3: Query wolfSSL configuration
wolfssl-config --cflags | grep -E "OCSP|CRL"
# Method 4: Examine build output
cat config.log | grep -E "HAVE_OCSP|HAVE_CRL"
# Method 5: Test at runtime
#include <wolfssl/ssl.h>
#ifdef HAVE_OCSP
printf("OCSP support: YES
");
#endif
#ifdef HAVE_CRL
printf("CRL support: YES
");
#endif
What happens if I disable CRL checking but keep OCSP enabled?
If you disable CRL checking while keeping OCSP enabled, you rely entirely on OCSP for revocation validation. This is a valid configuration and eliminates the CVE-2026-94417 vulnerability.
Tradeoff: You lose the fallback mechanism. If the OCSP responder is unavailable, you cannot verify revocation status. Depending on your soft-fail policy, connections may be allowed or blocked.
Configuration:
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(...);
wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL);
// Do NOT call wolfSSL_CTX_EnableCRL()
References
- CVE-2026-94417: wolfSSL OCSP/CRL Revocation Check Bypass
- wolfSSL Official Website: https://www.wolfssl.com/
- CWE-295: Improper Certificate Validation
- CWE-370: Missing Revocation Check
- RFC 6960: Online Certificate Status Protocol (OCSP)
- RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile
Document Version: 1.0
Last Updated: 2024
Classification: Security Advisory