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

41a6c3
 

This option enables OCSP validation of the client certificate

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

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

41a6c3
 
41a6c3
 

The OCSP responder used is either extracted from the certificate

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