Blame SOURCES/mod_nss-ocsp-tuning-knobs.patch

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