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

00df7d
 

This option enables OCSP validation of the client certificate

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

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

00df7d
 
00df7d
 

The OCSP responder used is either extracted from the certificate

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