@@ -14035,6 +14035,7 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args,
14035
14035
buffer* cert;
14036
14036
byte* subjectHash = NULL;
14037
14037
int alreadySigner = 0;
14038
+ Signer *extraSigners = NULL;
14038
14039
#if defined(HAVE_RPK)
14039
14040
int cType;
14040
14041
#endif
@@ -14136,9 +14137,13 @@ PRAGMA_GCC_DIAG_POP
14136
14137
return ret;
14137
14138
#endif
14138
14139
}
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
14140
14145
/* Parse Certificate */
14141
- ret = ParseCertRelative(args->dCert, certType, verify, SSL_CM(ssl));
14146
+ ret = ParseCertRelative(args->dCert, certType, verify, SSL_CM(ssl), extraSigners );
14142
14147
14143
14148
#if defined(HAVE_RPK)
14144
14149
/* if cert type has negotiated with peer, confirm the cert received has
@@ -14371,6 +14376,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
14371
14376
byte* subjectHash = NULL;
14372
14377
int alreadySigner = 0;
14373
14378
14379
+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
14380
+ int addToPendingCAs = 0;
14381
+ #endif
14374
14382
WOLFSSL_ENTER("ProcessPeerCerts");
14375
14383
14376
14384
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
@@ -14796,9 +14804,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
14796
14804
if (ret == 0) {
14797
14805
#ifdef HAVE_OCSP
14798
14806
#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)) {
14800
14809
ret = TLSX_CSR2_InitRequests(ssl->extensions,
14801
14810
args->dCert, 0, ssl->heap);
14811
+ addToPendingCAs = 1;
14802
14812
}
14803
14813
else /* skips OCSP and force CRL check */
14804
14814
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
@@ -14943,6 +14953,46 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
14943
14953
skipAddCA = 1;
14944
14954
}
14945
14955
#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
14946
14996
14947
14997
/* If valid CA then add to Certificate Manager */
14948
14998
if (ret == 0 && args->dCert->isCA &&
@@ -16062,6 +16112,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16062
16112
int ret = 0;
16063
16113
byte status_type;
16064
16114
word32 status_length;
16115
+ int endCertificateOK = 0;
16065
16116
16066
16117
WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_DO);
16067
16118
WOLFSSL_ENTER("DoCertificateStatus");
@@ -16085,6 +16136,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16085
16136
/* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */
16086
16137
case WOLFSSL_CSR2_OCSP:
16087
16138
ret = ProcessCSR(ssl, input, inOutIdx, status_length);
16139
+ endCertificateOK = (ret == 0);
16088
16140
break;
16089
16141
16090
16142
#endif
@@ -16095,6 +16147,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16095
16147
OcspRequest* request;
16096
16148
word32 list_length = status_length;
16097
16149
byte idx = 0;
16150
+ Signer *pendingCAs = NULL;
16098
16151
16099
16152
#ifdef WOLFSSL_SMALL_STACK
16100
16153
CertStatus* status;
@@ -16106,14 +16159,12 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16106
16159
OcspResponse response[1];
16107
16160
#endif
16108
16161
16109
- do {
16110
- if (ssl->status_request_v2) {
16111
- ssl->status_request_v2 = 0;
16112
- break;
16113
- }
16114
-
16162
+ if (!ssl->status_request_v2)
16115
16163
return BUFFER_ERROR;
16116
- } while(0);
16164
+
16165
+ ssl->status_request_v2 = 0;
16166
+
16167
+ pendingCAs = TLSX_CSR2_GetPendingSigners(ssl->extensions);
16117
16168
16118
16169
#ifdef WOLFSSL_SMALL_STACK
16119
16170
status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
@@ -16153,23 +16204,27 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16153
16204
if (status_length) {
16154
16205
InitOcspResponse(response, single, status, input +*inOutIdx,
16155
16206
status_length, ssl->heap);
16156
-
16207
+ response->pendingCAs = pendingCAs;
16157
16208
if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap,
16158
16209
0) != 0)
16159
16210
|| (response->responseStatus != OCSP_SUCCESSFUL)
16160
16211
|| (response->single->status->status != CERT_GOOD))
16161
16212
ret = BAD_CERTIFICATE_STATUS_ERROR;
16162
16213
16163
- while (ret == 0) {
16214
+ if (ret == 0) {
16164
16215
request = (OcspRequest*)TLSX_CSR2_GetRequest(
16165
- ssl->extensions, status_type, idx++ );
16216
+ ssl->extensions, status_type, idx);
16166
16217
16167
- if (request == NULL)
16218
+ if (request == NULL) {
16168
16219
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) {
16172
16222
ret = BAD_CERTIFICATE_STATUS_ERROR;
16223
+ }
16224
+ else {
16225
+ if (idx == 0) /* server cert must be OK */
16226
+ endCertificateOK = 1;
16227
+ }
16173
16228
}
16174
16229
16175
16230
/* only frees 'single' if single->isDynamic is set */
@@ -16178,6 +16233,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16178
16233
*inOutIdx += status_length;
16179
16234
list_length -= status_length;
16180
16235
}
16236
+ idx++;
16181
16237
}
16182
16238
16183
16239
ssl->status_request_v2 = 0;
@@ -16197,6 +16253,20 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
16197
16253
ret = BUFFER_ERROR;
16198
16254
}
16199
16255
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
+
16200
16270
if (ret != 0) {
16201
16271
WOLFSSL_ERROR_VERBOSE(ret);
16202
16272
SendAlert(ssl, alert_fatal, bad_certificate_status_response);
@@ -16600,44 +16670,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
16600
16670
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
16601
16671
return OUT_OF_ORDER_E;
16602
16672
}
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
16641
16673
16642
16674
break;
16643
16675
#endif
@@ -16710,6 +16742,54 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
16710
16742
return OUT_OF_ORDER_E;
16711
16743
}
16712
16744
}
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
16713
16793
break;
16714
16794
#endif
16715
16795
@@ -23187,7 +23267,7 @@ static int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request,
23187
23267
23188
23268
InitDecodedCert(cert, certData, length, ssl->heap);
23189
23269
/* 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 );
23191
23271
if (ret != 0) {
23192
23272
WOLFSSL_MSG("ParseCert failed");
23193
23273
}
0 commit comments