]> granicus.if.org Git - apache/commitdiff
Revamp CRL checking for client and remote servers:
authorKaspar Brand <kbrand@apache.org>
Sun, 4 Sep 2011 15:57:03 +0000 (15:57 +0000)
committerKaspar Brand <kbrand@apache.org>
Sun, 4 Sep 2011 15:57:03 +0000 (15:57 +0000)
- completely delegate CRL processing to OpenSSL
- introduce a new [Proxy]CARevocationCheck directive
- drop ssl_callback_SSLVerify_CRL from ssl_engine_kernel.c
- remove X509_STORE from modssl_ctx_t
- drop CRL store helper functions from ssl_util_ssl.c
- avoid sending "certificate_expired" SSL alerts to peers
  when the nextUpdate field of a CRL is in the past

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1165056 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_private.h
modules/ssl/ssl_util_ssl.c
modules/ssl/ssl_util_ssl.h

diff --git a/CHANGES b/CHANGES
index 86c1af7ee1d768d1bcf51fbfbe84f009ee202bdd..308d4ed9c348ab0d1e8f2adf967e9e02ad092ccd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.3.15
 
+  *) mod_ssl: revamp CRL-based revocation checking when validating
+     certificates of clients or proxied servers. Completely delegate
+     CRL processing to OpenSSL, and add a new [Proxy]CARevocationCheck
+     directive for controlling the revocation checking mode. [Kaspar Brand]
+
   *) Fix a regression in the CVE-2011-3192 byterange fix.
      PR 51748. [low_priority <lowprio20 gmail.com>]
 
index 9ea11ee4e6b48ea4928348dc51f6f996429111eb..37e766e083ce0be9dc2237420ec2ad28ed9491f0 100644 (file)
@@ -1033,6 +1033,43 @@ SSLCARevocationFile /usr/local/apache2/conf/ssl.crl/ca-bundle-client.crl
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>SSLCARevocationCheck</name>
+<description>Enable CRL-based revocation checking</description>
+<syntax>SSLCARevocationCheck chain|leaf|none</syntax>
+<default>SSLCARevocationCheck none</default>
+<contextlist><context>server config</context>
+<context>virtual host</context></contextlist>
+
+<usage>
+<p>
+Enables certificate revocation list (CRL) checking. At least one of
+<directive module="mod_ssl">SSLCARevocationFile</directive>
+or <directive module="mod_ssl">SSLCARevocationPath</directive> must be
+configured. When set to <code>chain</code> (recommended setting),
+CRL checks are applied to all certificates in the chain, while setting it to
+<code>leaf</code> limits the checks to the end-entity cert.
+</p>
+<note>
+<title>When set to <code>chain</code> or <code>leaf</code>,
+CRLs <em>must</em> be available for successful validation</title>
+<p>
+Prior to version 2.3.15, CRL checking in mod_ssl also succeeded when
+no CRL(s) were found in any of the locations configured with
+<directive module="mod_ssl">SSLCARevocationFile</directive>
+or <directive module="mod_ssl">SSLCARevocationPath</directive>.
+With the introduction of this directive, the behavior has been changed:
+when checking is enabled, CRLs <em>must</em> be present for the validation
+to succeed - otherwise it will fail with an
+<code>"unable to get certificate CRL"</code> error.
+</p>
+</note>
+<example><title>Example</title>
+SSLCARevocationCheck chain
+</example>
+</usage>
+</directivesynopsis>
+
 <directivesynopsis>
 <name>SSLVerifyClient</name>
 <description>Type of Client Certificate verification</description>
@@ -1784,6 +1821,44 @@ SSLProxyCARevocationFile /usr/local/apache2/conf/ssl.crl/ca-bundle-remote-server
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>SSLProxyCARevocationCheck</name>
+<description>Enable CRL-based revocation checking for Remote Server Auth</description>
+<syntax>SSLProxyCARevocationCheck chain|leaf|none</syntax>
+<default>SSLProxyCARevocationCheck none</default>
+<contextlist><context>server config</context>
+<context>virtual host</context></contextlist>
+
+<usage>
+<p>
+Enables certificate revocation list (CRL) checking for the
+<em>remote servers</em> you deal with. At least one of
+<directive module="mod_ssl">SSLProxyCARevocationFile</directive>
+or <directive module="mod_ssl">SSLProxyCARevocationPath</directive> must be
+configured. When set to <code>chain</code> (recommended setting),
+CRL checks are applied to all certificates in the chain, while setting it to
+<code>leaf</code> limits the checks to the end-entity cert.
+</p>
+<note>
+<title>When set to <code>chain</code> or <code>leaf</code>,
+CRLs <em>must</em> be available for successful validation</title>
+<p>
+Prior to version 2.3.15, CRL checking in mod_ssl also succeeded when
+no CRL(s) were found in any of the locations configured with
+<directive module="mod_ssl">SSLProxyCARevocationFile</directive>
+or <directive module="mod_ssl">SSLProxyCARevocationPath</directive>.
+With the introduction of this directive, the behavior has been changed:
+when checking is enabled, CRLs <em>must</em> be present for the validation
+to succeed - otherwise it will fail with an
+<code>"unable to get certificate CRL"</code> error.
+</p>
+</note>
+<example><title>Example</title>
+SSLProxyCARevocationCheck chain
+</example>
+</usage>
+</directivesynopsis>
+
 <directivesynopsis>
 <name>SSLUserName</name>
 <description>Variable name to determine user name</description>
index 2f1af8fb85c114c3b9f68adce313b1acd1537c6a..dbd98ae44f517508e347d428efbb6129045204cb 100644 (file)
@@ -112,6 +112,8 @@ static const command_rec ssl_config_cmds[] = {
     SSL_CMD_SRV(CARevocationFile, TAKE1,
                 "SSL CA Certificate Revocation List (CRL) file "
                 "('/path/to/file' - PEM encoded)")
+    SSL_CMD_SRV(CARevocationCheck, TAKE1,
+                "SSL CA Certificate Revocation List (CRL) checking mode")
     SSL_CMD_ALL(VerifyClient, TAKE1,
                 "SSL Client verify type "
                 "('none', 'optional', 'require', 'optional_no_ca')")
@@ -163,6 +165,8 @@ static const command_rec ssl_config_cmds[] = {
     SSL_CMD_SRV(ProxyCARevocationFile, TAKE1,
                 "SSL Proxy: CA Certificate Revocation List (CRL) file "
                 "('/path/to/file' - PEM encoded)")
+    SSL_CMD_SRV(ProxyCARevocationCheck, TAKE1,
+                "SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
     SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1,
                "SSL Proxy: file containing client certificates "
                "('/path/to/file' - PEM encoded certificates)")
index 8dd087ce667f70826af45610fe31519a200fc535..77c40ab2e1c059f9d3b7908ff4c496e9c61379de 100644 (file)
@@ -119,7 +119,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx)
 
     mctx->crl_path            = NULL;
     mctx->crl_file            = NULL;
-    mctx->crl                 = NULL; /* set during module init */
+    mctx->crl_check_mode      = SSL_CRLCHECK_UNSET;
 
     mctx->auth.ca_cert_path   = NULL;
     mctx->auth.ca_cert_file   = NULL;
@@ -238,6 +238,7 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
 
     cfgMerge(crl_path, NULL);
     cfgMerge(crl_file, NULL);
+    cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET);
 
     cfgMergeString(auth.ca_cert_path);
     cfgMergeString(auth.ca_cert_file);
@@ -902,6 +903,39 @@ const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
     return NULL;
 }
 
+static const char *ssl_cmd_crlcheck_parse(cmd_parms *parms,
+                                          const char *arg,
+                                          ssl_crlcheck_t *mode)
+{
+    if (strcEQ(arg, "none")) {
+        *mode = SSL_CRLCHECK_NONE;
+    }
+    else if (strcEQ(arg, "leaf")) {
+        *mode = SSL_CRLCHECK_LEAF;
+    }
+    else if (strcEQ(arg, "chain")) {
+        *mode = SSL_CRLCHECK_CHAIN;
+    }
+    else {
+        return apr_pstrcat(parms->temp_pool, parms->cmd->name,
+                           ": Invalid argument '", arg, "'",
+                           NULL);
+    }
+
+    return NULL;
+}
+
+const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd,
+                                         void *dcfg,
+                                         const char *arg)
+{   
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+    const char *err;
+
+    return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mode);
+}
+        
 static const char *ssl_cmd_verify_parse(cmd_parms *parms,
                                         const char *arg,
                                         ssl_verify_t *id)
@@ -1379,6 +1413,15 @@ const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
     return NULL;
 }
 
+const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd,
+                                              void *dcfg,
+                                              const char *arg)
+{   
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+    return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mode);
+}
+        
 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
                                                    void *dcfg,
                                                    const char *arg)
index ca8ed99b870c99a0f5536b81b616fc2f3bbfce64..bf32897bbfe8bda36dc4233c88b8f34ba6701678 100644 (file)
@@ -726,28 +726,55 @@ static void ssl_init_ctx_crl(server_rec *s,
                              apr_pool_t *ptemp,
                              modssl_ctx_t *mctx)
 {
+    X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
+    unsigned long crlflags = 0;
+    char *cfgp = mctx->pkp ? "SSLProxy" : "SSL";
+
     /*
      * Configure Certificate Revocation List (CRL) Details
      */
 
     if (!(mctx->crl_file || mctx->crl_path)) {
+        if (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ||
+            mctx->crl_check_mode == SSL_CRLCHECK_CHAIN) {
+            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
+                         "Host %s: CRL checking has been enabled, but "
+                         "neither %sCARevocationFile nor %sCARevocationPath "
+                         "is configured", mctx->sc->vhost_id, cfgp, cfgp);
+            ssl_die();
+        }
         return;
     }
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "Configuring certificate revocation facility");
 
-    mctx->crl =
-        SSL_X509_STORE_create((char *)mctx->crl_file,
-                              (char *)mctx->crl_path);
-
-    if (!mctx->crl) {
+    if (!store || !X509_STORE_load_locations(store, mctx->crl_file,
+                                             mctx->crl_path)) {
         ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
-                "Unable to configure X.509 CRL storage "
-                "for certificate revocation");
+                     "Host %s: unable to configure X.509 CRL storage "
+                     "for certificate revocation", mctx->sc->vhost_id);
         ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
         ssl_die();
     }
+
+    switch (mctx->crl_check_mode) {
+       case SSL_CRLCHECK_LEAF:
+           crlflags = X509_V_FLAG_CRL_CHECK;
+           break;
+       case SSL_CRLCHECK_CHAIN:
+           crlflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+           break;
+    }
+
+    if (crlflags) {
+        X509_STORE_set_flags(store, crlflags);
+    } else {
+        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+                     "Host %s: X.509 CRL storage locations configured, "
+                     "but CRL checking (%sCARevocationCheck) is not "
+                     "enabled", mctx->sc->vhost_id, cfgp);
+    }
 }
 
 static void ssl_init_ctx_pkcs7_cert_chain(server_rec *s, modssl_ctx_t *mctx)
@@ -1432,8 +1459,6 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
 
 static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
 {
-    MODSSL_CFG_ITEM_FREE(X509_STORE_free, mctx->crl);
-
     MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
 }
 
index 4cb918690f1b13974709e7e029bdce9d13e6edf7..70b142ad0be62cd1a4eadc0f1405615bb6b7368b 100644 (file)
@@ -1429,8 +1429,11 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
      */
     ssl_log_cxerror(SSLLOG_MARK, APLOG_DEBUG, 0, conn,
                     X509_STORE_CTX_get_current_cert(ctx),
-                    "Certificate Verification, depth %d",
-                    errdepth);
+                    "Certificate Verification, depth %d, "
+                    "CRL checking mode: %s", errdepth,
+                    mctx->crl_check_mode == SSL_CRLCHECK_CHAIN ?
+                    "chain" : (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ?
+                               "leaf" : "none"));
 
     /*
      * Check for optionally acceptable non-verifiable issuer situation
@@ -1464,19 +1467,30 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
     }
 
     /*
-     * Perform OCSP/CRL-based revocation checks
+     * Expired certificates vs. "expired" CRLs: by default, OpenSSL
+     * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
+     * SSL alert, but that's not really the message we should convey to the
+     * peer (at the very least, it's confusing, and in many cases, it's also
+     * inaccurate, as the certificate itself may very well not have expired
+     * yet). We set the X509_STORE_CTX error to something which OpenSSL's
+     * s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
+     * i.e. the peer will receive a "certificate_unknown(46)" alert.
+     * We do not touch errnum, though, so that later on we will still log
+     * the "real" error, as returned by OpenSSL.
      */
-    if (ok) {
-        if (!(ok = ssl_callback_SSLVerify_CRL(ok, ctx, conn))) {
-            errnum = X509_STORE_CTX_get_error(ctx);
-        }
-        
+    if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
+        X509_STORE_CTX_set_error(ctx, -1);
+    }
+
 #ifndef OPENSSL_NO_OCSP
+    /*
+     * Perform OCSP-based revocation checks
+     */
+    if (ok && sc->server->ocsp_enabled) {
         /* 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. */
-        if (ok && ssl_verify_error_is_optional(errnum)
-            && sc->server->ocsp_enabled) {
+        if (ssl_verify_error_is_optional(errnum)) {
             X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
             errnum = X509_V_ERR_APPLICATION_VERIFICATION;
             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn,
@@ -1484,52 +1498,28 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
                           "if issuer has not been verified "
                           "(optional_no_ca configured)");
             ok = FALSE;
-        }
-
-        if (ok && sc->server->ocsp_enabled) {
+        } else {
             ok = modssl_verify_ocsp(ctx, sc, s, conn, conn->pool);
             if (!ok) {
                 errnum = X509_STORE_CTX_get_error(ctx);
             }
         }
-#endif
     }
+#endif
 
     /*
      * If we already know it's not ok, log the real reason
      */
     if (!ok) {
-        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn,
-                      "Certificate Verification: Error (%d): %s",
-                      errnum, X509_verify_cert_error_string(errnum));
         if (APLOGcinfo(conn)) {
-            X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
-            BIO *bio = BIO_new(BIO_s_mem());
-            char buff[512]; /* should be plenty */
-            int n;
-
-            if (bio) {
-                BIO_puts(bio, "Failed certificate: subject: '");
-                X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0,
-                                   XN_FLAG_ONELINE);
-
-                BIO_puts(bio, "', issuer: '");
-                X509_NAME_print_ex(bio, X509_get_issuer_name(cert), 0,
-                                XN_FLAG_ONELINE);
-
-                BIO_puts(bio, "', notbefore: ");
-                ASN1_UTCTIME_print(bio, X509_get_notBefore(cert));
-
-                BIO_puts(bio, ", notafter: ");
-                ASN1_UTCTIME_print(bio, X509_get_notAfter(cert));
-
-                n = BIO_read(bio, buff, sizeof(buff) - 1);
-                BIO_free(bio);
-                if (n > 0) {
-                    buff[n] = '\0';
-                    ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, conn, "%s", buff);
-                }
-            }
+            ssl_log_cxerror(SSLLOG_MARK, APLOG_INFO, 0, conn,
+                            X509_STORE_CTX_get_current_cert(ctx),
+                            "Certificate Verification: Error (%d): %s",
+                            errnum, X509_verify_cert_error_string(errnum));
+        } else {
+            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn,
+                          "Certificate Verification: Error (%d): %s",
+                          errnum, X509_verify_cert_error_string(errnum));
         }
 
         if (sslconn->client_cert) {
@@ -1569,195 +1559,6 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
     return ok;
 }
 
-int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c)
-{
-    SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
-                                          SSL_get_ex_data_X509_STORE_CTX_idx());
-    request_rec *r      = (request_rec *)SSL_get_app_data2(ssl);
-    server_rec *s       = r ? r->server : mySrvFromConn(c);
-    SSLSrvConfigRec *sc = mySrvConfig(s);
-    SSLConnRec *sslconn = myConnConfig(c);
-    modssl_ctx_t *mctx  = myCtxConfig(sslconn, sc);
-    X509_OBJECT obj;
-    X509_NAME *subject, *issuer;
-    X509 *cert;
-    X509_CRL *crl;
-    EVP_PKEY *pubkey;
-    int i, n, rc;
-
-    /*
-     * Unless a revocation store for CRLs was created we
-     * cannot do any CRL-based verification, of course.
-     */
-    if (!mctx->crl) {
-        return ok;
-    }
-
-    /*
-     * Determine certificate ingredients in advance
-     */
-    cert    = X509_STORE_CTX_get_current_cert(ctx);
-    subject = X509_get_subject_name(cert);
-    issuer  = X509_get_issuer_name(cert);
-
-    /*
-     * OpenSSL provides the general mechanism to deal with CRLs but does not
-     * use them automatically when verifying certificates, so we do it
-     * explicitly here. We will check the CRL for the currently checked
-     * certificate, if there is such a CRL in the store.
-     *
-     * We come through this procedure for each certificate in the certificate
-     * chain, starting with the root-CA's certificate. At each step we've to
-     * both verify the signature on the CRL (to make sure it's a valid CRL)
-     * and its revocation list (to make sure the current certificate isn't
-     * revoked).  But because to check the signature on the CRL we need the
-     * public key of the issuing CA certificate (which was already processed
-     * one round before), we've a little problem. But we can both solve it and
-     * at the same time optimize the processing by using the following
-     * verification scheme (idea and code snippets borrowed from the GLOBUS
-     * project):
-     *
-     * 1. We'll check the signature of a CRL in each step when we find a CRL
-     *    through the _subject_ name of the current certificate. This CRL
-     *    itself will be needed the first time in the next round, of course.
-     *    But we do the signature processing one round before this where the
-     *    public key of the CA is available.
-     *
-     * 2. We'll check the revocation list of a CRL in each step when
-     *    we find a CRL through the _issuer_ name of the current certificate.
-     *    This CRLs signature was then already verified one round before.
-     *
-     * This verification scheme allows a CA to revoke its own certificate as
-     * well, of course.
-     */
-
-    /*
-     * Try to retrieve a CRL corresponding to the _subject_ of
-     * the current certificate in order to verify its integrity.
-     */
-    memset((char *)&obj, 0, sizeof(obj));
-    rc = SSL_X509_STORE_lookup(mctx->crl,
-                               X509_LU_CRL, subject, &obj);
-    crl = obj.data.crl;
-
-    if ((rc > 0) && crl) {
-        /*
-         * Log information about CRL
-         * (A little bit complicated because of ASN.1 and BIOs...)
-         */
-        if (APLOGtrace1(s)) {
-            char buff[512]; /* should be plenty */
-            BIO *bio = BIO_new(BIO_s_mem());
-
-            BIO_printf(bio, "CA CRL: Issuer: ");
-            X509_NAME_print(bio, issuer, 0);
-
-            BIO_printf(bio, ", lastUpdate: ");
-            ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl));
-
-            BIO_printf(bio, ", nextUpdate: ");
-            ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl));
-
-            n = BIO_read(bio, buff, sizeof(buff) - 1);
-            buff[n] = '\0';
-
-            BIO_free(bio);
-
-            ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "%s", buff);
-        }
-
-        /*
-         * Verify the signature on this CRL
-         */
-        pubkey = X509_get_pubkey(cert);
-        rc = X509_CRL_verify(crl, pubkey);
-        if (pubkey)
-            EVP_PKEY_free(pubkey);
-        if (rc <= 0) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
-                         "Invalid signature on CRL");
-
-            X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
-            X509_OBJECT_free_contents(&obj);
-            return FALSE;
-        }
-
-        /*
-         * Check date of CRL to make sure it's not expired
-         */
-        i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl));
-
-        if (i == 0) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
-                         "Found CRL has invalid nextUpdate field");
-
-            X509_STORE_CTX_set_error(ctx,
-                                     X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
-            X509_OBJECT_free_contents(&obj);
-
-            return FALSE;
-        }
-
-        if (i < 0) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
-                         "Found CRL is expired - "
-                         "revoking all certificates until you get updated CRL");
-
-            X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED);
-            X509_OBJECT_free_contents(&obj);
-
-            return FALSE;
-        }
-
-        X509_OBJECT_free_contents(&obj);
-    }
-
-    /*
-     * Try to retrieve a CRL corresponding to the _issuer_ of
-     * the current certificate in order to check for revocation.
-     */
-    memset((char *)&obj, 0, sizeof(obj));
-    rc = SSL_X509_STORE_lookup(mctx->crl,
-                               X509_LU_CRL, issuer, &obj);
-
-    crl = obj.data.crl;
-    if ((rc > 0) && crl) {
-        /*
-         * Check if the current certificate is revoked by this CRL
-         */
-        n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
-
-        for (i = 0; i < n; i++) {
-            X509_REVOKED *revoked =
-                sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
-
-            ASN1_INTEGER *sn = revoked->serialNumber;
-
-            if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) {
-                if (APLOGdebug(s)) {
-                    char *cp = X509_NAME_oneline(issuer, NULL, 0);
-                    long serial = ASN1_INTEGER_get(sn);
-
-                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-                                 "Certificate with serial %ld (0x%lX) "
-                                 "revoked per CRL from issuer %s",
-                                 serial, serial, cp);
-                    OPENSSL_free(cp);
-                }
-
-                X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
-                X509_OBJECT_free_contents(&obj);
-
-                return FALSE;
-            }
-        }
-
-        X509_OBJECT_free_contents(&obj);
-    }
-
-    return ok;
-}
-
 #define SSLPROXY_CERT_CB_LOG_FMT \
    "Proxy client certificate callback: (%s) "
 
index 479663516f8d849000e4f1f556551714d27b0e74..fd9ff2bd95c55d9c1876085bb1af09ec0c881e52 100644 (file)
@@ -325,6 +325,16 @@ typedef enum {
     || (errnum == X509_V_ERR_CERT_UNTRUSTED) \
     || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE))
 
+/**
+  * CRL checking modes
+  */
+typedef enum {
+    SSL_CRLCHECK_UNSET = UNSET,
+    SSL_CRLCHECK_NONE  = 0,
+    SSL_CRLCHECK_LEAF  = 1,
+    SSL_CRLCHECK_CHAIN = 2
+} ssl_crlcheck_t;
+
 /**
  * Define the SSL pass phrase dialog types
  */
@@ -565,9 +575,9 @@ typedef struct {
     const char  *pkcs7;
 
     /** certificate revocation list */
-    const char  *crl_path;
-    const char  *crl_file;
-    X509_STORE  *crl;
+    const char    *crl_path;
+    const char    *crl_file;
+    ssl_crlcheck_t crl_check_mode;
 
 #ifdef HAVE_OCSP_STAPLING
     /** OCSP stapling options */
@@ -665,6 +675,7 @@ const char  *ssl_cmd_SSLCADNRequestPath(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCADNRequestFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCARevocationPath(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *);
+const char  *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag);
 const char  *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *);
@@ -688,6 +699,7 @@ const char  *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *, void *, const char *
 const char  *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *, void *, const char *);
+const char  *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *, void *, const char *);
index 33a0e327bb832e6649b1b261d57c420a0e911b8d..f9ae5ee38a1c17dbed8df08168eb8f2c24f63fef 100644 (file)
@@ -182,55 +182,6 @@ int SSL_smart_shutdown(SSL *ssl)
     return rc;
 }
 
-/*  _________________________________________________________________
-**
-**  Certificate Revocation List (CRL) Storage
-**  _________________________________________________________________
-*/
-
-X509_STORE *SSL_X509_STORE_create(char *cpFile, char *cpPath)
-{
-    X509_STORE *pStore;
-    X509_LOOKUP *pLookup;
-    int rv = 1;
-
-    ERR_clear_error();
-
-    if (cpFile == NULL && cpPath == NULL)
-        return NULL;
-    if ((pStore = X509_STORE_new()) == NULL)
-        return NULL;
-    if (cpFile != NULL) {
-        pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file());
-        if (pLookup == NULL) {
-            X509_STORE_free(pStore);
-            return NULL;
-        }
-        rv = X509_LOOKUP_load_file(pLookup, cpFile, X509_FILETYPE_PEM);
-    }
-    if (cpPath != NULL && rv == 1) {
-        pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir());
-        if (pLookup == NULL) {
-            X509_STORE_free(pStore);
-            return NULL;
-        }
-        rv = X509_LOOKUP_add_dir(pLookup, cpPath, X509_FILETYPE_PEM);
-    }
-    return rv == 1 ? pStore : NULL;
-}
-
-int SSL_X509_STORE_lookup(X509_STORE *pStore, int nType,
-                          X509_NAME *pName, X509_OBJECT *pObj)
-{
-    X509_STORE_CTX pStoreCtx;
-    int rc;
-
-    X509_STORE_CTX_init(&pStoreCtx, pStore, NULL, NULL);
-    rc = X509_STORE_get_by_subject(&pStoreCtx, nType, pName, pObj);
-    X509_STORE_CTX_cleanup(&pStoreCtx);
-    return rc;
-}
-
 /*  _________________________________________________________________
 **
 **  Cipher Suite Spec String Creation
index d5a89908593449b4d7d3bc09423f81d929699210..d2f995de2b451fd1a2cdc6ea219ff48c6b919d1d 100644 (file)
@@ -63,8 +63,6 @@ void        SSL_set_app_data2(SSL *, void *);
 X509       *SSL_read_X509(char *, X509 **, pem_password_cb *);
 EVP_PKEY   *SSL_read_PrivateKey(char *, EVP_PKEY **, pem_password_cb *, void *);
 int         SSL_smart_shutdown(SSL *ssl);
-X509_STORE *SSL_X509_STORE_create(char *, char *);
-int         SSL_X509_STORE_lookup(X509_STORE *, int, X509_NAME *, X509_OBJECT *);
 char       *SSL_make_ciphersuite(apr_pool_t *, SSL *);
 BOOL        SSL_X509_isSGC(X509 *);
 BOOL        SSL_X509_getBC(X509 *, int *, int *);