From: Kaspar Brand Date: Mon, 6 Jan 2014 06:02:42 +0000 (+0000) Subject: Backport r1421323, r1534754, r1546693, r1555464 from trunk: X-Git-Tag: 2.4.8~271 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=876b00fcbe7d4a27065ec1eada56d352e990eee0;p=apache Backport r1421323, r1534754, r1546693, r1555464 from trunk: Add support for OpenSSL configuration commands by introducing the SSLOpenSSLConfCmd directive. Proposed by: kbrand Reviewed by: drh, trawick git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1555683 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 628586dc63..893a63df0f 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.8 + *) mod_ssl: Add support for OpenSSL configuration commands by introducing + the SSLOpenSSLConfCmd directive. [Stephen Henson, Kaspar Brand] + *) mod_proxy: Remove (never documented) syntax which is equivalent to . [Christophe Jaillet] diff --git a/STATUS b/STATUS index 6d4d6b61d9..8b223aca98 100644 --- a/STATUS +++ b/STATUS @@ -98,14 +98,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: Add support for OpenSSL configuration commands (SSLOpenSSLConfCmd) - trunk patches: https://svn.apache.org/r1421323 - https://svn.apache.org/r1534754 - https://svn.apache.org/r1546693 - https://svn.apache.org/r1555464 - 2.4.x patch: https://people.apache.org/~kbrand/mod_ssl-2.4.x-confcmd.diff - +1: kbrand, drh, trawick - * mod_cache_disk hangs on windows reading from closed files trunk patch: http://svn.apache.org/r1547845 2.4.x patch: trunk works diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index 84dbe5159a..d0a16d6909 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -2535,5 +2535,43 @@ CRIME attack).

+ +SSLOpenSSLConfCmd +Configure OpenSSL parameters through its SSL_CONF API +SSLOpenSSLConfCmd command-name command-value +server config +virtual host +Available in httpd 2.4.8 and later, if using OpenSSL 1.0.2 or later + + +

This directive exposes OpenSSL's SSL_CONF API to mod_ssl, +allowing a flexible configuration of OpenSSL parameters without the need +of implementing additional mod_ssl directives when new +features are added to OpenSSL.

+ +

The set of available SSLOpenSSLConfCmd commands +depends on the OpenSSL version being used for mod_ssl +(at least version 1.0.2 is required). For a list of supported command +names, see the section Supported configuration file commands in the +SSL_CONF_cmd(3) manual page for OpenSSL.

+ +

Some of the SSLOpenSSLConfCmd commands can be used +as an alternative to existing directives (such as +SSLCipherSuite or +SSLProtocol), +though it should be noted that the syntax / allowable values for the parameters +may sometimes differ.

+ +Examples + +SSLOpenSSLConfCmd Options -SessionTicket,ServerPreference +SSLOpenSSLConfCmd ECDHParameters brainpoolP256r1 +SSLOpenSSLConfCmd ServerInfoFile /usr/local/apache2/conf/server-info.pem +SSLOpenSSLConfCmd Protocol "-ALL, TLSv1.2" +SSLOpenSSLConfCmd SignatureAlgorithms RSA+SHA384:ECDSA+SHA256 + + +
+
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index f0499405d8..2afca28194 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -266,6 +266,11 @@ static const command_rec ssl_config_cmds[] = { "SSL stapling option to Force the OCSP Stapling URL") #endif +#ifdef HAVE_SSL_CONF_CMD + SSL_CMD_SRV(OpenSSLConfCmd, TAKE2, + "OpenSSL configuration command") +#endif + /* Deprecated directives. */ AP_INIT_RAW_ARGS("SSLLog", ap_set_deprecated, NULL, OR_ALL, "SSLLog directive is no longer supported - use ErrorLog."), diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index f519151eda..cf003e98b7 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -98,7 +98,7 @@ BOOL ssl_config_global_isfixed(SSLModConfigRec *mc) ** _________________________________________________________________ */ -static void modssl_ctx_init(modssl_ctx_t *mctx) +static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) { mctx->sc = NULL; /* set during module init */ @@ -153,6 +153,13 @@ static void modssl_ctx_init(modssl_ctx_t *mctx) mctx->srp_unknown_user_seed = NULL; mctx->srp_vbase = NULL; #endif +#ifdef HAVE_SSL_CONF_CMD + mctx->ssl_ctx_config = SSL_CONF_CTX_new(); + SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_FILE); + SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_SERVER); + SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_CERTIFICATE); + mctx->ssl_ctx_param = apr_array_make(p, 5, sizeof(ssl_ctx_param_t)); +#endif } static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc, @@ -162,7 +169,7 @@ static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc, mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy)); - modssl_ctx_init(mctx); + modssl_ctx_init(mctx, p); mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp)); @@ -180,7 +187,7 @@ static void modssl_ctx_init_server(SSLSrvConfigRec *sc, mctx = sc->server = apr_palloc(p, sizeof(*sc->server)); - modssl_ctx_init(mctx); + modssl_ctx_init(mctx, p); mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks)); @@ -241,7 +248,8 @@ void *ssl_config_server_create(apr_pool_t *p, server_rec *s) #define cfgMergeBool(el) cfgMerge(el, UNSET) #define cfgMergeInt(el) cfgMerge(el, UNSET) -static void modssl_ctx_cfg_merge(modssl_ctx_t *base, +static void modssl_ctx_cfg_merge(apr_pool_t *p, + modssl_ctx_t *base, modssl_ctx_t *add, modssl_ctx_t *mrg) { @@ -284,26 +292,32 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base, cfgMergeString(srp_vfile); cfgMergeString(srp_unknown_user_seed); #endif + +#ifdef HAVE_SSL_CONF_CMD + cfgMergeArray(ssl_ctx_param); +#endif } -static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base, +static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p, + modssl_ctx_t *base, modssl_ctx_t *add, modssl_ctx_t *mrg) { - modssl_ctx_cfg_merge(base, add, mrg); + modssl_ctx_cfg_merge(p, base, add, mrg); cfgMergeString(pkp->cert_file); cfgMergeString(pkp->cert_path); cfgMergeString(pkp->ca_cert_file); } -static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base, +static void modssl_ctx_cfg_merge_server(apr_pool_t *p, + modssl_ctx_t *base, modssl_ctx_t *add, modssl_ctx_t *mrg) { int i; - modssl_ctx_cfg_merge(base, add, mrg); + modssl_ctx_cfg_merge(p, base, add, mrg); for (i = 0; i < SSL_AIDX_MAX; i++) { cfgMergeString(pks->cert_files[i]); @@ -346,9 +360,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) cfgMergeBool(compression); #endif - modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); + modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy); - modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server); + modssl_ctx_cfg_merge_server(p, base->server, add->server, mrg->server); return mrg; } @@ -1808,6 +1822,38 @@ const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg, #endif /* HAVE_OCSP_STAPLING */ +#ifdef HAVE_SSL_CONF_CMD +const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg, + const char *arg1, const char *arg2) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config; + int value_type = SSL_CONF_cmd_value_type(cctx, arg1); + const char *err; + ssl_ctx_param_t *param; + + if (value_type == SSL_CONF_TYPE_UNKNOWN) { + return apr_psprintf(cmd->pool, + "'%s': invalid OpenSSL configuration command", + arg1); + } + + if (value_type == SSL_CONF_TYPE_FILE) { + if ((err = ssl_cmd_check_file(cmd, &arg2))) + return err; + } + else if (value_type == SSL_CONF_TYPE_DIR) { + if ((err = ssl_cmd_check_dir(cmd, &arg2))) + return err; + } + + param = apr_array_push(sc->server->ssl_ctx_param); + param->name = arg1; + param->value = arg2; + return NULL; +} +#endif + #ifdef HAVE_SRP const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index f6e010de7a..59a466b6d4 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -1287,12 +1287,62 @@ static void ssl_init_server_ctx(server_rec *s, apr_pool_t *ptemp, SSLSrvConfigRec *sc) { +#ifdef HAVE_SSL_CONF_CMD + ssl_ctx_param_t *param = (ssl_ctx_param_t *)sc->server->ssl_ctx_param->elts; + SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config; + int i; +#endif + ssl_init_server_check(s, p, ptemp, sc->server); ssl_init_ctx(s, p, ptemp, sc->server); ssl_init_server_certs(s, p, ptemp, sc->server); +#ifdef HAVE_SSL_CONF_CMD + SSL_CONF_CTX_set_ssl_ctx(cctx, sc->server->ssl_ctx); + for (i = 0; i < sc->server->ssl_ctx_param->nelts; i++, param++) { + ERR_clear_error(); + if (SSL_CONF_cmd(cctx, param->name, param->value) <= 0) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02407) + "\"SSLOpenSSLConfCmd %s %s\" failed for %s", + param->name, param->value, sc->vhost_id); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + ssl_die(s); + } else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02556) + "\"SSLOpenSSLConfCmd %s %s\" applied to %s", + param->name, param->value, sc->vhost_id); + } +#ifdef HAVE_OCSP_STAPLING + /* + * Special case: if OCSP stapling is enabled, and a certificate + * has been loaded via "SSLOpenSSLConfCmd Certificate ...", then + * we also need to call ssl_stapling_init_cert here. + */ + if ((sc->server->stapling_enabled == TRUE) && + !strcasecmp(param->name, "Certificate")) { + X509 *cert = SSL_CTX_get0_certificate(sc->server->ssl_ctx); + if (!cert || !ssl_stapling_init_cert(s, sc->server, cert)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02571) + "Unable to configure certificate loaded " + "from %s for %s for stapling", + param->value, sc->vhost_id); + } + } +#endif + } + + if (SSL_CONF_CTX_finish(cctx) == 0) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02547) + "SSL_CONF_CTX_finish() failed"); + SSL_CONF_CTX_free(cctx); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); + ssl_die(s); + } + SSL_CONF_CTX_free(cctx); +#endif + #ifdef HAVE_TLS_SESSION_TICKETS ssl_init_ticket_key(s, p, ptemp, sc->server); #endif diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 4ea924f339..af873ec634 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -131,6 +131,10 @@ #define HAVE_TLSV1_X #endif +#if defined(SSL_CONF_FLAG_FILE) +#define HAVE_SSL_CONF_CMD +#endif + /** * The following features all depend on TLS extension support. * Within this block, check again for features (not version numbers). @@ -577,6 +581,13 @@ typedef struct { } modssl_ticket_key_t; #endif +#ifdef HAVE_SSL_CONF_CMD +typedef struct { + const char *name; + const char *value; +} ssl_ctx_param_t; +#endif + typedef struct SSLSrvConfigRec SSLSrvConfigRec; typedef struct { @@ -633,7 +644,10 @@ typedef struct { long ocsp_resptime_skew; long ocsp_resp_maxage; apr_interval_time_t ocsp_responder_timeout; - +#ifdef HAVE_SSL_CONF_CMD + SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */ + apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */ +#endif } modssl_ctx_t; struct SSLSrvConfigRec { @@ -754,6 +768,10 @@ const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg); const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag); +#ifdef HAVE_SSL_CONF_CMD +const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg, const char *arg1, const char *arg2); +#endif + #ifdef HAVE_SRP const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, const char *arg); const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg, const char *arg);