trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shinr...@apache.org
Subject [trafficserver] branch master updated: Implement prefetched OCSP stapling responses
Date Thu, 02 May 2019 15:38:30 GMT
This is an automated email from the ASF dual-hosted git repository.

shinrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new d2386a5  Implement prefetched OCSP stapling responses
d2386a5 is described below

commit d2386a5027c186f6c4b5751c858fdb97264cfd23
Author: Valentin Gutierrez <vgutierrez@wikimedia.org>
AuthorDate: Wed Apr 3 15:38:12 2019 +0200

    Implement prefetched OCSP stapling responses
---
 doc/admin-guide/files/records.config.en.rst       |   8 ++
 doc/admin-guide/files/ssl_multicert.config.en.rst |   8 ++
 doc/admin-guide/security/index.en.rst             |   8 ++
 include/ts/ts.h                                   |   2 +-
 iocore/net/OCSPStapling.cc                        | 109 +++++++++++++++-------
 iocore/net/P_OCSPStapling.h                       |   2 +-
 iocore/net/P_SSLConfig.h                          |   1 +
 iocore/net/P_SSLUtils.h                           |  17 ++--
 iocore/net/SSLConfig.cc                           |   4 +
 iocore/net/SSLUtils.cc                            |  61 ++++++++----
 mgmt/RecordsConfig.cc                             |   4 +-
 src/traffic_server/InkAPI.cc                      |   4 +-
 src/traffic_server/InkAPITest.cc                  |   2 +-
 tests/gold_tests/autest-site/conditions.test.ext  |   4 +
 tests/gold_tests/tls/ssl/ca.ocsp.key              |  27 ++++++
 tests/gold_tests/tls/ssl/ca.ocsp.pem              |  20 ++++
 tests/gold_tests/tls/ssl/ocsp_response.der        | Bin 0 -> 2266 bytes
 tests/gold_tests/tls/ssl/responder.ocsp.key       |  27 ++++++
 tests/gold_tests/tls/ssl/responder.ocsp.pem       |  22 +++++
 tests/gold_tests/tls/ssl/server.ocsp.key          |  27 ++++++
 tests/gold_tests/tls/ssl/server.ocsp.pem          |  23 +++++
 tests/gold_tests/tls/tls_ocsp.test.py             |  73 +++++++++++++++
 22 files changed, 383 insertions(+), 70 deletions(-)

diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst
index 080a99b..b0d3c97 100644
--- a/doc/admin-guide/files/records.config.en.rst
+++ b/doc/admin-guide/files/records.config.en.rst
@@ -3516,6 +3516,14 @@ OCSP Stapling Configuration
 
    Update period (in seconds) for stapling caches.
 
+.. ts:cv:: CONFIG proxy.config.ssl.ocsp.response.path STRING NULL
+
+   The directory path of the prefetched OCSP stapling responses. Change this
+   variable only if you intend to use and administratively maintain
+   prefetched OCSP stapling responses. All stapling responses listed in
+   :file:`ssl_multicert.config` will be loaded relative to this
+   path.
+
 HTTP/2 Configuration
 ====================
 
diff --git a/doc/admin-guide/files/ssl_multicert.config.en.rst b/doc/admin-guide/files/ssl_multicert.config.en.rst
index e79ae46..54a391d 100644
--- a/doc/admin-guide/files/ssl_multicert.config.en.rst
+++ b/doc/admin-guide/files/ssl_multicert.config.en.rst
@@ -93,6 +93,14 @@ ssl_ca_name=FILENAME (optional)
   the certificate chain. *FILENAME* is resolved relative to the
   :ts:cv:`proxy.config.ssl.CA.cert.path` configuration variable.
 
+ssl_ocsp_name=FILENAME (optional)
+  The name of the file containing the prefetched OCSP stapling response
+  for this certificate. This field can be omitted to let trafficserver
+  fetch OCSP responses dynamically. Otherwise, when included, the administrator is
+  responsible for updating the file's content. *FILENAME* is resolved
+  relative to the :ts:cv:`proxy.config.ssl.ocsp.response.path`
+  configuration variable.
+
 ssl_ticket_enabled=1|0 (optional)
   Enable RFC 5077 stateless TLS session tickets. To support this,
   OpenSSL should be upgraded to version 0.9.8f or higher. This
diff --git a/doc/admin-guide/security/index.en.rst b/doc/admin-guide/security/index.en.rst
index 37ed096..84586c2 100644
--- a/doc/admin-guide/security/index.en.rst
+++ b/doc/admin-guide/security/index.en.rst
@@ -281,6 +281,13 @@ Authority Information Access field of the signed certificate. For example::
                 OCSP - URI:http://ocsp.digicert.com
                 CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
 
+Traffic Server can also use prefetched OCSP stapling responses if ssl_ocsp_name parameter
+is used in :file:`ssl_multicert.config`. Take into account that when using prefetched
+OCSP stapling responses traffic server will not refresh them and it should be done
+externally. This can be done using openssl:
+    $ openssl ocsp -issuer ca.crt -cert cert.crt -host ocsp.digicert.com:80 \
+      -header "Host=ocsp.digicert.com" -respout /var/cache/ocsp/cert.ocsp
+
 Support for OCSP Stapling can be tested using the -status option of the OpenSSL client::
 
     $ openssl s_client -connect mozillalabs.com:443 -status
@@ -301,6 +308,7 @@ in :file:`records.config` file:
 * :ts:cv:`proxy.config.ssl.ocsp.cache_timeout`
 * :ts:cv:`proxy.config.ssl.ocsp.request_timeout`
 * :ts:cv:`proxy.config.ssl.ocsp.update_period`
+* :ts:cv:`proxy.config.ssl.ocsp.response.path`
 
 .. _admin-split-dns:
 
diff --git a/include/ts/ts.h b/include/ts/ts.h
index 55bae84..cd4f46a 100644
--- a/include/ts/ts.h
+++ b/include/ts/ts.h
@@ -1234,7 +1234,7 @@ tsapi TSSslConnection TSVConnSSLConnectionGet(TSVConn sslp);
 tsapi TSSslContext TSSslContextFindByName(const char *name);
 tsapi TSSslContext TSSslContextFindByAddr(struct sockaddr const *);
 /*  Create a new SSL context based on the settings in records.config */
-tsapi TSSslContext TSSslServerContextCreate(TSSslX509 cert, const char *certname);
+tsapi TSSslContext TSSslServerContextCreate(TSSslX509 cert, const char *certname, const char
*rsp_file);
 tsapi void TSSslContextDestroy(TSSslContext ctx);
 tsapi void TSSslTicketKeyUpdate(char *ticketData, int ticketDataLen);
 tsapi TSNextProtocolSet TSUnregisterProtocol(TSNextProtocolSet protoset, const char *protocol);
diff --git a/iocore/net/OCSPStapling.cc b/iocore/net/OCSPStapling.cc
index 5a3121e..e6635ed 100644
--- a/iocore/net/OCSPStapling.cc
+++ b/iocore/net/OCSPStapling.cc
@@ -22,6 +22,7 @@
 #include "P_OCSPStapling.h"
 #if TS_USE_TLS_OCSP
 
+#include <openssl/bio.h>
 #include <openssl/ssl.h>
 #include <openssl/ocsp.h>
 #include "P_Net.h"
@@ -43,6 +44,7 @@ struct certinfo {
   ink_mutex stapling_mutex;
   unsigned char resp_der[MAX_STAPLING_DER];
   unsigned int resp_derlen;
+  bool is_prefetched;
   bool is_expire;
   time_t expire_time;
 };
@@ -141,11 +143,44 @@ end:
   return issuer;
 }
 
+static bool
+stapling_cache_response(OCSP_RESPONSE *rsp, certinfo *cinf)
+{
+  unsigned char resp_der[MAX_STAPLING_DER];
+  unsigned char *p;
+  unsigned int resp_derlen;
+
+  p           = resp_der;
+  resp_derlen = i2d_OCSP_RESPONSE(rsp, &p);
+
+  if (resp_derlen == 0) {
+    Error("stapling_cache_response: cannot decode OCSP response for %s", cinf->certname);
+    return false;
+  }
+
+  if (resp_derlen > MAX_STAPLING_DER) {
+    Error("stapling_cache_response: OCSP response too big (%u bytes) for %s", resp_derlen,
cinf->certname);
+    return false;
+  }
+
+  ink_mutex_acquire(&cinf->stapling_mutex);
+  memcpy(cinf->resp_der, resp_der, resp_derlen);
+  cinf->resp_derlen = resp_derlen;
+  cinf->is_expire   = false;
+  cinf->expire_time = time(nullptr) + SSLConfigParams::ssl_ocsp_cache_timeout;
+  ink_mutex_release(&cinf->stapling_mutex);
+
+  Debug("ssl_ocsp", "stapling_cache_response: success to cache response");
+  return true;
+}
+
 bool
-ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname)
+ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const char *rsp_file)
 {
   scoped_X509 issuer;
   STACK_OF(OPENSSL_STRING) *aia = nullptr;
+  BIO *rsp_bio                  = nullptr;
+  OCSP_RESPONSE *rsp            = nullptr;
 
   if (!cert) {
     Error("null cert passed in for %s", certname);
@@ -174,8 +209,33 @@ ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname)
   cinf->certname    = ats_strdup(certname);
   cinf->resp_derlen = 0;
   ink_mutex_init(&cinf->stapling_mutex);
-  cinf->is_expire   = true;
-  cinf->expire_time = 0;
+  cinf->is_prefetched = rsp_file ? true : false;
+  cinf->is_expire     = true;
+  cinf->expire_time   = 0;
+
+  if (cinf->is_prefetched) {
+    Debug("ssl_ocsp", "using OCSP prefetched response file %s", rsp_file);
+    rsp_bio = BIO_new_file(rsp_file, "r");
+    if (rsp_bio) {
+      rsp = d2i_OCSP_RESPONSE_bio(rsp_bio, nullptr);
+    }
+
+    if (!rsp_bio || !rsp) {
+      Note("cannot get prefetched response for %s from %s", certname, rsp_file);
+      goto err;
+    }
+
+    if (!stapling_cache_response(rsp, cinf)) {
+      Error("stapling_refresh_response: can not cache response");
+      goto err;
+    } else {
+      Debug("ssl_ocsp", "stapling_refresh_response: successful refresh OCSP response");
+      OCSP_RESPONSE_free(rsp);
+      rsp = nullptr;
+      BIO_free(rsp_bio);
+      rsp_bio = nullptr;
+    }
+  }
 
   issuer = stapling_get_issuer(ctx, cert);
   if (issuer == nullptr) {
@@ -222,6 +282,14 @@ err:
   if (map) {
     delete map;
   }
+
+  if (rsp) {
+    OCSP_RESPONSE_free(rsp);
+  }
+  if (rsp_bio) {
+    BIO_free(rsp_bio);
+  }
+
   return false;
 }
 
@@ -239,37 +307,6 @@ stapling_get_cert_info(SSL_CTX *ctx)
   return nullptr;
 }
 
-static bool
-stapling_cache_response(OCSP_RESPONSE *rsp, certinfo *cinf)
-{
-  unsigned char resp_der[MAX_STAPLING_DER];
-  unsigned char *p;
-  unsigned int resp_derlen;
-
-  p           = resp_der;
-  resp_derlen = i2d_OCSP_RESPONSE(rsp, &p);
-
-  if (resp_derlen == 0) {
-    Error("stapling_cache_response: cannot decode OCSP response for %s", cinf->certname);
-    return false;
-  }
-
-  if (resp_derlen > MAX_STAPLING_DER) {
-    Error("stapling_cache_response: OCSP response too big (%u bytes) for %s", resp_derlen,
cinf->certname);
-    return false;
-  }
-
-  ink_mutex_acquire(&cinf->stapling_mutex);
-  memcpy(cinf->resp_der, resp_der, resp_derlen);
-  cinf->resp_derlen = resp_derlen;
-  cinf->is_expire   = false;
-  cinf->expire_time = time(nullptr) + SSLConfigParams::ssl_ocsp_cache_timeout;
-  ink_mutex_release(&cinf->stapling_mutex);
-
-  Debug("ssl_ocsp", "stapling_cache_response: success to cache response");
-  return true;
-}
-
 static int
 stapling_check_response(certinfo *cinf, OCSP_RESPONSE *rsp)
 {
@@ -461,7 +498,7 @@ ocsp_update()
           cinf = iter->second;
           ink_mutex_acquire(&cinf->stapling_mutex);
           current_time = time(nullptr);
-          if (cinf->resp_derlen == 0 || cinf->is_expire || cinf->expire_time <
current_time) {
+          if ((cinf->resp_derlen == 0 || cinf->is_expire || cinf->expire_time <
current_time) && !cinf->is_prefetched) {
             ink_mutex_release(&cinf->stapling_mutex);
             if (stapling_refresh_response(cinf, &resp)) {
               Debug("Successfully refreshed OCSP for %s certificate. url=%s", cinf->certname,
cinf->uri);
@@ -506,7 +543,7 @@ ssl_callback_ocsp_stapling(SSL *ssl)
 
   ink_mutex_acquire(&cinf->stapling_mutex);
   time_t current_time = time(nullptr);
-  if (cinf->resp_derlen == 0 || cinf->is_expire || cinf->expire_time < current_time)
{
+  if ((cinf->resp_derlen == 0 || cinf->is_expire) || (cinf->expire_time < current_time
&& !cinf->is_prefetched)) {
     ink_mutex_release(&cinf->stapling_mutex);
     Debug("ssl_ocsp", "ssl_callback_ocsp_stapling: failed to get certificate status for %s",
cinf->certname);
     return SSL_TLSEXT_ERR_NOACK;
diff --git a/iocore/net/P_OCSPStapling.h b/iocore/net/P_OCSPStapling.h
index e3d5a6f..fbee110 100644
--- a/iocore/net/P_OCSPStapling.h
+++ b/iocore/net/P_OCSPStapling.h
@@ -28,7 +28,7 @@
 #include <openssl/ocsp.h>
 
 void ssl_stapling_ex_init();
-bool ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname);
+bool ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const char *rsp_file);
 void ocsp_update();
 int ssl_callback_ocsp_stapling(SSL *);
 #endif
diff --git a/iocore/net/P_SSLConfig.h b/iocore/net/P_SSLConfig.h
index 87a4a33..098d923 100644
--- a/iocore/net/P_SSLConfig.h
+++ b/iocore/net/P_SSLConfig.h
@@ -107,6 +107,7 @@ struct SSLConfigParams : public ConfigInfo {
   static int ssl_ocsp_request_timeout;
   static int ssl_ocsp_update_period;
   static int ssl_handshake_timeout_in;
+  char *ssl_ocsp_response_path_only;
 
   static size_t session_cache_number_buckets;
   static size_t session_cache_max_bucket_size;
diff --git a/iocore/net/P_SSLUtils.h b/iocore/net/P_SSLUtils.h
index b154dc1..932a8c3 100644
--- a/iocore/net/P_SSLUtils.h
+++ b/iocore/net/P_SSLUtils.h
@@ -45,14 +45,15 @@ typedef int ssl_error_t;
 struct SSLMultiCertConfigParams {
   SSLMultiCertConfigParams() { REC_ReadConfigInt32(session_ticket_enabled, "proxy.config.ssl.server.session_ticket.enable");
}
 
-  int session_ticket_enabled; ///< session ticket enabled
-  ats_scoped_str addr;        ///< IPv[64] address to match
-  ats_scoped_str cert;        ///< certificate
-  ats_scoped_str first_cert;  ///< the first certificate name when multiple cert files
are in 'ssl_cert_name'
-  ats_scoped_str ca;          ///< CA public certificate
-  ats_scoped_str key;         ///< Private key
-  ats_scoped_str dialog;      ///< Private key dialog
-  ats_scoped_str servername;  ///< Destination server
+  int session_ticket_enabled;   ///< session ticket enabled
+  ats_scoped_str addr;          ///< IPv[64] address to match
+  ats_scoped_str cert;          ///< certificate
+  ats_scoped_str first_cert;    ///< the first certificate name when multiple cert files
are in 'ssl_cert_name'
+  ats_scoped_str ca;            ///< CA public certificate
+  ats_scoped_str key;           ///< Private key
+  ats_scoped_str ocsp_response; ///< prefetched OCSP response
+  ats_scoped_str dialog;        ///< Private key dialog
+  ats_scoped_str servername;    ///< Destination server
   SSLCertContext::Option opt = SSLCertContext::OPT_NONE; ///< SSLCertContext special handling
option
 };
 
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index aa82eb0..eada98d 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -183,6 +183,7 @@ SSLConfigParams::initialize()
   char *clientCACertRelativePath        = nullptr;
   char *ssl_server_ca_cert_filename     = nullptr;
   char *ssl_client_ca_cert_filename     = nullptr;
+  char *ssl_ocsp_response_path          = nullptr;
 
   cleanup();
 
@@ -327,6 +328,9 @@ SSLConfigParams::initialize()
   REC_EstablishStaticConfigInt32(ssl_ocsp_cache_timeout, "proxy.config.ssl.ocsp.cache_timeout");
   REC_EstablishStaticConfigInt32(ssl_ocsp_request_timeout, "proxy.config.ssl.ocsp.request_timeout");
   REC_EstablishStaticConfigInt32(ssl_ocsp_update_period, "proxy.config.ssl.ocsp.update_period");
+  REC_ReadConfigStringAlloc(ssl_ocsp_response_path, "proxy.config.ssl.ocsp.response.path");
+  set_paths_helper(ssl_ocsp_response_path, nullptr, &ssl_ocsp_response_path_only, nullptr);
+  ats_free(ssl_ocsp_response_path);
 
   REC_ReadConfigInt32(async_handshake_enabled, "proxy.config.ssl.async.handshake.enabled");
   REC_ReadConfigStringAlloc(engine_conf_file, "proxy.config.ssl.engine.conf_file");
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 1e390fd..efc3f3e 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -69,6 +69,7 @@ using namespace std::literals;
 static constexpr std::string_view SSL_IP_TAG("dest_ip"sv);
 static constexpr std::string_view SSL_CERT_TAG("ssl_cert_name"sv);
 static constexpr std::string_view SSL_PRIVATE_KEY_TAG("ssl_key_name"sv);
+static constexpr std::string_view SSL_OCSP_RESPONSE_TAG("ssl_ocsp_name"sv);
 static constexpr std::string_view SSL_CA_TAG("ssl_ca_name"sv);
 static constexpr std::string_view SSL_ACTION_TAG("action"sv);
 static constexpr std::string_view SSL_ACTION_TUNNEL_TAG("tunnel"sv);
@@ -1360,26 +1361,6 @@ SSLMultiCertConfigLoader::init_server_ssl_ctx(std::vector<X509 *>
&cert_list, co
   SSL_CTX_set_next_protos_advertised_cb(ctx, SSLNetVConnection::advertise_next_protocol,
nullptr);
   SSL_CTX_set_alpn_select_cb(ctx, SSLNetVConnection::select_next_protocol, nullptr);
 
-#if TS_USE_TLS_OCSP
-  if (SSLConfigParams::ssl_ocsp_enabled) {
-    Debug("ssl", "SSL OCSP Stapling is enabled");
-    SSL_CTX_set_tlsext_status_cb(ctx, ssl_callback_ocsp_stapling);
-    const char *cert_name = sslMultCertSettings ? sslMultCertSettings->cert.get() : nullptr;
-
-    for (auto cert : cert_list) {
-      if (!ssl_stapling_init_cert(ctx, cert, cert_name)) {
-        Warning("failed to configure SSL_CTX for OCSP Stapling info for certificate at %s",
cert_name);
-      }
-    }
-  } else {
-    Debug("ssl", "SSL OCSP Stapling is disabled");
-  }
-#else
-  if (SSLConfigParams::ssl_ocsp_enabled) {
-    Warning("failed to enable SSL OCSP Stapling; this version of OpenSSL does not support
it");
-  }
-#endif /* TS_USE_TLS_OCSP */
-
   if (SSLConfigParams::init_ssl_ctx_cb) {
     SSLConfigParams::init_ssl_ctx_cb(ctx, true);
   }
@@ -1528,6 +1509,10 @@ ssl_extract_certificate(const matcher_line *line_info, SSLMultiCertConfigParams
       sslMultCertSettings.key = ats_strdup(value);
     }
 
+    if (strcasecmp(label, SSL_OCSP_RESPONSE_TAG) == 0) {
+      sslMultCertSettings.ocsp_response = ats_strdup(value);
+    }
+
     if (strcasecmp(label, SSL_SESSION_TICKET_ENABLED) == 0) {
       sslMultCertSettings.session_ticket_enabled = atoi(value);
     }
@@ -1785,6 +1770,27 @@ SSLMultiCertConfigLoader::load_certs(SSL_CTX *ctx, std::vector<X509
*> &cert_lis
     }
   }
 
+#if TS_USE_TLS_OCSP
+  if (SSLConfigParams::ssl_ocsp_enabled) {
+    Debug("ssl", "SSL OCSP Stapling is enabled");
+    SSL_CTX_set_tlsext_status_cb(ctx, ssl_callback_ocsp_stapling);
+  } else {
+    Debug("ssl", "SSL OCSP Stapling is disabled");
+  }
+  SimpleTokenizer ocsp_tok("", SSL_CERT_SEPARATE_DELIM);
+  if (sslMultCertSettings->ocsp_response) {
+    ocsp_tok.setString(sslMultCertSettings->ocsp_response);
+    if (cert_tok.getNumTokensRemaining() != ocsp_tok.getNumTokensRemaining()) {
+      Error("the number of certificates in ssl_cert_name and ssl_ocsp_name doesn't match");
+      return false;
+    }
+  }
+#else
+  if (SSLConfigParams::ssl_ocsp_enabled) {
+    Warning("failed to enable SSL OCSP Stapling; this version of OpenSSL does not support
it");
+  }
+#endif /* TS_USE_TLS_OCSP */
+
   for (const char *certname = cert_tok.getNext(); certname; certname = cert_tok.getNext())
{
     std::string completeServerCertPath = Layout::relative_to(params->serverCertPathOnly,
certname);
     scoped_BIO bio(BIO_new_file(completeServerCertPath.c_str(), "r"));
@@ -1845,6 +1851,21 @@ SSLMultiCertConfigLoader::load_certs(SSL_CTX *ctx, std::vector<X509
*> &cert_lis
         }
       }
     }
+#if TS_USE_TLS_OCSP
+    if (SSLConfigParams::ssl_ocsp_enabled) {
+      if (sslMultCertSettings->ocsp_response) {
+        const char *ocsp_response_name = ocsp_tok.getNext();
+        ats_scoped_str completeOCSPResponsePath(Layout::relative_to(params->ssl_ocsp_response_path_only,
ocsp_response_name));
+        if (!ssl_stapling_init_cert(ctx, cert, certname, (const char *)completeOCSPResponsePath))
{
+          Warning("failed to configure SSL_CTX for OCSP Stapling info for certificate at
%s", certname);
+        }
+      } else {
+        if (!ssl_stapling_init_cert(ctx, cert, certname, nullptr)) {
+          Warning("failed to configure SSL_CTX for OCSP Stapling info for certificate at
%s", certname);
+        }
+      }
+    }
+#endif /* TS_USE_TLS_OCSP */
   }
 
   return true;
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index b382acc..9b21975 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1186,7 +1186,9 @@ static const RecordElement RecordsConfig[] =
   //        # Update period for stapling caches. 60s (1 min) by default.
   {RECT_CONFIG, "proxy.config.ssl.ocsp.update_period", RECD_INT, "60", RECU_DYNAMIC, RR_NULL,
RECC_NULL, "^[0-9]+$", RECA_NULL}
   ,
-
+  //        # Base path for OCSP prefetched responses
+  {RECT_CONFIG, "proxy.config.ssl.ocsp.response.path", RECD_STRING, TS_BUILD_SYSCONFDIR,
RECU_RESTART_TS, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
+  ,
   //##############################################################################
   //#
   //# Configuration for TLSv1.3 and above
diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc
index 2111fa0..f2a2bd5 100644
--- a/src/traffic_server/InkAPI.cc
+++ b/src/traffic_server/InkAPI.cc
@@ -8998,7 +8998,7 @@ TSSslContextFindByAddr(struct sockaddr const *addr)
 }
 
 tsapi TSSslContext
-TSSslServerContextCreate(TSSslX509 cert, const char *certname)
+TSSslServerContextCreate(TSSslX509 cert, const char *certname, const char *rsp_file)
 {
   TSSslContext ret        = nullptr;
   SSLConfigParams *config = SSLConfig::acquire();
@@ -9007,7 +9007,7 @@ TSSslServerContextCreate(TSSslX509 cert, const char *certname)
 #if TS_USE_TLS_OCSP
     if (ret && SSLConfigParams::ssl_ocsp_enabled && cert && certname)
{
       if (SSL_CTX_set_tlsext_status_cb(reinterpret_cast<SSL_CTX *>(ret), ssl_callback_ocsp_stapling))
{
-        if (!ssl_stapling_init_cert(reinterpret_cast<SSL_CTX *>(ret), reinterpret_cast<X509
*>(cert), certname)) {
+        if (!ssl_stapling_init_cert(reinterpret_cast<SSL_CTX *>(ret), reinterpret_cast<X509
*>(cert), certname, rsp_file)) {
           Warning("failed to configure SSL_CTX for OCSP Stapling info for certificate at
%s", (const char *)certname);
         }
       }
diff --git a/src/traffic_server/InkAPITest.cc b/src/traffic_server/InkAPITest.cc
index 50e0c99..00daa08 100644
--- a/src/traffic_server/InkAPITest.cc
+++ b/src/traffic_server/InkAPITest.cc
@@ -9175,7 +9175,7 @@ REGRESSION_TEST(SDK_API_TSSslServerContextCreate)(RegressionTest *test,
int leve
   TSSslContext ctx;
 
   // See TS-4769: TSSslServerContextCreate always returns null.
-  ctx = TSSslServerContextCreate(nullptr, nullptr);
+  ctx = TSSslServerContextCreate(nullptr, nullptr, nullptr);
 
   *pstatus = ctx ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED;
   TSSslContextDestroy(ctx);
diff --git a/tests/gold_tests/autest-site/conditions.test.ext b/tests/gold_tests/autest-site/conditions.test.ext
index 9cac02f..e60c06c 100644
--- a/tests/gold_tests/autest-site/conditions.test.ext
+++ b/tests/gold_tests/autest-site/conditions.test.ext
@@ -19,6 +19,9 @@
 def HasOpenSSLVersion(self, version):
     return self.EnsureVersion(["openssl","version"],min_version=version)
 
+def HasCurlVersion(self, version):
+    return self.EnsureVersion(["curl","--version"],min_version=version)
+
 def HasCurlFeature(self, feature):
 
     def default(output):
@@ -60,6 +63,7 @@ def PluginExists(self, pluginname):
 
 ExtendCondition(HasOpenSSLVersion)
 ExtendCondition(HasATSFeature)
+ExtendCondition(HasCurlVersion)
 ExtendCondition(HasCurlFeature)
 ExtendCondition(PluginExists)
 
diff --git a/tests/gold_tests/tls/ssl/ca.ocsp.key b/tests/gold_tests/tls/ssl/ca.ocsp.key
new file mode 100644
index 0000000..ccae9f1
--- /dev/null
+++ b/tests/gold_tests/tls/ssl/ca.ocsp.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAsg7JDZ8J/yG/bBxl/Td9urR78e0E/IwSfuujWbewn2fulEkF
+jrvN8G4I8nmEG/Fg+2lMR2wKqUYYwbxKaq0tlprbZp/bB9QJqGdEqmX9HBKIPB6L
+n0GFMwj5yG4etx2sx3scdHPaJBZ12IPljxJXPKsHurIY/tXa9WS6IhEwHgcNef+p
+uVt8pNvmw35jyPMZhcXnN/Fs+bHX908SCrMgiwf4oKyPHFxh7WEqLVZj4Z2At7lH
+On0wRHnYjFB7wKSMgM44eUjhjN6zOe4gWLGdfbtXgZibxgKLYfYL8YBzcPPChdCY
+Evshn3RTbJ3IiwDHTAlBTchoDoBjV/gKlM8LbQIDAQABAoIBAQCMMeoJqIxFbrv6
+ko2XB2ceZ1cjz/xaIKu7dStDy8bsa/fEl44hqStoQCsZR6ZGHhK/QVRG9AGc8E0z
+1V4+iiZX64wOTJU3n7MO/mhpRi45OTo9I8vJU9xdp5aMQnA6u8m7supfooxCV9Dn
+7koEEWvQn9VRIUNe+uEQ0ANiKWhaauC4aODV3amNgmGTQVF1NKvcqdXbeQGCGHDy
+HKoehDVlbaoKvzZ03dt0kL1sa+vqQmC6pNHlWQ9pchML6E+KBdaQrNCeRFHbLLiO
+ULQg2KS0IF+kqbBrpBRd3lW4ZV2rglWZQ1998CJP0et3WXET14nqCTNfty3iTcUL
+tXPGnXAdAoGBAM3BcnSWeEkTtY8Sxu3y/M/zB9wF7f+mHNE88ISWrdx/hJni4imV
+diyzcnfyxTQc8uuett1UHA85SZuuDwdvVz7CD+UglmploFsaUvwl6Ytl05a2oFqT
+n5dmnsGgLCpnpSNAZWpT6gyddQR3lyzCw+k5fkQVikPzcGJrd7mk27YfAoGBAN2J
+1uYw3E7uiywjYlQXqrQ7L0Ouccw3wV0jcsSgDJGsffhTkPhn/BwZ2QQcldGR8TCB
+Y6Er02Kqzk1mGFG94TPQy5C+xJzZv2KKq9LSrOVQszh+wozEruh7bKARQ/uPDLPw
++F/DWFe6/0mDb5gZf40pyk+njFh1UT7yGE2poVTzAoGBAMaDQ2hU3Iy05VC6rw9Y
+hq4jLowLdIpYvCjsAKoLroa0yTynd8jjGPcb0u8DXVxgKcdGg+uagM/3V5tKHdnw
+hF5aYXeRL05L6qC7DyGTenYxsikQ3jlFgI5URgtN/A6VnPAb6zzg5UlyiTncIBDh
+gJ7+B2Ks3Y+dyepLAWItOoXFAoGBAMgahR2O7K/vD45it6I1bl81Rk/f9bH8eo/i
+QPwRhMjgATiYYs29Px8yya7JExoktLKXbKJbr6fjmEyY90Z+ODhRVE39wiHbHN+p
+WeInoTvQVNGmzZvQ3BvpwAglED7cyyCNfAsjq1wy7/w62EWOYoPjR3YDZOVRsn0k
+t4cOvUa5AoGAL2LxuYaU5GESEv3MAtM4oQUsc0sHApGyy/hJzGBF/RXpy+U4kYBF
+apAonFCQZ2VBr/t0XH0MW4GrRZoJsa1xWWhlXhARfOSWCRRS8tdTdir2TpLMmJJN
+QakM9/QgfIQQ+J25XeLe16dRl2i4acG1BA2b1S1isC8HmV/wy4sGopA=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/gold_tests/tls/ssl/ca.ocsp.pem b/tests/gold_tests/tls/ssl/ca.ocsp.pem
new file mode 100644
index 0000000..cd8114f
--- /dev/null
+++ b/tests/gold_tests/tls/ssl/ca.ocsp.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDWDCCAkCgAwIBAgIUUCa7m/ftLhb69KUqFfGBKwnw+lcwDQYJKoZIhvcNAQEL
+BQAwRDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMQ8wDQYDVQQKEwZBcGFjaGUx
+FzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMB4XDTE5MDUwMjEyNDAwMFoXDTQ5MDQy
+NDEyNDAwMFowRDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMQ8wDQYDVQQKEwZB
+cGFjaGUxFzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAsg7JDZ8J/yG/bBxl/Td9urR78e0E/IwSfuujWbewn2fu
+lEkFjrvN8G4I8nmEG/Fg+2lMR2wKqUYYwbxKaq0tlprbZp/bB9QJqGdEqmX9HBKI
+PB6Ln0GFMwj5yG4etx2sx3scdHPaJBZ12IPljxJXPKsHurIY/tXa9WS6IhEwHgcN
+ef+puVt8pNvmw35jyPMZhcXnN/Fs+bHX908SCrMgiwf4oKyPHFxh7WEqLVZj4Z2A
+t7lHOn0wRHnYjFB7wKSMgM44eUjhjN6zOe4gWLGdfbtXgZibxgKLYfYL8YBzcPPC
+hdCYEvshn3RTbJ3IiwDHTAlBTchoDoBjV/gKlM8LbQIDAQABo0IwQDAOBgNVHQ8B
+Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUmAVXj2UeCyJRWe73
+dBL672OFRKIwDQYJKoZIhvcNAQELBQADggEBAEf1Jntnfg+4W4/u7FGGFgkjiQ9e
+zS38xRsSyKhQ5pBipUHbkphbgwu0xXDa9jQkVJuwsk7xrMdvbKmbVx8DBg4OZKu+
+50eqw8/NTg401TVLKC+rJ5kcgUEGuZobegBhKtUqzuswQQF4F4KMTUreJBXWPeET
+CxFyy04LAxeewEYLzJ/Ylw4jgosC+MlTlXmN41SxtQ5URjOOIPmHOZF9CzSHoJcz
+qN84JT1cgcfd/gYgQD+r1pCPRjJrLU+5X3PCHHehNphIuU9cQ6KuJaCq1FABpovx
+iIMiW56fzZ4Wbon3Sh0zuCxzvtBhtM5qOd+eP3pbIB6Ps+J9Dfkrpa/wVe0=
+-----END CERTIFICATE-----
diff --git a/tests/gold_tests/tls/ssl/ocsp_response.der b/tests/gold_tests/tls/ssl/ocsp_response.der
new file mode 100644
index 0000000..fd6d9a6
Binary files /dev/null and b/tests/gold_tests/tls/ssl/ocsp_response.der differ
diff --git a/tests/gold_tests/tls/ssl/responder.ocsp.key b/tests/gold_tests/tls/ssl/responder.ocsp.key
new file mode 100644
index 0000000..c71e4e5
--- /dev/null
+++ b/tests/gold_tests/tls/ssl/responder.ocsp.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAtjD9/eCvlUxtKoXVh43ab60uriYqkbzOTm2r0URwfXndQAWh
+d35vA2goUosnNNKcssvh8SZFpNNtYvD/5r+4LZL09nlCOdJ/+JEqKDxR0WfXNCxd
+UB2RwFnf1rMSAfyj5sT7bBYlPy2EX8LvbruGlzI00MBS1zLsYKNFWq2V1gu8rl0z
+pFkJhhOJqXUUbINlfCH+NvLaO9NByjV1esYfHe4lYtnHxno9Q0vuxT1dobuE4pUV
+6v+SnSg8VP0ZdFQSuuss0E412NNna3naBoZn14cBWkFjAtNxqNC+a9dHYxOZrsEo
+joB8R1E96YZwY0oJ47/LmG/Sp5IQKWZWFZ4pnQIDAQABAoIBAD32gZujm/PJ72LD
+67BThVPv8W1XG6k/LmcsE4Bzp1J1bNMGVzj9riHZfcU9AFONwa9peel7G7qIEa7R
+yiafU7NkRJ3C9cwWlGFkdZMDmMwAZgefgwjpVZW2u1MYyeoVE2U730qOaZKIF3o+
+IRJnAspPT/kjP8liz1O6k67YVJpcBcp9nJruDJh8BZtgneb2z+di8aV6gi2d2Cfq
+rPrAxlwDc1XiMgG+Auuq0OQs++K1GFAcy6pMutjIpXMDl3eAUddPjEPBuKlUiRO1
+GqR9d3YRWR+/KZV++RzdwPbZVjiK2STSrimsDfyufibD6xoQ3TuKtdL8UsSVdOkr
+OORojd0CgYEAwfJ1EnJXhXmJhZj6qXE2Es61c2/JLXFbk0ryE7nIdmalU1rT7h0J
+jPp+uzl1mtSRrx/aTesLOqHFefJqMOiTVjFO/7+J+fe7gsnHAvB9cHXLkSY6FN37
+p7PQ6yFlb+k8Biug+6tyuGv78MxADZMZ9pWc/AD4VQZlDkAygIFbVVcCgYEA8Hup
+70Xv7O2lxnaPAhbqm1Ijm+ABDgObh8s1CaTO7F4upwmOSZ+EOrMdP6+vdPq0Hrm/
+KObaqRM5Vwi74hEoxKCoLulBslEnq2KbU0t22TnqCF+UBYledfFKgYTJmfvqGCxg
+uVPQ1qZp//9yQxcrIhr4AwQDr3dX1Mb8VfH3TCsCgYEAkDHIMsfKJFVhFm/PZSzj
+jAYdR88DnoKaGB9vbZUB4m2cWyW7TVxPXn5avK4SruN90Nr4vleTCKt/m5PMucIg
+0MNmPaTVW4CA69NC3/+W84bQq4DlS+BimqOJH1e8CAE6/Edxr8sfRtgZ/0SMFsuY
+UQmZJo8+ElDnzzmRkpMaKY8CgYA/KHtM+BU3KILtSJ3uco5TFJN9kKs2PwRN+bSI
+P9yIf4PJIt1XwKk9sWTxIPb3xhAgMbBe0aKD3SSmEwklKlSGr5r8Fw7GAkJk5JTe
+n2crTeaFJHT/r0A7wY9LzNAVvO+SQbV1dunWNgaI0VH1BNSzNFoGkLtXDgTnQQts
+lwvX2QKBgQCjMNbYh+7TSe/L/ys/TG+tuFkNaprvrHeRYigI4U43rWKiY2EteYi/
+V/eVY/t7hWDnwV9FDo5q/v4dneWWgl2kJA8NlP/p65M+YrTY1nVRrbJX4+GIlxxY
+yaGI4Ab1WBFsYkpHC4BpBommJV/znaOcNS/EBY3G3ZmW+EzGmiTuvw==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/gold_tests/tls/ssl/responder.ocsp.pem b/tests/gold_tests/tls/ssl/responder.ocsp.pem
new file mode 100644
index 0000000..03753b8
--- /dev/null
+++ b/tests/gold_tests/tls/ssl/responder.ocsp.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDlzCCAn+gAwIBAgIURxCF64GDk44IQeo7HFw5EB5jKNUwDQYJKoZIhvcNAQEL
+BQAwRDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMQ8wDQYDVQQKEwZBcGFjaGUx
+FzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMB4XDTE5MDUwMjEyNDAwMFoXDTQ5MDQy
+NDEyNDAwMFowUDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMQ8wDQYDVQQKEwZB
+cGFjaGUxIzAhBgNVBAMTGm9jc3AtcmVzcG9uZGVyLmV4YW1wbGUuY29tMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtjD9/eCvlUxtKoXVh43ab60uriYq
+kbzOTm2r0URwfXndQAWhd35vA2goUosnNNKcssvh8SZFpNNtYvD/5r+4LZL09nlC
+OdJ/+JEqKDxR0WfXNCxdUB2RwFnf1rMSAfyj5sT7bBYlPy2EX8LvbruGlzI00MBS
+1zLsYKNFWq2V1gu8rl0zpFkJhhOJqXUUbINlfCH+NvLaO9NByjV1esYfHe4lYtnH
+xno9Q0vuxT1dobuE4pUV6v+SnSg8VP0ZdFQSuuss0E412NNna3naBoZn14cBWkFj
+AtNxqNC+a9dHYxOZrsEojoB8R1E96YZwY0oJ47/LmG/Sp5IQKWZWFZ4pnQIDAQAB
+o3UwczAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwDAYDVR0T
+AQH/BAIwADAdBgNVHQ4EFgQUGOVVyRVQ7T9HG+yyb+evtoXW1/wwHwYDVR0jBBgw
+FoAUmAVXj2UeCyJRWe73dBL672OFRKIwDQYJKoZIhvcNAQELBQADggEBAKSA6zdF
+BFEy/gLQcGBsJ6IxnIpL3kijk/cdfMMraj+WgFpdr4utZXMI5kJ8s9C09nVqfYIk
+os2XEUkpWOTbbXJDcgYjOtUy/3VPJ6BTELQYLR/IDISDiIwdehTtBOosHwuSoW1t
+LnPQFtmZda6PvYfETKGBsAIKSM16GZQHJFrEKldWYALynjDAKwBN+SQDC6SHs48U
+Md4V7XPm1GXysewBg+GIXZxPECBE7BstcQbOViiMY0ZvSbR8mMoxiSYLNA+2QrTu
+QBFQPf2Bpyc10vSyM+8P+pZb++p9raK0BWqS8rNi0BP7OnakzpvZygwtwY8sRYM8
+AToAbPRxJMJaIAU=
+-----END CERTIFICATE-----
diff --git a/tests/gold_tests/tls/ssl/server.ocsp.key b/tests/gold_tests/tls/ssl/server.ocsp.key
new file mode 100644
index 0000000..0379039
--- /dev/null
+++ b/tests/gold_tests/tls/ssl/server.ocsp.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA53sB/uEdZNJIFLiMJr+5KaB75lTCEBIg98FCCfxBPsL1XqNO
+s3Tx1ihmCMeT6wnvxIi+RIIbf0ymSquImmkzAodZdW0MGs/G9Vo2HsjclfkOsZhN
+M5k8/AXF/FaGOjGd/WOKZFGejhd6utzqOo+Bj+STm2u+bCNtI4IZF+icTri7rIIK
+CMdZalN5Au33DqT+MuKhtTmRYs1Pw8Qf2inv311y7f5Ok/TvBnfbAU18Jo+Ga/M0
+94bVAMA8WH6RyABZZlr8VIn6e5YadFfHVt7GrMIO/2QV4mlCK7zEC2NamNNslf4c
+n2NpQNQToV1UbOK3uH5SNtB6CqJDBR9sIPnTKwIDAQABAoIBADgrmjVeLQLNIB6f
+FatFdMoMHmSrBphdvdBA/iRsKOzw5Be96xgS9agxD2lr/JHZTGxVfk4jgEaos+WE
+sFY/1tfzPhsHhhtvdekNpfpcZWKjGBSyT3GI6sqBICT2XgX7Ckp1gByNzbrPKcH0
+X4YsUpU3MzZQs9mL0yz9odcyY9OZ/BMX2lHb/G/IzZqb2a5YCbew1eZyU3pMRs2X
+POtKJgCfiKOGcI+Kv3gL8CWtMWkxZN6CeNF1GicndNLWBdW6KSPOjAWf7eBAu8cs
+nC7gtpCcpqL2GVOx7rzuPPjTRY62Xqf1/2AjeJkAqkeBbqs9shlK4Nm76WvDsDp9
+V7ZxjpECgYEA8YX3lCy0Ba+VE9xmHrzIqBzl39s73du17hiWlNcI05fer3lKt9g6
+IINnH60nzYXYW3hKHoKBUJiop2/TI6/aaLTrlpJ/0lcFNLI2ZXOQ7fQ4s/iFyWrP
+DkCE5Z1qlUNsPjCN1ZG4xMciGy83JtzjsQfoj3sHBUnrk8uqftp7hAMCgYEA9Vrw
+j45Z9WKbBb/ilRv0UhkZ8uFYDut2udZZ2fp//Cb0C9ykdKeu6Q9p6MdFjdCPiNWi
+DDx885arMmtJuRS4MGAt9qps4BIsOQAdsLW/5BB9hRR5nqYSaaOA/FZ/X2uFtmIk
+5zjkHXktBBTqoVNVqGwnjeQyGqCpWxRXtNtTz7kCgYEA3IzfZnnj8oVB9x7+SfdO
+rOWmrOMAKjpmSgQ+DbDHqKE4griaGIPloKcd1nlCrZUZ231fAble6QBekne1MRN2
+uMLtl1Q0URmR8WsD7WS45fJsjTvWv/U/Gt6j/SHgoGkvQSMJggtN1LObW4OkM2Lm
+sVRtdAh+gr/b1dzX1nsg640CgYAWQbaavyYH7Xb0kZCDSDLkk6RX9Psg91kgyIIE
+FQYxIHN48/3zGxbxy1UnKZR0pduvZPm7NG19R0imXTcl0+xVbxQcUR9pQBzE2u7W
+jdYnYRuRy+awbo4zCQL1YP9S75UEk2iXlQCUb96WhTM3iTC3A4CfDXlCExrpyTGf
+lVnH+QKBgQCGanhp+cL4gmbgFvu2KuLXGneK+gIRL3X9neLTq/0XoVE2pNiTZBne
+bHVerfcogPXMSdFfCnjpWqx82UoXrQWghaOB9iLTPu+HH2SWWrvSle6JBYoF8iv8
+Y8/YKzlnZV62KpCPeKaal6RsPbNiPD5o6jONPKZmnxQeCa694ImLwg==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/gold_tests/tls/ssl/server.ocsp.pem b/tests/gold_tests/tls/ssl/server.ocsp.pem
new file mode 100644
index 0000000..a8b14c0
--- /dev/null
+++ b/tests/gold_tests/tls/ssl/server.ocsp.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID6TCCAtGgAwIBAgIUZyBINUwv8M98Rr31B9y2zXyuFDAwDQYJKoZIhvcNAQEL
+BQAwRDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMQ8wDQYDVQQKEwZBcGFjaGUx
+FzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMB4XDTE5MDUwMjEyNDAwMFoXDTQ5MDQy
+NDEyNDAwMFowSDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMQ8wDQYDVQQKEwZB
+cGFjaGUxGzAZBgNVBAMTEnNlcnZlci5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAOd7Af7hHWTSSBS4jCa/uSmge+ZUwhASIPfBQgn8
+QT7C9V6jTrN08dYoZgjHk+sJ78SIvkSCG39MpkqriJppMwKHWXVtDBrPxvVaNh7I
+3JX5DrGYTTOZPPwFxfxWhjoxnf1jimRRno4Xerrc6jqPgY/kk5trvmwjbSOCGRfo
+nE64u6yCCgjHWWpTeQLt9w6k/jLiobU5kWLNT8PEH9op799dcu3+TpP07wZ32wFN
+fCaPhmvzNPeG1QDAPFh+kcgAWWZa/FSJ+nuWGnRXx1bexqzCDv9kFeJpQiu8xAtj
+WpjTbJX+HJ9jaUDUE6FdVGzit7h+UjbQegqiQwUfbCD50ysCAwEAAaOBzjCByzAO
+BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIw
+ADAdBgNVHQ4EFgQUeLq8rzbtQim/wBI+OmgVScP+cWgwHwYDVR0jBBgwFoAUmAVX
+j2UeCyJRWe73dBL672OFRKIwMQYIKwYBBQUHAQEEJTAjMCEGCCsGAQUFBzABhhVo
+dHRwOi8vbG9jYWxob3N0Ojg4ODgwIwYDVR0RBBwwGoISc2VydmVyLmV4YW1wbGUu
+Y29thwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCwLPIR8qzABd2OUvBOBXSWnXm2
+YiGY11805CISiDB+SGkRO+cd82wcjzI7bhPG9jtZ4ydrmOZ5FNmjtc0dgtmfnd3s
+zGRQQ/cej5iWZbmWJOUKeCFZ1KC6c4DbwJe4iYekP0YIxcRK3hnRO1GBQ+zNwWs4
+74toxUp4dLUOuUaDZLsk0tsTqZO8alszpmIYNn1VzEguqE6FwBcFxNx110/dtH6P
+chSOOG4m8ZJkZuV2PmdtOhqi4RdnUGIGS6kWjDYM6Qe+zworGzmNHv1iZMcaVvzm
+YOQ54MTQ/V8o411Ckszzu1N0edC/WPBcE1ARrRMTN1hXzlGIwsLvGz51/lwd
+-----END CERTIFICATE-----
diff --git a/tests/gold_tests/tls/tls_ocsp.test.py b/tests/gold_tests/tls/tls_ocsp.test.py
new file mode 100644
index 0000000..69f319e
--- /dev/null
+++ b/tests/gold_tests/tls/tls_ocsp.test.py
@@ -0,0 +1,73 @@
+'''
+'''
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+import os
+Test.Summary = '''
+Test tls server prefetched OCSP responses
+'''
+
+# curl --cert-status option has been introduced in version 7.41.0
+Test.SkipUnless(
+    Condition.HasCurlVersion("7.41.0")
+)
+
+# Define default ATS
+ts = Test.MakeATSProcess("ts", select_ports=False)
+server = Test.MakeOriginServer("server")
+request_header = {"headers": "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n", "timestamp":
"1469733493.993", "body": ""}
+# desired response form the origin server
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp":
"1469733493.993", "body": ""}
+server.addResponse("sessionlog.json", request_header, response_header)
+
+ts.addSSLfile("ssl/ca.ocsp.pem")
+ts.addSSLfile("ssl/server.ocsp.pem")
+ts.addSSLfile("ssl/server.ocsp.key")
+ts.addSSLfile("ssl/ocsp_response.der")
+
+ts.Variables.ssl_port = 4443
+ts.Disk.remap_config.AddLine(
+    'map https://example.com:4443 http://127.0.0.1:{0}'.format(server.Variables.Port)
+)
+
+ts.Disk.ssl_multicert_config.AddLine(
+    'dest_ip=* ssl_cert_name=server.ocsp.pem ssl_key_name=server.ocsp.key ssl_ocsp_name=ocsp_response.der'
+)
+
+# Case 1, global config policy=permissive properties=signature
+#         override for foo.com policy=enforced properties=all
+ts.Disk.records_config.update({
+    'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.ssl.server.cert_chain.filename': 'ca.ocsp.pem',
+    # enable prefetched OCSP responses
+    'proxy.config.ssl.ocsp.response.path': '{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.ssl.ocsp.enabled': 1,
+    # enable ssl port
+    'proxy.config.http.server_ports': '{0} {1}:proto=http2;http:ssl'.format(ts.Variables.port,
ts.Variables.ssl_port),
+    'proxy.config.ssl.server.cipher_suite': 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2',
+    'proxy.config.exec_thread.autoconfig.scale': 1.0
+})
+
+
+tr = Test.AddTestRun("Check OCSP response using curl")
+tr.Processes.Default.StartBefore(server)
+tr.Processes.Default.StartBefore(Test.Processes.ts, ready=When.PortOpen(ts.Variables.ssl_port))
+tr.StillRunningAfter = server
+tr.StillRunningAfter = ts
+tr.Processes.Default.Command = "curl -v --cacert {0} --cert-status -H \"host:example.com\"
https://127.0.0.1:{1}".format(os.path.join(ts.Variables.SSLDir, "ca.ocsp.pem"), ts.Variables.ssl_port)
+tr.ReturnCode = 0


Mime
View raw message