mirror of
https://github.com/curl/curl.git
synced 2026-06-03 07:04:16 +03:00
gtls: verify OCSP response signature in gtls_verify_ocsp_status
Since aeb1a281ca ("gtls: fix OCSP stapling management"), the function
parses the stapled OCSP response and reads the certificate status via
gnutls_ocsp_resp_get_single(), but never calls gnutls_ocsp_resp_verify()
or gnutls_ocsp_resp_verify_direct(). A response with a forged or
corrupted signature is accepted without question.
Fix by calling gnutls_ocsp_resp_verify() against the trust list obtained
from the session credentials immediately after gnutls_ocsp_resp_import().
This handles both directly-signed responses and delegated OCSP responders
without requiring the issuer certificate to be present in the peer chain.
The missing check only affects the CURLOPT_SSL_VERIFYSTATUS code path
when CURLOPT_SSL_VERIFYPEER is disabled. With peer verification enabled,
gnutls_certificate_verify_peers2() independently catches the invalid
response via GNUTLS_CERT_INVALID_OCSP_STATUS before
gtls_verify_ocsp_status() is reached. As a result, no attack is possible
that is not already trivially achievable without OCSP stapling when peer
verification is off. This is a correctness and consistency fix, not a
security vulnerability.
Reported-by: Joshua Rogers
Closes #21677
This commit is contained in:
parent
d191de891a
commit
be6c4ee7fa
1 changed files with 17 additions and 4 deletions
|
|
@ -1429,6 +1429,9 @@ static CURLcode gtls_verify_ocsp_status(struct Curl_easy *data,
|
|||
{
|
||||
gnutls_ocsp_resp_t ocsp_resp = NULL;
|
||||
gnutls_datum_t status_request;
|
||||
gnutls_certificate_credentials_t creds = NULL;
|
||||
gnutls_x509_trust_list_t tlist = NULL;
|
||||
unsigned int verify_status = 0;
|
||||
gnutls_ocsp_cert_status_t status = GNUTLS_OCSP_CERT_UNKNOWN;
|
||||
gnutls_x509_crl_reason_t reason;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
|
@ -1461,13 +1464,23 @@ static CURLcode gtls_verify_ocsp_status(struct Curl_easy *data,
|
|||
goto out;
|
||||
}
|
||||
|
||||
rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
|
||||
&status, NULL, NULL, NULL, &reason);
|
||||
if(rc < 0) {
|
||||
failf(data, "Invalid OCSP response received");
|
||||
if(!gnutls_credentials_get(session, GNUTLS_CRD_CERTIFICATE,
|
||||
(void **)&creds))
|
||||
gnutls_certificate_get_trust_list(creds, &tlist);
|
||||
if(!tlist) {
|
||||
failf(data, "OCSP response signature verification failed");
|
||||
result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
goto out;
|
||||
}
|
||||
rc = gnutls_ocsp_resp_verify(ocsp_resp, tlist, &verify_status, 0);
|
||||
if(rc < 0 || verify_status) {
|
||||
failf(data, "OCSP response signature verification failed");
|
||||
result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
(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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue