Possible backport patch attached.

On Tue, May 5, 2015 at 3:14 PM, Yann Ylavic <ylavic....@gmail.com> wrote:
> I'd like to propose those 2.4.x CHANGES (r1542327+r1569005+r1542327)
> for backport to 2.2.x (in reverse order):
>
>   *) mod_ssl: Fix tmp DH parameter leak, adjust selection to prefer
>      larger keys and support up to 8192-bit keys.  [Ruediger Pluem,
>      Joe Orton]
>
>   *) 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]
>
> or at least partly.
>
> Beyond the (problematic?) requirement on OpenSSL 0.9.8a (discussed
> below), and what may look like an improvement only (first one), there
> are also security considerations:
> - ephemeral DH keys (for EDH ciphers) are currently limited to 1024
> bits in 2.2.x, so with 2048 bits or more certificates (quite
> recommended today), one should use its own dhparams for (E)DH ciphers,
> - ecparams loadable from certificate allow to configure the curve/key
> (plus SSL_CTX_set_ecdh_auto() when openssl >= 1.0.2),
> - export grade ciphers (removed from openssl's maintained versions)
> are still in use with default/general configurations (FREAK, ...).
>
> Regarding requirement on OpenSSL 0.9.8a (what's the actual requirement
> in 2.2.x?), if that's really a stopper, it only concerns the use of
> get_rfc{2409,3526}_prime_{1024,2048,..}() introduced in 0.9.8a
> (AFAICT), and we could eventually include (statically) that primes in
> the code for versions < 0.9.8a.
> But is there real 2.2.x user with OpenSSL < 0.9.8a?
>
> Also, those changes are effective since 2.4.7, and hence are quite
> largely tested already.
>
> Any pros/cons/comments before I try to resolve (hopefully) small conflicts?
>
> Regards,
> Yann.
Index: CHANGES
===================================================================
--- CHANGES	(revision 1677836)
+++ CHANGES	(working copy)
@@ -1,7 +1,15 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.2.30
 
+  *) 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.
 
+  *) 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]
 
 Changes with Apache 2.2.29
 
Index: docs/manual/mod/mod_ssl.xml
===================================================================
--- docs/manual/mod/mod_ssl.xml	(revision 1677836)
+++ docs/manual/mod/mod_ssl.xml	(working copy)
@@ -691,6 +691,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>
 </ul>
+
+<note>
+<title><code>aNULL</code>, <code>eNULL</code> and <code>EXP</code>
+ciphers are always disabled</title>
+<p>Beginning with version 2.2.30, 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>
+</note>
+
 <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
@@ -767,12 +776,34 @@ SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW
 
 <usage>
 <p>
-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.2.30 - 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.
+</p>
+<p>
+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>
+
+<note>
+<title>DH parameter interoperability with primes > 1024 bit</title>
+<p>
+Beginning with version 2.2.30, mod_ssl makes use of
+standardized DH parameters with prime lengths of 2048, 3072, 4096, 6144 and
+8192 bits (from <a href="http://www.ietf.org/rfc/rfc3526.txt";>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.
+</p>
+</note>
+
 <example><title>Example</title>
 SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
 </example>
Index: docs/manual/ssl/ssl_faq.xml
===================================================================
--- docs/manual/ssl/ssl_faq.xml	(revision 1677836)
+++ docs/manual/ssl/ssl_faq.xml	(working copy)
@@ -684,6 +684,7 @@ HTTPS to an Apache+mod_ssl server with Microsoft I
 <li><a href="#nn">Why do I get I/O errors, or the message "Netscape has 
 encountered bad data from the server", when connecting via
 HTTPS to an Apache+mod_ssl server with Netscape Navigator?</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>
 </ul>
 
 <section id="random"><title>Why do I get lots of random SSL protocol 
@@ -929,7 +930,39 @@ HTTPS to an Apache+mod_ssl server with Netscape Na
     implementation is correct, so when you encounter I/O errors with Netscape
     Navigator it is usually caused by the configured certificates.</p>
 </section>
+
+<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.2.30,
+    <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>java.security.InvalidAlgorithmParameterException: 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="http://www.ietf.org/rfc/rfc2409.txt";>RFC 2409</a>,
+    section 6.2 to the respective
+    <directive module="ssl">SSLCertificateFile</directive> file:</p>
+    <example><pre>-----BEGIN DH PARAMETERS-----
+MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
+Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
+/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
+-----END DH PARAMETERS-----</pre></example>
 </section>
+
+</section>
 <!-- /aboutssl -->
 
 <section id="support"><title>mod_ssl Support</title>
Index: modules/ssl/mod_ssl.c
===================================================================
--- modules/ssl/mod_ssl.c	(revision 1677836)
+++ modules/ssl/mod_ssl.c	(working copy)
@@ -436,15 +436,6 @@ int ssl_init_ssl_connection(conn_rec *c)
 
     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);
-#endif
-
     SSL_set_verify_result(ssl, X509_V_OK);
 
     ssl_io_filter_init(c, ssl);
Index: modules/ssl/ssl_engine_config.c
===================================================================
--- modules/ssl/ssl_engine_config.c	(revision 1677836)
+++ modules/ssl/ssl_engine_config.c	(working copy)
@@ -76,8 +76,6 @@ SSLModConfigRec *ssl_config_global_create(server_r
     mc->szCryptoDevice         = NULL;
 #endif
 
-    memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
-
     apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
                           apr_pool_cleanup_null,
                           pool);
@@ -680,6 +678,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;
     }
@@ -1382,6 +1383,9 @@ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms
 {
     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;
Index: modules/ssl/ssl_engine_dh.c
===================================================================
--- modules/ssl/ssl_engine_dh.c	(revision 1677836)
+++ modules/ssl/ssl_engine_dh.c	(working copy)
@@ -41,18 +41,6 @@
 **         0e:3e:30:06:80:a3:03:0c:6e:4c:37:57:d0:8f:70:
 **         e6:aa:87:10:33
 **     generator: 2 (0x2)
-** Diffie-Hellman-Parameters: (1024 bit)
-**     prime:
-**         00:d6:7d:e4:40:cb:bb:dc:19:36:d6:93:d3:4a:fd:
-**         0a:d5:0c:84:d2:39:a4:5f:52:0b:b8:81:74:cb:98:
-**         bc:e9:51:84:9f:91:2e:63:9c:72:fb:13:b4:b4:d7:
-**         17:7e:16:d5:5a:c1:79:ba:42:0b:2a:29:fe:32:4a:
-**         46:7a:63:5e:81:ff:59:01:37:7b:ed:dc:fd:33:16:
-**         8a:46:1a:ad:3b:72:da:e8:86:00:78:04:5b:07:a7:
-**         db:ca:78:74:08:7d:15:10:ea:9f:cc:9d:dd:33:05:
-**         07:dd:62:db:88:ae:aa:74:7d:e0:f4:d6:e2:bd:68:
-**         b0:e7:39:3e:0f:24:21:8e:b3
-**     generator: 2 (0x2)
 */
 
 static unsigned char dh512_p[] = {
@@ -73,6 +61,22 @@ static DH *get_dh512(void)
                                dh512_g, sizeof(dh512_g));
 }
 
+#if 0 /* Legacy (replaced by RFC2409's below) */
+/*
+** Diffie-Hellman-Parameters: (1024 bit)
+**     prime:
+**         00:d6:7d:e4:40:cb:bb:dc:19:36:d6:93:d3:4a:fd:
+**         0a:d5:0c:84:d2:39:a4:5f:52:0b:b8:81:74:cb:98:
+**         bc:e9:51:84:9f:91:2e:63:9c:72:fb:13:b4:b4:d7:
+**         17:7e:16:d5:5a:c1:79:ba:42:0b:2a:29:fe:32:4a:
+**         46:7a:63:5e:81:ff:59:01:37:7b:ed:dc:fd:33:16:
+**         8a:46:1a:ad:3b:72:da:e8:86:00:78:04:5b:07:a7:
+**         db:ca:78:74:08:7d:15:10:ea:9f:cc:9d:dd:33:05:
+**         07:dd:62:db:88:ae:aa:74:7d:e0:f4:d6:e2:bd:68:
+**         b0:e7:39:3e:0f:24:21:8e:b3
+**     generator: 2 (0x2)
+*/
+
 static unsigned char dh1024_p[] = {
     0xD6, 0x7D, 0xE4, 0x40, 0xCB, 0xBB, 0xDC, 0x19, 0x36, 0xD6, 0x93, 0xD3,
     0x4A, 0xFD, 0x0A, 0xD5, 0x0C, 0x84, 0xD2, 0x39, 0xA4, 0x5F, 0x52, 0x0B,
@@ -95,23 +99,581 @@ static DH *get_dh1024(void)
     return modssl_dh_configure(dh1024_p, sizeof(dh1024_p),
                                dh1024_g, sizeof(dh1024_g));
 }
+#endif
 
 /* ----END GENERATED SECTION---------- */
 
+/*
+ * "Second Oakley Default Group" from RFC2409, section 6.2.
+ *
+ * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ *
+ * RFC2409 specifies a generator of 2.
+ */
+static unsigned char dh1024_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static unsigned char dh1024_g[] = {
+    0x02,
+};
+
+static DH *get_dh1024(void)
+{
+    return modssl_dh_configure(dh1024_p, sizeof(dh1024_p),
+                               dh1024_g, sizeof(dh1024_g));
+}
+
+/*
+ * "2048-bit MODP Group" from RFC3526, Section 3.
+ *
+ * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+static unsigned char dh2048_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static unsigned char dh2048_g[] = {
+    0x02,
+};
+
+static DH *get_dh2048(void)
+{
+    return modssl_dh_configure(dh2048_p, sizeof(dh2048_p),
+                               dh2048_g, sizeof(dh2048_g));
+}
+
+/*
+ * "3072-bit MODP Group" from RFC3526, Section 4.
+ *
+ * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+static unsigned char dh3072_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static unsigned char dh3072_g[] = {
+    0x02,
+};
+
+static DH *get_dh3072(void)
+{
+    return modssl_dh_configure(dh3072_p, sizeof(dh3072_p),
+                               dh3072_g, sizeof(dh3072_g));
+}
+
+/*
+ * "4096-bit MODP Group" from RFC3526, Section 5.
+ *
+ * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+static unsigned char dh4096_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+    0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+    0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+    0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+    0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+    0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+    0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+    0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+    0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+    0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+    0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+    0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static unsigned char dh4096_g[] = {
+    0x02,
+};
+
+static DH *get_dh4096(void)
+{
+    return modssl_dh_configure(dh4096_p, sizeof(dh4096_p),
+                               dh4096_g, sizeof(dh4096_g));
+}
+
+/*
+ * "6144-bit MODP Group" from RFC3526, Section 6.
+ *
+ * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+static unsigned char dh6144_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+    0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+    0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+    0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+    0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+    0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+    0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+    0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+    0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+    0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+    0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+    0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+    0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+    0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+    0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+    0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+    0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+    0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+    0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+    0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+    0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+    0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+    0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+    0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+    0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+    0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+    0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+    0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+    0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+    0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+    0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+    0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+    0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+    0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+    0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+    0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+    0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+    0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+    0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+    0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+    0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+    0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+    0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+    0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static unsigned char dh6144_g[] = {
+    0x02,
+};
+
+static DH *get_dh6144(void)
+{
+    return modssl_dh_configure(dh6144_p, sizeof(dh6144_p),
+                               dh6144_g, sizeof(dh6144_g));
+}
+
+/*
+ * "8192-bit MODP Group" from RFC3526, Section 7.
+ *
+ * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+static unsigned char dh8192_p[] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+    0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+    0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+    0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+    0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+    0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+    0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+    0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+    0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+    0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+    0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+    0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+    0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+    0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+    0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+    0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+    0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+    0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+    0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+    0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+    0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+    0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+    0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+    0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+    0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+    0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+    0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+    0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+    0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+    0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+    0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+    0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+    0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+    0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+    0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+    0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+    0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+    0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+    0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+    0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+    0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+    0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+    0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+    0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59,
+    0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
+    0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C,
+    0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA,
+    0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
+    0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED,
+    0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66,
+    0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
+    0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78,
+    0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D,
+    0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
+    0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07,
+    0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7,
+    0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
+    0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD,
+    0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8,
+    0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
+    0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6,
+    0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D,
+    0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
+    0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1,
+    0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D,
+    0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
+    0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73,
+    0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68,
+    0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
+    0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7,
+    0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B,
+    0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
+    0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA,
+    0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF,
+    0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
+    0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static unsigned char dh8192_g[] = {
+    0x02,
+};
+
+static DH *get_dh8192(void)
+{
+    return modssl_dh_configure(dh8192_p, sizeof(dh8192_p),
+                               dh8192_g, sizeof(dh8192_g));
+}
+
+/* Storage and initialization for DH parameters. */
+static struct dhparam {
+    DH *(*const make)(void);          /* function to generate... */
+    DH *dh;                           /* ...this, used for keys.... */
+    const unsigned int min;           /* ...of length >= this. */
+} dhparams[] = {
+    { get_dh8192, NULL, 6145 },
+    { get_dh6144, NULL, 4097 },
+    { get_dh4096, NULL, 3073 },
+    { get_dh3072, NULL, 2049 },
+    { get_dh2048, NULL, 1025 },
+    { get_dh1024, NULL,  513 },
+    { get_dh512,  NULL,    0 }
+};
+
+int ssl_dh_InitParams(server_rec *s)
+{
+    unsigned n;
+
+    for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) {
+        const unsigned int bits =
+            dhparams[n].min ? (dhparams[n].min - 1) * 2 : 512;
+#ifdef HAVE_FIPS
+        if (bits < 1024 && FIPS_mode()) {
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                         "Init: Skipping generating temporary "
+                         "%ld bit DH parameters in FIPS mode", bits);
+            continue;
+        }
+#endif
+        dhparams[n].dh = dhparams[n].make();
+        if (!dhparams[n].dh) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                         "Init: Failed to generate temporary "
+                         "%d bit DH parameters", bits);
+            return !OK;
+        }
+    }
+    return OK;
+}
+
+void ssl_dh_FreeParams(void)
+{
+    unsigned n;
+
+    /* DH_free() is a noop for a NULL parameter, so these are harmless
+     * in the (unexpected) case where these variables are already
+     * NULL. */
+    for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) {
+        DH_free(dhparams[n].dh);
+        dhparams[n].dh = NULL;
+    }
+}
+
+/* Hand out the same DH structure though once generated as we leak
+ * memory otherwise and freeing the structure up after use would be
+ * hard to track and in fact is not needed at all as it is safe to
+ * use the same parameters over and over again security wise (in
+ * contrast to the keys itself) and code safe as the returned structure
+ * is duplicated by OpenSSL anyway. Hence no modification happens
+ * to our copy. */
 DH *ssl_dh_GetTmpParam(int nKeyLen)
 {
-    DH *dh;
+    unsigned n;
 
-    if (nKeyLen == 512)
-        dh = get_dh512();
-    else if (nKeyLen == 1024)
-        dh = get_dh1024();
-    else
-        dh = get_dh1024();
-    return dh;
+    for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++)
+        if (nKeyLen >= dhparams[n].min)
+            return dhparams[n].dh;
+        
+    return NULL; /* impossible to reach. */
 }
 
-DH *ssl_dh_GetParamFromFile(char *file)
+DH *ssl_dh_GetParamFromFile(const char *file)
 {
     DH *dh = NULL;
     BIO *bio;
@@ -127,6 +689,20 @@ DH *ssl_dh_GetTmpParam(int nKeyLen)
     return (dh);
 }
 
+#ifndef OPENSSL_NO_EC
+EC_GROUP *ssl_ec_GetParamFromFile(const char *file)
+{
+    EC_GROUP *group = NULL;
+    BIO *bio;
+
+    if ((bio = BIO_new_file(file, "r")) == NULL)
+        return NULL;
+    group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
+    BIO_free(bio);
+    return (group);
+}
+#endif
+
 /*
 =cut
 ##
Index: modules/ssl/ssl_engine_init.c
===================================================================
--- modules/ssl/ssl_engine_init.c	(revision 1677836)
+++ modules/ssl/ssl_engine_init.c	(working copy)
@@ -51,162 +51,7 @@ static void ssl_add_version_components(apr_pool_t
                  modver, AP_SERVER_BASEVERSION, incver);
 }
 
-
 /*
- * Handle the Temporary RSA Keys and DH Params
- */
-
-#define MODSSL_TMP_KEY_FREE(mc, type, idx) \
-    if (mc->pTmpKeys[idx]) { \
-        type##_free((type *)mc->pTmpKeys[idx]); \
-        mc->pTmpKeys[idx] = NULL; \
-    }
-
-#define MODSSL_TMP_KEYS_FREE(mc, type) \
-    MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \
-    MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024)
-
-static void ssl_tmp_keys_free(server_rec *s)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-
-    MODSSL_TMP_KEYS_FREE(mc, RSA);
-    MODSSL_TMP_KEYS_FREE(mc, DH);
-#ifndef OPENSSL_NO_EC
-    MODSSL_TMP_KEY_FREE(mc, EC_KEY, SSL_TMP_KEY_EC_256);
-#endif
-}
-
-static int ssl_tmp_key_init_rsa(server_rec *s,
-                                int bits, int idx)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-
-#ifdef HAVE_FIPS
-
-    if (FIPS_mode() && bits < 1024) {
-        mc->pTmpKeys[idx] = NULL;
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-                     "Init: Skipping generating temporary "
-                     "%d bit RSA private key in FIPS mode", bits);
-        return OK;
-    }
-
-#endif
-
-    if (!(mc->pTmpKeys[idx] =
-          RSA_generate_key(bits, RSA_F4, NULL, NULL)))
-    {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                     "Init: Failed to generate temporary "
-                     "%d bit RSA private key", bits);
-        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
-        return !OK;
-    }
-
-    return OK;
-}
-
-static int ssl_tmp_key_init_dh(server_rec *s,
-                               int bits, int idx)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-
-#ifdef HAVE_FIPS
-
-    if (FIPS_mode() && bits < 1024) {
-        mc->pTmpKeys[idx] = NULL;
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
-                     "Init: Skipping generating temporary "
-                     "%d bit DH parameters in FIPS mode", bits);
-        return OK;
-    }
-
-#endif
-
-    if (!(mc->pTmpKeys[idx] =
-          ssl_dh_GetTmpParam(bits)))
-    {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                     "Init: Failed to generate temporary "
-                     "%d bit DH parameters", bits);
-        return !OK;
-    }
-
-    return OK;
-}
-
-#ifndef OPENSSL_NO_EC
-static int ssl_tmp_key_init_ec(server_rec *s,
-                               int bits, int idx)
-{
-    SSLModConfigRec *mc = myModConfig(s);
-    EC_KEY *ecdh = NULL;
-
-    /* XXX: Are there any FIPS constraints we should enforce? */
-
-    if (bits != 256) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                     "Init: Failed to generate temporary "
-                     "%d bit EC parameters, only 256 bits supported", bits);
-        return !OK;
-    }
-
-    if ((ecdh = EC_KEY_new()) == NULL ||
-        EC_KEY_set_group(ecdh, EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) != 1)
-    {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                     "Init: Failed to generate temporary "
-                     "%d bit EC parameters", bits);
-        return !OK;
-    }
-
-    mc->pTmpKeys[idx] = ecdh;
-    return OK;
-}
-
-#define MODSSL_TMP_KEY_INIT_EC(s, bits) \
-    ssl_tmp_key_init_ec(s, bits, SSL_TMP_KEY_EC_##bits)
-
-#endif
-
-#define MODSSL_TMP_KEY_INIT_RSA(s, bits) \
-    ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits)
-
-#define MODSSL_TMP_KEY_INIT_DH(s, bits) \
-    ssl_tmp_key_init_dh(s, bits, SSL_TMP_KEY_DH_##bits)
-
-static int ssl_tmp_keys_init(server_rec *s)
-{
-    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
-                 "Init: Generating temporary RSA private keys (512/1024 bits)");
-
-    if (MODSSL_TMP_KEY_INIT_RSA(s, 512) ||
-        MODSSL_TMP_KEY_INIT_RSA(s, 1024)) {
-        return !OK;
-    }
-
-    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
-                 "Init: Generating temporary DH parameters (512/1024 bits)");
-
-    if (MODSSL_TMP_KEY_INIT_DH(s, 512) ||
-        MODSSL_TMP_KEY_INIT_DH(s, 1024)) {
-        return !OK;
-    }
-
-#ifndef OPENSSL_NO_EC
-    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
-                 "Init: Generating temporary EC parameters (256 bits)");
-
-    if (MODSSL_TMP_KEY_INIT_EC(s, 256)) {
-        return !OK;
-    }
-#endif
-
-    return OK;
-}
-
-/*
  *  Per-module initialization
  */
 int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
@@ -335,10 +180,6 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plo
      */
     ssl_pphrase_Handle(base_server, ptemp);
 
-    if (ssl_tmp_keys_init(base_server)) {
-        return !OK;
-    }
-
     /*
      * initialize the mutex handling
      */
@@ -384,6 +225,10 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plo
 
     SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */
 
+    if (ssl_dh_InitParams(base_server) != OK) {
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     return OK;
 }
 
@@ -607,6 +452,9 @@ static void ssl_init_ctx_protocol(server_rec *s,
      * Configure additional context ingredients
      */
     SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
+#ifndef OPENSSL_NO_EC
+    SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
+#endif
 
 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
     /*
@@ -647,11 +495,7 @@ static void ssl_init_ctx_callbacks(server_rec *s,
 {
     SSL_CTX *ctx = mctx->ssl_ctx;
 
-    SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
     SSL_CTX_set_tmp_dh_callback(ctx,  ssl_callback_TmpDH);
-#ifndef OPENSSL_NO_EC
-    SSL_CTX_set_tmp_ecdh_callback(ctx,ssl_callback_TmpECDH);
-#endif
 
     SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
 }
@@ -747,14 +591,16 @@ static void ssl_init_ctx_cipher_suite(server_rec *
                                       modssl_ctx_t *mctx)
 {
     SSL_CTX *ctx = mctx->ssl_ctx;
-    const char *suite = mctx->auth.cipher_suite;
+    const char *suite;
 
     /*
-     *  Configure SSL Cipher Suite
+     *  Configure SSL Cipher Suite. Always disable NULL and export ciphers,
+     *  see also ssl_engine_config.c:ssl_cmd_SSLCipherSuite().
+     *  OpenSSL's SSL_DEFAULT_CIPHER_LIST already includes !aNULL:!eNULL,
+     *  so only prepend !EXP in this case.
      */
-    if (!suite) {
-        return;
-    }
+    suite = mctx->auth.cipher_suite ? mctx->auth.cipher_suite :
+            apr_pstrcat(ptemp, "!EXP:", SSL_DEFAULT_CIPHER_LIST, NULL);
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                  "Configuring permitted SSL ciphers [%s]",
@@ -1041,10 +887,14 @@ static void ssl_init_server_certs(server_rec *s,
     const char *rsa_id, *dsa_id;
 #ifndef OPENSSL_NO_EC
     const char *ecc_id;
+    EC_GROUP *ecparams;
+    int nid;
+    EC_KEY *eckey = NULL;
 #endif
     const char *vhost_id = mctx->sc->vhost_id;
     int i;
     int have_rsa, have_dsa;
+    DH *dhparams;
 #ifndef OPENSSL_NO_EC
     int have_ecc;
 #endif
@@ -1099,6 +949,46 @@ static void ssl_init_server_certs(server_rec *s,
 #endif
         ssl_die();
     }
+
+    /*
+     * Try to read DH parameters from the (first) SSLCertificateFile
+     */
+    if ((mctx->pks->cert_files[0] != NULL) &&
+        (dhparams = ssl_dh_GetParamFromFile(mctx->pks->cert_files[0]))) {
+        SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams);
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                     "Custom DH parameters (%d bits) for %s loaded from %s",
+                     BN_num_bits(dhparams->p), vhost_id,
+                     mctx->pks->cert_files[0]);
+    }
+
+#ifndef OPENSSL_NO_EC
+    /*
+     * Similarly, try to read the ECDH curve name from SSLCertificateFile...
+     */
+    if ((mctx->pks->cert_files[0] != NULL) &&
+        (ecparams = ssl_ec_GetParamFromFile(mctx->pks->cert_files[0])) &&
+        (nid = EC_GROUP_get_curve_name(ecparams)) &&
+        (eckey = EC_KEY_new_by_curve_name(nid))) {
+        SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                     "ECDH curve %s for %s specified in %s",
+                     OBJ_nid2sn(nid), vhost_id, mctx->pks->cert_files[0]);
+    }
+    /*
+     * ...otherwise, enable auto curve selection (OpenSSL 1.0.2 and later)
+     * or configure NIST P-256 (required to enable ECDHE for earlier versions)
+     */
+    else {
+#if defined(SSL_CTX_set_ecdh_auto)
+        SSL_CTX_set_ecdh_auto(mctx->ssl_ctx, 1);
+#else
+        eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+        SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
+#endif
+    }
+    EC_KEY_free(eckey);
+#endif
 }
 
 static void ssl_init_proxy_certs(server_rec *s,
@@ -1567,11 +1457,6 @@ apr_status_t ssl_init_ModuleKill(void *data)
     ssl_scache_kill(base_server);
 
     /*
-     * Destroy the temporary keys and params
-     */
-    ssl_tmp_keys_free(base_server);
-
-    /*
      * Free the non-pool allocated structures
      * in the per-server configurations
      */
@@ -1583,6 +1468,8 @@ apr_status_t ssl_init_ModuleKill(void *data)
         ssl_init_ctx_cleanup_server(sc->server);
     }
 
+    ssl_dh_FreeParams();
+
     return APR_SUCCESS;
 }
 
Index: modules/ssl/ssl_engine_kernel.c
===================================================================
--- modules/ssl/ssl_engine_kernel.c	(revision 1677836)
+++ modules/ssl/ssl_engine_kernel.c	(working copy)
@@ -1187,118 +1187,38 @@ int ssl_hook_Fixup(request_rec *r)
 */
 
 /*
- * Handle out temporary RSA private keys on demand
- *
- * The background of this as the TLSv1 standard explains it:
- *
- * | D.1. Temporary RSA keys
- * |
- * |    US Export restrictions limit RSA keys used for encryption to 512
- * |    bits, but do not place any limit on lengths of RSA keys used for
- * |    signing operations. Certificates often need to be larger than 512
- * |    bits, since 512-bit RSA keys are not secure enough for high-value
- * |    transactions or for applications requiring long-term security. Some
- * |    certificates are also designated signing-only, in which case they
- * |    cannot be used for key exchange.
- * |
- * |    When the public key in the certificate cannot be used for encryption,
- * |    the server signs a temporary RSA key, which is then exchanged. In
- * |    exportable applications, the temporary RSA key should be the maximum
- * |    allowable length (i.e., 512 bits). Because 512-bit RSA keys are
- * |    relatively insecure, they should be changed often. For typical
- * |    electronic commerce applications, it is suggested that keys be
- * |    changed daily or every 500 transactions, and more often if possible.
- * |    Note that while it is acceptable to use the same temporary key for
- * |    multiple transactions, it must be signed each time it is used.
- * |
- * |    RSA key generation is a time-consuming process. In many cases, a
- * |    low-priority process can be assigned the task of key generation.
- * |    Whenever a new key is completed, the existing temporary key can be
- * |    replaced with the new one.
- *
- * XXX: base on comment above, if thread support is enabled,
- * we should spawn a low-priority thread to generate new keys
- * on the fly.
- *
- * So we generated 512 and 1024 bit temporary keys on startup
- * which we now just hand out on demand....
- */
-
-RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen)
-{
-    conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
-    SSLModConfigRec *mc = myModConfigFromConn(c);
-    int idx;
-
-    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
-                  "handing out temporary %d bit RSA key", keylen);
-
-    /* doesn't matter if export flag is on,
-     * we won't be asked for keylen > 512 in that case.
-     * if we are asked for a keylen > 1024, it is too expensive
-     * to generate on the fly.
-     * XXX: any reason not to generate 2048 bit keys at startup?
-     */
-
-    switch (keylen) {
-      case 512:
-        idx = SSL_TMP_KEY_RSA_512;
-        break;
-
-      case 1024:
-      default:
-        idx = SSL_TMP_KEY_RSA_1024;
-    }
-
-    return (RSA *)mc->pTmpKeys[idx];
-}
-
-/*
  * Hand out the already generated DH parameters...
+ * Based on the authentication strength.
  */
 DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
 {
     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
-    SSLModConfigRec *mc = myModConfigFromConn(c);
-    int idx;
+    EVP_PKEY *pkey = SSL_get_privatekey(ssl);
+    int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
 
     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
-                  "handing out temporary %d bit DH key", keylen);
+                  "handing out built-in DH parameters for %d-bit "
+                  "authenticated connection", keylen);
 
-    switch (keylen) {
-      case 512:
-        idx = SSL_TMP_KEY_DH_512;
-        break;
-
-      case 1024:
-      default:
-        idx = SSL_TMP_KEY_DH_1024;
+    /*
+     * OpenSSL will call us with either keylen == 512 or keylen == 1024
+     * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
+     * Adjust the DH parameter length according to the size of the
+     * RSA/DSA private key used for the current connection, and always
+     * use at least 1024-bit parameters.
+     * Note: This may cause interoperability issues with implementations
+     * which limit their DH support to 1024 bit - e.g. Java 7 and earlier.
+     * In this case, SSLCertificateFile can be used to specify fixed
+     * 1024-bit DH parameters (with the effect that OpenSSL skips this
+     * callback).
+     */
+    if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
+        keylen = EVP_PKEY_bits(pkey);
     }
 
-    return (DH *)mc->pTmpKeys[idx];
+    return ssl_dh_GetTmpParam(keylen);
 }
 
-#ifndef OPENSSL_NO_EC
-EC_KEY *ssl_callback_TmpECDH(SSL *ssl, int export, int keylen)
-{
-    conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
-    SSLModConfigRec *mc = myModConfigFromConn(c);
-    int idx;
-
-    /* XXX Uses 256-bit key for now. TODO: support other sizes. */
-    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
-                  "handing out temporary 256 bit ECC key");
-
-    switch (keylen) {
-      case 256:
-      default:
-        idx = SSL_TMP_KEY_EC_256;
-    }
-
-    return (EC_KEY *)mc->pTmpKeys[idx];
-}
-#endif
-
 /*
  * This OpenSSL callback function is called when OpenSSL
  * does client authentication and verifies the certificate chain.
Index: modules/ssl/ssl_private.h
===================================================================
--- modules/ssl/ssl_private.h	(revision 1677836)
+++ modules/ssl/ssl_private.h	(working copy)
@@ -207,23 +207,7 @@ typedef int ssl_algo_t;
 #define SSL_AIDX_MAX     (2)
 #endif
 
-
 /**
- * Define IDs for the temporary RSA keys and DH params
- */
-
-#define SSL_TMP_KEY_RSA_512  (0)
-#define SSL_TMP_KEY_RSA_1024 (1)
-#define SSL_TMP_KEY_DH_512   (2)
-#define SSL_TMP_KEY_DH_1024  (3)
-#ifndef OPENSSL_NO_EC
-#define SSL_TMP_KEY_EC_256   (4)
-#define SSL_TMP_KEY_MAX      (5)
-#else
-#define SSL_TMP_KEY_MAX      (4)
-#endif
-
-/**
  * Define the SSL options
  */
 #define SSL_OPT_NONE           (0)
@@ -431,7 +415,6 @@ typedef struct {
     apr_global_mutex_t   *pMutex;
     apr_array_header_t   *aRandSeed;
     apr_hash_t     *tVHostKeys;
-    void           *pTmpKeys[SSL_TMP_KEY_MAX];
     apr_hash_t     *tPublicCert;
     apr_hash_t     *tPrivateKey;
 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
@@ -638,11 +621,7 @@ int          ssl_hook_Upgrade(request_rec *);
 void         ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s);
 
 /**  OpenSSL callbacks */
-RSA         *ssl_callback_TmpRSA(SSL *, int, int);
 DH          *ssl_callback_TmpDH(SSL *, int, int);
-#ifndef OPENSSL_NO_EC
-EC_KEY      *ssl_callback_TmpECDH(SSL *, int, int);
-#endif
 int          ssl_callback_SSLVerify(int, X509_STORE_CTX *);
 int          ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *);
 int          ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey);
@@ -717,8 +696,13 @@ int          ssl_init_ssl_connection(conn_rec *c);
 void         ssl_pphrase_Handle(server_rec *, apr_pool_t *);
 
 /**  Diffie-Hellman Parameter Support  */
-DH           *ssl_dh_GetTmpParam(int);
-DH           *ssl_dh_GetParamFromFile(char *);
+DH          *ssl_dh_GetTmpParam(int nKeyLen);
+DH          *ssl_dh_GetParamFromFile(const char *);
+#ifndef OPENSSL_NO_EC
+EC_GROUP    *ssl_ec_GetParamFromFile(const char *);
+#endif
+int          ssl_dh_InitParams(server_rec *);
+void         ssl_dh_FreeParams(void);
 
 unsigned char *ssl_asn1_table_set(apr_hash_t *table,
                                   const char *key,
Index: .
===================================================================
--- .	(revision 1677836)
+++ .	(working copy)

Property changes on: .
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /httpd/httpd/trunk:r1526168,1527291,1527295,1563420,1666363

Reply via email to