|
|
1ef406 |
From 8d6121731175f3a9a1fa1fbe3752763b0b48a67d Mon Sep 17 00:00:00 2001
|
|
|
1ef406 |
From: Rob Crittenden <rcritten@redhat.com>
|
|
|
1ef406 |
Date: Mon, 31 Oct 2016 15:06:36 -0400
|
|
|
1ef406 |
Subject: [PATCH] Add OCSP cache and timeout tuning knobs
|
|
|
1ef406 |
|
|
|
1ef406 |
NSS provides functions to control the timeout for connecting to
|
|
|
1ef406 |
an OCSP server and for caching the results. This includes the
|
|
|
1ef406 |
number of responses to cache and the duration to cache them.
|
|
|
1ef406 |
|
|
|
1ef406 |
Based on a patch by Jack Magne
|
|
|
1ef406 |
---
|
|
|
1ef406 |
docs/mod_nss.html | 42 ++++++++++++++++++++++++++
|
|
|
1ef406 |
mod_nss.c | 12 ++++++++
|
|
|
1ef406 |
mod_nss.h | 8 +++++
|
|
|
1ef406 |
nss_engine_config.c | 86 +++++++++++++++++++++++++++++++++++++++++++----------
|
|
|
1ef406 |
nss_engine_init.c | 47 +++++++++++++++++++++++++++++
|
|
|
1ef406 |
5 files changed, 179 insertions(+), 16 deletions(-)
|
|
|
1ef406 |
|
|
|
1ef406 |
diff --git a/docs/mod_nss.html b/docs/mod_nss.html
|
|
|
1ef406 |
index 65d0bd8..655d2f2 100644
|
|
|
1ef406 |
--- a/docs/mod_nss.html
|
|
|
1ef406 |
+++ b/docs/mod_nss.html
|
|
|
1ef406 |
@@ -544,6 +544,48 @@ Example
|
|
|
1ef406 |
|
|
|
1ef406 |
NSSOCSP on
|
|
|
1ef406 |
|
|
|
1ef406 |
+<big><big>NSSOCSPTimeout</big></big>
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Configure the maximum time to wait for an OCSP response in seconds.
|
|
|
1ef406 |
+There are no constraints or special meanings for this value. The default
|
|
|
1ef406 |
+is 60 seconds.
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Example
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+NSSOCSPTimeout 30
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+<big><big>NSSOCSPCacheSize</big></big>
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Configures the maximum number of entries in the OCSP cache. A value of
|
|
|
1ef406 |
+-1 will disable the cache completely. A value of 0 configures an unlimited
|
|
|
1ef406 |
+number of cache entries. The default is 1000.
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Example
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+NSSOCSPCacheSize 300
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+<big><big>NSSOCSPMinCacheEntryDuration</big></big>
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Configure the minimum amount of time an OCSP response is cached in seconds.
|
|
|
1ef406 |
+The default is 3600 seconds (1 hour).
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Example
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+NSSOCSPMinCacheEntryDuration 30
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+<big><big>NSSOCSPMaxCacheEntryDuration</big></big>
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Configure the maximum amount of time an OCSP response is cached in seconds
|
|
|
1ef406 |
+before being updated. The default is 86400 seconds (24 hours).
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+Example
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+NSSOCSPMaxCacheEntryDuration 300
|
|
|
1ef406 |
+
|
|
|
1ef406 |
<big><big>NSSCipherSuite
|
|
|
1ef406 |
</big></big>
|
|
|
1ef406 |
There are two options for configuring the available ciphers. mod_nss
|
|
|
1ef406 |
diff --git a/mod_nss.c b/mod_nss.c
|
|
|
1ef406 |
index 38098c8..dca5a73 100644
|
|
|
1ef406 |
--- a/mod_nss.c
|
|
|
1ef406 |
+++ b/mod_nss.c
|
|
|
1ef406 |
@@ -66,6 +66,18 @@ static const command_rec nss_config_cmds[] = {
|
|
|
1ef406 |
SSL_CMD_SRV(OCSP, FLAG,
|
|
|
1ef406 |
"OCSP (Online Certificate Status Protocol)"
|
|
|
1ef406 |
"(`on', `off')")
|
|
|
1ef406 |
+ SSL_CMD_SRV(OCSPTimeout, TAKE1,
|
|
|
1ef406 |
+ "OCSP Timeout"
|
|
|
1ef406 |
+ "(`N' - Max number of seconds to wait for an OCSP response.)")
|
|
|
1ef406 |
+ SSL_CMD_SRV(OCSPCacheSize, TAKE1,
|
|
|
1ef406 |
+ "OCSP Cache size"
|
|
|
1ef406 |
+ "(`N' - number of entries -1 for no cache)")
|
|
|
1ef406 |
+ SSL_CMD_SRV(OCSPMinCacheEntryDuration, TAKE1,
|
|
|
1ef406 |
+ "OCSP Minimum time until next fetch attempt"
|
|
|
1ef406 |
+ "(`N' - Time in seconds)")
|
|
|
1ef406 |
+ SSL_CMD_SRV(OCSPMaxCacheEntryDuration, TAKE1,
|
|
|
1ef406 |
+ "OCSP Maximum time until next fetch attempt"
|
|
|
1ef406 |
+ "(`N' - Time in seconds)")
|
|
|
1ef406 |
SSL_CMD_SRV(OCSPDefaultResponder, FLAG,
|
|
|
1ef406 |
"Use a default OCSP Responder"
|
|
|
1ef406 |
"(`on', `off')")
|
|
|
1ef406 |
diff --git a/mod_nss.h b/mod_nss.h
|
|
|
1ef406 |
index 226f7a8..8643e88 100644
|
|
|
1ef406 |
--- a/mod_nss.h
|
|
|
1ef406 |
+++ b/mod_nss.h
|
|
|
1ef406 |
@@ -325,6 +325,10 @@ struct SSLSrvConfigRec {
|
|
|
1ef406 |
const char *ocsp_url;
|
|
|
1ef406 |
const char *ocsp_name;
|
|
|
1ef406 |
BOOL ocsp;
|
|
|
1ef406 |
+ int ocsp_timeout;
|
|
|
1ef406 |
+ int ocsp_cache_size;
|
|
|
1ef406 |
+ int ocsp_min_cache_entry_duration;
|
|
|
1ef406 |
+ int ocsp_max_cache_entry_duration;
|
|
|
1ef406 |
BOOL enabled;
|
|
|
1ef406 |
BOOL sni;
|
|
|
1ef406 |
BOOL strict_sni_vhost_check;
|
|
|
1ef406 |
@@ -398,6 +402,10 @@ const char *nss_cmd_NSSSNI(cmd_parms *, void *, int);
|
|
|
1ef406 |
const char *nss_cmd_NSSStrictSNIVHostCheck(cmd_parms *, void *, int);
|
|
|
1ef406 |
const char *nss_cmd_NSSEngine(cmd_parms *, void *, int);
|
|
|
1ef406 |
const char *nss_cmd_NSSOCSP(cmd_parms *, void *, int);
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPTimeout(cmd_parms *, void *, const char *arg);
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPCacheSize(cmd_parms *, void *, const char *arg);
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPMinCacheEntryDuration(cmd_parms *, void *, const char *arg);
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPMaxCacheEntryDuration(cmd_parms *, void *, const char *arg);
|
|
|
1ef406 |
const char *nss_cmd_NSSOCSPDefaultResponder(cmd_parms *, void *, int);
|
|
|
1ef406 |
const char *nss_cmd_NSSOCSPDefaultURL(cmd_parms *, void *dcfg, const char *arg);
|
|
|
1ef406 |
const char *nss_cmd_NSSOCSPDefaultName(cmd_parms *, void *, const char *arg);
|
|
|
1ef406 |
diff --git a/nss_engine_config.c b/nss_engine_config.c
|
|
|
1ef406 |
index e1fbe41..597d56d 100644
|
|
|
1ef406 |
--- a/nss_engine_config.c
|
|
|
1ef406 |
+++ b/nss_engine_config.c
|
|
|
1ef406 |
@@ -129,22 +129,26 @@ static SSLSrvConfigRec *nss_config_server_new(apr_pool_t *p)
|
|
|
1ef406 |
{
|
|
|
1ef406 |
SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
|
|
|
1ef406 |
|
|
|
1ef406 |
- sc->mc = NULL;
|
|
|
1ef406 |
- sc->ocsp = UNSET;
|
|
|
1ef406 |
- sc->ocsp_default = UNSET;
|
|
|
1ef406 |
- sc->ocsp_url = NULL;
|
|
|
1ef406 |
- sc->ocsp_name = NULL;
|
|
|
1ef406 |
- sc->fips = UNSET;
|
|
|
1ef406 |
- sc->enabled = UNSET;
|
|
|
1ef406 |
- sc->sni = TRUE;
|
|
|
1ef406 |
- sc->strict_sni_vhost_check = TRUE;
|
|
|
1ef406 |
- sc->proxy_enabled = UNSET;
|
|
|
1ef406 |
- sc->vhost_id = NULL; /* set during module init */
|
|
|
1ef406 |
- sc->vhost_id_len = 0; /* set during module init */
|
|
|
1ef406 |
- sc->proxy = NULL;
|
|
|
1ef406 |
- sc->server = NULL;
|
|
|
1ef406 |
- sc->proxy_ssl_check_peer_cn = TRUE;
|
|
|
1ef406 |
- sc->session_tickets = FALSE;
|
|
|
1ef406 |
+ sc->mc = NULL;
|
|
|
1ef406 |
+ sc->ocsp = UNSET;
|
|
|
1ef406 |
+ sc->ocsp_timeout = 60;
|
|
|
1ef406 |
+ sc->ocsp_cache_size = 1000;
|
|
|
1ef406 |
+ sc->ocsp_min_cache_entry_duration = 1*60*60L;
|
|
|
1ef406 |
+ sc->ocsp_max_cache_entry_duration = 24*60*60L;
|
|
|
1ef406 |
+ sc->ocsp_default = UNSET;
|
|
|
1ef406 |
+ sc->ocsp_url = NULL;
|
|
|
1ef406 |
+ sc->ocsp_name = NULL;
|
|
|
1ef406 |
+ sc->fips = UNSET;
|
|
|
1ef406 |
+ sc->enabled = UNSET;
|
|
|
1ef406 |
+ sc->sni = TRUE;
|
|
|
1ef406 |
+ sc->strict_sni_vhost_check = TRUE;
|
|
|
1ef406 |
+ sc->proxy_enabled = UNSET;
|
|
|
1ef406 |
+ sc->vhost_id = NULL; /* set during module init */
|
|
|
1ef406 |
+ sc->vhost_id_len = 0; /* set during module init */
|
|
|
1ef406 |
+ sc->proxy = NULL;
|
|
|
1ef406 |
+ sc->server = NULL;
|
|
|
1ef406 |
+ sc->proxy_ssl_check_peer_cn = TRUE;
|
|
|
1ef406 |
+ sc->session_tickets = FALSE;
|
|
|
1ef406 |
|
|
|
1ef406 |
modnss_ctx_init_proxy(sc, p);
|
|
|
1ef406 |
|
|
|
1ef406 |
@@ -213,6 +217,10 @@ void *nss_config_server_merge(apr_pool_t *p, void *basev, void *addv) {
|
|
|
1ef406 |
|
|
|
1ef406 |
cfgMerge(mc, NULL);
|
|
|
1ef406 |
cfgMergeBool(ocsp);
|
|
|
1ef406 |
+ cfgMergeInt(ocsp_timeout);
|
|
|
1ef406 |
+ cfgMergeInt(ocsp_cache_size);
|
|
|
1ef406 |
+ cfgMergeInt(ocsp_min_cache_entry_duration);
|
|
|
1ef406 |
+ cfgMergeInt(ocsp_max_cache_entry_duration);
|
|
|
1ef406 |
cfgMergeBool(ocsp_default);
|
|
|
1ef406 |
cfgMerge(ocsp_url, NULL);
|
|
|
1ef406 |
cfgMerge(ocsp_name, NULL);
|
|
|
1ef406 |
@@ -376,6 +384,52 @@ const char *nss_cmd_NSSOCSP(cmd_parms *cmd, void *dcfg, int flag)
|
|
|
1ef406 |
return NULL;
|
|
|
1ef406 |
}
|
|
|
1ef406 |
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPTimeout(cmd_parms *cmd, void *dcfg, const char *arg)
|
|
|
1ef406 |
+{
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ sc->ocsp_timeout = atoi(arg);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ return NULL;
|
|
|
1ef406 |
+}
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPCacheSize(cmd_parms *cmd, void *dcfg, const char *arg)
|
|
|
1ef406 |
+{
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ sc->ocsp_cache_size = atoi(arg);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ if (sc->ocsp_cache_size < -1) {
|
|
|
1ef406 |
+ return "NSSOCSPCacheSize: must be >= -1";
|
|
|
1ef406 |
+ }
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ return NULL;
|
|
|
1ef406 |
+}
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPMinCacheEntryDuration(cmd_parms *cmd, void *dcfg,
|
|
|
1ef406 |
+ const char *arg)
|
|
|
1ef406 |
+{
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ sc->ocsp_min_cache_entry_duration = atoi(arg);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ return NULL;
|
|
|
1ef406 |
+}
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+const char *nss_cmd_NSSOCSPMaxCacheEntryDuration(cmd_parms *cmd, void *dcfg,
|
|
|
1ef406 |
+ const char *arg)
|
|
|
1ef406 |
+{
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ sc->ocsp_max_cache_entry_duration = atoi(arg);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ return NULL;
|
|
|
1ef406 |
+}
|
|
|
1ef406 |
+
|
|
|
1ef406 |
const char *nss_cmd_NSSOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, int flag)
|
|
|
1ef406 |
{
|
|
|
1ef406 |
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
|
1ef406 |
diff --git a/nss_engine_init.c b/nss_engine_init.c
|
|
|
1ef406 |
index 14f86d8..2571591 100644
|
|
|
1ef406 |
--- a/nss_engine_init.c
|
|
|
1ef406 |
+++ b/nss_engine_init.c
|
|
|
1ef406 |
@@ -174,6 +174,18 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p)
|
|
|
1ef406 |
}
|
|
|
1ef406 |
}
|
|
|
1ef406 |
|
|
|
1ef406 |
+ if (ocspenabled) {
|
|
|
1ef406 |
+ if (sc->ocsp_min_cache_entry_duration > sc->ocsp_max_cache_entry_duration) {
|
|
|
1ef406 |
+ ap_log_error(APLOG_MARK,APLOG_ERR, 0, base_server,
|
|
|
1ef406 |
+ "OCSP minimum cache duration must be less than the maximum.");
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ if (mc->nInitCount == 1)
|
|
|
1ef406 |
+ nss_die();
|
|
|
1ef406 |
+ else
|
|
|
1ef406 |
+ return;
|
|
|
1ef406 |
+ }
|
|
|
1ef406 |
+ }
|
|
|
1ef406 |
+
|
|
|
1ef406 |
if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0)
|
|
|
1ef406 |
dbdir = (char *)mc->pCertificateDatabase + 4;
|
|
|
1ef406 |
else
|
|
|
1ef406 |
@@ -343,10 +355,45 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p)
|
|
|
1ef406 |
}
|
|
|
1ef406 |
|
|
|
1ef406 |
if (ocspenabled) {
|
|
|
1ef406 |
+ SECStatus rv;
|
|
|
1ef406 |
+
|
|
|
1ef406 |
CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
|
|
|
1ef406 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
|
|
|
1ef406 |
"OCSP is enabled.");
|
|
|
1ef406 |
|
|
|
1ef406 |
+ /* Set desired OCSP Cache Settings, values already checked. */
|
|
|
1ef406 |
+ rv = CERT_OCSPCacheSettings((PRInt32)sc->ocsp_cache_size,
|
|
|
1ef406 |
+ (PRUint32)sc->ocsp_min_cache_entry_duration,
|
|
|
1ef406 |
+ (PRUint32)sc->ocsp_max_cache_entry_duration);
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ if (rv == SECFailure) {
|
|
|
1ef406 |
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server,
|
|
|
1ef406 |
+ "Unable to set the OCSP cache settings.");
|
|
|
1ef406 |
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, base_server);
|
|
|
1ef406 |
+ if (mc->nInitCount == 1)
|
|
|
1ef406 |
+ nss_die();
|
|
|
1ef406 |
+ else
|
|
|
1ef406 |
+ return;
|
|
|
1ef406 |
+ } else {
|
|
|
1ef406 |
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
|
|
|
1ef406 |
+ "OCSP cache size %d, duration %d - %d seconds.", sc->ocsp_cache_size, sc->ocsp_min_cache_entry_duration, sc->ocsp_max_cache_entry_duration);
|
|
|
1ef406 |
+ }
|
|
|
1ef406 |
+
|
|
|
1ef406 |
+ /* Set OCSP timeout. */
|
|
|
1ef406 |
+ rv = CERT_SetOCSPTimeout((PRUint32) sc->ocsp_timeout);
|
|
|
1ef406 |
+ if (rv == SECFailure) {
|
|
|
1ef406 |
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server,
|
|
|
1ef406 |
+ "Unable to set the OCSP timeout. (this shouldn't happen.");
|
|
|
1ef406 |
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, base_server);
|
|
|
1ef406 |
+ if (mc->nInitCount == 1)
|
|
|
1ef406 |
+ nss_die();
|
|
|
1ef406 |
+ else
|
|
|
1ef406 |
+ return;
|
|
|
1ef406 |
+ } else {
|
|
|
1ef406 |
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
|
|
|
1ef406 |
+ "OCSP timeout set to %d.", sc->ocsp_timeout);
|
|
|
1ef406 |
+ }
|
|
|
1ef406 |
+
|
|
|
1ef406 |
/* We ensure that ocspname and ocspurl are not NULL above. */
|
|
|
1ef406 |
if (ocspdefault) {
|
|
|
1ef406 |
SECStatus sv;
|
|
|
1ef406 |
--
|
|
|
1ef406 |
2.9.3
|
|
|
1ef406 |
|