@@ -14022,6 +14022,7 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args,
1402214022 buffer* cert;
1402314023 byte* subjectHash = NULL;
1402414024 int alreadySigner = 0;
14025+ Signer *extraSigners = NULL;
1402514026#if defined(HAVE_RPK)
1402614027 int cType;
1402714028#endif
@@ -14123,9 +14124,13 @@ PRAGMA_GCC_DIAG_POP
1412314124 return ret;
1412414125 #endif
1412514126 }
14126-
14127+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
14128+ if (verify != NO_VERIFY && TLSX_CSR2_IsMulti(ssl->extensions)) {
14129+ extraSigners = TLSX_CSR2_GetPendingSigners(ssl->extensions);
14130+ }
14131+ #endif
1412714132 /* Parse Certificate */
14128- ret = ParseCertRelative (args->dCert, certType, verify, SSL_CM(ssl));
14133+ ret = ParseCertRelativeEx (args->dCert, certType, verify, SSL_CM(ssl), extraSigners );
1412914134
1413014135#if defined(HAVE_RPK)
1413114136 /* if cert type has negotiated with peer, confirm the cert received has
@@ -14358,6 +14363,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1435814363 byte* subjectHash = NULL;
1435914364 int alreadySigner = 0;
1436014365
14366+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
14367+ int addToPendingCAs = 0;
14368+ #endif
1436114369 WOLFSSL_ENTER("ProcessPeerCerts");
1436214370
1436314371#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
@@ -14783,9 +14791,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1478314791 if (ret == 0) {
1478414792 #ifdef HAVE_OCSP
1478514793 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
14786- if (ssl->status_request_v2) {
14794+ addToPendingCAs = 0;
14795+ if (ssl->status_request_v2 && TLSX_CSR2_IsMulti(ssl->extensions)) {
1478714796 ret = TLSX_CSR2_InitRequests(ssl->extensions,
1478814797 args->dCert, 0, ssl->heap);
14798+ addToPendingCAs = 1;
1478914799 }
1479014800 else /* skips OCSP and force CRL check */
1479114801 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
@@ -14930,6 +14940,45 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1493014940 skipAddCA = 1;
1493114941 }
1493214942 #endif
14943+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
14944+ if (ret == 0 && addToPendingCAs && !alreadySigner) {
14945+ DecodedCert dCertAdd;
14946+ DerBuffer *derBuffer;
14947+ buffer* cert = &args->certs[args->certIdx];
14948+ Signer *s;
14949+ InitDecodedCert(&dCertAdd, cert->buffer, cert->length, ssl->heap);
14950+ ret = ParseCert(&dCertAdd, CA_TYPE, NO_VERIFY, SSL_CM(ssl));
14951+ if (ret != 0) {
14952+ FreeDecodedCert(&dCertAdd);
14953+ goto exit_ppc;
14954+ }
14955+ ret = AllocDer(&derBuffer, cert->length, CA_TYPE, ssl->heap);
14956+ if (ret != 0 || derBuffer == NULL) {
14957+ FreeDecodedCert(&dCertAdd);
14958+ goto exit_ppc;
14959+ }
14960+ XMEMCPY(derBuffer->buffer, cert->buffer, cert->length);
14961+ s = MakeSigner(SSL_CM(ssl)->heap);
14962+ if (s == NULL) {
14963+ FreeDecodedCert(&dCertAdd);
14964+ ret = MEMORY_E;
14965+ goto exit_ppc;
14966+ }
14967+ ret = FillSigner(s, &dCertAdd, CA_TYPE, derBuffer);
14968+ FreeDecodedCert(&dCertAdd);
14969+ FreeDer(&derBuffer);
14970+ if (ret != 0) {
14971+ FreeSigner(s, SSL_CM(ssl)->heap);
14972+ goto exit_ppc;
14973+ }
14974+ skipAddCA = 1;
14975+ ret = TLSX_CSR2_AddPendingSigner(ssl->extensions, s);
14976+ if (ret != 0) {
14977+ FreeSigner(s, ssl->heap);
14978+ goto exit_ppc;
14979+ }
14980+ }
14981+ #endif
1493314982
1493414983 /* If valid CA then add to Certificate Manager */
1493514984 if (ret == 0 && args->dCert->isCA &&
@@ -16082,6 +16131,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1608216131 OcspRequest* request;
1608316132 word32 list_length = status_length;
1608416133 byte idx = 0;
16134+ Signer *pendingCAs = NULL;
1608516135
1608616136 #ifdef WOLFSSL_SMALL_STACK
1608716137 CertStatus* status;
@@ -16098,6 +16148,8 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1609816148
1609916149 ssl->status_request_v2 = 0;
1610016150
16151+ pendingCAs = TLSX_CSR2_GetPendingSigners(ssl->extensions);
16152+
1610116153 #ifdef WOLFSSL_SMALL_STACK
1610216154 status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
1610316155 DYNAMIC_TYPE_OCSP_STATUS);
@@ -16136,7 +16188,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1613616188 if (status_length) {
1613716189 InitOcspResponse(response, single, status, input +*inOutIdx,
1613816190 status_length, ssl->heap);
16139-
16191+ response->pendingCAs = pendingCAs;
1614016192 if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap,
1614116193 0) != 0)
1614216194 || (response->responseStatus != OCSP_SUCCESSFUL)
@@ -16180,6 +16232,17 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1618016232 ret = BUFFER_ERROR;
1618116233 }
1618216234
16235+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
16236+ if (ret == 0) {
16237+ if (TLSX_CSR2_MergePendingCA(ssl) < 0) {
16238+ WOLFSSL_MSG("Failed to merge pending CAs");
16239+ }
16240+ }
16241+ else {
16242+ TLSX_CSR2_ClearPendingCA(ssl);
16243+ }
16244+ #endif
16245+
1618316246 if (ret != 0) {
1618416247 WOLFSSL_ERROR_VERBOSE(ret);
1618516248 SendAlert(ssl, alert_fatal, bad_certificate_status_response);
0 commit comments