Commit f46c6fbe authored by Alessandro Ghedini's avatar Alessandro Ghedini Committed by Daniel Stenberg
Browse files

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.
parent f13669a3
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
@@ -60,6 +60,12 @@
#include <cert.h>
#include <cert.h>
#include <prerror.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 "curl_memory.h"
#include "rawstr.h"
#include "rawstr.h"
#include "warnless.h"
#include "warnless.h"
@@ -639,6 +645,34 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
                                    PRBool isServer)
                                    PRBool isServer)
{
{
  struct connectdata *conn = (struct connectdata *)arg;
  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) {
  if(!conn->data->set.ssl.verifypeer) {
    infof(conn->data, "skipping SSL peer certificate verification\n");
    infof(conn->data, "skipping SSL peer certificate verification\n");
    return SECSuccess;
    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]);
    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
#ifdef USE_NGHTTP2
  if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
  if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
#ifdef SSL_ENABLE_NPN
#ifdef SSL_ENABLE_NPN
@@ -1908,4 +1950,13 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
  PK11_DestroyContext(MD5pw, PR_TRUE);
  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 */
#endif /* USE_NSS */
+3 −0
Original line number Original line Diff line number Diff line
@@ -60,6 +60,8 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
                     unsigned char *md5sum, /* output */
                     unsigned char *md5sum, /* output */
                     size_t md5len);
                     size_t md5len);


bool Curl_nss_cert_status_request(void);

/* this backend supports the CAPATH option */
/* this backend supports the CAPATH option */
#define have_curlssl_ca_path 1
#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_data_pending(x,y) ((void)x, (void)y, 0)
#define curlssl_random(x,y,z) Curl_nss_random(x,y,z)
#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_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
#define CURL_SSL_BACKEND CURLSSLBACKEND_NSS


#endif /* USE_NSS */
#endif /* USE_NSS */