]> granicus.if.org Git - curl/commitdiff
nss: add support for the Certificate Status Request TLS extension
authorAlessandro Ghedini <alessandro@ghedini.me>
Tue, 24 Jun 2014 21:25:59 +0000 (23:25 +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 NSS 3.15 or higher.

lib/vtls/nss.c
lib/vtls/nssg.h

index 37fe48079b32d860425de749fb93e63ed8a67d2f..519a61e36baeea098cfeab5745c0a502cc54fe28 100644 (file)
 #include <cert.h>
 #include <prerror.h>
 
+#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
+
+#if NSSVERNUM >= 0x030f00 /* 3.15.0 */
+#include <ocsp.h>
+#endif
+
 #include "curl_memory.h"
 #include "rawstr.h"
 #include "warnless.h"
@@ -639,6 +645,34 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
                                     PRBool isServer)
 {
   struct connectdata *conn = (struct connectdata *)arg;
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(conn->data->set.ssl.verifystatus) {
+    SECStatus cacheResult;
+
+    const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
+    if(!csa) {
+      failf(conn->data, "Invalid OCSP response");
+      return SECFailure;
+    }
+
+    if(csa->len == 0) {
+      failf(conn->data, "No OCSP response received");
+      return SECFailure;
+    }
+
+    cacheResult = CERT_CacheOCSPResponseFromSideChannel(
+      CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
+      PR_Now(), &csa->items[0], arg
+    );
+
+    if(cacheResult != SECSuccess) {
+      failf(conn->data, "Invalid OCSP response");
+      return cacheResult;
+    }
+  }
+#endif
+
   if(!conn->data->set.ssl.verifypeer) {
     infof(conn->data, "skipping SSL peer certificate verification\n");
     return SECSuccess;
@@ -1620,6 +1654,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
   }
 
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(data->set.ssl.verifystatus) {
+    if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
+        != SECSuccess)
+      goto error;
+  }
+#endif
+
 #ifdef USE_NGHTTP2
   if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
 #ifdef SSL_ENABLE_NPN
@@ -1908,4 +1950,13 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
   PK11_DestroyContext(MD5pw, PR_TRUE);
 }
 
+bool Curl_nss_cert_status_request(void)
+{
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
 #endif /* USE_NSS */
index 74840e831103907e7b9be7556b27d6107263cb56..963ce4a356613bf27e722bff7a5fadd0e758c781 100644 (file)
@@ -60,6 +60,8 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
                      unsigned char *md5sum, /* output */
                      size_t md5len);
 
+bool Curl_nss_cert_status_request(void);
+
 /* this backend supports the CAPATH option */
 #define have_curlssl_ca_path 1
 
@@ -86,6 +88,7 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
 #define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
 #define curlssl_random(x,y,z) Curl_nss_random(x,y,z)
 #define curlssl_md5sum(a,b,c,d) Curl_nss_md5sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_nss_cert_status_request()
 #define CURL_SSL_BACKEND CURLSSLBACKEND_NSS
 
 #endif /* USE_NSS */