Browse files

Merge r1526168, r1527291, r1527294, r1527295, r1527926 from trunk:

Streamline ephemeral key handling:

- drop support for ephemeral RSA keys (only allowed/needed
  for export ciphers)

- drop pTmpKeys from the per-process SSLModConfigRec, and remove
  the temp key generation at startup (unnecessary for DHE/ECDHE)

- unconditionally disable null and export-grade ciphers by always
  prepending "!aNULL:!eNULL:!EXP:" to any cipher suite string

- do not configure per-connection SSL_tmp_*_callbacks, as it is
  sufficient to set them for the SSL_CTX

- set default curve for ECDHE at startup, obviating the need
  for a per-handshake callback, for the time being (and also
  configure SSL_OP_SINGLE_ECDH_USE, previously left out)

For additional background, see

Follow-up fixes for r1526168:

- drop SSL_TMP_KEY_* constants from ssl_private.h, too

- make sure we also disable aNULL, eNULL and EXP ciphers
  for per-directory SSLCipherSuite directives

- apply the same treatment to SSLProxyCipherSuite

Increase minimum required OpenSSL version to 0.9.8a (in preparation
for the next mod_ssl commit, which will rely on the get_rfcX_prime_Y
functions added in that release):

- remove obsolete #defines / macros

- in ssl_private.h, regroup definitions based on whether
  they depend on TLS extension support or not

- for ECC and SRP support, set HAVE_X and change the rather awkward
  #ifndef OPENSSL_NO_X lines accordingly

For the discussion prior to taking this step, see

Improve ephemeral key handling (companion to r1526168):

- allow to configure custom DHE or ECDHE parameters via the
  SSLCertificateFile directive, and adapt its documentation
  accordingly (addresses PR 49559)

- add standardized DH parameters from RFCs 2409 and 3526,
  use them based on the length of the certificate's RSA/DSA key,
  and add a FAQ entry for clients which limit DH support
  to 1024 bits (such as Java 7 and earlier)

- move ssl_dh_GetParamFromFile() from ssl_engine_dh.c to
  ssl_util_ssl.c, and add ssl_ec_GetParamFromFile()

- drop ssl_engine_dh.c from mod_ssl

For the standardized DH parameters, OpenSSL version 0.9.8a
or later is required, which was therefore made a new minimum
requirement in r1527294.

PR 55616 (add missing APLOGNO), part 2
Submitted by: kbrand
Reviewed/backported by: jim

git-svn-id: 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent a811da9 commit 3a14aba1b65f627ab27d2bd4bb10e779635b6bcc @jimjag jimjag committed Nov 15, 2013
@@ -2,6 +2,18 @@
Changes with Apache 2.4.7
+ *) mod_ssl: Improve handling of ephemeral DH and ECDH keys by
+ allowing custom parameters to be configured via SSLCertificateFile,
+ and by adding standardized DH parameters for 1024/2048/3072/4096 bits.
+ Unless custom parameters are configured, the standardized parameters
+ are applied based on the certificate's RSA/DSA key size. [Kaspar Brand]
+ *) mod_ssl, configure: Require OpenSSL 0.9.8a or later. [Kaspar Brand]
+ *) mod_ssl: drop support for export-grade ciphers with ephemeral RSA
+ keys, and unconditionally disable aNULL, eNULL and EXP ciphers
+ (not overridable via SSLCipherSuite). [Kaspar Brand]
*) Add experimental cmake-based build system for Windows. [Jeff Trawick,
Tom Donovan]
@@ -108,7 +108,6 @@ modules/ ................ Manditory and Add-In Apache stock modules
mod_ssl.c ............... main source file containing API structures
mod_ssl.h ............... common header file of mod_ssl
ssl_engine_config.c ..... module configuration handling
- ssl_engine_dh.c ......... DSA/DH support
ssl_engine_init.c ....... module initialization
ssl_engine_io.c ......... I/O support
ssl_engine_kernel.c ..... SSL engine kernel
@@ -97,28 +97,6 @@ RELEASE SHOWSTOPPERS:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * mod_ssl: improve ephemeral key handling - in particular, support DH params
- with more than 1024 bits, and allow custom configuration. For a detailed
- list of the changes, see the text at the beginning of the 2.4.x patch.
- trunk patches:
- 2.4.x patch:
- +1: kbrand, jim, jorton
- [wrowe comments] is it possible to split the patch into 'accepted for 2.2'
- which is straightforward to review (and commit seperately) from those
- features 'new to 2.4'? I think that would attract the necessary eyeballs.
- kbrand: not sure what exactly "accepted for 2.2" would mean here, basically
- all these changes are enhancements, not bug fixes (and only the
- latter I would consider for backporting to a "legacy branch").
- Identifying those bullets at the beginning of the 2.4.x patch
- which you consider "accepted 2.2" might help / give further clues,
- though it should be noted that mod_ssl in 2.4 has drifted
- away from 2.2 quite somewhat meanwhile (think of the removal of
- ssl_toolkit_compat.h e.g.).
* easy proposals to synch 2.4.x and trunk
- mod_proxy.c: Eclipse code analysis warning
- mod_mime_magic.c: Reduce stack usage by 3k
@@ -728,6 +728,15 @@ prefixes are:</p>
<li><code>-</code>: remove cipher from list (can be added later again)</li>
<li><code>!</code>: kill cipher from list completely (can <strong>not</strong> be added later again)</li>
+<title><code>aNULL</code>, <code>eNULL</code> and <code>EXP</code>
+ciphers are always disabled</title>
+<p>Beginning with version 2.4.7, null and export-grade
+ciphers are always disabled, as mod_ssl unconditionally prepends any supplied
+cipher suite string with <code>!aNULL:!eNULL:!EXP:</code> at initialization.</p>
<p>A simpler way to look at all of this is to use the ``<code>openssl ciphers
-v</code>'' command which provides a nice way to successively create the
correct <em>cipher-spec</em> string. The default <em>cipher-spec</em> string
@@ -799,12 +808,33 @@ SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW
-This directive points to the PEM-encoded Certificate file for the server and
-optionally also to the corresponding RSA or DSA Private Key file for it
-(contained in the same file). If the contained Private Key is encrypted the
-Pass Phrase dialog is forced at startup time. This directive can be used up to
-three times (referencing different filenames) when both a RSA, a DSA, and an
-ECC based server certificate is used in parallel.</p>
+This directive points to the file with the PEM-encoded certificate,
+optionally also the corresponding private key, and - beginning with
+version 2.4.7 - DH parameters and/or an EC curve name
+for ephemeral keys (as generated by <code>openssl dhparam</code>
+and <code>openssl ecparam</code>, respectively). If the private key
+is encrypted, the pass phrase dialog is forced at startup time.
+This directive can be used up to three times (referencing different filenames)
+when both an RSA, a DSA, and an ECC based server certificate is used in
+parallel. Note that DH and ECDH parameters are only read from the first
+<directive>SSLCertificateFile</directive> directive.</p>
+<title>DH parameter interoperability with primes > 1024 bit</title>
+Beginning with version 2.4.7, mod_ssl makes use of
+standardized DH parameters with prime lengths of 2048, 3072 and 4096 bits
+(from <a href="">RFC 3526</a>), and hands
+them out to clients based on the length of the certificate's RSA/DSA key.
+With Java-based clients in particular (Java 7 or earlier), this may lead
+to handshake failures - see this
+<a href="../ssl/ssl_faq.html#javadh">FAQ answer</a> for working around
+such issues.
<highlight language="config">
SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
@@ -519,6 +519,8 @@ Does this mean the username/password is being sent unencrypted?</a></li>
<li><a href="#msie">Why do I get I/O errors when connecting via
HTTPS to an Apache+mod_ssl server with Microsoft Internet Explorer
+<li><a href="#srp">How do I enable TLS-SRP?</a></li>
+<li><a href="#javadh">Why do I get handshake failures with Java-based clients when using a certificate with more than 1024 bits?</a></li>
<section id="random"><title>Why do I get lots of random SSL protocol
@@ -740,6 +742,37 @@ SetEnvIf User-Agent "MSIE [2-5]" \
+<section id="javadh"><title>Why do I get handshake failures with Java-based clients when using a certificate with more than 1024 bits?</title>
+ <p>Beginning with version 2.4.7,
+ <module>mod_ssl</module> will use DH parameters which include primes
+ with lengths of more than 1024 bits. Java 7 and earlier limit their
+ support for DH prime sizes to a maximum of 1024 bits, however.</p>
+ <p>If your Java-based client aborts with exceptions such as
+ <code>java.lang.RuntimeException: Could not generate DH keypair</code> and
+ <code> Prime size must be
+ multiple of 64, and can only range from 512 to 1024 (inclusive)</code>,
+ and httpd logs <code>tlsv1 alert internal error (SSL alert number 80)</code>
+ (at <directive module="core">LogLevel</directive> <code>info</code>
+ or higher), you can either rearrange mod_ssl's cipher list with
+ <directive module="mod_ssl">SSLCipherSuite</directive>
+ (possibly in conjunction with <directive module="mod_ssl">SSLHonorCipherOrder</directive>),
+ or you can use the <directive module="mod_ssl">SSLCertificateFile</directive>
+ directive to configure custom DH parameters with a 1024-bit prime, which
+ will always have precedence over any of the built-in DH parameters.</p>
+ <p>To generate custom DH parameters, use the <code>openssl dhparam</code>
+ command. Alternatively, you can append the following standard 1024-bit DH
+ parameters from <a href="">RFC 2409</a>,
+ section 6.2 to the respective
+ <directive module="ssl">SSLCertificateFile</directive> file:</p>
+ <example><pre>-----BEGIN DH PARAMETERS-----
+-----END DH PARAMETERS-----</pre></example>
<!-- /aboutssl -->
@@ -20,7 +20,6 @@ dnl # list of module object files
mod_ssl.lo dnl
ssl_engine_config.lo dnl
-ssl_engine_dh.lo dnl
ssl_engine_init.lo dnl
ssl_engine_io.lo dnl
ssl_engine_kernel.lo dnl
@@ -148,7 +148,7 @@ static const command_rec ssl_config_cmds[] = {
"Strict SNI virtual host checking")
+#ifdef HAVE_SRP
"SRP verifier file "
"('/path/to/file' - created by srptool)")
@@ -471,15 +471,6 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
sslconn->ssl = ssl;
- /*
- * Configure callbacks for SSL connection
- */
- SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA);
- SSL_set_tmp_dh_callback(ssl, ssl_callback_TmpDH);
-#ifndef OPENSSL_NO_EC
- SSL_set_tmp_ecdh_callback(ssl, ssl_callback_TmpECDH);
SSL_set_verify_result(ssl, X509_V_OK);
ssl_io_filter_init(c, r, ssl);
@@ -112,10 +112,6 @@ SOURCE=.\ssl_engine_config.c
# End Source File
# Begin Source File
-# End Source File
-# Begin Source File
# End Source File
# Begin Source File
@@ -75,8 +75,6 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s)
mc->stapling_mutex = NULL;
- memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
@@ -150,7 +148,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx)
mctx->stapling_force_url = NULL;
+#ifdef HAVE_SRP
mctx->srp_vfile = NULL;
mctx->srp_unknown_user_seed = NULL;
mctx->srp_vbase = NULL;
@@ -208,7 +206,7 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET;
sc->proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET;
sc->proxy_ssl_check_peer_name = SSL_ENABLED_UNSET;
sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
#ifdef HAVE_FIPS
@@ -282,7 +280,7 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
cfgMerge(stapling_force_url, NULL);
+#ifdef HAVE_SRP
@@ -338,7 +336,7 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET);
cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET);
cfgMerge(proxy_ssl_check_peer_name, SSL_ENABLED_UNSET);
cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
#ifdef HAVE_FIPS
@@ -645,6 +643,9 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+ /* always disable null and export ciphers */
+ arg = apr_pstrcat(cmd->pool, "!aNULL:!eNULL:!EXP:", arg, NULL);
if (cmd->path) {
dc->szCipherSuite = arg;
@@ -1384,6 +1385,9 @@ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ /* always disable null and export ciphers */
+ arg = apr_pstrcat(cmd->pool, "!aNULL:!eNULL:!EXP:", arg, NULL);
sc->proxy->auth.cipher_suite = arg;
return NULL;
@@ -1645,7 +1649,7 @@ const char *ssl_cmd_SSLProxyCheckPeerName(cmd_parms *cmd, void *dcfg, int flag)
const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag)
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
@@ -1804,7 +1808,7 @@ const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg,
+#ifdef HAVE_SRP
const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg,
const char *arg)
@@ -1828,7 +1832,7 @@ const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg,
return NULL;
-#endif /* OPENSSL_NO_SRP */
+#endif /* HAVE_SRP */
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
Oops, something went wrong.

0 comments on commit 3a14aba

Please sign in to comment.