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 <[email protected]>
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