diff --git a/configure.ac b/configure.ac index 57670efde..4f5ea6101 100644 --- a/configure.ac +++ b/configure.ac @@ -9163,7 +9163,6 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PRIORITIZE_PSK" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CHECK_ALERT_ON_ERR" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TICKET_HAVE_ID" - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_OCSP_ISSUER_CHECK" ENABLED_TRUSTED_PEER_CERT=yes else CFLAGS=$(printf "%s" "$CFLAGS" | sed 's/-DOPENSSL_COMPATIBLE_DEFAULTS//g') diff --git a/src/internal.c b/src/internal.c index 3082c757a..b95d97e04 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8689,6 +8689,13 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) #endif #ifdef OPENSSL_EXTRA XFREE(ssl->param, ssl->heap, DYNAMIC_TYPE_OPENSSL); +#ifdef HAVE_OCSP + if (ssl->ocspResp) { + XFREE(ssl->ocspResp, NULL, 0); + ssl->ocspResp = NULL; + ssl->ocspRespSz = 0; + } +#endif #endif #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) while (ssl->certReqCtx != NULL) { @@ -9014,6 +9021,14 @@ void FreeHandshakeResources(WOLFSSL* ssl) * !WOLFSSL_POST_HANDSHAKE_AUTH */ #endif /* HAVE_TLS_EXTENSIONS && !NO_TLS */ +#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA) + if (ssl->ocspResp != NULL) { + XFREE(ssl->ocspResp, NULL, 0); + ssl->ocspResp = NULL; + ssl->ocspRespSz = 0; + } +#endif /* HAVE_OCSP && OPENSSL_EXTRA */ + #ifdef WOLFSSL_STATIC_MEMORY /* when done with handshake decrement current handshake count */ if (ssl->heap != NULL) { @@ -24099,7 +24114,7 @@ int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request, ret = InitOcspRequest(request, cert, 0, ssl->heap); if (ret == 0) { /* make sure ctx OCSP request is updated */ - if (!ssl->buffers.weOwnCert) { + if (!ssl->buffers.weOwnCert && SSL_CM(ssl) != NULL) { wolfSSL_Mutex* ocspLock = &SSL_CM(ssl)->ocsp_stapling->ocspLock; if (wc_LockMutex(ocspLock) == 0) { if (ssl->ctx->certOcspRequest == NULL) { @@ -24840,6 +24855,50 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, return ret; } #endif + +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)) +static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl) +{ + WOLFSSL_OCSP *ocsp; + void *ioCtx = NULL; + buffer response; + int ret; + + ocsp = SSL_CM(ssl)->ocsp_stapling; + if (ocsp == NULL || ocsp->statusCb == NULL) + return BAD_FUNC_ARG; + ioCtx = (ssl && ssl->ocspIOCtx != NULL) ? + ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; + XMEMSET(&response, 0, sizeof(response)); + WOLFSSL_MSG("Calling ocsp->statusCb"); + ret = ocsp->statusCb(ssl, ioCtx); + switch (ret) { + case SSL_TLSEXT_ERR_OK: + if (ssl->ocspResp == NULL || ssl->ocspRespSz == 0) { + ret = 0; + break; + } + response.buffer = ssl->ocspResp; + response.length = ssl->ocspRespSz; + ret = BuildCertificateStatus(ssl, WOLFSSL_CSR_OCSP, &response, 1); + break; + case SSL_TLSEXT_ERR_NOACK: + /* No OCSP response to send */ + ret = 0; + break; + case SSL_TLSEXT_ERR_ALERT_FATAL: + /* fall through */ + default: + ret = WOLFSSL_FATAL_ERROR; + break; + } + return ret; +} +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST && (defined(OPENSSL_ALL) || +defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)) +*/ #endif /* NO_WOLFSSL_SERVER */ /* handle generation of certificate_status (22) */ @@ -24860,6 +24919,20 @@ int SendCertificateStatus(WOLFSSL* ssl) #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 status_type = status_type ? status_type : ssl->status_request_v2; #endif + if (ssl == NULL || SSL_CM(ssl) == NULL) { + WOLFSSL_MSG("SendCertificateStatus bad args"); + return BAD_FUNC_ARG; + } + +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ +(defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)) + if (SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + if (ssl->status_request == WOLFSSL_CSR_OCSP) + return BuildCertificateStatusWithStatusCB(ssl); + } +#endif switch (status_type) { diff --git a/src/ocsp.c b/src/ocsp.c index 0b9343dba..1287a0048 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -480,31 +480,6 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, ioCtx = (ssl && ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) - if (ocsp->statusCb != NULL && ssl != NULL) { - WOLFSSL_MSG("Calling ocsp->statusCb"); - ret = ocsp->statusCb(ssl, ioCtx); - switch (ret) { - case SSL_TLSEXT_ERR_OK: - ret = wolfSSL_get_ocsp_response(ssl, &response); - ret = CheckOcspResponse(ocsp, response, ret, responseBuffer, - status, entry, NULL, heap); - XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL); - break; - case SSL_TLSEXT_ERR_NOACK: - ret = OCSP_LOOKUP_FAIL; - break; - case SSL_TLSEXT_ERR_ALERT_FATAL: - default: - WOLFSSL_LEAVE("CheckOcspRequest", ocsp->error); - ret = WOLFSSL_FATAL_ERROR; - break; - } - WOLFSSL_LEAVE("CheckOcspRequest", ret); - return ret; - } -#endif - if (ocsp->cm->ocspUseOverrideURL) { url = ocsp->cm->ocspOverrideURL; if (url != NULL && url[0] != '\0') diff --git a/src/ssl.c b/src/ssl.c index 33ce34a06..503fb1aaa 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17371,6 +17371,7 @@ long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, if (s == NULL) return WOLFSSL_FAILURE; + XFREE(s->ocspResp, NULL, 0); s->ocspResp = resp; s->ocspRespSz = len; diff --git a/src/tls.c b/src/tls.c index c035092d1..13147686f 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3238,6 +3238,15 @@ word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest, #endif #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) { +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) + if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL && + SSL_CM(csr->ssl)->ocsp_stapling != NULL && + SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL && + idx == 0) { + return OPAQUE8_LEN + OPAQUE24_LEN + csr->ssl->ocspRespSz; + } +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA */ return (word16)(OPAQUE8_LEN + OPAQUE24_LEN + csr->responses[idx].length); } @@ -3247,6 +3256,71 @@ word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest, return size; } +#if (defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)) && \ +(defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ +defined(OPENSSL_EXTRA)) +static int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl) +{ + void *ioCtx = NULL; + WOLFSSL_OCSP *ocsp; + int ret; + + if (ssl == NULL || SSL_CM(ssl) == NULL) + return BAD_FUNC_ARG; + ocsp = SSL_CM(ssl)->ocsp_stapling; + if (ocsp == NULL || ocsp->statusCb == NULL) + return BAD_FUNC_ARG; + ioCtx = (ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; + ret = ocsp->statusCb(ssl, ioCtx); + switch (ret) { + case SSL_TLSEXT_ERR_OK: + if (ssl->ocspRespSz > 0) { + /* ack the extension, status cb provided the response in + * ssl->ocspResp */ + TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); + ssl->status_request = WOLFSSL_CSR_OCSP; + } + ret = 0; + break; + case SSL_TLSEXT_ERR_NOACK: + /* suppressing as not critical */ + ret = 0; + break; + case SSL_TLSEXT_ERR_ALERT_FATAL: + default: + ret = WOLFSSL_FATAL_ERROR; + break; + } + return ret; +} + +static int TLSX_CSR_WriteWithStatusCB(CertificateStatusRequest* csr, + byte* output) +{ + WOLFSSL *ssl = csr->ssl; + WOLFSSL_OCSP *ocsp; + word16 offset = 0; + byte *response; + int respSz; + + if (ssl == NULL || SSL_CM(ssl) == NULL) + return BAD_FUNC_ARG; + ocsp = SSL_CM(ssl)->ocsp_stapling; + if (ocsp == NULL || ocsp->statusCb == NULL) + return BAD_FUNC_ARG; + response = ssl->ocspResp; + respSz = ssl->ocspRespSz; + if (response == NULL || respSz == 0) + return BAD_FUNC_ARG; + output[offset++] = WOLFSSL_CSR_OCSP; + c32to24(respSz, output + offset); + offset += OPAQUE24_LEN; + XMEMCPY(output + offset, response, respSz); + return offset + respSz; +} +#endif /* (TLS13 && !NO_WOLFSLL_SERVER) && (OPENSSL_ALL || WOLFSSL_NGINX || +WOLFSSL_HAPROXY || OPENSSL_EXTRA) */ + static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest) { return TLSX_CSR_GetSize_ex(csr, isRequest, 0); @@ -3299,6 +3373,16 @@ int TLSX_CSR_Write_ex(CertificateStatusRequest* csr, byte* output, #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) { word16 offset = 0; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) + if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL && + SSL_CM(csr->ssl)->ocsp_stapling != NULL && + SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL && + idx == 0) { + return TLSX_CSR_WriteWithStatusCB(csr, output); + } +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || +defined(OPENSSL_EXTRA) */ output[offset++] = csr->status_type; c32to24(csr->responses[idx].length, output + offset); offset += OPAQUE24_LEN; @@ -3574,7 +3658,24 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length, #if defined(WOLFSSL_TLS13) if (ssl->options.tls1_3) { - +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) + if (ssl != NULL && SSL_CM(ssl) != NULL && + SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + return TLSX_CSR_SetResponseWithStatusCB(ssl); +} +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || \ + defined(OPENSSL_EXTRA) */ +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) + if (ssl != NULL && SSL_CM(ssl) != NULL && + SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + return TLSX_CSR_SetResponseWithStatusCB(ssl); + } +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || +defined(OPENSSL_EXTRA) */ if (ssl->buffers.certificate == NULL) { WOLFSSL_MSG("Certificate buffer not set!"); return BUFFER_ERROR; @@ -4071,6 +4172,15 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length, continue; } +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \ + || defined(OPENSSL_EXTRA) + /* OpenSSL status CB supports only CERTIFICATE STATUS REQ V1 */ + if (ssl != NULL && SSL_CM(ssl) != NULL && + SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + return 0; + } +#endif /* if using status_request and already sending it, remove it * and prefer to use the v2 version */ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST