Loading HuntDB...

CVE-2024-8096: OCSP stapling bypass with GnuTLS

Medium
C
curl
Submitted None
Reported by kurohiro

Vulnerability Details

Technical details and impact analysis

Improper Certificate Validation
## Summary: When the TLS backend is GnuTLS, there is an issue with the OCSP stapling validation process. As a result, even if the certificate is revoked, the connection can be established without resulting in an error. When the OCSP stapling status response is "revoked," gnutls_certificate_verify_peers2() returns an error. However, gnutls_certificate_verify_peers2() only returns an error when the OCSP status is "revoked." For other statuses, gnutls_certificate_verify_peers2() returns a successful result. In curl, the verification of the OCSP stapling status response is performed not only with the above function but also with gnutls_ocsp_status_request_is_checked(). However, this function returns a non-zero value if the OCSP stapling status response exists. As a result, if any response exists, it is treated as a successful case, and the verification process concludes. ``` if(config->verifystatus) { if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) { gnutls_datum_t status_request; gnutls_ocsp_resp_t ocsp_resp; gnutls_ocsp_cert_status_t status; gnutls_x509_crl_reason_t reason; rc = gnutls_ocsp_status_request_get(session, &status_request); infof(data, " server certificate status verification FAILED"); if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { failf(data, "No OCSP response received"); return CURLE_SSL_INVALIDCERTSTATUS; } if(rc < 0) { failf(data, "Invalid OCSP response received"); return CURLE_SSL_INVALIDCERTSTATUS; } gnutls_ocsp_resp_init(&ocsp_resp); rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); if(rc < 0) { failf(data, "Invalid OCSP response received"); return CURLE_SSL_INVALIDCERTSTATUS; } (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, &status, NULL, NULL, NULL, &reason); switch(status) { case GNUTLS_OCSP_CERT_GOOD: break; case GNUTLS_OCSP_CERT_REVOKED: { const char *crl_reason; switch(reason) { default: case GNUTLS_X509_CRLREASON_UNSPECIFIED: crl_reason = "unspecified reason"; break; case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: crl_reason = "private key compromised"; break; case GNUTLS_X509_CRLREASON_CACOMPROMISE: crl_reason = "CA compromised"; break; case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: crl_reason = "affiliation has changed"; break; case GNUTLS_X509_CRLREASON_SUPERSEDED: crl_reason = "certificate superseded"; break; case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: crl_reason = "operation has ceased"; break; case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: crl_reason = "certificate is on hold"; break; case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: crl_reason = "will be removed from delta CRL"; break; case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: crl_reason = "privilege withdrawn"; break; case GNUTLS_X509_CRLREASON_AACOMPROMISE: crl_reason = "AA compromised"; break; } failf(data, "Server certificate was revoked: %s", crl_reason); break; } default: case GNUTLS_OCSP_CERT_UNKNOWN: failf(data, "Server certificate status is unknown"); break; } gnutls_ocsp_resp_deinit(ocsp_resp); return CURLE_SSL_INVALIDCERTSTATUS; } else infof(data, " server certificate status verification OK"); } else infof(data, " server certificate status verification SKIPPED"); ``` ## Steps To Reproduce: I have set up a test site, so please try it out. OCSP stapling status response is configured to return "unauthorized (6)." 1. Prepare curl with GnuTLS backend. 2. curl https://ocsp4test.sytes.net:4433 --cert-status An error will occur if the TLS backend is OpenSSL. I noticed while researching that starting from GnuTLS 3.1.2, OCSP stapling is enabled by default with gnutls_init. As a result, whether you specify --cert-status or not, the behavior remains the same (currently, in the curl source code, it is not possible to disable OCSP stapling). https://www.gnutls.org/manual/html_node/Session-initialization.html ## Impact Bypassing OCSP verification.

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Submitted

Weakness

Improper Certificate Validation