-*- coding: utf-8 -*-
Changes with Apache 2.4.34
+ *) mod_ssl: Extend SSLOCSPEnable with mode 'leaf' that only checks the leaf
+ of a certificate chain. PR62112.
+ [Ricardo Martin Camarero <rickyepoderi yahoo.es>]
+
*) http: Fix small memory leak per request when handling persistent
connections. [Ruediger Pluem, Joe Orton]
<directivesynopsis>
<name>SSLOCSPEnable</name>
<description>Enable OCSP validation of the client certificate chain</description>
-<syntax>SSLOCSPEnable on|off</syntax>
+<syntax>SSLOCSPEnable on|leaf|off</syntax>
<default>SSLOCSPEnable off</default>
<contextlist><context>server config</context>
<context>virtual host</context></contextlist>
+<compatibility>Mode <em>leaf</em> available in httpd 2.4.34 and later</compatibility>
<usage>
<p>This option enables OCSP validation of the client certificate
chain. If this option is enabled, certificates in the client's
certificate chain will be validated against an OCSP responder after
-normal verification (including CRL checks) have taken place.</p>
+normal verification (including CRL checks) have taken place. In
+mode 'leaf', only the client certificate itself will be validated.</p>
<p>The OCSP responder used is either extracted from the certificate
itself, or derived by configuration; see the
"request body if a per-location SSL renegotiation is required due to "
"changed access control requirements")
- SSL_CMD_SRV(OCSPEnable, FLAG,
- "Enable use of OCSP to verify certificate revocation ('on', 'off')")
+ SSL_CMD_SRV(OCSPEnable, RAW_ARGS,
+ "Enable use of OCSP to verify certificate revocation mode ('on', 'leaf', 'off')")
SSL_CMD_SRV(OCSPDefaultResponder, TAKE1,
"URL of the default OCSP Responder")
SSL_CMD_SRV(OCSPOverrideResponder, FLAG,
mctx->auth.verify_depth = UNSET;
mctx->auth.verify_mode = SSL_CVERIFY_UNSET;
- mctx->ocsp_enabled = FALSE;
- mctx->ocsp_force_default = FALSE;
+ mctx->ocsp_mask = UNSET;
+ mctx->ocsp_force_default = UNSET;
mctx->ocsp_responder = NULL;
mctx->ocsp_resptime_skew = UNSET;
mctx->ocsp_resp_maxage = UNSET;
cfgMergeInt(auth.verify_depth);
cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
- cfgMergeBool(ocsp_enabled);
+ cfgMergeInt(ocsp_mask);
cfgMergeBool(ocsp_force_default);
cfgMerge(ocsp_responder, NULL);
cfgMergeInt(ocsp_resptime_skew);
return NULL;
}
-const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag)
+static const char *ssl_cmd_ocspcheck_parse(cmd_parms *parms,
+ const char *arg,
+ int *mask)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *w;
+
+ w = ap_getword_conf(parms->temp_pool, &arg);
+ if (strcEQ(w, "off")) {
+ *mask = SSL_OCSPCHECK_NONE;
+ }
+ else if (strcEQ(w, "leaf")) {
+ *mask = SSL_OCSPCHECK_LEAF;
+ }
+ else if (strcEQ(w, "on")) {
+ *mask = SSL_OCSPCHECK_CHAIN;
+ }
+ else {
+ return apr_pstrcat(parms->temp_pool, parms->cmd->name,
+ ": Invalid argument '", w, "'",
+ NULL);
+ }
+
+ while (*arg) {
+ w = ap_getword_conf(parms->temp_pool, &arg);
+ if (strcEQ(w, "no_ocsp_for_cert_ok")) {
+ *mask |= SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK;
+ }
+ else {
+ return apr_pstrcat(parms->temp_pool, parms->cmd->name,
+ ": Invalid argument '", w, "'",
+ NULL);
+ }
+ }
- sc->server->ocsp_enabled = flag ? TRUE : FALSE;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
#ifdef OPENSSL_NO_OCSP
if (flag) {
}
#endif
- return NULL;
+ return ssl_cmd_ocspcheck_parse(cmd, arg, &sc->server->ocsp_mask);
}
const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag)
}
}
+
char *cfgp = mctx->pkp ? "SSLProxy" : "SSL";
int crl_check_mode;
+ if (mctx->ocsp_mask == UNSET) {
+ mctx->ocsp_mask = SSL_OCSPCHECK_NONE;
+ }
+
if (mctx->crl_check_mask == UNSET) {
mctx->crl_check_mask = SSL_CRLCHECK_NONE;
}
int errdepth = X509_STORE_CTX_get_error_depth(ctx);
int depth, verify;
-
/*
* Log verification information
*/
/*
* Perform OCSP-based revocation checks
*/
- if (ok && sc->server->ocsp_enabled) {
+ if (ok && ((sc->server->ocsp_mask & SSL_OCSPCHECK_CHAIN) ||
+ (errdepth == 0 && (sc->server->ocsp_mask & SSL_OCSPCHECK_LEAF)))) {
/* If there was an optional verification error, it's not
* possible to perform OCSP validation since the issuer may be
* missing/untrusted. Fail in that case. */
ruri = determine_responder_uri(sc, cert, c, pool);
if (!ruri) {
- return V_OCSP_CERTSTATUS_UNKNOWN;
+ if (sc->server->ocsp_mask & SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK) {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ "Skipping OCSP check for certificate cos no OCSP URL"
+ " found and no_ocsp_for_cert_ok is set");
+ return V_OCSP_CERTSTATUS_GOOD;
+ } else {
+ return V_OCSP_CERTSTATUS_UNKNOWN;
+ }
}
request = create_request(ctx, cert, &certID, s, pool, sc);
SSL_CRLCHECK_NO_CRL_FOR_CERT_OK = (1 << 2)
} ssl_crlcheck_t;
+/**
+ * OCSP checking mask (mode | flags)
+ */
+typedef enum {
+ SSL_OCSPCHECK_NONE = (0),
+ SSL_OCSPCHECK_LEAF = (1 << 0),
+ SSL_OCSPCHECK_CHAIN = (1 << 1),
+ SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK = (1 << 2)
+} ssl_ocspcheck_t;
+
/**
* Define the SSL pass phrase dialog types
*/
modssl_auth_ctx_t auth;
- BOOL ocsp_enabled; /* true if OCSP verification enabled */
+ int ocsp_mask;
BOOL ocsp_force_default; /* true if the default responder URL is
* used regardless of per-cert URL */
const char *ocsp_responder; /* default responder URL */
const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg);
const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg);
const char *ssl_cmd_SSLOCSPUseRequestNonce(cmd_parms *cmd, void *dcfg, int flag);
-const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag);
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *arg);
const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd, void *dcfg, const char *arg);
/* Declare OCSP Responder Certificate Verification Directive */