You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2018/03/26 14:03:36 UTC
svn commit: r1827767 - /httpd/httpd/patches/2.4.x/ssl-policy.patch
Author: icing
Date: Mon Mar 26 14:03:35 2018
New Revision: 1827767
URL: http://svn.apache.org/viewvc?rev=1827767&view=rev
Log:
backport patch for SSLPolicy directive
Added:
httpd/httpd/patches/2.4.x/ssl-policy.patch
Added: httpd/httpd/patches/2.4.x/ssl-policy.patch
URL: http://svn.apache.org/viewvc/httpd/httpd/patches/2.4.x/ssl-policy.patch?rev=1827767&view=auto
==============================================================================
--- httpd/httpd/patches/2.4.x/ssl-policy.patch (added)
+++ httpd/httpd/patches/2.4.x/ssl-policy.patch Mon Mar 26 14:03:35 2018
@@ -0,0 +1,928 @@
+Index: CHANGES
+===================================================================
+--- CHANGES (revision 1827760)
++++ CHANGES (working copy)
+@@ -1,6 +1,10 @@
+ -*- coding: utf-8 -*-
+ Changes with Apache 2.4.34
+
++ *) mod_ssl: Add new SSLPolicy directive with flavours "modern",
++ "intermedate" and "old" as defined by Mozilla Security.
++ [Stefan Eissing]
++
+ *) core: On ECBDIC platforms, some errors related to oversized headers
+ may be misreported or be logged as ASCII escapes. PR62200
+ [Hank Ibell <hwibell gmail.com>]
+Index: docs/manual/mod/mod_ssl.xml
+===================================================================
+--- docs/manual/mod/mod_ssl.xml (revision 1827760)
++++ docs/manual/mod/mod_ssl.xml (working copy)
+@@ -2820,4 +2820,39 @@
+ </usage>
+ </directivesynopsis>
+
++<directivesynopsis>
++<name>SSLPolicy</name>
++<description>Apply a SSLPolicy by name</description>
++<syntax>SSLPolicy <em>name</em></syntax>
++<contextlist><context>server config</context>
++<context>virtual host</context></contextlist>
++<compatibility>Available in httpd 2.4.30 and later</compatibility>
++
++<usage>
++<p>This directive applies the set of SSL* directives defined
++under 'name' (see <directive type="section">SSLPolicyDefine</directive>) as the <em>base</em>
++settings in the current context. Apache comes with the following pre-defined policies from
++Mozilla, the makers of the Firefox browser
++(<a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations">see here
++for a detailed description by them.</a>):
++</p>
++<ul>
++ <li><code>modern</code>: recommended when your server is accessible on the open Internet. Works with all modern browsers, but old devices might be unable to connect.</li>
++ <li><code>intermediate</code>: the fallback if you need to support old (but not very old) clients.</li>
++ <li><code>old</code>: when you need to give Windows XP/Internet Explorer 6 access. The last resort.</li>
++</ul>
++<p>SSLPolicy applies configuration settings in place, meaning previous values are
++overwritten. Configuration directives following an SSLPolicy may overwrite it.
++</p>
++
++<p>You can check the detailed description of all defined policies via the command line:</p>
++<example><title>List all Defined Policies</title>
++<highlight language="sh">
++httpd -t -D DUMP_SSL_POLICIES
++</highlight>
++</example>
++
++</usage>
++</directivesynopsis>
++
+ </modulesynopsis>
+Index: modules/ssl/mod_ssl.c
+===================================================================
+--- modules/ssl/mod_ssl.c (revision 1827760)
++++ modules/ssl/mod_ssl.c (working copy)
+@@ -308,6 +308,8 @@
+ AP_INIT_RAW_ARGS("SSLLogLevel", ap_set_deprecated, NULL, OR_ALL,
+ "SSLLogLevel directive is no longer supported - use LogLevel."),
+
++ AP_INIT_TAKE1("SSLPolicy", ssl_cmd_SSLPolicyApply, NULL, RSRC_CONF,
++ "Apply the SSL* (not the SSLProxy*) settings from the policy with the given name."),
+ AP_END_CMD
+ };
+
+Index: modules/ssl/mod_ssl.dsp
+===================================================================
+--- modules/ssl/mod_ssl.dsp (revision 1827760)
++++ modules/ssl/mod_ssl.dsp (working copy)
+@@ -180,6 +180,10 @@
+ # End Source File
+ # Begin Source File
+
++SOURCE=.\ssl_policies.h
++# End Source File
++# Begin Source File
++
+ SOURCE=.\ssl_util_ssl.h
+ # End Source File
+ # Begin Source File
+Index: modules/ssl/ssl_engine_config.c
+===================================================================
+--- modules/ssl/ssl_engine_config.c (revision 1827760)
++++ modules/ssl/ssl_engine_config.c (working copy)
+@@ -27,6 +27,7 @@
+ damned if you don't.''
+ -- Unknown */
+ #include "ssl_private.h"
++#include "ssl_policies.h"
+ #include "util_mutex.h"
+ #include "ap_provider.h"
+
+@@ -89,7 +90,7 @@
+
+ BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
+ {
+- return mc->bFixed;
++ return mc && mc->bFixed;
+ }
+
+ /* _________________________________________________________________
+@@ -526,6 +527,130 @@
+ modssl_ctx_cfg_merge_proxy(p, base->proxy, conf->proxy, conf->proxy);
+ }
+
++/* _________________________________________________________________
++**
++** Policy handling
++** _________________________________________________________________
++*/
++
++static void add_policy(apr_hash_t *policies, apr_pool_t *p, const char *name,
++ int protocols, const char *ciphers,
++ int honor_order, int compression, int session_tickets)
++{
++ SSLPolicyRec *policy;
++
++ policy = apr_pcalloc(p, sizeof(*policy));
++ policy->name = name;
++ policy->sc = ssl_config_server_new(p);
++
++ if (protocols || ciphers) {
++ policy->sc->server->protocol_set = 1;
++ policy->sc->server->protocol = protocols;
++ }
++
++ if (ciphers) {
++ policy->sc->server->auth.cipher_suite = ciphers;
++ }
++
++#ifndef OPENSSL_NO_COMP
++ policy->sc->compression = compression ? TRUE : FALSE;
++#endif
++ policy->sc->session_tickets = session_tickets ? TRUE : FALSE;
++
++ apr_hash_set(policies, policy->name, APR_HASH_KEY_STRING, policy);
++}
++
++static apr_hash_t *get_policies(apr_pool_t *p, int create)
++{
++ apr_hash_t *policies;
++ void *vp;
++
++ apr_pool_userdata_get(&vp, SSL_MOD_POLICIES_KEY, p);
++ if (vp) {
++ return vp; /* reused for lifetime of the pool */
++ }
++ if (create) {
++ policies = apr_hash_make(p);
++
++#if SSL_POLICY_MODERN
++ add_policy(policies, p, "modern",
++ SSL_POLICY_MODERN_PROTOCOLS,
++ SSL_POLICY_MODERN_CIPHERS,
++ SSL_POLICY_HONOR_ORDER,
++ SSL_POLICY_COMPRESSION,
++ SSL_POLICY_SESSION_TICKETS);
++#endif
++#if SSL_POLICY_INTERMEDIATE
++ add_policy(policies, p, "intermediate",
++ SSL_POLICY_INTERMEDIATE_PROTOCOLS,
++ SSL_POLICY_INTERMEDIATE_CIPHERS,
++ SSL_POLICY_HONOR_ORDER,
++ SSL_POLICY_COMPRESSION,
++ SSL_POLICY_SESSION_TICKETS);
++#endif
++#if SSL_POLICY_OLD
++ add_policy(policies, p, "old",
++ SSL_POLICY_OLD_PROTOCOLS,
++ SSL_POLICY_OLD_CIPHERS,
++ SSL_POLICY_HONOR_ORDER,
++ SSL_POLICY_COMPRESSION,
++ SSL_POLICY_SESSION_TICKETS);
++#endif
++
++ apr_pool_userdata_set(policies, SSL_MOD_POLICIES_KEY,
++ apr_pool_cleanup_null, p);
++ return policies;
++ }
++ return NULL;
++}
++
++static int policy_collect_names(void *baton, const void *key, apr_ssize_t klen, const void *val)
++{
++ apr_array_header_t *names = baton;
++ APR_ARRAY_PUSH(names, const char *) = (const char*)key;
++ return 1;
++}
++
++static int qstrcmp(const void *v1, const void *v2)
++{
++ return strcmp(*(const char**)v1, *(const char**)v2);
++}
++
++static apr_array_header_t *get_policy_names(apr_pool_t *p, int create)
++{
++ apr_array_header_t *names = apr_array_make(p, 10, sizeof(const char*));
++ apr_hash_t *policies = get_policies(p, create);
++
++ if (policies) {
++ apr_hash_do(policy_collect_names, names, policies);
++ qsort(names->elts, names->nelts, sizeof(const char*), qstrcmp);
++ }
++ return names;
++}
++
++SSLPolicyRec *ssl_policy_lookup(apr_pool_t *pool, const char *name)
++{
++ apr_hash_t *policies = get_policies(pool, 1);
++ return apr_hash_get(policies, name, APR_HASH_KEY_STRING);
++}
++
++const char *ssl_cmd_SSLPolicyApply(cmd_parms *cmd, void *mconfig, const char *arg)
++{
++ SSLSrvConfigRec *mrg, *sc = mySrvConfig(cmd->server);
++ SSLPolicyRec *policy;
++
++ policy = ssl_policy_lookup(cmd->pool, arg);
++ if (policy) {
++ mrg = ssl_config_server_merge(cmd->pool, policy->sc, sc);
++ /* apply in place */
++ memcpy(sc, mrg, sizeof(*sc));
++ return NULL;
++ }
++ return apr_pstrcat(cmd->pool,
++ "An SSLPolicy with the name '", arg,
++ "' does not exist", NULL);
++}
++
+ /*
+ * Configuration functions for particular directives
+ */
+@@ -2034,34 +2159,404 @@
+ return NULL;
+ }
+
++static void ssl_srv_dump(SSLSrvConfigRec *sc, apr_pool_t *p,
++ apr_file_t *out, const char *indent, const char **psep);
++static void ssl_policy_dump(SSLPolicyRec *policy, apr_pool_t *p,
++ apr_file_t *out, const char *indent);
++
+ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
+ {
+ apr_file_t *out = NULL;
+- if (!ap_exists_config_define("DUMP_CERTS")) {
++ if (ap_exists_config_define("DUMP_CERTS")) {
++ apr_file_open_stdout(&out, pconf);
++ apr_file_printf(out, "Server certificates:\n");
++
++ /* Dump the filenames of all configured server certificates to
++ * stdout. */
++ while (s) {
++ SSLSrvConfigRec *sc = mySrvConfig(s);
++
++ if (sc && sc->server && sc->server->pks) {
++ modssl_pk_server_t *const pks = sc->server->pks;
++ int i;
++
++ for (i = 0; (i < pks->cert_files->nelts) &&
++ APR_ARRAY_IDX(pks->cert_files, i, const char *);
++ i++) {
++ apr_file_printf(out, " %s\n",
++ APR_ARRAY_IDX(pks->cert_files,
++ i, const char *));
++ }
++ }
++
++ s = s->next;
++ }
+ return;
+ }
+- apr_file_open_stdout(&out, pconf);
+- apr_file_printf(out, "Server certificates:\n");
+
+- /* Dump the filenames of all configured server certificates to
+- * stdout. */
+- while (s) {
+- SSLSrvConfigRec *sc = mySrvConfig(s);
++ if (ap_exists_config_define("DUMP_SSL_POLICIES")) {
++ apr_array_header_t *names = get_policy_names(pconf, 1);
++ SSLPolicyRec *policy;
++ const char *name, *sep = "";
++ int i;
++
++ apr_file_open_stdout(&out, pconf);
++ apr_file_printf(out, "SSLPolicies: {");
++ for (i = 0; i < names->nelts; ++i) {
++ name = APR_ARRAY_IDX(names, i, const char*);
++ policy = ssl_policy_lookup(pconf, name);
++ if (policy) {
++ apr_file_printf(out, "%s\n \"%s\": {", sep, name);
++ sep = ", ";
++ ssl_policy_dump(policy, pconf, out, " ");
++ apr_file_printf(out, "\n }");
++ }
++ }
++ apr_file_printf(out, "\n}\n");
++ return;
++ }
++}
+
+- if (sc && sc->server && sc->server->pks) {
+- modssl_pk_server_t *const pks = sc->server->pks;
+- int i;
++/* _________________________________________________________________
++**
++** Dump Config Data
++** _________________________________________________________________
++*/
+
+- for (i = 0; (i < pks->cert_files->nelts) &&
+- APR_ARRAY_IDX(pks->cert_files, i, const char *);
+- i++) {
+- apr_file_printf(out, " %s\n",
+- APR_ARRAY_IDX(pks->cert_files,
+- i, const char *));
++static const char *json_quote(const char *s, apr_pool_t *p)
++{
++ const char *src, *dq = s;
++ int n = 0;
++
++ while ((dq = ap_strchr_c(dq, '\"'))) {
++ ++n;
++ ++dq;
++ }
++ if (n > 0) {
++ char *dst, c;
++ src = s;
++ s = dst = apr_pcalloc(p, strlen(s) + n + 1);
++ while ((c = *src++)) {
++ if (c == '\"') {
++ *dst++ = '\\';
+ }
++ *dst++ = c;
+ }
++ }
++ return s;
++}
+
+- s = s->next;
++static void val_str_dump(apr_file_t *out, const char *key, const char *val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val) {
++ /* TODO: JSON quite string val */
++ apr_file_printf(out, "%s\n%s\"%s\": \"%s\"", *psep, indent, key, json_quote(val, p));
++ *psep = ", ";
+ }
++}
+
++static void val_str_array_dump(apr_file_t *out, const char *key, apr_array_header_t *val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val && val->nelts > 0) {
++ const char *s;
++ int i;
++
++ for (i = 0; i < val->nelts; ++i) {
++ s = APR_ARRAY_IDX(val, i, const char*);
++ val_str_dump(out, key, s, p, indent, psep);
++ }
++ }
+ }
++
++static void val_long_dump(apr_file_t *out, const char *key, long val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val != UNSET) {
++ apr_file_printf(out, "%s\n%s\"%s\": %ld", *psep, indent, key, val);
++ *psep = ", ";
++ }
++}
++
++static void val_itime_dump(apr_file_t *out, const char *key, apr_interval_time_t val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val != UNSET) {
++ apr_file_printf(out, "%s\n%s\"%s\": %f", *psep, indent, key,
++ ((double)val/APR_USEC_PER_SEC));
++ *psep = ", ";
++ }
++}
++
++static void val_onoff_dump(apr_file_t *out, const char *key, BOOL val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val != UNSET) {
++ val_str_dump(out, key, val? "on" : "off", p, indent, psep);
++ }
++}
++
++static void val_uri_dump(apr_file_t *out, const char *key, apr_uri_t *val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val) {
++ val_str_dump(out, key, apr_uri_unparse(p, val, 0), p, indent, psep);
++ }
++}
++
++static void val_verify_dump(apr_file_t *out, const char *key, ssl_verify_t mode,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ switch (mode) {
++ case SSL_CVERIFY_NONE:
++ val_str_dump(out, key, "none", p, indent, psep);
++ return;
++ case SSL_CVERIFY_OPTIONAL:
++ val_str_dump(out, key, "optional", p, indent, psep);
++ return;
++ case SSL_CVERIFY_REQUIRE:
++ val_str_dump(out, key, "require", p, indent, psep);
++ return;
++ case SSL_CVERIFY_OPTIONAL_NO_CA:
++ val_str_dump(out, key, "optional_no_ca", p, indent, psep);
++ return;
++ default:
++ return;
++ }
++}
++
++static void val_enabled_dump(apr_file_t *out, const char *key, ssl_enabled_t val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ switch (val) {
++ case SSL_ENABLED_FALSE:
++ val_str_dump(out, key, "off", p, indent, psep);
++ return;
++ case SSL_ENABLED_TRUE:
++ val_str_dump(out, key, "on", p, indent, psep);
++ return;
++ case SSL_ENABLED_OPTIONAL:
++ val_str_dump(out, key, "optional", p, indent, psep);
++ return;
++ default:
++ return;
++ }
++}
++
++static void val_pphrase_dump(apr_file_t *out, const char *key,
++ ssl_pphrase_t pphrase_type, const char *path,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ switch (pphrase_type) {
++ case SSL_PPTYPE_BUILTIN:
++ val_str_dump(out, key, "builtin", p, indent, psep);
++ return;
++ case SSL_PPTYPE_FILTER:
++ val_str_dump(out, key, apr_pstrcat(p, "|", path, NULL), p, indent, psep);
++ return;
++ case SSL_PPTYPE_PIPE:
++ val_str_dump(out, key, apr_pstrcat(p, "exec:", path, NULL), p, indent, psep);
++ return;
++ default:
++ return;
++ }
++}
++
++static void val_crl_check_dump(apr_file_t *out, const char *key, int mask,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (mask != UNSET) {
++ if (mask == SSL_CRLCHECK_NONE) {
++ val_str_dump(out, key, "none", p, indent, psep);
++ }
++ else if (mask == SSL_CRLCHECK_LEAF) {
++ val_str_dump(out, key, "leaf", p, indent, psep);
++ }
++ else if (mask == SSL_CRLCHECK_CHAIN) {
++ val_str_dump(out, key, "chain", p, indent, psep);
++ }
++ else if (mask == (SSL_CRLCHECK_CHAIN|SSL_CRLCHECK_NO_CRL_FOR_CERT_OK)) {
++ val_str_dump(out, key, "chain no_crl_for_cert_ok", p, indent, psep);
++ }
++ else {
++ val_str_dump(out, key, "???", p, indent, psep);
++ }
++ }
++}
++
++static const char *protocol_str(ssl_proto_t proto, apr_pool_t *p)
++{
++ if (SSL_PROTOCOL_NONE == proto) {
++ return "none";
++ }
++ else if (SSL_PROTOCOL_ALL == proto) {
++ return "all";
++ }
++ else {
++ /* icing: I think it is nuts that we define our own IETF protocol constants
++ * only whent the linked *SSL lib supports them. */
++ apr_array_header_t *names = apr_array_make(p, 5, sizeof(const char*));
++ if ((1<<4) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+TLSv1.2";
++ }
++ if ((1<<3) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+TLSv1.1";
++ }
++ if ((1<<2) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+TLSv1.0";
++ }
++ if ((1<<1) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+SSLv3";
++ }
++ return apr_array_pstrcat(p, names, ' ');
++ }
++}
++
++#define DMP_STRING(k,v) \
++ val_str_dump(out, k, v, p, indent, psep)
++#define DMP_LONG(k,v) \
++ val_long_dump(out, k, v, p, indent, psep)
++#define DMP_ITIME(k,v) \
++ val_itime_dump(out, k, v, p, indent, psep)
++#define DMP_STRARR(k,v) \
++ val_str_array_dump(out, k, v, p, indent, psep)
++#define DMP_VERIFY(k,v) \
++ val_verify_dump(out, k, v, p, indent, psep)
++#define DMP_ON_OFF(k,v) \
++ val_onoff_dump(out, k, v, p, indent, psep)
++#define DMP_URI(k,v) \
++ val_uri_dump(out, k, v, p, indent, psep)
++#define DMP_CRLCHK(k,v) \
++ val_crl_check_dump(out, k, v, p, indent, psep)
++#define DMP_PHRASE(k,v, v2) \
++ val_pphrase_dump(out, k, v, v2, p, indent, psep)
++#define DMP_ENABLD(k,v) \
++ val_enabled_dump(out, k, v, p, indent, psep)
++#define DMP_OPTION(n,v) \
++ val_option_dump(out, "SSLOption", n, v, \
++ dc->nOptions, dc->nOptionsAdd, dc->nOptionsDel, p, indent, psep);
++
++static void modssl_auth_ctx_dump(modssl_auth_ctx_t *auth, apr_pool_t *p, int proxy,
++ apr_file_t *out, const char *indent, const char **psep)
++{
++ DMP_STRING(proxy? "SSLProxyCipherSuite" : "SSLCipherSuite", auth->cipher_suite);
++ DMP_VERIFY(proxy? "SSLProxyVerify" : "SSLVerifyClient", auth->verify_mode);
++ DMP_LONG( proxy? "SSLProxyVerify" : "SSLVerifyDepth", auth->verify_depth);
++ DMP_STRING(proxy? "SSLProxyCACertificateFile" : "SSLCACertificateFile", auth->ca_cert_file);
++ DMP_STRING(proxy? "SSLProxyCACertificatePath" : "SSLCACertificatePath", auth->ca_cert_path);
++}
++
++static void modssl_ctx_dump(modssl_ctx_t *ctx, apr_pool_t *p, int proxy,
++ apr_file_t *out, const char *indent, const char **psep)
++{
++#ifdef HAVE_SSL_CONF_CMD
++ int i;
++#endif
++
++ if (ctx->protocol_set) {
++ DMP_STRING(proxy? "SSLProxyProtocol" : "SSLProtocol", protocol_str(ctx->protocol, p));
++ }
++
++ modssl_auth_ctx_dump(&ctx->auth, p, proxy, out, indent, psep);
++
++ DMP_STRING(proxy? "SSLProxyCARevocationFile" : "SSLCARevocationFile", ctx->crl_file);
++ DMP_STRING(proxy? "SSLProxyCARevocationPath" : "SSLCARevocationPath", ctx->crl_path);
++ DMP_CRLCHK(proxy? "SSLProxyCARevocationCheck" : "SSLCARevocationCheck", ctx->crl_check_mask);
++ if (!proxy) {
++ DMP_PHRASE("SSLPassPhraseDialog", ctx->pphrase_dialog_type, ctx->pphrase_dialog_path);
++ if (ctx->pks) {
++ DMP_STRING("SSLCADNRequestFile", ctx->pks->ca_name_file);
++ DMP_STRING("SSLCADNRequestPath", ctx->pks->ca_name_path);
++ DMP_STRARR("SSLCertificateFile", ctx->pks->cert_files);
++ DMP_STRARR("SSLCertificateKeyFile", ctx->pks->key_files);
++ }
++#ifdef HAVE_OCSP_STAPLING
++ DMP_ON_OFF("SSLUseStapling", ctx->stapling_enabled);
++ DMP_LONG( "SSLStaplingResponseTimeSkew", ctx->stapling_resptime_skew);
++ DMP_LONG( "SSLStaplingResponseMaxAge", ctx->stapling_resp_maxage);
++ DMP_LONG( "SSLStaplingStandardCacheTimeout", ctx->stapling_cache_timeout);
++ DMP_ON_OFF("SSLStaplingReturnResponderErrors", ctx->stapling_return_errors);
++ DMP_ON_OFF("SSLStaplingFakeTryLater", ctx->stapling_fake_trylater);
++ DMP_LONG( "SSLStaplingErrorCacheTimeout", ctx->stapling_errcache_timeout);
++ DMP_ITIME( "SSLStaplingResponderTimeout", ctx->stapling_responder_timeout);
++ DMP_STRING("SSLStaplingForceURL", ctx->stapling_force_url);
++#endif /* if HAVE_OCSP_STAPLING */
++
++#ifdef HAVE_SRP
++ DMP_STRING("SSLSRPUnknownUserSeed", ctx->srp_unknown_user_seed);
++ DMP_STRING("SSLSRPVerifierFile", ctx->srp_vfile);
++#endif
++ DMP_ON_OFF("SSLOCSPEnable", ctx->ocsp_enabled);
++ DMP_ON_OFF("SSLOCSPOverrideResponder", ctx->ocsp_force_default);
++ DMP_STRING("SSLOCSPDefaultResponder", ctx->ocsp_responder);
++ DMP_LONG( "SSLOCSPResponseTimeSkew", ctx->ocsp_resptime_skew);
++ DMP_LONG( "SSLOCSPResponseMaxAge", ctx->ocsp_resp_maxage);
++ DMP_ITIME( "SSLOCSPResponderTimeout", ctx->ocsp_responder_timeout);
++ DMP_ON_OFF("SSLOCSPUseRequestNonce", ctx->ocsp_use_request_nonce);
++ DMP_URI( "SSLOCSPProxyURL", ctx->proxy_uri);
++ DMP_ON_OFF("SSLOCSPNoVerify", ctx->ocsp_noverify);
++ DMP_STRING("SSLOCSPResponderCertificateFile", ctx->ocsp_certs_file);
++
++#ifdef HAVE_SSL_CONF_CMD
++ if (ctx->ssl_ctx_param && ctx->ssl_ctx_param->nelts > 0) {
++ ssl_ctx_param_t *param = (ssl_ctx_param_t *)ctx->ssl_ctx_param->elts;
++ for (i = 0; i < ctx->ssl_ctx_param->nelts; ++i, ++param) {
++ apr_file_printf(out, "%s\n%s\"%s\": \"%s %s\"", *psep, indent,
++ "SSLOpenSSLConfCmd", json_quote(param->name, p),
++ json_quote(param->value, p));
++ *psep = ", ";
++ }
++ }
++#endif
++
++#ifdef HAVE_TLS_SESSION_TICKETS
++ if (ctx->ticket_key) {
++ DMP_STRING("SSLSessionTicketKeyFile", ctx->ticket_key->file_path);
++ }
++#endif
++ }
++ else { /* proxy */
++ if (ctx->pkp) {
++ DMP_STRING("SSLProxyMachineCertificateFile", ctx->pkp->cert_file);
++ DMP_STRING("SSLProxyMachineCertificatePath", ctx->pkp->cert_path);
++ DMP_STRING("SSLProxyMachineCertificateChainFile", ctx->pkp->ca_cert_file);
++ }
++ DMP_ON_OFF("SSLProxyCheckPeerCN", ctx->ssl_check_peer_cn);
++ DMP_ON_OFF("SSLProxyCheckPeerName", ctx->ssl_check_peer_cn);
++ DMP_ON_OFF("SSLProxyCheckPeerExpire", ctx->ssl_check_peer_expire);
++ }
++}
++
++static void ssl_srv_dump(SSLSrvConfigRec *sc, apr_pool_t *p,
++ apr_file_t *out, const char *indent, const char **psep)
++{
++ DMP_ENABLD("SSLEngine", sc->enabled);
++ DMP_ON_OFF("SSLHonorCipherOrder", sc->cipher_server_pref);
++
++#ifndef OPENSSL_NO_COMP
++ DMP_ON_OFF("SSLCompression", sc->compression);
++#endif
++
++ modssl_ctx_dump(sc->server, p, 0, out, indent, psep);
++
++ DMP_LONG( "SSLSessionCacheTimeout", sc->session_cache_timeout);
++ DMP_ON_OFF("SSLInsecureRenegotiation", sc->insecure_reneg);
++ DMP_ON_OFF("SSLStrictSNIVHostCheck", sc->strict_sni_vhost_check);
++#ifdef HAVE_FIPS
++ DMP_ON_OFF("SSLFIPS", sc->fips);
++#endif
++ DMP_ON_OFF("SSLSessionTickets", sc->session_tickets);
++}
++
++static void ssl_policy_dump(SSLPolicyRec *policy, apr_pool_t *p,
++ apr_file_t *out, const char *indent)
++{
++ const char *sep = "";
++ if (policy->sc) {
++ ssl_srv_dump(policy->sc, p, out, indent, &sep);
++ }
++}
++
++
++
+Index: modules/ssl/ssl_policies.h
+===================================================================
+--- modules/ssl/ssl_policies.h (nonexistent)
++++ modules/ssl/ssl_policies.h (working copy)
+@@ -0,0 +1,85 @@
++/* Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++/**
++ * @verbatim
++ _ _
++ _ __ ___ ___ __| | ___ ___| | mod_ssl
++ | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
++ | | | | | | (_) | (_| | \__ \__ \ |
++ |_| |_| |_|\___/ \__,_|___|___/___/_|
++ |_____|
++ @endverbatim
++ * @file ssl_policies.h
++ * @brief Additional Utility Functions for OpenSSL
++ *
++ * @defgroup MOD_SSL_UTIL Utilities
++ * @ingroup MOD_SSL
++ * @{
++ */
++
++#ifndef __SSL_POLICIES_H__
++#define __SSL_POLICIES_H__
++
++#define SSL_MOD_POLICIES_KEY "ssl_module_policies"
++
++#ifndef OPENSSL_NO_SSL3
++#define SSL_PROTOCOL_CONSTANTS_SSLV3 SSL_PROTOCOL_SSLV3
++#else
++#define SSL_PROTOCOL_CONSTANTS_SSLV3 0
++#endif
++
++#ifdef HAVE_TLSV1_X
++#define SSL_POLICY_LEGACY_PROTOCOLS \
++ (SSL_PROTOCOL_CONSTANTS_SSLV3|SSL_PROTOCOL_TLSV1|SSL_PROTOCOL_TLSV1_1)
++#endif
++
++/* Settings for all policies */
++#define SSL_POLICY_HONOR_ORDER 1
++#define SSL_POLICY_COMPRESSION 0
++#define SSL_POLICY_SESSION_TICKETS 0
++
++/**
++ * Define a core set of policies that are always there:
++ * - 'modern' from https://wiki.mozilla.org/Security/Server_Side_TLS
++ * - 'intermediate' from https://wiki.mozilla.org/Security/Server_Side_TLS
++ * - 'old' from https://wiki.mozilla.org/Security/Server_Side_TLS
++ * The JSON version can be retrieved here:
++ * https://statics.tls.security.mozilla.org/server-side-tls-conf.json
++ */
++
++#define SSL_POLICY_MOZILLA_VERSION 4.0
++
++#ifdef HAVE_TLSV1_X
++#define SSL_POLICY_MODERN 1
++#define SSL_POLICY_MODERN_CIPHERS "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
++#define SSL_POLICY_MODERN_PROTOCOLS SSL_PROTOCOL_TLSV1_2
++#else /* ifdef HAVE_TLSV1_X */
++#define SSL_POLICY_MODERN 0
++#endif /* ifdef HAVE_TLSV1_X, else part */
++
++#define SSL_POLICY_INTERMEDIATE 1
++#define SSL_POLICY_INTERMEDIATE_CIPHERS "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
++#define SSL_POLICY_INTERMEDIATE_PROTOCOLS (SSL_PROTOCOL_ALL & ~(SSL_PROTOCOL_CONSTANTS_SSLV3))
++
++#define SSL_POLICY_OLD 1
++#define SSL_POLICY_OLD_CIPHERS "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP"
++#define SSL_POLICY_OLD_PROTOCOLS SSL_PROTOCOL_ALL
++
++
++#endif /* __SSL_POLICIES_H__ */
++/** @} */
++
+Index: modules/ssl/ssl_policies.h.in
+===================================================================
+Index: modules/ssl/ssl_private.h
+===================================================================
+--- modules/ssl/ssl_private.h (revision 1827760)
++++ modules/ssl/ssl_private.h (working copy)
+@@ -770,6 +770,14 @@
+ BOOL proxy_post_config;
+ };
+
++typedef struct SSLPolicyRec SSLPolicyRec;
++struct SSLPolicyRec {
++ const char *name;
++ SSLSrvConfigRec *sc;
++};
++
++SSLPolicyRec *ssl_policy_lookup(apr_pool_t *pool, const char *name);
++
+ /**
+ * function prototypes
+ */
+@@ -787,6 +795,7 @@
+ void *ssl_config_perdir_merge(apr_pool_t *, void *, void *);
+ void ssl_config_proxy_merge(apr_pool_t *,
+ SSLDirConfigRec *, SSLDirConfigRec *);
++const char *ssl_cmd_SSLPolicyApply(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
+Index: modules/ssl/update_policies.py
+===================================================================
+--- modules/ssl/update_policies.py (nonexistent)
++++ modules/ssl/update_policies.py (working copy)
+@@ -0,0 +1,133 @@
++#!/usr/bin/env python
++
++import json
++import os
++import sys
++
++from httplib import HTTPSConnection
++
++# The location were Mozilla defines the *current* TLS Security in JSON format
++#
++MOZ_TLS_CONF_SERVER = "statics.tls.security.mozilla.org"
++MOZ_TLS_CONF_PATH = "/server-side-tls-conf.json"
++MOZ_TLS_CONF_URL = "https://%s%s" % (MOZ_TLS_CONF_SERVER, MOZ_TLS_CONF_PATH)
++
++# The version we already know. Accept nothing less.
++#
++MOZ_TLS_CONF_VERSION_MIN = 4.0
++
++# keys inside the JSON document
++#
++KEY_CONF = 'configurations'
++KEY_HREF = 'href'
++KEY_OSSL_CIPHERS = 'openssl_ciphersuites'
++KEY_TLS_VERSIONS = 'tls_versions'
++KEY_VERSION = 'version'
++
++# TLS Versions we know how to handle
++#
++TLS_VERSIONS = {
++ 'TLSv1.2' : "SSL_PROTOCOL_TLSV1_2",
++ 'TLSv1.1' : "SSL_PROTOCOL_TLSV1_1",
++ 'TLSv1' : "SSL_PROTOCOL_TLSV1",
++ 'SSLv3' : "SSL_PROTOCOL_CONSTANTS_SSLV3",
++}
++TLS_1_X_VERSIONS = [ 'TLSv1.2' ]
++
++# the Security configurations to extract
++POLICY_NAMES = [ 'modern', 'intermediate', 'old' ]
++
++
++def fail(msg):
++ sys.stderr.write(msg)
++ sys.exit(1)
++
++
++def proto_string(tls_version):
++ if tls_version in TLS_VERSIONS:
++ return TLS_VERSIONS[tls_version]
++ fail("Unknown TLS protocol '%s'" % tls_version)
++
++
++def proto_conf(tls_versions):
++ if len(TLS_VERSIONS) < len(tls_versions):
++ fail("more TLS versions used than we know: %s" % tls_versions)
++ if len(tls_versions) == 1:
++ return proto_string(tls_versions[0])
++ missing = []
++ for tls in TLS_VERSIONS:
++ if not tls in tls_versions:
++ missing.append(proto_string(tls))
++ if len(missing):
++ return "(SSL_PROTOCOL_ALL & ~(%s))" % "|".join(missing)
++ return "SSL_PROTOCOL_ALL"
++
++
++# return an #ifdef required for a policy or None
++#
++def required_ifdef(conf):
++ for tlsv in conf[KEY_TLS_VERSIONS]:
++ # if it has a non-1_X protocol, it works without OpenSSL 1.0.2
++ if not tlsv in TLS_1_X_VERSIONS:
++ return None
++ return "HAVE_TLSV1_X"
++
++
++def getPolicyDef():
++ c = HTTPSConnection(MOZ_TLS_CONF_SERVER)
++ c.request('GET', MOZ_TLS_CONF_PATH)
++ data = c.getresponse().read()
++ c.close()
++ return data
++
++
++def printPolicies(doc):
++ print "#define SSL_POLICY_MOZILLA_VERSION %s" % doc[KEY_VERSION]
++ print ""
++ for pname in POLICY_NAMES:
++ prefix = "SSL_POLICY_%s" % pname.upper()
++ if not pname in doc[KEY_CONF]:
++ vars[prefix] = 0
++ continue
++ p = doc[KEY_CONF][pname]
++
++ ifdef = required_ifdef(p)
++ if ifdef:
++ print "#ifdef %s" % ifdef
++
++ print "#define %s 1" % prefix
++ print "#define %s_CIPHERS \"%s\"" % (prefix, p[KEY_OSSL_CIPHERS])
++ print "#define %s_PROTOCOLS %s" % (prefix, proto_conf(p[KEY_TLS_VERSIONS]))
++
++ if ifdef:
++ print "#else /* ifdef %s */" % ifdef
++ print "#define %s 0" % prefix
++ print "#endif /* ifdef %s, else part */" % ifdef
++ print ""
++
++
++def main(argv):
++ data = getPolicyDef()
++ doc = json.loads(data)
++
++ if MOZ_TLS_CONF_URL != doc[KEY_HREF]:
++ fail("ERROR: Unexpected href in policy document: %s\n" % doc[KEY_HREF])
++ if doc[KEY_VERSION] < MOZ_TLS_CONF_VERSION_MIN:
++ fail("ERROR: Expected at least version %s, but policy document has %s\n" \
++ % (MOZ_TLS_CONF_VERSION_MIN, doc[KEY_VERSION]))
++
++ if 1 == len(argv):
++ printPolicies(doc)
++ elif 2 == len(argv):
++ with open(argv[1]) as f:
++ for line in f:
++ if line == "@MOZILLA_SECURITY_POLICIES@\n":
++ printPolicies(doc)
++ else:
++ sys.stdout.write(line)
++ else:
++ fail("usage: %s [file] \nDownload and print/replace the Mozilla TLS Security policies" % argv[0])
++
++
++if __name__ == "__main__":
++ main(sys.argv)
+Index: .
+===================================================================
+--- . (revision 1827760)
++++ . (working copy)
+
+Property changes on: .
+___________________________________________________________________
+Modified: svn:mergeinfo
+## -0,0 +0,1 ##
+ Merged /httpd/httpd/trunk:r1805186,1807709,1808244,1808335,1817381,1817894,1818030,1827561,1827760