summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mod_nss.c9
-rw-r--r--mod_nss.h6
-rw-r--r--nss.conf.in12
-rw-r--r--nss_engine_config.c37
-rw-r--r--nss_engine_init.c55
5 files changed, 116 insertions, 3 deletions
diff --git a/mod_nss.c b/mod_nss.c
index e528109..31632a8 100644
--- a/mod_nss.c
+++ b/mod_nss.c
@@ -63,6 +63,15 @@ static const command_rec nss_config_cmds[] = {
SSL_CMD_SRV(OCSP, FLAG,
"OCSP (Online Certificate Status Protocol)"
"(`on', `off')")
+ SSL_CMD_SRV(OCSPDefaultResponder, FLAG,
+ "Use a default OCSP Responder"
+ "(`on', `off')")
+ SSL_CMD_SRV(OCSPDefaultURL, TAKE1,
+ "The URL of the OCSP default responder"
+ "(`http://example.com:80/ocsp")
+ SSL_CMD_SRV(OCSPDefaultName, TAKE1,
+ "The nickname of the certificate to trust to sign the OCSP responses."
+ "(`OCSP_Cert`")
SSL_CMD_SRV(RandomSeed, TAKE23,
"SSL Pseudo Random Number Generator (PRNG) seeding source "
"(`startup builtin|file:/path|exec:/path [bytes]')")
diff --git a/mod_nss.h b/mod_nss.h
index 1e4ccd3..51df89c 100644
--- a/mod_nss.h
+++ b/mod_nss.h
@@ -291,6 +291,9 @@ typedef struct {
struct SSLSrvConfigRec {
SSLModConfigRec *mc;
BOOL fips;
+ BOOL ocsp_default;
+ const char *ocsp_url;
+ const char *ocsp_name;
BOOL ocsp;
BOOL enabled;
BOOL proxy_enabled;
@@ -370,6 +373,9 @@ void *nss_config_server_merge(apr_pool_t *p, void *basev, void *addv);
const char *nss_cmd_NSSFIPS(cmd_parms *, void *, int);
const char *nss_cmd_NSSEngine(cmd_parms *, void *, int);
const char *nss_cmd_NSSOCSP(cmd_parms *, void *, int);
+const char *nss_cmd_NSSOCSPDefaultResponder(cmd_parms *, void *, int);
+const char *nss_cmd_NSSOCSPDefaultURL(cmd_parms *, void *dcfg, const char *arg);
+const char *nss_cmd_NSSOCSPDefaultName(cmd_parms *, void *, const char *arg);
const char *nss_cmd_NSSCertificateDatabase(cmd_parms *cmd, void *dcfg, const char *arg);
const char *nss_cmd_NSSDBPrefix(cmd_parms *cmd, void *dcfg, const char *arg);
const char *nss_cmd_NSSCipherSuite(cmd_parms *cmd, void *dcfg, const char *arg);
diff --git a/nss.conf.in b/nss.conf.in
index 1c8172e..65d2406 100644
--- a/nss.conf.in
+++ b/nss.conf.in
@@ -131,6 +131,18 @@ NSSCertificateDatabase @apache_conf@
# Verify that certificates have not been revoked before accepting them.
#NSSOCSP off
+#
+# Use a default OCSP responder. If enabled this will be used regardless
+# of whether one is included in a client certificate. Note that the
+# server certificate is verified during startup.
+#
+# NSSOCSPDefaultURL defines the service URL of the OCSP responder
+# NSSOCSPDefaultName is the nickname of the certificate to trust to
+# sign the OCSP responses.
+#NSSOCSPDefaultResponder on
+#NSSOCSPDefaultURL http://example.com/ocsp/status
+#NSSOCSPDefaultName ocsp-nickname
+
# Access Control:
# With SSLRequire you can do per-directory access control based
# on arbitrary complex boolean expressions containing server
diff --git a/nss_engine_config.c b/nss_engine_config.c
index dd54fdb..b72530e 100644
--- a/nss_engine_config.c
+++ b/nss_engine_config.c
@@ -126,6 +126,9 @@ static SSLSrvConfigRec *nss_config_server_new(apr_pool_t *p)
sc->mc = NULL;
sc->ocsp = UNSET;
+ sc->ocsp_default = UNSET;
+ sc->ocsp_url = NULL;
+ sc->ocsp_name = NULL;
sc->fips = UNSET;
sc->enabled = UNSET;
sc->proxy_enabled = UNSET;
@@ -197,6 +200,9 @@ void *nss_config_server_merge(apr_pool_t *p, void *basev, void *addv) {
cfgMerge(mc, NULL);
cfgMergeBool(ocsp);
+ cfgMergeBool(ocsp_default);
+ cfgMerge(ocsp_url, NULL);
+ cfgMerge(ocsp_name, NULL);
cfgMergeBool(fips);
cfgMergeBool(enabled);
cfgMergeBool(proxy_enabled);
@@ -314,6 +320,37 @@ const char *nss_cmd_NSSOCSP(cmd_parms *cmd, void *dcfg, int flag)
return NULL;
}
+const char *nss_cmd_NSSOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->ocsp_default = flag ? TRUE : FALSE;
+
+ return NULL;
+}
+
+const char *nss_cmd_NSSOCSPDefaultURL(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->ocsp_url = arg;
+
+ return NULL;
+}
+
+const char *nss_cmd_NSSOCSPDefaultName(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->ocsp_name = arg;
+
+ return NULL;
+}
+
const char *nss_cmd_NSSCertificateDatabase(cmd_parms *cmd,
void *dcfg,
const char *arg)
diff --git a/nss_engine_init.c b/nss_engine_init.c
index 1e5bed9..2c09055 100644
--- a/nss_engine_init.c
+++ b/nss_engine_init.c
@@ -21,6 +21,7 @@
#include "pk11func.h"
#include "ocsp.h"
#include "keyhi.h"
+#include "cert.h"
static SECStatus ownBadCertHandler(void *arg, PRFileDesc * socket);
static SECStatus ownHandshakeCallback(PRFileDesc * socket, void *arg);
@@ -137,7 +138,8 @@ static void nss_add_version_components(apr_pool_t *p,
* passwords.
*/
static void nss_init_SSLLibrary(server_rec *s, int sslenabled, int fipsenabled,
- int ocspenabled)
+ int ocspenabled, int ocspdefault,
+ const char * ocspurl, const char *ocspname)
{
SECStatus rv;
SSLModConfigRec *mc = myModConfig(s);
@@ -280,6 +282,30 @@ static void nss_init_SSLLibrary(server_rec *s, int sslenabled, int fipsenabled,
CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
"OCSP is enabled.");
+
+ /* We ensure that ocspname and ocspurl are not NULL in nss_init_Module
+ */
+ if (ocspdefault) {
+ SECStatus sv;
+
+ sv = CERT_SetOCSPDefaultResponder(CERT_GetDefaultCertDB(),
+ ocspurl, ocspname);
+
+ if (sv == SECFailure) {
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ "Unable to set OCSP default responder nickname %s.", ocspname);
+ nss_log_nss_error(APLOG_MARK, APLOG_INFO, s);
+ nss_die();
+ }
+
+ sv = CERT_EnableOCSPDefaultResponder(CERT_GetDefaultCertDB());
+ if (sv == SECFailure) {
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ "Unable to enable the OCSP default responder, %s (this shouldn't happen).", ocspname);
+ nss_log_nss_error(APLOG_MARK, APLOG_INFO, s);
+ nss_die();
+ }
+ }
}
}
@@ -293,6 +319,9 @@ int nss_init_Module(apr_pool_t *p, apr_pool_t *plog,
int sslenabled = FALSE;
int fipsenabled = FALSE;
int ocspenabled = FALSE;
+ int ocspdefault = FALSE;
+ const char * ocspurl = NULL;
+ const char * ocspname = NULL;
mc->nInitCount++;
@@ -382,9 +411,21 @@ int nss_init_Module(apr_pool_t *p, apr_pool_t *plog,
if (sc->proxy_enabled == UNSET) {
sc->proxy_enabled = FALSE;
}
+
+ if (sc->ocsp_default == TRUE) {
+ ocspdefault = TRUE;
+ ocspurl = sc->ocsp_url;
+ ocspname = sc->ocsp_name;
+ if ((ocspurl == NULL) || (ocspname == NULL)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "When NSSOCSPDefaultResponder is enabled both a default URL (NSSOCSPDefaultUrl) and certificate nickname (NSSOCSPDefaultName) are required.");
+ nss_die();
+ }
+ }
}
- nss_init_SSLLibrary(base_server, sslenabled, fipsenabled, ocspenabled);
+ nss_init_SSLLibrary(base_server, sslenabled, fipsenabled, ocspenabled,
+ ocspdefault, ocspurl, ocspname);
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
"done Init: Initializing NSS library");
@@ -1061,11 +1102,19 @@ apr_status_t nss_init_ModuleKill(void *data)
}
if (shutdown) {
+ if (CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB())
+ != SECSuccess) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "Turning off the OCSP default responder failed.");
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, NULL);
+ }
+
SSL_ShutdownServerSessionIDCache();
if ((rv = NSS_Shutdown()) != SECSuccess) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
- "NSS_Shutdown failed: %d", PR_GetError());
+ "NSS_Shutdown failed");
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, NULL);
}
}