diff options
-rw-r--r-- | mod_nss.c | 9 | ||||
-rw-r--r-- | mod_nss.h | 6 | ||||
-rw-r--r-- | nss.conf.in | 12 | ||||
-rw-r--r-- | nss_engine_config.c | 37 | ||||
-rw-r--r-- | nss_engine_init.c | 55 |
5 files changed, 116 insertions, 3 deletions
@@ -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]')") @@ -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); } } |