@@ -14035,6 +14035,7 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args,
1403514035 buffer* cert;
1403614036 byte* subjectHash = NULL;
1403714037 int alreadySigner = 0;
14038+ Signer *extraSigners = NULL;
1403814039#if defined(HAVE_RPK)
1403914040 int cType;
1404014041#endif
@@ -14136,9 +14137,13 @@ PRAGMA_GCC_DIAG_POP
1413614137 return ret;
1413714138 #endif
1413814139 }
14139-
14140+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
14141+ if (verify != NO_VERIFY && TLSX_CSR2_IsMulti(ssl->extensions)) {
14142+ extraSigners = TLSX_CSR2_GetPendingSigners(ssl->extensions);
14143+ }
14144+ #endif
1414014145 /* Parse Certificate */
14141- ret = ParseCertRelative(args->dCert, certType, verify, SSL_CM(ssl));
14146+ ret = ParseCertRelative(args->dCert, certType, verify, SSL_CM(ssl), extraSigners );
1414214147
1414314148#if defined(HAVE_RPK)
1414414149 /* if cert type has negotiated with peer, confirm the cert received has
@@ -14371,6 +14376,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1437114376 byte* subjectHash = NULL;
1437214377 int alreadySigner = 0;
1437314378
14379+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
14380+ int addToPendingCAs = 0;
14381+ #endif
1437414382 WOLFSSL_ENTER("ProcessPeerCerts");
1437514383
1437614384#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
@@ -14796,9 +14804,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1479614804 if (ret == 0) {
1479714805 #ifdef HAVE_OCSP
1479814806 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
14799- if (ssl->status_request_v2) {
14807+ addToPendingCAs = 0;
14808+ if (ssl->status_request_v2 && TLSX_CSR2_IsMulti(ssl->extensions)) {
1480014809 ret = TLSX_CSR2_InitRequests(ssl->extensions,
1480114810 args->dCert, 0, ssl->heap);
14811+ addToPendingCAs = 1;
1480214812 }
1480314813 else /* skips OCSP and force CRL check */
1480414814 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
@@ -14943,6 +14953,46 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1494314953 skipAddCA = 1;
1494414954 }
1494514955 #endif
14956+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
14957+ if (ret == 0 && addToPendingCAs && !alreadySigner) {
14958+ DecodedCert dCertAdd;
14959+ DerBuffer *derBuffer;
14960+ buffer* cert = &args->certs[args->certIdx];
14961+ Signer *s;
14962+ InitDecodedCert(&dCertAdd, cert->buffer, cert->length, ssl->heap);
14963+ ret = ParseCert(&dCertAdd, CA_TYPE, NO_VERIFY, SSL_CM(ssl));
14964+ if (ret != 0) {
14965+ FreeDecodedCert(&dCertAdd);
14966+ goto exit_ppc;
14967+ }
14968+ ret = AllocDer(&derBuffer, cert->length, CA_TYPE, ssl->heap);
14969+ if (ret != 0 || derBuffer == NULL) {
14970+ FreeDecodedCert(&dCertAdd);
14971+ goto exit_ppc;
14972+ }
14973+ XMEMCPY(derBuffer->buffer, cert->buffer, cert->length);
14974+ s = MakeSigner(SSL_CM(ssl)->heap);
14975+ if (s == NULL) {
14976+ FreeDecodedCert(&dCertAdd);
14977+ FreeDer(&derBuffer);
14978+ ret = MEMORY_E;
14979+ goto exit_ppc;
14980+ }
14981+ ret = FillSigner(s, &dCertAdd, CA_TYPE, derBuffer);
14982+ FreeDecodedCert(&dCertAdd);
14983+ FreeDer(&derBuffer);
14984+ if (ret != 0) {
14985+ FreeSigner(s, SSL_CM(ssl)->heap);
14986+ goto exit_ppc;
14987+ }
14988+ skipAddCA = 1;
14989+ ret = TLSX_CSR2_AddPendingSigner(ssl->extensions, s);
14990+ if (ret != 0) {
14991+ FreeSigner(s, ssl->heap);
14992+ goto exit_ppc;
14993+ }
14994+ }
14995+ #endif
1494614996
1494714997 /* If valid CA then add to Certificate Manager */
1494814998 if (ret == 0 && args->dCert->isCA &&
@@ -16062,6 +16112,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1606216112 int ret = 0;
1606316113 byte status_type;
1606416114 word32 status_length;
16115+ int endCertificateOK = 0;
1606516116
1606616117 WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_DO);
1606716118 WOLFSSL_ENTER("DoCertificateStatus");
@@ -16085,6 +16136,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1608516136 /* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */
1608616137 case WOLFSSL_CSR2_OCSP:
1608716138 ret = ProcessCSR(ssl, input, inOutIdx, status_length);
16139+ endCertificateOK = (ret == 0);
1608816140 break;
1608916141
1609016142 #endif
@@ -16095,6 +16147,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1609516147 OcspRequest* request;
1609616148 word32 list_length = status_length;
1609716149 byte idx = 0;
16150+ Signer *pendingCAs = NULL;
1609816151
1609916152 #ifdef WOLFSSL_SMALL_STACK
1610016153 CertStatus* status;
@@ -16106,14 +16159,12 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1610616159 OcspResponse response[1];
1610716160 #endif
1610816161
16109- do {
16110- if (ssl->status_request_v2) {
16111- ssl->status_request_v2 = 0;
16112- break;
16113- }
16114-
16162+ if (!ssl->status_request_v2)
1611516163 return BUFFER_ERROR;
16116- } while(0);
16164+
16165+ ssl->status_request_v2 = 0;
16166+
16167+ pendingCAs = TLSX_CSR2_GetPendingSigners(ssl->extensions);
1611716168
1611816169 #ifdef WOLFSSL_SMALL_STACK
1611916170 status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
@@ -16153,23 +16204,27 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1615316204 if (status_length) {
1615416205 InitOcspResponse(response, single, status, input +*inOutIdx,
1615516206 status_length, ssl->heap);
16156-
16207+ response->pendingCAs = pendingCAs;
1615716208 if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap,
1615816209 0) != 0)
1615916210 || (response->responseStatus != OCSP_SUCCESSFUL)
1616016211 || (response->single->status->status != CERT_GOOD))
1616116212 ret = BAD_CERTIFICATE_STATUS_ERROR;
1616216213
16163- while (ret == 0) {
16214+ if (ret == 0) {
1616416215 request = (OcspRequest*)TLSX_CSR2_GetRequest(
16165- ssl->extensions, status_type, idx++ );
16216+ ssl->extensions, status_type, idx);
1616616217
16167- if (request == NULL)
16218+ if (request == NULL) {
1616816219 ret = BAD_CERTIFICATE_STATUS_ERROR;
16169- else if (CompareOcspReqResp(request, response) == 0)
16170- break;
16171- else if (idx == 1) /* server cert must be OK */
16220+ }
16221+ else if (CompareOcspReqResp(request, response) != 0) {
1617216222 ret = BAD_CERTIFICATE_STATUS_ERROR;
16223+ }
16224+ else {
16225+ if (idx == 0) /* server cert must be OK */
16226+ endCertificateOK = 1;
16227+ }
1617316228 }
1617416229
1617516230 /* only frees 'single' if single->isDynamic is set */
@@ -16178,6 +16233,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1617816233 *inOutIdx += status_length;
1617916234 list_length -= status_length;
1618016235 }
16236+ idx++;
1618116237 }
1618216238
1618316239 ssl->status_request_v2 = 0;
@@ -16197,6 +16253,20 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1619716253 ret = BUFFER_ERROR;
1619816254 }
1619916255
16256+ /* end certificate MUST be present */
16257+ if (endCertificateOK == 0)
16258+ ret = BAD_CERTIFICATE_STATUS_ERROR;
16259+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
16260+ if (ret == 0) {
16261+ if (TLSX_CSR2_MergePendingCA(ssl) < 0) {
16262+ WOLFSSL_MSG("Failed to merge pending CAs");
16263+ }
16264+ }
16265+ else {
16266+ TLSX_CSR2_ClearPendingCA(ssl);
16267+ }
16268+ #endif
16269+
1620016270 if (ret != 0) {
1620116271 WOLFSSL_ERROR_VERBOSE(ret);
1620216272 SendAlert(ssl, alert_fatal, bad_certificate_status_response);
@@ -16600,44 +16670,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1660016670 WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1660116671 return OUT_OF_ORDER_E;
1660216672 }
16603- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
16604- defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
16605- if (ssl->msgsReceived.got_certificate_status == 0) {
16606- int csrRet = 0;
16607- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
16608- if (csrRet == 0 && ssl->status_request) {
16609- WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
16610- csrRet = TLSX_CSR_ForceRequest(ssl);
16611- }
16612- #endif
16613- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
16614- if (csrRet == 0 && ssl->status_request_v2) {
16615- WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
16616- csrRet = TLSX_CSR2_ForceRequest(ssl);
16617- }
16618- #endif
16619- if (csrRet != 0) {
16620- /* Error out if OCSP lookups are enabled and failed or if
16621- * the user requires stapling. */
16622- if (SSL_CM(ssl)->ocspEnabled || SSL_CM(ssl)->ocspMustStaple)
16623- return csrRet;
16624- }
16625- /* Check that a status request extension was seen as the
16626- * CertificateStatus wasn't when an OCSP staple is required.
16627- */
16628- if (
16629- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
16630- !ssl->status_request &&
16631- #endif
16632- #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
16633- !ssl->status_request_v2 &&
16634- #endif
16635- SSL_CM(ssl)->ocspMustStaple) {
16636- WOLFSSL_ERROR_VERBOSE(OCSP_CERT_UNKNOWN);
16637- return OCSP_CERT_UNKNOWN;
16638- }
16639- }
16640- #endif
1664116673
1664216674 break;
1664316675#endif
@@ -16710,6 +16742,54 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1671016742 return OUT_OF_ORDER_E;
1671116743 }
1671216744 }
16745+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
16746+ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
16747+ if (ssl->msgsReceived.got_certificate_status == 0) {
16748+ int csrRet = 0;
16749+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
16750+ if (csrRet == 0 && ssl->status_request) {
16751+ WOLFSSL_MSG("No CertificateStatus before ServerHelloDone");
16752+ csrRet = TLSX_CSR_ForceRequest(ssl);
16753+ }
16754+ #endif
16755+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
16756+ if (csrRet == 0 && ssl->status_request_v2) {
16757+ WOLFSSL_MSG("No CertificateStatus before ServerHelloDone");
16758+ csrRet = TLSX_CSR2_ForceRequest(ssl);
16759+ }
16760+ if (ssl->status_request_v2) {
16761+ if (csrRet == 0) {
16762+ if (TLSX_CSR2_MergePendingCA(ssl) < 0) {
16763+ WOLFSSL_MSG("Failed to merge pending CAs");
16764+ }
16765+ }
16766+ else {
16767+ TLSX_CSR2_ClearPendingCA(ssl);
16768+ }
16769+ }
16770+ #endif
16771+ if (csrRet != 0) {
16772+ /* Error out if OCSP lookups are enabled and failed or if
16773+ * the user requires stapling. */
16774+ if (SSL_CM(ssl)->ocspEnabled || SSL_CM(ssl)->ocspMustStaple)
16775+ return csrRet;
16776+ }
16777+ /* Check that a status request extension was seen as the
16778+ * CertificateStatus wasn't when an OCSP staple is required.
16779+ */
16780+ if (
16781+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
16782+ !ssl->status_request &&
16783+ #endif
16784+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
16785+ !ssl->status_request_v2 &&
16786+ #endif
16787+ SSL_CM(ssl)->ocspMustStaple) {
16788+ WOLFSSL_ERROR_VERBOSE(OCSP_CERT_UNKNOWN);
16789+ return OCSP_CERT_UNKNOWN;
16790+ }
16791+ }
16792+ #endif
1671316793 break;
1671416794#endif
1671516795
@@ -23187,7 +23267,7 @@ static int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request,
2318723267
2318823268 InitDecodedCert(cert, certData, length, ssl->heap);
2318923269 /* TODO: Setup async support here */
23190- ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, SSL_CM(ssl));
23270+ ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, SSL_CM(ssl), NULL );
2319123271 if (ret != 0) {
2319223272 WOLFSSL_MSG("ParseCert failed");
2319323273 }
0 commit comments