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

gtls: add support for the Certificate Status Request TLS extension

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.
parent 3af90a6e
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -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 */
+3 −0
Original line number Diff line number Diff line
@@ -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 */