From dabfad9f6c0b2e6a1f41dca2d51144453a59b561 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 18 Jun 2024 19:43:44 +0200 Subject: [PATCH 1/7] Fix ocsp stapling test 2 --- scripts/ocsp-stapling2.test | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/scripts/ocsp-stapling2.test b/scripts/ocsp-stapling2.test index 7b51653fbf..0b3f5b12f5 100755 --- a/scripts/ocsp-stapling2.test +++ b/scripts/ocsp-stapling2.test @@ -334,9 +334,19 @@ openssl ocsp -port $port3 -nmin 1 \ "$@" \ & +# NEW: openssl isn't being cleaned up, invoke directly in script for cleanup +# purposes! +openssl ocsp -port $port4 -nmin 1 \ + -index certs/ocsp/index-ca-and-intermediate-cas.txt \ + -rsigner certs/ocsp/ocsp-responder-cert.pem \ + -rkey certs/ocsp/ocsp-responder-key.pem \ + -CA certs/ocsp/root-ca-cert.pem \ + "$@" \ + & + sleep 0.1 # "jobs" is not portable for posix. Must use bash interpreter! -[ $(jobs -r | wc -l) -ne 3 ] && printf '\n\n%s\n' "Setup ocsp responder failed, skipping" && exit 0 +[ $(jobs -r | wc -l) -ne 4 ] && printf '\n\n%s\n' "Setup ocsp responder failed, skipping" && exit 0 printf '\n\n%s\n\n' "All OCSP responders started successfully!" printf '%s\n\n' "------------- TEST CASE 1 SHOULD PASS ------------------------" @@ -352,18 +362,18 @@ RESULT=$? [ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 1 failed" && exit 1 printf '%s\n\n' "Test PASSED!" -printf '%s\n\n' "TEST CASE 2 DISABLED PENDING REVIEW" -#printf '%s\n\n' "------------- TEST CASE 2 SHOULD PASS ------------------------" -#remove_single_rF $ready_file5 -#./examples/server/server -c certs/ocsp/server3-cert.pem \ -# -k certs/ocsp/server3-key.pem -R $ready_file5 \ -# -p $port5 & -#wait_for_readyFile $ready_file5 $server_pid5 $port5 -#./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 3 -v 3 \ -# -p $port5 -#RESULT=$? -#[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 2 failed" && exit 1 -#printf '%s\n\n' "Test PASSED!" +printf '%s\n\n' "------------- TEST CASE 2 SHOULD PASS ------------------------" +remove_single_rF $ready_file5 +./examples/server/server -c certs/ocsp/server3-cert.pem \ + -k certs/ocsp/server3-key.pem -R $ready_file5 \ + -p $port5 & +server_pid5=$! +wait_for_readyFile $ready_file5 $server_pid5 $port5 +./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 3 -v 3 \ + -p $port5 +RESULT=$? +[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 2 failed" && exit 1 +printf '%s\n\n' "Test PASSED!" printf '%s\n\n' "------------- TEST CASE 3 SHOULD REVOKE ----------------------" # client test against our own server - REVOKED SERVER CERT From 7814e4c264068d09b3750b838d13a9c8238fa03a Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 18 Jun 2024 19:53:54 +0200 Subject: [PATCH 2/7] DoCertificateStatus: Clean up logic in WOLFSSL_CSR2_OCSP_MULTI --- src/internal.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/internal.c b/src/internal.c index 02b854508e..eb6fd5aa0e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -16093,14 +16093,10 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, OcspResponse response[1]; #endif - do { - if (ssl->status_request_v2) { - ssl->status_request_v2 = 0; - break; - } - + if (!ssl->status_request_v2) return BUFFER_ERROR; - } while(0); + + ssl->status_request_v2 = 0; #ifdef WOLFSSL_SMALL_STACK status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap, From b5206e8504c01cb1eaade4f4e20b2a89de25e2d9 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 1 Jul 2024 13:56:26 +0200 Subject: [PATCH 3/7] csrv2multi: pending ca list --- src/internal.c | 71 ++++++++++++++++++++-- src/ocsp.c | 29 +++++++-- src/ssl.c | 105 +++++++++++--------------------- src/tls.c | 87 +++++++++++++++++++++++++++ wolfcrypt/src/asn.c | 129 +++++++++++++++++++++++++++++++++++++--- wolfssl/internal.h | 7 +++ wolfssl/wolfcrypt/asn.h | 6 +- 7 files changed, 347 insertions(+), 87 deletions(-) diff --git a/src/internal.c b/src/internal.c index eb6fd5aa0e..691643241e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14022,6 +14022,7 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args, buffer* cert; byte* subjectHash = NULL; int alreadySigner = 0; + Signer *extraSigners = NULL; #if defined(HAVE_RPK) int cType; #endif @@ -14123,9 +14124,13 @@ PRAGMA_GCC_DIAG_POP return ret; #endif } - +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + if (verify != NO_VERIFY && TLSX_CSR2_IsMulti(ssl->extensions)) { + extraSigners = TLSX_CSR2_GetPendingSigners(ssl->extensions); + } +#endif /* Parse Certificate */ - ret = ParseCertRelative(args->dCert, certType, verify, SSL_CM(ssl)); + ret = ParseCertRelativeEx(args->dCert, certType, verify, SSL_CM(ssl), extraSigners); #if defined(HAVE_RPK) /* if cert type has negotiated with peer, confirm the cert received has @@ -14358,6 +14363,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, byte* subjectHash = NULL; int alreadySigner = 0; +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + int addToPendingCAs = 0; +#endif WOLFSSL_ENTER("ProcessPeerCerts"); #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP) @@ -14783,9 +14791,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ret == 0) { #ifdef HAVE_OCSP #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - if (ssl->status_request_v2) { + addToPendingCAs = 0; + if (ssl->status_request_v2 && TLSX_CSR2_IsMulti(ssl->extensions)) { ret = TLSX_CSR2_InitRequests(ssl->extensions, args->dCert, 0, ssl->heap); + addToPendingCAs = 1; } else /* skips OCSP and force CRL check */ #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ @@ -14930,6 +14940,45 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, skipAddCA = 1; } #endif +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ret == 0 && addToPendingCAs && !alreadySigner) { + DecodedCert dCertAdd; + DerBuffer *derBuffer; + buffer* cert = &args->certs[args->certIdx]; + Signer *s; + InitDecodedCert(&dCertAdd, cert->buffer, cert->length, ssl->heap); + ret = ParseCert(&dCertAdd, CA_TYPE, NO_VERIFY, SSL_CM(ssl)); + if (ret != 0) { + FreeDecodedCert(&dCertAdd); + goto exit_ppc; + } + ret = AllocDer(&derBuffer, cert->length, CA_TYPE, ssl->heap); + if (ret != 0 || derBuffer == NULL) { + FreeDecodedCert(&dCertAdd); + goto exit_ppc; + } + XMEMCPY(derBuffer->buffer, cert->buffer, cert->length); + s = MakeSigner(SSL_CM(ssl)->heap); + if (s == NULL) { + FreeDecodedCert(&dCertAdd); + ret = MEMORY_E; + goto exit_ppc; + } + ret = FillSigner(s, &dCertAdd, CA_TYPE, derBuffer); + FreeDecodedCert(&dCertAdd); + FreeDer(&derBuffer); + if (ret != 0) { + FreeSigner(s, SSL_CM(ssl)->heap); + goto exit_ppc; + } + skipAddCA = 1; + ret = TLSX_CSR2_AddPendingSigner(ssl->extensions, s); + if (ret != 0) { + FreeSigner(s, ssl->heap); + goto exit_ppc; + } + } +#endif /* If valid CA then add to Certificate Manager */ if (ret == 0 && args->dCert->isCA && @@ -16082,6 +16131,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, OcspRequest* request; word32 list_length = status_length; byte idx = 0; + Signer *pendingCAs = NULL; #ifdef WOLFSSL_SMALL_STACK CertStatus* status; @@ -16098,6 +16148,8 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->status_request_v2 = 0; + pendingCAs = TLSX_CSR2_GetPendingSigners(ssl->extensions); + #ifdef WOLFSSL_SMALL_STACK status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap, DYNAMIC_TYPE_OCSP_STATUS); @@ -16136,7 +16188,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (status_length) { InitOcspResponse(response, single, status, input +*inOutIdx, status_length, ssl->heap); - + response->pendingCAs = pendingCAs; if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0) != 0) || (response->responseStatus != OCSP_SUCCESSFUL) @@ -16180,6 +16232,17 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = BUFFER_ERROR; } +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ret == 0) { + if (TLSX_CSR2_MergePendingCA(ssl) < 0) { + WOLFSSL_MSG("Failed to merge pending CAs"); + } + } + else { + TLSX_CSR2_ClearPendingCA(ssl); + } +#endif + if (ret != 0) { WOLFSSL_ERROR_VERBOSE(ret); SendAlert(ssl, alert_fatal, bad_certificate_status_response); diff --git a/src/ocsp.c b/src/ocsp.c index e6966eb40c..681f95b8bc 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -328,7 +328,12 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz, #endif InitOcspResponse(ocspResponse, newSingle, newStatus, response, (word32)responseSz, ocsp->cm->heap); - +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ocspRequest != NULL && ocspRequest->ssl != NULL && + TLSX_CSR2_IsMulti(((WOLFSSL*)ocspRequest->ssl)->extensions)) { + ocspResponse->pendingCAs = TLSX_CSR2_GetPendingSigners(((WOLFSSL*)ocspRequest->ssl)->extensions); + } +#endif ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0); if (ret != 0) { ocsp->error = ret; @@ -555,7 +560,7 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, #ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert, - void* vp) { + 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; @@ -574,8 +579,16 @@ static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert, /* End loop if no more issuers found or if we have found a self * signed cert (ca == prev) */ - for (ca = GetCAByName(cm, single->issuerHash); ca != NULL && ca != prev; - prev = ca, ca = GetCAByName(cm, ca->issuerNameHash)) { + ca = GetCAByName(cm, single->issuerHash); +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ca == NULL && pendingCAs != NULL) { + ca = findSignerByName(pendingCAs, single->issuerHash); + } +#else + (void)pendingCAs; +#endif + for (; ca != NULL && ca != prev; + prev = ca) { if (XMEMCMP(cert->issuerHash, ca->issuerNameHash, OCSP_DIGEST_SIZE) == 0) { WOLFSSL_MSG("\tOCSP Response signed by authorized " @@ -584,6 +597,12 @@ static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert, passed = 1; break; } + ca = GetCAByName(cm, ca->issuerNameHash); +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ca == NULL && pendingCAs != NULL) { + ca = findSignerByName(pendingCAs, single->issuerHash); + } +#endif } return passed; } @@ -632,7 +651,7 @@ int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp) } #ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK else if (vp != NULL) { - passed = CheckOcspResponderChain(single, cert, vp); + passed = CheckOcspResponderChain(single, cert, vp, bs->pendingCAs); } #endif } diff --git a/src/ssl.c b/src/ssl.c index 7af8bc4ac5..1289eca259 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5283,6 +5283,38 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify) } #endif /* WOLFSSL_TRUST_PEER_CERT */ +int AddSigner(WOLFSSL_CERT_MANAGER* cm, Signer *s) +{ + byte* subjectHash; + Signer* signers; + word32 row; + + if (cm == NULL || s == NULL) + return BAD_FUNC_ARG; + +#ifndef NO_SKID + subjectHash = s->subjectKeyIdHash; +#else + subjectHash = s->subjectNameHash; +#endif + + if (AlreadySigner(cm, subjectHash)) { + FreeSigner(s, cm->heap); + return 0; + } + + row = HashSigner(subjectHash); + + if (wc_LockMutex(&cm->caLock) != 0) + return BAD_MUTEX_E; + + signers = cm->caTable[row]; + s->next = signers; + cm->caTable[row] = s; + + wc_UnLockMutex(&cm->caLock); + return 0; +} /* owns der, internal now uses too */ /* type flag ids from user or from chain received during verify @@ -5437,76 +5469,8 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) if (!signer) ret = MEMORY_ERROR; } - -#ifdef WOLFSSL_DUAL_ALG_CERTS - if (ret == 0 && signer != NULL) { - if (cert->extSapkiSet && cert->sapkiLen > 0) { - /* Allocated space for alternative public key. */ - signer->sapkiDer = (byte*)XMALLOC(cert->sapkiLen, cm->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (signer->sapkiDer == NULL) { - ret = MEMORY_E; - } - else { - XMEMCPY(signer->sapkiDer, cert->sapkiDer, cert->sapkiLen); - signer->sapkiLen = cert->sapkiLen; - signer->sapkiOID = cert->sapkiOID; - } - } - } -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - -#if defined(WOLFSSL_AKID_NAME) || defined(HAVE_CRL) - if (ret == 0 && signer != NULL) - ret = CalcHashId(cert->serial, cert->serialSz, signer->serialHash); -#endif - if (ret == 0 && signer != NULL) { - #ifdef WOLFSSL_SIGNER_DER_CERT - ret = AllocDer(&signer->derCert, der->length, der->type, NULL); - } if (ret == 0 && signer != NULL) { - XMEMCPY(signer->derCert->buffer, der->buffer, der->length); - #endif - signer->keyOID = cert->keyOID; - if (cert->pubKeyStored) { - signer->publicKey = cert->publicKey; - signer->pubKeySize = cert->pubKeySize; - } - - if (cert->subjectCNStored) { - signer->nameLen = cert->subjectCNLen; - signer->name = cert->subjectCN; - } - signer->maxPathLen = cert->maxPathLen; - signer->selfSigned = cert->selfSigned; - #ifndef IGNORE_NAME_CONSTRAINTS - signer->permittedNames = cert->permittedNames; - signer->excludedNames = cert->excludedNames; - #endif - #ifndef NO_SKID - XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId, - SIGNER_DIGEST_SIZE); - #endif - XMEMCPY(signer->subjectNameHash, cert->subjectHash, - SIGNER_DIGEST_SIZE); - #if defined(HAVE_OCSP) || defined(HAVE_CRL) - XMEMCPY(signer->issuerNameHash, cert->issuerHash, - SIGNER_DIGEST_SIZE); - #endif - #ifdef HAVE_OCSP - XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash, - KEYID_SIZE); - #endif - signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage - : 0xFFFF; - signer->next = NULL; /* If Key Usage not set, all uses valid. */ - cert->publicKey = 0; /* in case lock fails don't free here. */ - cert->subjectCN = 0; - #ifndef IGNORE_NAME_CONSTRAINTS - cert->permittedNames = NULL; - cert->excludedNames = NULL; - #endif - signer->type = (byte)type; + ret = FillSigner(signer, cert, type, der); #ifndef NO_SKID row = HashSigner(signer->subjectKeyIdHash); @@ -5514,7 +5478,8 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) row = HashSigner(signer->subjectNameHash); #endif - if (wc_LockMutex(&cm->caLock) == 0) { + + if (ret == 0 && wc_LockMutex(&cm->caLock) == 0) { signer->next = cm->caTable[row]; cm->caTable[row] = signer; /* takes ownership */ wc_UnLockMutex(&cm->caLock); diff --git a/src/tls.c b/src/tls.c index 558afea0d4..d233241119 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3579,10 +3579,20 @@ int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type, #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 +static void TLSX_CSR2_FreePendingSigners(Signer *s, void* heap) +{ + Signer* next; + while(s) { + next = s->next; + FreeSigner(s, heap); + s = next; + } +} static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2, void* heap) { CertificateStatusRequestItemV2* next; + TLSX_CSR2_FreePendingSigners(csr2->pendingSigners, heap); for (; csr2; csr2 = next) { next = csr2->next; @@ -3853,6 +3863,83 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length, return 0; } +static CertificateStatusRequestItemV2* TLSX_CSR2_GetMulti(TLSX *extensions) +{ + TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2); + CertificateStatusRequestItemV2* csr2 = extension ? + (CertificateStatusRequestItemV2*)extension->data : NULL; + + for (; csr2; csr2 = csr2->next) { + if (csr2->status_type == WOLFSSL_CSR2_OCSP_MULTI) + return csr2; + } + return NULL; +} + +int TLSX_CSR2_IsMulti(TLSX *extensions) +{ + return TLSX_CSR2_GetMulti(extensions) != NULL; +} + +int TLSX_CSR2_AddPendingSigner(TLSX *extensions, Signer *s) +{ + CertificateStatusRequestItemV2* csr2; + + csr2 = TLSX_CSR2_GetMulti(extensions); + if (!csr2) + return -1; + + s->next = csr2->pendingSigners; + csr2->pendingSigners = s; + return 0; +} + +Signer* TLSX_CSR2_GetPendingSigners(TLSX *extensions) +{ + CertificateStatusRequestItemV2* csr2; + + csr2 = TLSX_CSR2_GetMulti(extensions); + if (!csr2) + return NULL; + + return csr2->pendingSigners; +} + +int TLSX_CSR2_ClearPendingCA(WOLFSSL *ssl) +{ + CertificateStatusRequestItemV2* csr2; + + csr2 = TLSX_CSR2_GetMulti(ssl->extensions); + if (csr2 == NULL) + return 0; + + TLSX_CSR2_FreePendingSigners(csr2->pendingSigners, SSL_CM(ssl)->heap); + csr2->pendingSigners = NULL; + return 0; +} + +int TLSX_CSR2_MergePendingCA(WOLFSSL* ssl) +{ + CertificateStatusRequestItemV2* csr2; + Signer *s, *next; + int r = 0; + + csr2 = TLSX_CSR2_GetMulti(ssl->extensions); + if (csr2 == NULL) + return 0; + + s = csr2->pendingSigners; + while (s != NULL) { + next = s->next; + r = AddSigner(SSL_CM(ssl), s); + if (r != 0) + FreeSigner(s, SSL_CM(ssl)->heap); + s = next; + } + csr2->pendingSigners = NULL; + return r; +} + int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer, void* heap) { diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 87e68a4e6c..22f16642b3 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -23388,8 +23388,18 @@ int wc_CertGetPubKey(const byte* cert, word32 certSz, return ret; } #endif +Signer* findSignerByName(Signer *list, byte *hash) +{ + Signer *s; + for (s = list; s != NULL; s = s->next) { + if (XMEMCMP(s->subjectNameHash, hash, SIGNER_DIGEST_SIZE) == 0) { + return s; + } + } + return NULL; +} -int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) +int ParseCertRelativeEx(DecodedCert* cert, int type, int verify, void* cm, Signer *extraCAList) { int ret = 0; #ifndef WOLFSSL_ASN_TEMPLATE @@ -23402,6 +23412,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) int idx = 0; #endif byte* sce_tsip_encRsaKeyIdx; + (void)extraCAList; if (cert == NULL) { return BAD_FUNC_ARG; @@ -23720,8 +23731,13 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) if (!cert->selfSigned || (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE)) { cert->ca = NULL; +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + if (extraCAList != NULL) { + cert->ca = findSignerByName(extraCAList, cert->issuerHash); + } +#endif #ifndef NO_SKID - if (cert->extAuthKeyIdSet) { + if (cert->ca == NULL && cert->extAuthKeyIdSet) { cert->ca = GetCA(cm, cert->extAuthKeyId); #ifdef WOLFSSL_AKID_NAME if (cert->ca == NULL) { @@ -24040,6 +24056,93 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) return ret; } +int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) +{ + return ParseCertRelativeEx(cert, type, verify, cm, NULL); +} + +int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der) +{ + int ret = 0; + + if (signer == NULL || cert == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == 0 && signer != NULL) { + if (cert->extSapkiSet && cert->sapkiLen > 0) { + /* Allocated space for alternative public key. */ + signer->sapkiDer = (byte*)XMALLOC(cert->sapkiLen, cm->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (signer->sapkiDer == NULL) { + ret = MEMORY_E; + } + else { + XMEMCPY(signer->sapkiDer, cert->sapkiDer, cert->sapkiLen); + signer->sapkiLen = cert->sapkiLen; + signer->sapkiOID = cert->sapkiOID; + } + } + } +#endif /* WOLFSSL_DUAL_ALG_CERTS */ + +#if defined(WOLFSSL_AKID_NAME) || defined(HAVE_CRL) + if (ret == 0 && signer != NULL) + ret = CalcHashId(cert->serial, cert->serialSz, signer->serialHash); +#endif + if (ret == 0 && signer != NULL) { + #ifdef WOLFSSL_SIGNER_DER_CERT + ret = AllocDer(&signer->derCert, der->length, der->type, NULL); + } + if (ret == 0 && signer != NULL) { + XMEMCPY(signer->derCert->buffer, der->buffer, der->length); + #else + (void)der; + #endif + signer->keyOID = cert->keyOID; + if (cert->pubKeyStored) { + signer->publicKey = cert->publicKey; + signer->pubKeySize = cert->pubKeySize; + } + + if (cert->subjectCNStored) { + signer->nameLen = cert->subjectCNLen; + signer->name = cert->subjectCN; + } + signer->maxPathLen = cert->maxPathLen; + signer->selfSigned = cert->selfSigned; + #ifndef IGNORE_NAME_CONSTRAINTS + signer->permittedNames = cert->permittedNames; + signer->excludedNames = cert->excludedNames; + #endif + #ifndef NO_SKID + XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId, + SIGNER_DIGEST_SIZE); + #endif + XMEMCPY(signer->subjectNameHash, cert->subjectHash, + SIGNER_DIGEST_SIZE); + #if defined(HAVE_OCSP) || defined(HAVE_CRL) + XMEMCPY(signer->issuerNameHash, cert->issuerHash, + SIGNER_DIGEST_SIZE); + #endif + #ifdef HAVE_OCSP + XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash, + KEYID_SIZE); + #endif + signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage + : 0xFFFF; + signer->next = NULL; /* If Key Usage not set, all uses valid. */ + cert->publicKey = 0; /* in case lock fails don't free here. */ + cert->subjectCN = 0; + #ifndef IGNORE_NAME_CONSTRAINTS + cert->permittedNames = NULL; + cert->excludedNames = NULL; + #endif + signer->type = (byte)type; + } + return ret; +} + /* Create and init an new signer */ Signer* MakeSigner(void* heap) { @@ -36458,9 +36561,9 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, cert_inited = 1; /* Don't verify if we don't have access to Cert Manager. */ - ret = ParseCertRelative(cert, CERT_TYPE, + ret = ParseCertRelativeEx(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY_OCSP_CERT, - cm); + cm, resp->pendingCAs); if (ret < 0) { WOLFSSL_MSG("\tOCSP Responder certificate parsing failed"); break; @@ -36519,7 +36622,11 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, #else ca = GetCA(cm, resp->single->issuerHash); #endif - +#if defined(HAVE_CERTIFICATE_STATUS_V2) + if (ca == NULL && resp->pendingCAs != NULL) { + ca = findSignerByName(resp->pendingCAs, resp->single->issuerHash); + } +#endif if (ca) { SignatureCtx sigCtx; InitSignatureCtx(&sigCtx, heap, INVALID_DEVID); @@ -36616,8 +36723,8 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, certInit = 1; /* Parse the certificate and don't verify if we don't have access to * Cert Manager. */ - ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY, - cm); + ret = ParseCertRelativeEx(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY, + cm, resp->pendingCAs); if (ret < 0) { WOLFSSL_MSG("\tOCSP Responder certificate parsing failed"); } @@ -36656,6 +36763,13 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, #else ca = GetCA(cm, resp->single->issuerHash); #endif + + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ca == NULL && resp->pendingCAs != NULL) { + ca = findSignerByName(resp->pendingCAs, resp->single->issuerHash); + } + #endif + if (ca) { SignatureCtx sigCtx; @@ -36713,6 +36827,7 @@ void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status, resp->source = source; resp->maxIdx = inSz; resp->heap = heap; + resp->pendingCAs = NULL; } void FreeOcspResponse(OcspResponse* resp) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 7bac1f6cf8..4b3d7f52ed 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3194,11 +3194,17 @@ typedef struct CSRIv2 { OcspRequest ocsp[1 + MAX_CHAIN_DEPTH]; } request; struct CSRIv2* next; + Signer *pendingSigners; } CertificateStatusRequestItemV2; WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, byte options, void* heap, int devId); #ifndef NO_CERTS +WOLFSSL_LOCAL int TLSX_CSR2_IsMulti(TLSX *extensions); +WOLFSSL_LOCAL int TLSX_CSR2_AddPendingSigner(TLSX *extensions, Signer *s); +WOLFSSL_LOCAL Signer* TLSX_CSR2_GetPendingSigners(TLSX *extensions); +WOLFSSL_LOCAL int TLSX_CSR2_ClearPendingCA(WOLFSSL *ssl); +WOLFSSL_LOCAL int TLSX_CSR2_MergePendingCA(WOLFSSL* ssl); WOLFSSL_LOCAL int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer, void* heap); #endif @@ -4054,6 +4060,7 @@ int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 inSz, word16 sz); #ifndef NO_CERTS + WOLFSSL_LOCAL int AddSigner(WOLFSSL_CERT_MANAGER* cm, Signer *s); WOLFSSL_LOCAL int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify); WOLFSSL_LOCAL diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 20c41b7628..893ee882c3 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2188,6 +2188,8 @@ WOLFSSL_ASN_API int AddSignature(byte* buf, int bodySz, const byte* sig, int sig int sigAlgoType); WOLFSSL_LOCAL int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm); +WOLFSSL_LOCAL int ParseCertRelativeEx(DecodedCert* cert, int type, int verify, + void* cm, Signer *extraCa); WOLFSSL_LOCAL int DecodeToKey(DecodedCert* cert, int verify); #ifdef WOLFSSL_ASN_TEMPLATE WOLFSSL_LOCAL int DecodeCert(DecodedCert* cert, int verify, int* criticalExt); @@ -2196,6 +2198,8 @@ WOLFSSL_LOCAL int TryDecodeRPKToKey(DecodedCert* cert); WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate); WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz); +WOLFSSL_LOCAL Signer* findSignerByName(Signer *list, byte *hash); +WOLFSSL_LOCAL int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der); WOLFSSL_LOCAL Signer* MakeSigner(void* heap); WOLFSSL_LOCAL void FreeSigner(Signer* signer, void* heap); WOLFSSL_LOCAL void FreeSignerTable(Signer** table, int rows, void* heap); @@ -2565,7 +2569,7 @@ struct OcspResponse { byte* source; /* pointer to source buffer, not owned */ word32 maxIdx; /* max offset based on init size */ - + Signer* pendingCAs; #ifdef OPENSSL_EXTRA int verifyError; #endif From 9222cb13046dd2fc9ae8e7bbc30175d466a27c3c Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 1 Jul 2024 22:51:31 +0200 Subject: [PATCH 4/7] ocsp: improvements --- src/internal.c | 107 +++++++++++++++++++++++++++++-------------------- src/tls.c | 6 +-- 2 files changed, 67 insertions(+), 46 deletions(-) diff --git a/src/internal.c b/src/internal.c index 691643241e..e222babbba 100644 --- a/src/internal.c +++ b/src/internal.c @@ -16098,6 +16098,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, int ret = 0; byte status_type; word32 status_length; + int endCertificateOK = 0; WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_DO); WOLFSSL_ENTER("DoCertificateStatus"); @@ -16121,6 +16122,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */ case WOLFSSL_CSR2_OCSP: ret = ProcessCSR(ssl, input, inOutIdx, status_length); + endCertificateOK = (ret == 0); break; #endif @@ -16197,14 +16199,19 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, while (ret == 0) { request = (OcspRequest*)TLSX_CSR2_GetRequest( - ssl->extensions, status_type, idx++); + ssl->extensions, status_type, idx); - if (request == NULL) + if (request == NULL) { ret = BAD_CERTIFICATE_STATUS_ERROR; - else if (CompareOcspReqResp(request, response) == 0) - break; - else if (idx == 1) /* server cert must be OK */ + } + else if (CompareOcspReqResp(request, response) != 0) { ret = BAD_CERTIFICATE_STATUS_ERROR; + } + else { + if (idx == 0) /* server cert must be OK */ + endCertificateOK = 1; + break; + } } /* only frees 'single' if single->isDynamic is set */ @@ -16213,6 +16220,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, *inOutIdx += status_length; list_length -= status_length; } + idx++; } ssl->status_request_v2 = 0; @@ -16232,6 +16240,9 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = BUFFER_ERROR; } + /* end certificate MUST be present */ + if (endCertificateOK == 0) + ret = BAD_CERTIFICATE_STATUS_ERROR; #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) if (ret == 0) { if (TLSX_CSR2_MergePendingCA(ssl) < 0) { @@ -16646,44 +16657,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E); return OUT_OF_ORDER_E; } -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ - defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) - if (ssl->msgsReceived.got_certificate_status == 0) { - int csrRet = 0; -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST - if (csrRet == 0 && ssl->status_request) { - WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange"); - csrRet = TLSX_CSR_ForceRequest(ssl); - } -#endif -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - if (csrRet == 0 && ssl->status_request_v2) { - WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange"); - csrRet = TLSX_CSR2_ForceRequest(ssl); - } -#endif - if (csrRet != 0) { - /* Error out if OCSP lookups are enabled and failed or if - * the user requires stapling. */ - if (SSL_CM(ssl)->ocspEnabled || SSL_CM(ssl)->ocspMustStaple) - return csrRet; - } - /* Check that a status request extension was seen as the - * CertificateStatus wasn't when an OCSP staple is required. - */ - if ( -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST - !ssl->status_request && -#endif -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - !ssl->status_request_v2 && -#endif - SSL_CM(ssl)->ocspMustStaple) { - WOLFSSL_ERROR_VERBOSE(OCSP_CERT_UNKNOWN); - return OCSP_CERT_UNKNOWN; - } - } -#endif break; #endif @@ -16756,6 +16729,54 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) return OUT_OF_ORDER_E; } } +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ssl->msgsReceived.got_certificate_status == 0) { + int csrRet = 0; +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + if (csrRet == 0 && ssl->status_request) { + WOLFSSL_MSG("No CertificateStatus before ServerHelloDone"); + csrRet = TLSX_CSR_ForceRequest(ssl); + } +#endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + if (csrRet == 0 && ssl->status_request_v2) { + WOLFSSL_MSG("No CertificateStatus before ServerHelloDone"); + csrRet = TLSX_CSR2_ForceRequest(ssl); + } + if (ssl->status_request_v2) { + if (csrRet == 0) { + if (TLSX_CSR2_MergePendingCA(ssl) < 0) { + WOLFSSL_MSG("Failed to merge pending CAs"); + } + } + else { + TLSX_CSR2_ClearPendingCA(ssl); + } + } +#endif + if (csrRet != 0) { + /* Error out if OCSP lookups are enabled and failed or if + * the user requires stapling. */ + if (SSL_CM(ssl)->ocspEnabled || SSL_CM(ssl)->ocspMustStaple) + return csrRet; + } + /* Check that a status request extension was seen as the + * CertificateStatus wasn't when an OCSP staple is required. + */ + if ( +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + !ssl->status_request && +#endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + !ssl->status_request_v2 && +#endif + SSL_CM(ssl)->ocspMustStaple) { + WOLFSSL_ERROR_VERBOSE(OCSP_CERT_UNKNOWN); + return OCSP_CERT_UNKNOWN; + } + } +#endif break; #endif diff --git a/src/tls.c b/src/tls.c index d233241119..65292169e0 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4021,10 +4021,10 @@ int TLSX_CSR2_ForceRequest(WOLFSSL* ssl) /* followed by */ case WOLFSSL_CSR2_OCSP_MULTI: - if (SSL_CM(ssl)->ocspEnabled) { - csr2->request.ocsp[0].ssl = ssl; + if (SSL_CM(ssl)->ocspEnabled && csr2->requests >= 1) { + csr2->request.ocsp[csr2->requests-1].ssl = ssl; return CheckOcspRequest(SSL_CM(ssl)->ocsp, - &csr2->request.ocsp[0], NULL, NULL); + &csr2->request.ocsp[csr2->requests-1], NULL, NULL); } else { WOLFSSL_ERROR_VERBOSE(OCSP_LOOKUP_FAIL); From fe932b893c218cd144319c9b6a6f5323db64cdb0 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Thu, 4 Jul 2024 10:17:18 +0200 Subject: [PATCH 5/7] fixup! csrv2multi: pending ca list --- src/internal.c | 5 +++-- src/ocsp.c | 4 ++-- src/ssl.c | 6 +++--- src/ssl_certman.c | 6 +++--- src/ssl_p7p12.c | 4 ++-- src/x509.c | 10 +++++----- wolfcrypt/src/asn.c | 19 +++++++------------ wolfcrypt/src/pkcs12.c | 2 +- wolfssl/wolfcrypt/asn.h | 2 -- 9 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/internal.c b/src/internal.c index e222babbba..a5a15b501e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14130,7 +14130,7 @@ PRAGMA_GCC_DIAG_POP } #endif /* Parse Certificate */ - ret = ParseCertRelativeEx(args->dCert, certType, verify, SSL_CM(ssl), extraSigners); + ret = ParseCertRelative(args->dCert, certType, verify, SSL_CM(ssl), extraSigners); #if defined(HAVE_RPK) /* if cert type has negotiated with peer, confirm the cert received has @@ -14961,6 +14961,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, s = MakeSigner(SSL_CM(ssl)->heap); if (s == NULL) { FreeDecodedCert(&dCertAdd); + FreeDer(&derBuffer); ret = MEMORY_E; goto exit_ppc; } @@ -23254,7 +23255,7 @@ static int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request, InitDecodedCert(cert, certData, length, ssl->heap); /* TODO: Setup async support here */ - ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, SSL_CM(ssl)); + ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, SSL_CM(ssl), NULL); if (ret != 0) { WOLFSSL_MSG("ParseCert failed"); } diff --git a/src/ocsp.c b/src/ocsp.c index 681f95b8bc..9051ecf011 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -802,7 +802,7 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id( InitDecodedCert(cert, subject->derCert->buffer, subject->derCert->length, NULL); - if (ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm) != 0) { + if (ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm, NULL) != 0) { FreeDecodedCert(cert); goto out; } @@ -892,7 +892,7 @@ int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs, InitDecodedCert(cert, bs->cert, bs->certSz, NULL); certInit = 1; - if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm) < 0) + if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm, NULL) < 0) goto out; if (!(flags & OCSP_NOCHECKS)) { diff --git a/src/ssl.c b/src/ssl.c index 1289eca259..f9f04fd7c8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6211,7 +6211,7 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, DerBuffer* altKey, size = cert->length; buff = cert->buffer; InitDecodedCert_ex(der, buff, size, heap, devId); - if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL) != 0) { + if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL, NULL) != 0) { FreeDecodedCert(der); #ifdef WOLFSSL_SMALL_STACK XFREE(der, heap, DYNAMIC_TYPE_DCERT); @@ -13313,7 +13313,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object. */ InitDecodedCert(cert, (byte*)in, (word32)len, NULL); - if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) { + if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL)) == 0) { /* Check if x509 was not previously initialized by wolfSSL_X509_new() */ if (x509->dynamicMemory != TRUE) InitX509(x509, 0, NULL); @@ -17756,7 +17756,7 @@ WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx) InitDecodedCert(cert, chain->certs[idx].buffer, chain->certs[idx].length, NULL); - if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0) { + if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL)) != 0) { WOLFSSL_MSG("Failed to parse cert"); } else { diff --git a/src/ssl_certman.c b/src/ssl_certman.c index d9af7bc66b..e666059352 100644 --- a/src/ssl_certman.c +++ b/src/ssl_certman.c @@ -698,7 +698,7 @@ int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const unsigned char* buff, /* Parse DER into decoded certificate fields and verify signature * against a known CA. */ - ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, cm); + ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, cm, NULL); } #ifdef HAVE_CRL @@ -1817,7 +1817,7 @@ int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, InitDecodedCert(cert, der, (word32)sz, NULL); /* Parse certificate and perform CRL checks. */ - ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm); + ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm, NULL); if (ret != 0) { WOLFSSL_MSG("ParseCert failed"); } @@ -2289,7 +2289,7 @@ int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, InitDecodedCert(cert, der, (word32)sz, NULL); /* Parse certificate and perform CRL checks. */ - ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm); + ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm, NULL); if (ret != 0) { WOLFSSL_MSG("ParseCert failed"); } diff --git a/src/ssl_p7p12.c b/src/ssl_p7p12.c index dca512f46c..11b6c40a9a 100644 --- a/src/ssl_p7p12.c +++ b/src/ssl_p7p12.c @@ -1932,7 +1932,7 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, DYNAMIC_TYPE_X509); InitX509(x509, 1, heap); InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap); - if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) { + if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL, NULL) != 0) { WOLFSSL_MSG("Issue with parsing certificate"); FreeDecodedCert(DeCert); wolfSSL_X509_free(x509); @@ -2009,7 +2009,7 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, } InitX509(*cert, 1, heap); InitDecodedCert(DeCert, certData, certDataSz, heap); - if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) { + if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL, NULL) != 0) { WOLFSSL_MSG("Issue with parsing certificate"); } if (CopyDecodedToX509(*cert, DeCert) != 0) { diff --git a/src/x509.c b/src/x509.c index 1d31328e8c..72a4f37ece 100644 --- a/src/x509.c +++ b/src/x509.c @@ -3612,7 +3612,7 @@ static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509, #ifdef WOLFSSL_CERT_REQ cert->isCSR = (byte)req; #endif - if (ParseCertRelative(cert, type, 0, NULL) == 0) { + if (ParseCertRelative(cert, type, 0, NULL, NULL) == 0) { newX509 = wolfSSL_X509_new_ex(heap); if (newX509 != NULL) { if (CopyDecodedToX509(newX509, cert) != 0) { @@ -5254,7 +5254,7 @@ static WOLFSSL_X509* loadX509orX509REQFromBuffer( #endif { InitDecodedCert(cert, der->buffer, der->length, NULL); - ret = ParseCertRelative(cert, type, 0, NULL); + ret = ParseCertRelative(cert, type, 0, NULL, NULL); if (ret == 0) { x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL, DYNAMIC_TYPE_X509); @@ -13403,7 +13403,7 @@ int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen, #endif InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL); - ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL); + ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL); if (ret != 0) { goto out; } @@ -13474,7 +13474,7 @@ int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc, if (ret == WOLFSSL_SUCCESS) { InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL); - ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL); + ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL); if (ret != 0) { ret = WOLFSSL_FAILURE; } @@ -13613,7 +13613,7 @@ static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm, /* Use existing CA retrieval APIs that use DecodedCert. */ InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, cm->heap); - if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0 + if (ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL) == 0 && !cert->selfSigned) { #ifndef NO_SKID if (cert->extAuthKeyIdSet) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 22f16642b3..45942c0391 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -22501,7 +22501,7 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm) char* ptr; #endif - ret = ParseCertRelative(cert, type, verify, cm); + ret = ParseCertRelative(cert, type, verify, cm, NULL); if (ret < 0) return ret; @@ -23399,7 +23399,7 @@ Signer* findSignerByName(Signer *list, byte *hash) return NULL; } -int ParseCertRelativeEx(DecodedCert* cert, int type, int verify, void* cm, Signer *extraCAList) +int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, Signer *extraCAList) { int ret = 0; #ifndef WOLFSSL_ASN_TEMPLATE @@ -24056,11 +24056,6 @@ int ParseCertRelativeEx(DecodedCert* cert, int type, int verify, void* cm, Signe return ret; } -int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) -{ - return ParseCertRelativeEx(cert, type, verify, cm, NULL); -} - int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der) { int ret = 0; @@ -26681,7 +26676,7 @@ static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz, InitDecodedCert_ex((DecodedCert*)cert->decodedCert, der, derSz, cert->heap, devId); ret = ParseCertRelative((DecodedCert*)cert->decodedCert, - CERT_TYPE, 0, NULL); + CERT_TYPE, 0, NULL, NULL); if (ret >= 0) { cert->der = (byte*)der; } @@ -32425,7 +32420,7 @@ static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz, #endif InitDecodedCert_ex(decoded, der, (word32)derSz, NULL, devId); - ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); + ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0, NULL); if (ret < 0) { WOLFSSL_MSG("ParseCertRelative error"); @@ -32624,7 +32619,7 @@ static int SetNameFromCert(CertName* cn, const byte* der, int derSz, int devId) #endif InitDecodedCert_ex(decoded, der, (word32)derSz, NULL, devId); - ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); + ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0, NULL); if (ret < 0) { WOLFSSL_MSG("ParseCertRelative error"); @@ -36561,7 +36556,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, cert_inited = 1; /* Don't verify if we don't have access to Cert Manager. */ - ret = ParseCertRelativeEx(cert, CERT_TYPE, + ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY_OCSP_CERT, cm, resp->pendingCAs); if (ret < 0) { @@ -36723,7 +36718,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, certInit = 1; /* Parse the certificate and don't verify if we don't have access to * Cert Manager. */ - ret = ParseCertRelativeEx(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY, + ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY, cm, resp->pendingCAs); if (ret < 0) { WOLFSSL_MSG("\tOCSP Responder certificate parsing failed"); diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 87ef8a86b2..ef111a6dfb 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -1126,7 +1126,7 @@ static WARN_UNUSED_RESULT int freeDecCertList(WC_DerCertList** list, while (current != NULL) { InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap); - if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) { + if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL, NULL) == 0) { if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, DeCert, 0) == 1) { WOLFSSL_MSG("Key Pair found"); *cert = current->buffer; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 893ee882c3..503c985790 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2187,8 +2187,6 @@ WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, WOLFSSL_ASN_API int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, int sigAlgoType); WOLFSSL_LOCAL int ParseCertRelative(DecodedCert* cert, int type, int verify, - void* cm); -WOLFSSL_LOCAL int ParseCertRelativeEx(DecodedCert* cert, int type, int verify, void* cm, Signer *extraCa); WOLFSSL_LOCAL int DecodeToKey(DecodedCert* cert, int verify); #ifdef WOLFSSL_ASN_TEMPLATE From 3e58cfd864dc264827ef02769ab1e3f1f3844f2c Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Thu, 4 Jul 2024 10:09:05 +0200 Subject: [PATCH 6/7] fixup! ocsp: improvements --- src/internal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/internal.c b/src/internal.c index a5a15b501e..c748c401d8 100644 --- a/src/internal.c +++ b/src/internal.c @@ -16198,7 +16198,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, || (response->single->status->status != CERT_GOOD)) ret = BAD_CERTIFICATE_STATUS_ERROR; - while (ret == 0) { + if (ret == 0) { request = (OcspRequest*)TLSX_CSR2_GetRequest( ssl->extensions, status_type, idx); @@ -16211,7 +16211,6 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, else { if (idx == 0) /* server cert must be OK */ endCertificateOK = 1; - break; } } From 053170613a5be40fb63f5620d546553646600622 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Fri, 5 Jul 2024 15:26:41 +0000 Subject: [PATCH 7/7] fixup! csrv2multi: pending ca list --- src/ocsp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ocsp.c b/src/ocsp.c index 9051ecf011..4760c50989 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -599,9 +599,9 @@ static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert, } ca = GetCAByName(cm, ca->issuerNameHash); #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) - if (ca == NULL && pendingCAs != NULL) { - ca = findSignerByName(pendingCAs, single->issuerHash); - } + if (ca == NULL && pendingCAs != NULL) { + ca = findSignerByName(pendingCAs, single->issuerHash); + } #endif } return passed;