@@ -6721,13 +6721,21 @@ int InitSSL_Suites(WOLFSSL* ssl)
67216721 !havePSK && !haveAnon && !haveMcast) {
67226722
67236723 /* server certificate must be loaded */
6724- if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer) {
6724+ if ((!ssl->buffers.certificate || !ssl->buffers.certificate->buffer)
6725+ #ifdef WOLFSSL_CERT_SETUP_CB
6726+ && ssl->ctx->certSetupCb == NULL
6727+ #endif
6728+ ) {
67256729 WOLFSSL_MSG("Server missing certificate");
67266730 WOLFSSL_ERROR_VERBOSE(NO_PRIVATE_KEY);
67276731 return NO_PRIVATE_KEY;
67286732 }
67296733
6730- if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
6734+ if ((!ssl->buffers.key || !ssl->buffers.key->buffer)
6735+ #ifdef WOLFSSL_CERT_SETUP_CB
6736+ && ssl->ctx->certSetupCb == NULL
6737+ #endif
6738+ ) {
67316739 /* allow no private key if using existing key */
67326740 #ifdef WOLF_PRIVATE_KEY_ID
67336741 if (ssl->devId != INVALID_DEVID
@@ -7037,9 +7045,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
70377045 ssl->buffers.certificate = ctx->certificate;
70387046 ssl->buffers.certChain = ctx->certChain;
70397047#endif
7040- #ifdef WOLFSSL_TLS13
70417048 ssl->buffers.certChainCnt = ctx->certChainCnt;
7042- #endif
70437049#ifndef WOLFSSL_BLIND_PRIVATE_KEY
70447050#ifdef WOLFSSL_COPY_KEY
70457051 if (ctx->privateKey != NULL) {
@@ -8702,11 +8708,12 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl)
87028708#ifdef OPENSSL_EXTRA
87038709 XFREE(ssl->param, ssl->heap, DYNAMIC_TYPE_OPENSSL);
87048710#endif
8705- #if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY))
8706- if (ssl->ocspResp) {
8707- XFREE(ssl->ocspResp, NULL, 0);
8708- ssl->ocspResp = NULL;
8709- ssl->ocspRespSz = 0;
8711+ #if defined(HAVE_OCSP)
8712+ {
8713+ size_t i;
8714+ for (i = 0; i < XELEM_CNT(ssl->ocspCsrResp); i++)
8715+ XFREE(ssl->ocspCsrResp[i].buffer, NULL, 0);
8716+ XMEMSET(ssl->ocspCsrResp, 0, sizeof(ssl->ocspCsrResp));
87108717 }
87118718#endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */
87128719#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
@@ -9037,11 +9044,12 @@ void FreeHandshakeResources(WOLFSSL* ssl)
90379044 * !WOLFSSL_POST_HANDSHAKE_AUTH */
90389045#endif /* HAVE_TLS_EXTENSIONS && !NO_TLS */
90399046
9040- #if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY))
9041- if (ssl->ocspResp != NULL) {
9042- XFREE(ssl->ocspResp, NULL, 0);
9043- ssl->ocspResp = NULL;
9044- ssl->ocspRespSz = 0;
9047+ #if defined(HAVE_OCSP)
9048+ {
9049+ size_t i;
9050+ for (i = 0; i < XELEM_CNT(ssl->ocspCsrResp); i++)
9051+ XFREE(ssl->ocspCsrResp[i].buffer, NULL, 0);
9052+ XMEMSET(ssl->ocspCsrResp, 0, sizeof(ssl->ocspCsrResp));
90459053 }
90469054#endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */
90479055
@@ -13897,6 +13905,29 @@ int CopyDecodedAcertToX509(WOLFSSL_X509_ACERT* x509, DecodedAcert* dAcert)
1389713905
1389813906#if (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
1389913907 defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) && !defined(WOLFSSL_NO_TLS12)
13908+ static int CsrDoStatusVerifyCb(WOLFSSL* ssl, byte* input, word32 inputSz, word32 idx,
13909+ int ret)
13910+ {
13911+ if (ssl->ctx->ocspStatusVerifyCb != NULL) {
13912+ int verRet;
13913+ WOLFSSL_MSG("Calling OCSP status verify callback");
13914+ verRet = ssl->ctx->ocspStatusVerifyCb(ssl, ret,
13915+ input, inputSz, idx, ssl->ctx->ocspStatusVerifyCbArg);
13916+ if (verRet > 0) {
13917+ WOLFSSL_MSG("\tInvalid OCSP status verify callback return");
13918+ ret = BAD_CERTIFICATE_STATUS_ERROR;
13919+ }
13920+ else {
13921+ if (ret == 0 && verRet < 0)
13922+ WOLFSSL_MSG("\tforcing error");
13923+ else if (ret < 0 && verRet == 0)
13924+ WOLFSSL_MSG("\toverriding error");
13925+ ret = verRet;
13926+ }
13927+ }
13928+ return ret;
13929+ }
13930+
1390013931static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1390113932 word32 status_length, int idx)
1390213933{
@@ -13949,9 +13980,6 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1394913980 return BUFFER_ERROR;
1395013981 } while(0);
1395113982
13952- if (request == NULL)
13953- return BAD_CERTIFICATE_STATUS_ERROR; /* not expected */
13954-
1395513983 #ifdef WOLFSSL_SMALL_STACK
1395613984 status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
1395713985 DYNAMIC_TYPE_OCSP_STATUS);
@@ -13976,22 +14004,34 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1397614004 #endif
1397714005
1397814006 /* InitOcspResponse sets single and status to response struct. */
13979- InitOcspResponse(response, single, status, input +*inOutIdx, status_length, ssl->heap);
14007+ InitOcspResponse(response, single, status, input +*inOutIdx, status_length,
14008+ ssl->heap);
1398014009
13981- if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0, 0) != 0)
13982- ret = BAD_CERTIFICATE_STATUS_ERROR;
13983- else if (CompareOcspReqResp(request, response) != 0)
13984- ret = BAD_CERTIFICATE_STATUS_ERROR;
13985- else if (response->responseStatus != OCSP_SUCCESSFUL)
14010+ /* Extract producedDate */
14011+ if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 1, 1) != 0)
1398614012 ret = BAD_CERTIFICATE_STATUS_ERROR;
13987- else if (response->single->status->status == CERT_REVOKED)
13988- ret = OCSP_CERT_REVOKED;
13989- else if (response->single->status->status != CERT_GOOD)
13990- ret = BAD_CERTIFICATE_STATUS_ERROR;
13991-
13992- else {
13993- XMEMCPY(ssl->ocspProducedDate, response->producedDate, sizeof ssl->ocspProducedDate);
14013+ if (ret == 0) {
14014+ XMEMCPY(ssl->ocspProducedDate, response->producedDate,
14015+ sizeof(ssl->ocspProducedDate));
1399414016 ssl->ocspProducedDateFormat = response->producedDateFormat;
14017+
14018+ /* Reset response */
14019+ FreeOcspResponse(response);
14020+ InitOcspResponse(response, single, status, input + *inOutIdx,
14021+ status_length, ssl->heap);
14022+
14023+ if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0, 0) != 0)
14024+ ret = BAD_CERTIFICATE_STATUS_ERROR;
14025+ else if (CompareOcspReqResp(request, response) != 0)
14026+ ret = BAD_CERTIFICATE_STATUS_ERROR;
14027+ else if (response->responseStatus != OCSP_SUCCESSFUL)
14028+ ret = BAD_CERTIFICATE_STATUS_ERROR;
14029+ else if (response->single->status->status == CERT_REVOKED)
14030+ ret = OCSP_CERT_REVOKED;
14031+ else if (response->single->status->status != CERT_GOOD)
14032+ ret = BAD_CERTIFICATE_STATUS_ERROR;
14033+
14034+ ret = CsrDoStatusVerifyCb(ssl, input + *inOutIdx, status_length, idx, ret);
1399514035 }
1399614036
1399714037 *inOutIdx += status_length;
@@ -17121,15 +17161,16 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1712117161 else if (CompareOcspReqResp(request, response) != 0) {
1712217162 ret = BAD_CERTIFICATE_STATUS_ERROR;
1712317163 }
17124- else {
17125- if (idx == 0) /* server cert must be OK */
17126- endCertificateOK = 1;
17127- }
1712817164 }
1712917165
1713017166 /* only frees 'single' if single->isDynamic is set */
1713117167 FreeOcspResponse(response);
1713217168
17169+ ret = CsrDoStatusVerifyCb(ssl, input + *inOutIdx, status_length,
17170+ idx, ret);
17171+ if (ret == 0 && idx == 0) /* server cert must be OK */
17172+ endCertificateOK = 1;
17173+
1713317174 *inOutIdx += status_length;
1713417175 list_length -= status_length;
1713517176 }
@@ -24325,10 +24366,9 @@ int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request,
2432524366
2432624367 InitDecodedCert(cert, certData, length, ssl->heap);
2432724368 /* TODO: Setup async support here */
24328- ret = ParseCertRelative(cert, CERT_TYPE, VERIFY , SSL_CM(ssl), NULL);
24329- if (ret != 0) {
24369+ ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY , SSL_CM(ssl), NULL);
24370+ if (ret != 0)
2433024371 WOLFSSL_MSG("ParseCert failed");
24331- }
2433224372 if (ret == 0)
2433324373 ret = InitOcspRequest(request, cert, 0, ssl->heap);
2433424374 if (ret == 0) {
@@ -25081,51 +25121,53 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
2508125121}
2508225122#endif
2508325123
25084- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
25085- (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
25086- defined(WOLFSSL_HAPROXY))
25087- static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl)
25124+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
25125+ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
25126+ static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl, byte status_type)
2508825127{
2508925128 WOLFSSL_OCSP *ocsp;
25090- void *ioCtx = NULL;
25091- buffer response;
25092- int ret;
25129+ int ret = 0;
2509325130
25094- if (ssl == NULL) {
25131+ if (ssl == NULL || (status_type != WOLFSSL_CSR2_OCSP &&
25132+ status_type != WOLFSSL_CSR2_OCSP_MULTI))
2509525133 return BAD_FUNC_ARG;
25096- }
2509725134
2509825135 ocsp = SSL_CM(ssl)->ocsp_stapling;
2509925136 if (ocsp == NULL || ocsp->statusCb == NULL)
2510025137 return BAD_FUNC_ARG;
25101- ioCtx = (ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx;
25102- XMEMSET(&response, 0, sizeof(response));
2510325138 WOLFSSL_MSG("Calling ocsp->statusCb");
25104- ret = ocsp->statusCb(ssl, ioCtx );
25139+ ret = ocsp->statusCb(ssl, ocsp->statusCbArg );
2510525140 switch (ret) {
25106- case SSL_TLSEXT_ERR_OK:
25107- if (ssl->ocspResp == NULL || ssl->ocspRespSz == 0) {
25108- ret = 0;
25109- break;
25141+ case WOLFSSL_OCSP_STATUS_CB_OK: {
25142+ byte cnt = 1;
25143+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
25144+ if (status_type == WOLFSSL_CSR2_OCSP_MULTI) {
25145+ /* Find last response set */
25146+ for (cnt = XELEM_CNT(ssl->ocspCsrResp);
25147+ cnt > 0 && ssl->ocspCsrResp[cnt-1].buffer == NULL;
25148+ cnt--);
25149+ cnt = MIN(cnt, ssl->buffers.certChainCnt + 1);
2511025150 }
25111- response.buffer = ssl->ocspResp;
25112- response.length = ssl->ocspRespSz;
25113- ret = BuildCertificateStatus(ssl, WOLFSSL_CSR_OCSP, &response, 1 );
25151+ #endif
25152+ ret = BuildCertificateStatus( ssl, status_type, ssl->ocspCsrResp,
25153+ cnt );
2511425154 break;
25115- case SSL_TLSEXT_ERR_NOACK:
25155+ }
25156+ case WOLFSSL_OCSP_STATUS_CB_NOACK:
2511625157 /* No OCSP response to send */
2511725158 ret = 0;
2511825159 break;
25119- case SSL_TLSEXT_ERR_ALERT_FATAL :
25160+ case WOLFSSL_OCSP_STATUS_CB_ALERT_FATAL :
2512025161 /* fall through */
2512125162 default:
2512225163 ret = WOLFSSL_FATAL_ERROR;
2512325164 break;
2512425165 }
25166+
2512525167 return ret;
2512625168}
25127- #endif /* HAVE_CERTIFICATE_STATUS_REQUEST && (defined(OPENSSL_ALL) ||
25128- defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */
25169+ #endif /* HAVE_CERTIFICATE_STATUS_REQUEST ||
25170+ * HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
2512925171
2513025172#endif /* NO_WOLFSSL_SERVER */
2513125173
@@ -25151,13 +25193,11 @@ int SendCertificateStatus(WOLFSSL* ssl)
2515125193 status_type = status_type ? status_type : ssl->status_request_v2;
2515225194#endif
2515325195
25154- #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
25155- (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
25156- defined(WOLFSSL_HAPROXY))
25196+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
25197+ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
2515725198 if (SSL_CM(ssl)->ocsp_stapling != NULL &&
2515825199 SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) {
25159- if (ssl->status_request == WOLFSSL_CSR_OCSP)
25160- return BuildCertificateStatusWithStatusCB(ssl);
25200+ return BuildCertificateStatusWithStatusCB(ssl, status_type);
2516125201 }
2516225202#endif
2516325203
@@ -25247,14 +25287,14 @@ int SendCertificateStatus(WOLFSSL* ssl)
2524725287 return MEMORY_E;
2524825288 }
2524925289
25250- /* use certChain if available, otherwise use peer certificate */
25290+ /* use certChain if available, otherwise use certificate */
2525125291 chain = ssl->buffers.certChain;
2525225292 if (chain == NULL) {
2525325293 chain = ssl->buffers.certificate;
2525425294 }
2525525295
2525625296 if (chain && chain->buffer) {
25257- while (idx + OPAQUE24_LEN < chain->length) {
25297+ while (ret == 0 && idx + OPAQUE24_LEN < chain->length) {
2525825298 c24to32(chain->buffer + idx, &der.length);
2525925299 idx += OPAQUE24_LEN;
2526025300
@@ -25267,7 +25307,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
2526725307 der.length, &ctxOwnsRequest);
2526825308 if (ret == 0) {
2526925309 request->ssl = ssl;
25270- ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling,
25310+ ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling,
2527125311 request, &responses[i + 1], ssl->heap);
2527225312
2527325313 /* Suppressing, not critical */
@@ -31670,7 +31710,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
3167031710 word16 len;
3167131711 word32 begin = *inOutIdx;
3167231712 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
31673- defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
31713+ defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
31714+ defined(WOLFSSL_CERT_SETUP_CB)
3167431715 int ret;
3167531716 #endif
3167631717 #ifdef OPENSSL_EXTRA
@@ -31817,6 +31858,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
3181731858 len -= (word16)(OPAQUE16_LEN) + dnSz;
3181831859 }
3181931860
31861+ #ifdef WOLFSSL_CERT_SETUP_CB
3182031862 #ifdef OPENSSL_EXTRA
3182131863 /* call client cert callback if no cert has been loaded */
3182231864 if ((ssl->ctx->CBClientCert != NULL) &&
@@ -31838,6 +31880,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
3183831880 return WOLFSSL_ERROR_WANT_X509_LOOKUP;
3183931881 }
3184031882 }
31883+ #endif
3184131884 if ((ret = CertSetupCbWrapper(ssl)) != 0)
3184231885 return ret;
3184331886 #endif
@@ -38671,7 +38714,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3867138714 #endif
3867238715#endif
3867338716
38674- #ifdef OPENSSL_EXTRA
38717+ #ifdef WOLFSSL_CERT_SETUP_CB
3867538718 /* Give user last chance to provide a cert for cipher selection */
3867638719 if (ret == 0 && ssl->ctx->certSetupCb != NULL)
3867738720 ret = CertSetupCbWrapper(ssl);
0 commit comments