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 <code>chain</code> or <code>leaf</code>, -CRLs <em>must</em> 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 */