]> granicus.if.org Git - curl/commitdiff
gtls: add support for the Certificate Status Request TLS extension
authorAlessandro Ghedini <alessandro@ghedini.me>
Mon, 16 Jun 2014 11:21:02 +0000 (13:21 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 16 Jan 2015 22:23:29 +0000 (23:23 +0100)
Also known as "status_request" or OCSP stapling, defined in RFC6066 section 8.

This requires GnuTLS 3.1.3 or higher to build, however it's recommended to use
at least GnuTLS 3.3.11 since previous versions had a bug that caused the OCSP
response verfication to fail even on valid responses.

lib/vtls/gtls.c
lib/vtls/gtls.h

index 5d4e48a258a4cd36b643a59c63c1f6db801b84f5..27ca691e057996b827fac065953821c3fd91ffff 100644 (file)
@@ -98,6 +98,14 @@ static bool gtls_inited = FALSE;
 #      define HAS_ALPN
 #    endif
 #  endif
+
+#  if (GNUTLS_VERSION_NUMBER >= 0x03020d)
+#    define HAS_OCSP
+#  endif
+#endif
+
+#ifdef HAS_OCSP
+# include <gnutls/ocsp.h>
 #endif
 
 /*
@@ -663,6 +671,16 @@ gtls_connect_step1(struct connectdata *conn,
   /* lowat must be set to zero when using custom push and pull functions. */
   gnutls_transport_set_lowat(session, 0);
 
+#ifdef HAS_OCSP
+  if(data->set.ssl.verifystatus) {
+    rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif
+
   /* This might be a reconnect, so we check for a session ID in the cache
      to speed up things */
 
@@ -822,6 +840,23 @@ gtls_connect_step3(struct connectdata *conn,
   else
     infof(data, "\t server certificate verification SKIPPED\n");
 
+#ifdef HAS_OCSP
+  if(data->set.ssl.verifystatus) {
+    if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
+      if(verify_status & GNUTLS_CERT_REVOKED)
+        failf(data, "SSL server certificate was REVOKED\n");
+      else
+        failf(data, "SSL server certificate status verification FAILED");
+
+      return CURLE_SSL_INVALIDCERTSTATUS;
+    }
+    else
+      infof(data, "SSL server certificate status verification OK\n");
+  }
+  else
+    infof(data, "SSL server certificate status verification SKIPPED\n");
+#endif
+
   /* initialize an X.509 certificate structure. */
   gnutls_x509_crt_init(&x509_cert);
 
@@ -1392,4 +1427,13 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
 #endif
 }
 
+bool Curl_gtls_cert_status_request(void)
+{
+#ifdef HAS_OCSP
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
 #endif /* USE_GNUTLS */
index 12460beda3dc7891708a4ae87778e7b583694412..d02a366a6e33cf5617424fb630cd7901a12c9910 100644 (file)
@@ -53,6 +53,8 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
                       unsigned char *md5sum, /* output */
                       size_t md5len);
 
+bool Curl_gtls_cert_status_request(void);
+
 /* API setup for GnuTLS */
 #define curlssl_init Curl_gtls_init
 #define curlssl_cleanup Curl_gtls_cleanup
@@ -70,6 +72,7 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
 #define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
 #define curlssl_random(x,y,z) Curl_gtls_random(x,y,z)
 #define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_gtls_cert_status_request()
 #define CURL_SSL_BACKEND CURLSSLBACKEND_GNUTLS
 
 #endif /* USE_GNUTLS */