Remove CheckOcspResponderChain and related references. Function is not compliant with RFC 6960, 4.2.2.2.

remove unused vp parameter

Update ChangeLog.md to include OCSP responder change
This commit is contained in:
Ruby Martin
2026-05-26 12:10:05 -06:00
parent 4c0c093fe9
commit 08a7c4590e
6 changed files with 16 additions and 94 deletions
-1
View File
@@ -844,7 +844,6 @@ WOLFSSL_NO_KCAPI_SHA224
WOLFSSL_NO_KTRI_ORACLE_WARNING
WOLFSSL_NO_LMS_SHAKE256_256
WOLFSSL_NO_OCSP_DATE_CHECK
WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
WOLFSSL_NO_OCSP_OPTIONAL_CERTS
WOLFSSL_NO_RSA_KEY_CHECK
WOLFSSL_NO_SERVER_GROUPS_EXT
+8
View File
@@ -46,6 +46,14 @@
per-record nonce. Scoped to TLS 1.3, non-DTLS, non-QUIC; requires
`WOLF_CRYPTO_CB` and `WOLF_CRYPTO_CB_AES_SETKEY`.
* **BREAKING (RFC 6960 4.2.2.2)**: OCSP responder authorization is now
strictly enforced. Removes the non-compliant `CheckOcspResponderChain()`
fallback, which authorized any OCSP responder cert issued by an ancestor
of the target's issuer; [RFC 6960 4.2.2.2](https://datatracker.ietf.org/doc/html/rfc6960#section-4.2.2.2)
requires direct issuance by the CA identified in the request. Also
removes the now-unused `WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK` macro and
the `vp` parameter from `CheckOcspResponder()`.
# wolfSSL Release 5.9.1 (Apr. 8, 2026)
Release 5.9.1 has been developed according to wolfSSL's development and QA
+2 -87
View File
@@ -21,15 +21,6 @@
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
/* Name change compatibility layer no longer needs to be included here */
/*
* WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK:
* Disable looking for an authorized responder in the verification path of
* the issuer. This will make the authorized responder only look at the
* OCSP response signer and direct issuer.
*/
/*
* OCSP responder missing features:
* - Support for multiple requests and responses in a single OCSP exchange
@@ -590,80 +581,13 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
return ret;
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
static int CheckOcspResponderChain(OcspEntry* single, byte* issuerNameHash,
byte* issuerKeyHash, void* vp, Signer* pendingCAs) {
/* Attempt to build a chain up to cert's issuer */
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
Signer* ca = NULL;
Signer* prev = NULL;
int passed = 0;
/*
* Relation between certs:
* CA
* / \
* intermediate(s) cert in OCSP response
* | with OCSP key usage ext
* issuer of cert
* in OCSP request
*/
if (issuerKeyHash == NULL)
return 0;
/* Select CertID issuer by key hash so a same-DN / different-key trust
* anchor cannot hijack the starting point. */
ca = GetCAByKeyHash(cm, single->issuerKeyHash);
if (ca != NULL && XMEMCMP(ca->subjectNameHash, single->issuerHash,
OCSP_DIGEST_SIZE) != 0) {
ca = NULL;
}
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
if (ca == NULL && pendingCAs != NULL) {
ca = findSignerByKeyHash(pendingCAs, single->issuerKeyHash);
if (ca != NULL && XMEMCMP(ca->subjectNameHash, single->issuerHash,
OCSP_DIGEST_SIZE) != 0) {
ca = NULL;
}
}
#else
(void)pendingCAs;
#endif
for (; ca != NULL && ca != prev;
prev = ca) {
Signer* parent = GetCAByName(cm, ca->issuerNameHash);
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
if (parent == NULL && pendingCAs != NULL) {
parent = findSignerByName(pendingCAs, ca->issuerNameHash);
}
#endif
if (parent == NULL || parent == ca)
break;
if (XMEMCMP(parent->subjectNameHash, issuerNameHash,
OCSP_DIGEST_SIZE) == 0 &&
XMEMCMP(parent->subjectKeyHash, issuerKeyHash,
KEYID_SIZE) == 0) {
WOLFSSL_MSG("\tOCSP Response signed by authorized "
"responder delegated by issuer "
"(found in chain)");
passed = 1;
break;
}
ca = parent;
}
return passed;
}
#endif
/* Enforce https://www.rfc-editor.org/rfc/rfc6960#section-4.2.2.2. Both halves
* of CertID (issuerNameHash and issuerKeyHash) must match; name-only matching
* would authorize a same-DN / different-key CA. issuerKeyHash may be NULL when
* unavailable, which disables the delegated branch. */
int CheckOcspResponder(OcspResponse *bs, byte* subjectNameHash,
byte* subjectKeyHash, byte extExtKeyUsage, byte* issuerNameHash,
byte* issuerKeyHash, void* vp)
byte* issuerKeyHash)
{
int ret = 0;
OcspEntry* single;
@@ -671,8 +595,6 @@ int CheckOcspResponder(OcspResponse *bs, byte* subjectNameHash,
/* Both evaluate to enum values so can't use a pre-processor check */
WOLFSSL_ASSERT_EQ(OCSP_DIGEST_SIZE, SIGNER_DIGEST_SIZE);
(void)vp;
WOLFSSL_ENTER("CheckOcspResponder");
/* In the future if this API is used more then it could be beneficial to
@@ -702,12 +624,6 @@ int CheckOcspResponder(OcspResponse *bs, byte* subjectNameHash,
"delegated by issuer");
passed = 1;
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
else if (vp != NULL) {
passed = CheckOcspResponderChain(single, issuerNameHash,
issuerKeyHash, vp, bs->pendingCAs);
}
#endif
}
if (!passed) {
@@ -1111,8 +1027,7 @@ static int OcspVerifySigner(WOLFSSL_OCSP_BASICRESP *resp, DecodedCert *cert,
if ((flags & WOLFSSL_OCSP_NOCHECKS) == 0) {
ret = CheckOcspResponder(resp, c->subjectHash, c->subjectKeyHash,
c->extExtKeyUsage, c->issuerHash,
(c->ca != NULL) ? c->ca->subjectKeyHash : NULL,
st->cm);
(c->ca != NULL) ? c->ca->subjectKeyHash : NULL);
}
else {
ret = 0;
+4 -4
View File
@@ -33718,7 +33718,7 @@ static int OcspRespIdMatch(OcspResponse *resp, const byte *NameHash,
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
static int OcspRespCheck(OcspResponse *resp, Signer *responder, void* vp)
static int OcspRespCheck(OcspResponse *resp, Signer *responder)
{
OcspEntry *s;
int ret;
@@ -33733,7 +33733,7 @@ static int OcspRespCheck(OcspResponse *resp, Signer *responder, void* vp)
ret = CheckOcspResponder(resp, responder->subjectNameHash,
responder->subjectKeyHash, responder->extKeyUsage,
responder->issuerNameHash, responder->issuerKeyHash, vp);
responder->issuerNameHash, responder->issuerKeyHash);
if (ret != 0)
return -1;
@@ -33823,7 +33823,7 @@ static int OcspCheckCert(OcspResponse *resp, int noVerify,
if (ret == 0 && !noVerify) {
ret = CheckOcspResponder(resp, cert->subjectHash, cert->subjectKeyHash,
cert->extExtKeyUsage, cert->issuerHash,
(cert->ca != NULL) ? cert->ca->subjectKeyHash : NULL, cm);
(cert->ca != NULL) ? cert->ca->subjectKeyHash : NULL);
if (ret != 0) {
WOLFSSL_MSG("\tOCSP Responder certificate issuer check failed");
goto err;
@@ -34044,7 +34044,7 @@ static int DecodeBasicOcspResponse(const byte* source, word32* ioIndex,
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
if (ret == 0 && !noVerifySignature && !sigValid) {
if (OcspRespCheck(resp, ca, cm) != 0) {
if (OcspRespCheck(resp, ca) != 0) {
ret = BAD_OCSP_RESPONDER;
}
}
+1 -1
View File
@@ -8905,7 +8905,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
return ASN_NO_SIGNER_E;
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
if (OcspRespCheck(resp, ca, cm) != 0)
if (OcspRespCheck(resp, ca) != 0)
return BAD_OCSP_RESPONDER;
#endif
InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
+1 -1
View File
@@ -76,7 +76,7 @@ WOLFSSL_LOCAL int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int resp
WOLFSSL_LOCAL int CheckOcspResponder(OcspResponse *bs, byte* subjectNameHash,
byte* subjectKeyHash, byte extExtKeyUsage, byte* issuerNameHash,
byte* issuerKeyHash, void* vp);
byte* issuerKeyHash);
/* Allocates and initializes a WOLFSSL_OCSP object */
WOLFSSL_API WOLFSSL_OCSP* wc_NewOCSP(WOLFSSL_CERT_MANAGER* cm);