201 lines
6.5 KiB
Diff
201 lines
6.5 KiB
Diff
From aeb1a281cab13c7ba791cb104e556b20e713941f Mon Sep 17 00:00:00 2001
|
|
From: Daniel Stenberg <daniel@haxx.se>
|
|
Date: Tue, 20 Aug 2024 16:14:39 +0200
|
|
Subject: [PATCH] gtls: fix OCSP stapling management
|
|
|
|
Reported-by: Hiroki Kurosawa
|
|
Closes #14642
|
|
---
|
|
lib/vtls/gtls.c | 146 ++++++++++++++++++++++++------------------------
|
|
1 file changed, 73 insertions(+), 73 deletions(-)
|
|
|
|
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
|
|
index 03d6fcc038aac3..c7589d9d39bc81 100644
|
|
--- a/lib/vtls/gtls.c
|
|
+++ b/lib/vtls/gtls.c
|
|
@@ -850,6 +850,13 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
|
|
init_flags |= GNUTLS_NO_TICKETS;
|
|
#endif
|
|
|
|
+#if defined(GNUTLS_NO_STATUS_REQUEST)
|
|
+ if(!config->verifystatus)
|
|
+ /* Disable the "status_request" TLS extension, enabled by default since
|
|
+ GnuTLS 3.8.0. */
|
|
+ init_flags |= GNUTLS_NO_STATUS_REQUEST;
|
|
+#endif
|
|
+
|
|
rc = gnutls_init(>ls->session, init_flags);
|
|
if(rc != GNUTLS_E_SUCCESS) {
|
|
failf(data, "gnutls_init() failed: %d", rc);
|
|
@@ -1321,104 +1328,97 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
|
|
infof(data, " server certificate verification SKIPPED");
|
|
|
|
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_datum_t status_request;
|
|
+ gnutls_ocsp_resp_t ocsp_resp;
|
|
+ gnutls_ocsp_cert_status_t status;
|
|
+ gnutls_x509_crl_reason_t reason;
|
|
|
|
- gnutls_ocsp_cert_status_t status;
|
|
- gnutls_x509_crl_reason_t reason;
|
|
+ rc = gnutls_ocsp_status_request_get(session, &status_request);
|
|
|
|
- rc = gnutls_ocsp_status_request_get(session, &status_request);
|
|
+ if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
|
+ failf(data, "No OCSP response received");
|
|
+ return CURLE_SSL_INVALIDCERTSTATUS;
|
|
+ }
|
|
|
|
- infof(data, " server certificate status verification FAILED");
|
|
+ if(rc < 0) {
|
|
+ failf(data, "Invalid OCSP response received");
|
|
+ return CURLE_SSL_INVALIDCERTSTATUS;
|
|
+ }
|
|
|
|
- if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
|
- failf(data, "No OCSP response received");
|
|
- return CURLE_SSL_INVALIDCERTSTATUS;
|
|
- }
|
|
+ gnutls_ocsp_resp_init(&ocsp_resp);
|
|
|
|
- if(rc < 0) {
|
|
- failf(data, "Invalid OCSP response received");
|
|
- return CURLE_SSL_INVALIDCERTSTATUS;
|
|
- }
|
|
+ rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
|
|
+ if(rc < 0) {
|
|
+ failf(data, "Invalid OCSP response received");
|
|
+ return CURLE_SSL_INVALIDCERTSTATUS;
|
|
+ }
|
|
|
|
- gnutls_ocsp_resp_init(&ocsp_resp);
|
|
+ (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
|
|
+ &status, NULL, NULL, NULL, &reason);
|
|
|
|
- rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
|
|
- if(rc < 0) {
|
|
- failf(data, "Invalid OCSP response received");
|
|
- return CURLE_SSL_INVALIDCERTSTATUS;
|
|
- }
|
|
+ switch(status) {
|
|
+ case GNUTLS_OCSP_CERT_GOOD:
|
|
+ break;
|
|
|
|
- (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
|
|
- &status, NULL, NULL, NULL, &reason);
|
|
+ case GNUTLS_OCSP_CERT_REVOKED: {
|
|
+ const char *crl_reason;
|
|
|
|
- switch(status) {
|
|
- case GNUTLS_OCSP_CERT_GOOD:
|
|
+ switch(reason) {
|
|
+ default:
|
|
+ case GNUTLS_X509_CRLREASON_UNSPECIFIED:
|
|
+ crl_reason = "unspecified reason";
|
|
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_KEYCOMPROMISE:
|
|
+ crl_reason = "private key compromised";
|
|
+ break;
|
|
|
|
- case GNUTLS_X509_CRLREASON_SUPERSEDED:
|
|
- crl_reason = "certificate superseded";
|
|
- break;
|
|
+ case GNUTLS_X509_CRLREASON_CACOMPROMISE:
|
|
+ crl_reason = "CA compromised";
|
|
+ break;
|
|
|
|
- case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
|
|
- crl_reason = "operation has ceased";
|
|
- break;
|
|
+ case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
|
|
+ crl_reason = "affiliation has changed";
|
|
+ break;
|
|
|
|
- case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
|
|
- crl_reason = "certificate is on hold";
|
|
- break;
|
|
+ case GNUTLS_X509_CRLREASON_SUPERSEDED:
|
|
+ crl_reason = "certificate superseded";
|
|
+ break;
|
|
|
|
- case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
|
|
- crl_reason = "will be removed from delta CRL";
|
|
- break;
|
|
+ case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
|
|
+ crl_reason = "operation has ceased";
|
|
+ break;
|
|
|
|
- case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
|
|
- crl_reason = "privilege withdrawn";
|
|
- break;
|
|
+ case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
|
|
+ crl_reason = "certificate is on hold";
|
|
+ break;
|
|
|
|
- case GNUTLS_X509_CRLREASON_AACOMPROMISE:
|
|
- crl_reason = "AA compromised";
|
|
- break;
|
|
- }
|
|
+ case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
|
|
+ crl_reason = "will be removed from delta CRL";
|
|
+ break;
|
|
|
|
- failf(data, "Server certificate was revoked: %s", crl_reason);
|
|
+ case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
|
|
+ crl_reason = "privilege withdrawn";
|
|
break;
|
|
- }
|
|
|
|
- default:
|
|
- case GNUTLS_OCSP_CERT_UNKNOWN:
|
|
- failf(data, "Server certificate status is unknown");
|
|
+ case GNUTLS_X509_CRLREASON_AACOMPROMISE:
|
|
+ crl_reason = "AA compromised";
|
|
break;
|
|
}
|
|
|
|
- gnutls_ocsp_resp_deinit(ocsp_resp);
|
|
+ failf(data, "Server certificate was revoked: %s", crl_reason);
|
|
+ break;
|
|
+ }
|
|
|
|
- return CURLE_SSL_INVALIDCERTSTATUS;
|
|
+ default:
|
|
+ case GNUTLS_OCSP_CERT_UNKNOWN:
|
|
+ failf(data, "Server certificate status is unknown");
|
|
+ break;
|
|
}
|
|
- else
|
|
- infof(data, " server certificate status verification OK");
|
|
+
|
|
+ gnutls_ocsp_resp_deinit(ocsp_resp);
|
|
+ if(status != GNUTLS_OCSP_CERT_GOOD)
|
|
+ return CURLE_SSL_INVALIDCERTSTATUS;
|
|
}
|
|
else
|
|
infof(data, " server certificate status verification SKIPPED");
|