From f46c6fbee03ffd14038b1c5a5a73a86fbf862380 Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Tue, 24 Jun 2014 23:25:59 +0200 Subject: [PATCH] nss: add support for the Certificate Status Request TLS extension Also known as "status_request" or OCSP stapling, defined in RFC6066 section 8. This requires NSS 3.15 or higher. --- lib/vtls/nss.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/vtls/nssg.h | 3 +++ 2 files changed, 54 insertions(+) diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c index 37fe48079b32d8..519a61e36baeea 100644 --- a/lib/vtls/nss.c +++ b/lib/vtls/nss.c @@ -60,6 +60,12 @@ #include #include +#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH) + +#if NSSVERNUM >= 0x030f00 /* 3.15.0 */ +#include +#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 */ diff --git a/lib/vtls/nssg.h b/lib/vtls/nssg.h index 74840e83110390..963ce4a356613b 100644 --- a/lib/vtls/nssg.h +++ b/lib/vtls/nssg.h @@ -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 */