Blame SOURCES/httpd-2.4.6-r1826995.patch

008793
diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en
008793
index 4580f1c..fb8202e 100644
008793
--- a/docs/manual/mod/mod_ssl.html.en
008793
+++ b/docs/manual/mod/mod_ssl.html.en
008793
@@ -991,7 +991,8 @@ the certificate being verified.

008793
 

This option enables OCSP validation of the client certificate

008793
 chain.  If this option is enabled, certificates in the client's
008793
 certificate chain will be validated against an OCSP responder after
008793
-normal verification (including CRL checks) have taken place.

008793
+normal verification (including CRL checks) have taken place. In 
008793
+mode 'leaf', only the client certificate itself will be validated.

008793
 
008793
 

The OCSP responder used is either extracted from the certificate

008793
 itself, or derived by configuration; see the
008793
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
008793
index 4a8b661..e637a9d 100644
008793
--- a/modules/ssl/mod_ssl.c
008793
+++ b/modules/ssl/mod_ssl.c
008793
@@ -227,8 +227,8 @@ static const command_rec ssl_config_cmds[] = {
008793
                 "request body if a per-location SSL renegotiation is required due to "
008793
                 "changed access control requirements")
008793
 
008793
-    SSL_CMD_SRV(OCSPEnable, FLAG,
008793
-               "Enable use of OCSP to verify certificate revocation ('on', 'off')")
008793
+    SSL_CMD_SRV(OCSPEnable, RAW_ARGS,
008793
+               "Enable use of OCSP to verify certificate revocation mode ('on', 'leaf', 'off')")
008793
     SSL_CMD_SRV(OCSPDefaultResponder, TAKE1,
008793
                "URL of the default OCSP Responder")
008793
     SSL_CMD_SRV(OCSPOverrideResponder, FLAG,
008793
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
008793
index 86a7f0f..714aee9 100644
008793
--- a/modules/ssl/ssl_engine_config.c
008793
+++ b/modules/ssl/ssl_engine_config.c
008793
@@ -130,7 +130,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx)
008793
     mctx->auth.verify_depth   = UNSET;
008793
     mctx->auth.verify_mode    = SSL_CVERIFY_UNSET;
008793
 
008793
-    mctx->ocsp_enabled        = FALSE;
008793
+    mctx->ocsp_mask           = UNSET;
008793
     mctx->ocsp_force_default  = FALSE;
008793
     mctx->ocsp_responder      = NULL;
008793
     mctx->ocsp_resptime_skew  = UNSET;
008793
@@ -264,7 +264,7 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
008793
     cfgMergeInt(auth.verify_depth);
008793
     cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
008793
 
008793
-    cfgMergeBool(ocsp_enabled);
008793
+    cfgMergeInt(ocsp_mask);
008793
     cfgMergeBool(ocsp_force_default);
008793
     cfgMerge(ocsp_responder, NULL);
008793
     cfgMergeInt(ocsp_resptime_skew);
008793
@@ -1575,11 +1575,46 @@ const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
008793
     return NULL;
008793
 }
008793
 
008793
-const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag)
008793
+static const char *ssl_cmd_ocspcheck_parse(cmd_parms *parms,
008793
+                                           const char *arg,
008793
+                                           int *mask)
008793
 {
008793
-    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
008793
+    const char *w;
008793
+
008793
+    w = ap_getword_conf(parms->temp_pool, &arg;;
008793
+    if (strcEQ(w, "off")) {
008793
+        *mask = SSL_OCSPCHECK_NONE;
008793
+    }
008793
+    else if (strcEQ(w, "leaf")) {
008793
+        *mask = SSL_OCSPCHECK_LEAF;
008793
+    }
008793
+    else if (strcEQ(w, "on")) {
008793
+        *mask = SSL_OCSPCHECK_CHAIN;
008793
+    }
008793
+    else {
008793
+        return apr_pstrcat(parms->temp_pool, parms->cmd->name,
008793
+                           ": Invalid argument '", w, "'",
008793
+                           NULL);
008793
+    }
008793
+
008793
+    while (*arg) {
008793
+        w = ap_getword_conf(parms->temp_pool, &arg;;
008793
+        if (strcEQ(w, "no_ocsp_for_cert_ok")) {
008793
+            *mask |= SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK;
008793
+        }
008793
+        else {
008793
+            return apr_pstrcat(parms->temp_pool, parms->cmd->name,
008793
+                               ": Invalid argument '", w, "'",
008793
+                               NULL);
008793
+        }
008793
+    }
008793
 
008793
-    sc->server->ocsp_enabled = flag ? TRUE : FALSE;
008793
+    return NULL;
008793
+}
008793
+
008793
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *arg)
008793
+{
008793
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
008793
 
008793
 #ifdef OPENSSL_NO_OCSP
008793
     if (flag) {
008793
@@ -1588,7 +1623,7 @@ const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag)
008793
     }
008793
 #endif
008793
 
008793
-    return NULL;
008793
+    return ssl_cmd_ocspcheck_parse(cmd, arg, &sc->server->ocsp_mask);
008793
 }
008793
 
008793
 const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag)
008793
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
008793
index 672760c..57b76c0 100644
008793
--- a/modules/ssl/ssl_engine_init.c
008793
+++ b/modules/ssl/ssl_engine_init.c
008793
@@ -762,6 +762,10 @@ static void ssl_init_ctx_crl(server_rec *s,
008793
     unsigned long crlflags = 0;
008793
     char *cfgp = mctx->pkp ? "SSLProxy" : "SSL";
008793
 
008793
+    if (mctx->ocsp_mask == UNSET) {
008793
+        mctx->ocsp_mask = SSL_OCSPCHECK_NONE;
008793
+    }
008793
+
008793
     /*
008793
      * Configure Certificate Revocation List (CRL) Details
008793
      */
008793
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
008793
index 5ff35f5..9dc236c 100644
008793
--- a/modules/ssl/ssl_engine_kernel.c
008793
+++ b/modules/ssl/ssl_engine_kernel.c
008793
@@ -1416,7 +1416,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
008793
     /*
008793
      * Perform OCSP-based revocation checks
008793
      */
008793
-    if (ok && sc->server->ocsp_enabled) {
008793
+    if (ok && ((mctx->ocsp_mask & SSL_OCSPCHECK_CHAIN) ||
008793
+         (errdepth == 0 && (mctx->ocsp_mask & SSL_OCSPCHECK_LEAF)))) {
008793
         /* If there was an optional verification error, it's not
008793
          * possible to perform OCSP validation since the issuer may be
008793
          * missing/untrusted.  Fail in that case. */
008793
diff --git a/modules/ssl/ssl_engine_ocsp.c b/modules/ssl/ssl_engine_ocsp.c
008793
index 90da5c2..58d267b 100644
008793
--- a/modules/ssl/ssl_engine_ocsp.c
008793
+++ b/modules/ssl/ssl_engine_ocsp.c
008793
@@ -136,7 +136,14 @@ static int verify_ocsp_status(X509 *cert, X509_STORE_CTX *ctx, conn_rec *c,
008793
 
008793
     ruri = determine_responder_uri(sc, cert, c, pool);
008793
     if (!ruri) {
008793
-        return V_OCSP_CERTSTATUS_UNKNOWN;
008793
+        if (sc->server->ocsp_mask & SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK) {
008793
+            ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, 
008793
+                          "Skipping OCSP check for certificate cos no OCSP URL"
008793
+                          " found and no_ocsp_for_cert_ok is set");
008793
+            return V_OCSP_CERTSTATUS_GOOD;
008793
+        } else {
008793
+            return V_OCSP_CERTSTATUS_UNKNOWN;
008793
+        }
008793
     }
008793
 
008793
     request = create_request(ctx, cert, &certID, s, pool);
008793
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
008793
index b601316..2d505f9 100644
008793
--- a/modules/ssl/ssl_private.h
008793
+++ b/modules/ssl/ssl_private.h
008793
@@ -379,6 +379,16 @@ typedef enum {
008793
 } ssl_crlcheck_t;
008793
 
008793
 /**
008793
+  * OCSP checking mask (mode | flags)
008793
+  */
008793
+typedef enum {
008793
+    SSL_OCSPCHECK_NONE  = (0),
008793
+    SSL_OCSPCHECK_LEAF  = (1 << 0),
008793
+    SSL_OCSPCHECK_CHAIN = (1 << 1),
008793
+    SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK = (1 << 2)
008793
+} ssl_ocspcheck_t;
008793
+
008793
+/**
008793
  * Define the SSL pass phrase dialog types
008793
  */
008793
 typedef enum {
008793
@@ -668,7 +678,7 @@ typedef struct {
008793
 
008793
     modssl_auth_ctx_t auth;
008793
 
008793
-    BOOL ocsp_enabled; /* true if OCSP verification enabled */
008793
+    int ocsp_mask;
008793
     BOOL ocsp_force_default; /* true if the default responder URL is
008793
                               * used regardless of per-cert URL */
008793
     const char *ocsp_responder; /* default responder URL */
008793
@@ -796,7 +806,7 @@ const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const ch
008793
 const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg);
008793
 const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg);
008793
 const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg);
008793
-const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag);
008793
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *flag);
008793
 
008793
 #ifndef OPENSSL_NO_SRP
008793
 const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, const char *arg);