From: Yann Ylavic
Date: Fri, 11 Mar 2016 13:51:17 +0000 (+0000)
Subject: mod_ssl: Add no_crl_for_cert_ok flag to SSLCARevocationCheck directive
X-Git-Tag: 2.5.0-alpha~1915
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bafafe600b4363724d382904cd01da6877788cdc;p=apache
mod_ssl: Add no_crl_for_cert_ok flag to SSLCARevocationCheck directive
to opt-in previous behaviour (2.2) with CRLs verification when checking
certificate(s) with no corresponding CRL.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1734561 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/CHANGES b/CHANGES
index 0871f4851c..0c00524d05 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.0
+ *) mod_ssl: Add "no_crl_for_cert_ok" flag to SSLCARevocationCheck directive
+ to opt-in previous behaviour (2.2) with CRLs verification when checking
+ certificate(s) with no corresponding CRL. [Yann Ylavic]
+
*) mod_proxy_http2: rescheduling of requests that have not been processed
by the backend when receiving a GOAWAY frame before done.
[Stefan Eissing]
diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml
index 9bac1ebca0..8b22b35e03 100644
--- a/docs/manual/mod/mod_ssl.xml
+++ b/docs/manual/mod/mod_ssl.xml
@@ -1205,10 +1205,12 @@ SSLCARevocationFile /usr/local/apache2/conf/ssl.crl/ca-bundle-client.crl
SSLCARevocationCheck
Enable CRL-based revocation checking
-SSLCARevocationCheck chain|leaf|none
+SSLCARevocationCheck chain|leaf|none flags
SSLCARevocationCheck none
server config
virtual host
+Optional flags available in httpd 2.5-dev or
+later
@@ -1219,25 +1221,38 @@ configured. When set to chain
(recommended setting),
CRL checks are applied to all certificates in the chain, while setting it to
leaf
limits the checks to the end-entity cert.
-
-When set to chain
or leaf
,
-CRLs must be available for successful validation
-
-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
-SSLCARevocationFile
-or SSLCARevocationPath.
-With the introduction of this directive, the behavior has been changed:
-when checking is enabled, CRLs must be present for the validation
-to succeed - otherwise it will fail with an
-"unable to get certificate CRL"
error.
-
-
+The available flags are:
+
+no_crl_for_cert_ok
+
+ Prior to version 2.3.15, CRL checking in mod_ssl also succeeded when
+ no CRL(s) for the checked certificate(s) were found in any of the locations
+ configured with SSLCARevocationFile
+ or SSLCARevocationPath.
+
+
+ With the introduction of SSLCARevocationFile,
+ the behavior has been changed: by default with chain
or
+ leaf
, CRLs must be present for the
+ validation to succeed - otherwise it will fail with an
+ "unable to get certificate CRL"
error.
+
+
+ The flag no_crl_for_cert_ok
allows to restore
+ previous behaviour.
+
+
+
Example
SSLCARevocationCheck chain
+Compatibility with versions 2.2
+
+SSLCARevocationCheck chain no_crl_for_cert_ok
+
+
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index cff0d0c420..a19e24f18f 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -124,7 +124,7 @@ 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_CMD_SRV(CARevocationCheck, RAW_ARGS,
"SSL CA Certificate Revocation List (CRL) checking mode")
SSL_CMD_ALL(VerifyClient, TAKE1,
"SSL Client verify type "
@@ -202,7 +202,7 @@ 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_CMD_SRV(ProxyCARevocationCheck, RAW_ARGS,
"SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1,
"SSL Proxy: file containing client certificates "
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index 1b872629cb..d2c2b30de6 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -122,6 +122,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
mctx->crl_path = NULL;
mctx->crl_file = NULL;
mctx->crl_check_mode = SSL_CRLCHECK_UNSET;
+ mctx->crl_check_flags = UNSET;
mctx->auth.ca_cert_path = NULL;
mctx->auth.ca_cert_file = NULL;
@@ -272,6 +273,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
cfgMerge(crl_path, NULL);
cfgMerge(crl_file, NULL);
cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET);
+ cfgMergeInt(crl_check_flags);
cfgMergeString(auth.ca_cert_path);
cfgMergeString(auth.ca_cert_file);
@@ -998,8 +1000,29 @@ const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd,
const char *arg)
{
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err, *w;
- return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mode);
+ w = ap_getword_conf(cmd->temp_pool, &arg);
+ err = ssl_cmd_crlcheck_parse(cmd, w, &sc->server->crl_check_mode);
+ if (err || sc->server->crl_check_mode == SSL_CRLCHECK_NONE) {
+ return err;
+ }
+
+ if (sc->server->crl_check_flags == UNSET) {
+ sc->server->crl_check_flags = 0;
+ }
+ while (*arg) {
+ w = ap_getword_conf(cmd->temp_pool, &arg);
+ if (strcEQ(w, "no_crl_for_cert_ok")) {
+ sc->server->crl_check_flags |= MODSSL_CCF_NO_CRL_FOR_CERT_OK;
+ }
+ else {
+ return apr_pstrcat(cmd->temp_pool, cmd->cmd->name,
+ ": Invalid flag '", w, "'",
+ NULL);
+ }
+ }
+ return NULL;
}
static const char *ssl_cmd_verify_parse(cmd_parms *parms,
@@ -1512,8 +1535,29 @@ const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd,
const char *arg)
{
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err, *w;
- return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mode);
+ w = ap_getword_conf(cmd->temp_pool, &arg);
+ err = ssl_cmd_crlcheck_parse(cmd, w, &sc->proxy->crl_check_mode);
+ if (err || sc->proxy->crl_check_mode == SSL_CRLCHECK_NONE) {
+ return err;
+ }
+
+ if (sc->proxy->crl_check_flags == UNSET) {
+ sc->proxy->crl_check_flags = 0;
+ }
+ while (*arg) {
+ w = ap_getword_conf(cmd->temp_pool, &arg);
+ if (strcEQ(w, "no_crl_for_cert_ok")) {
+ sc->proxy->crl_check_flags |= MODSSL_CCF_NO_CRL_FOR_CERT_OK;
+ }
+ else {
+ return apr_pstrcat(cmd->temp_pool, cmd->cmd->name,
+ ": Invalid flag '", w, "'",
+ NULL);
+ }
+ }
+ return NULL;
}
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index e8a9487d50..ad15d89fcd 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -229,6 +229,13 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
sc->fips = FALSE;
}
#endif
+
+ if (sc->server && sc->server->crl_check_flags == UNSET) {
+ sc->server->crl_check_flags = 0;
+ }
+ if (sc->proxy && sc->proxy->crl_check_flags == UNSET) {
+ sc->proxy->crl_check_flags = 0;
+ }
}
#if APR_HAS_THREADS
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 8f50785c88..952c92e6e0 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -1581,10 +1581,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), APLOGNO(02275)
"Certificate Verification, depth %d, "
- "CRL checking mode: %s", errdepth,
+ "CRL checking mode: %s (%x)", errdepth,
mctx->crl_check_mode == SSL_CRLCHECK_CHAIN ?
"chain" : (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ?
- "leaf" : "none"));
+ "leaf" : "none"),
+ mctx->crl_check_flags);
/*
* Check for optionally acceptable non-verifiable issuer situation
@@ -1633,6 +1634,12 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
X509_STORE_CTX_set_error(ctx, -1);
}
+ if (!ok && errnum == X509_V_ERR_UNABLE_TO_GET_CRL
+ && (sc->server->crl_check_flags & MODSSL_CCF_NO_CRL_FOR_CERT_OK)) {
+ errnum = X509_V_OK;
+ ok = TRUE;
+ }
+
#ifndef OPENSSL_NO_OCSP
/*
* Perform OCSP-based revocation checks
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 7ba9903b98..690e8476bb 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -338,6 +338,7 @@ typedef enum {
/**
* CRL checking modes
*/
+#define MODSSL_CCF_NO_CRL_FOR_CERT_OK (1 << 0)
typedef enum {
SSL_CRLCHECK_UNSET = UNSET,
SSL_CRLCHECK_NONE = 0,
@@ -601,6 +602,7 @@ typedef struct {
const char *crl_path;
const char *crl_file;
ssl_crlcheck_t crl_check_mode;
+ int crl_check_flags;
#ifdef HAVE_OCSP_STAPLING
/** OCSP stapling options */