ANT-2026-7DG11TPA · wolfssl/wolfssl
other critical
Severity Claude critical · Security research firm - · Maintainer critical
Anthropic's analysis of this finding, sealed at approval.
ANT-2026-7DG11TPA: [SECURITY: critical] Universal ECDSA certificate forgery for arbitrary hosts
ConfirmSignature() in wolfcrypt/src/asn.c uses the certificate's attacker-controlled sigOID to pick the hash step and the trusted CA's keyOID to pick the verifier, but never checks that the two agree. Setting sigOID to CTC_ED25519/CTC_ED448 makes HashForSignature() a no-op, leaving digestSz at its zero-initialized value, and the ECDSA verifier (selected by keyOID=ECDSAk) accepts a zero-length hash. With e=0 the ECDSA verification equation collapses to a relation involving only r, s, and the CA's public point Q, so the attacker can compute a valid (r,s) for arbitrary tbsCertificate content using only the CA's public key. This lets an attacker forge a leaf certificate that chains to any trusted ECDSA root (e.g., DigiCert Global Root G3) and MITM any wolfSSL TLS client.
Target
Project: wolfssl/wolfssl
Location: ConfirmSignature() in wolfcrypt/src/asn.c (HashForSignature at asn.c:15926-15938; verifier dispatch at asn.c:16682; wc_ecc_verify_hash at ecc.c:8578)
Technical Details
The root cause is a missing cross-check between keyOID and sigOID in ConfirmSignature(): HashForSignature() intentionally skips hashing for EdDSA OIDs (asn.c:15926-15938) and returns success without setting *digestSz, which remains 0 from the earlier XMEMSET of sigCtx (asn.c:15652). The dispatch at asn.c:16682 then calls wc_ecc_verify_hash with digestSz=0; ecc.c:8578 only upper-bounds hashlen, so e is read as 0 and the verification reduces to x(r·s^-1·Q) == r, which the attacker satisfies by picking k, setting r = x(k·Q) and s = r·k^-1.
Reproduction
- Extract the target ECDSA CA's public point Q from its certificate.
- Pick random scalar k; compute P = k·Q; set r = x(P) mod n and s = r·k^-1 mod n.
- Build an arbitrary tbsCertificate (any CN/SANs, attacker's own leaf key) with issuer = CA and signatureAlgorithm = Ed25519 (or Ed448).
- Attach the DER-encoded (r,s) as the signature to produce forged.pem.
- Serve forged.pem from an attacker-controlled TLS endpoint and redirect the victim to it.
- wolfSSL's ConfirmSignature() hashes nothing (EdDSA sigOID), verifies e=0 under ECDSA against the CA key, and accepts the chain.
[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]
Suggested Fix
Add an algorithm-compatibility check at the top of ConfirmSignature() that rejects (ASN_SIG_OID_E) when keyOID and sigOID families disagree (e.g., keyOID=ECDSAk but sigOID is not a CTC_*wECDSA value), and as defense-in-depth reject hashlen == 0 in wc_ecc_verify_hash(). Patch attached; updates test_wc_CheckCertSigPubKey's expected error from ASN_PARSE_E to ASN_SIG_OID_E.
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-7DG11TPA.
Reference: ANT-2026-7DG11TPA
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure
Dates from discovery through public reveal.
- 2026-03-26 Sent to maintainer
- 2026-03-26 Maintainer acknowledged
- 2026-04-07 Patch released
- 2026-05-14 Reported to tracker
- 2026-06-02 Publicly revealed
SHA-3-512 hash:
795b824d3a8ae740b46f0ead862b0ea39eba87b6fe127e9eb774ef4e34a17aec032cfd1a1cfeb29958f591e5118f4525adc14699a2e0c6f103f24dc793aa9a99
Committed 2026-03-26 16:21 PT
Revealed 2026-06-02 11:00 PT