aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Ghedini <alessandro@ghedini.me>2014-06-24 23:25:59 +0200
committerDaniel Stenberg <daniel@haxx.se>2015-01-16 23:23:29 +0100
commitf46c6fbee03ffd14038b1c5a5a73a86fbf862380 (patch)
treea64584823500dbbd15f459c759666b735ac222f4
parentf13669a375f5bfd14797bda91642cabe076974fa (diff)
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.
-rw-r--r--lib/vtls/nss.c51
-rw-r--r--lib/vtls/nssg.h3
2 files changed, 54 insertions, 0 deletions
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 37fe48079..519a61e36 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -60,6 +60,12 @@
#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 */
diff --git a/lib/vtls/nssg.h b/lib/vtls/nssg.h
index 74840e831..963ce4a35 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 */