]> granicus.if.org Git - apache/commitdiff
Merge r1826995, r1827001 from trunk:
authorYann Ylavic <ylavic@apache.org>
Fri, 22 Jun 2018 09:45:39 +0000 (09:45 +0000)
committerYann Ylavic <ylavic@apache.org>
Fri, 22 Jun 2018 09:45:39 +0000 (09:45 +0000)
Extend SSLOCSPEnable with mode 'leaf' that only checks the leaf of a
certificate chain. PR62112 [Ricardo Martin Camarero <rickyepoderi yahoo.es>]

Fixed OCSPEnable to keep accepting "off", not "none".

Submitted by: icing
Reviewedby: icing, ylavic, rpluem

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1834089 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_ssl.xml
modules/ssl/mod_ssl.c
modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_init.c
modules/ssl/ssl_engine_kernel.c
modules/ssl/ssl_engine_ocsp.c
modules/ssl/ssl_private.h

diff --git a/CHANGES b/CHANGES
index cc74c694650ec823103a28dccaab2d7b657033d3..352d44cc509a70c10a1d766a26171dd718c94676 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- 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]
 
index cae5ae69e4f406460e1b105eb78b0c3f4ddd4fe3..5f7282760ec24e57f74b7dd76542bc405c5e2664 100644 (file)
@@ -2298,16 +2298,18 @@ SSLCryptoDevice ubsec
 <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
index 48d64cb6248d085b7ebebf07185d42a6be37d39c..b716a7b371cde39f2d4ed60d33c8d51deb649121 100644 (file)
@@ -243,8 +243,8 @@ static const command_rec ssl_config_cmds[] = {
                 "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,
index e5fd90165884b0089c7069294dd98c0644b75169..195380e2f371d9543fb8b3ac59ee755f4230fdd7 100644 (file)
@@ -137,8 +137,8 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
     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;
@@ -281,7 +281,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
     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);
@@ -1681,11 +1681,46 @@ const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
     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) {
@@ -1694,7 +1729,7 @@ const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int 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)
@@ -2073,3 +2108,4 @@ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
     }
 
 }
+
index c75e51ebddb598f58c46b195bcc52cddd8fe265f..4f4daab052a9d95e374c3cdb85222f6780d033b5 100644 (file)
@@ -902,6 +902,10 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s,
     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;
     }
index b1591edc5fe4b2ff4d73f844def7d986b7733e65..e34fc55fa2933c66d653e8e56a42e8774e790898 100644 (file)
@@ -1578,7 +1578,6 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
     int errdepth = X509_STORE_CTX_get_error_depth(ctx);
     int depth, verify;
 
-
     /*
      * Log verification information
      */
@@ -1652,7 +1651,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
     /*
      * 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. */
index ae0f84253caf5652937f1f78ac83cc4c6a3aa602..bfb8952bf46e1b0d823af530d0d8435f8d4de061 100644 (file)
@@ -139,7 +139,14 @@ static int verify_ocsp_status(X509 *cert, X509_STORE_CTX *ctx, conn_rec *c,
 
     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);
index a39569cbf7be4a2cfbb4c3d554b17f6c5fc399e7..9683a1ae898e6cb7aa5ba3b987425ab0ea61a561 100644 (file)
@@ -417,6 +417,16 @@ typedef enum {
     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
  */
@@ -701,7 +711,7 @@ typedef struct {
 
     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 */
@@ -844,7 +854,7 @@ const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const ch
 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 */