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);