diff -Nru apache2-2.2.22/debian/changelog apache2-2.2.22/debian/changelog
--- apache2-2.2.22/debian/changelog	2014-12-23 23:44:50.000000000 +0100
+++ apache2-2.2.22/debian/changelog	2015-06-03 15:34:16.000000000 +0200
@@ -1,3 +1,10 @@
+apache2 (2.2.22-13+deb7u4tarent1) tarent; urgency=high
+
+  * Non-maintainer upload.
+  * Backport support for adding DH parameters to the SSLCertificateFile.
+
+ -- Thorsten Glaser <t.glaser@tarent.de>  Wed, 03 Jun 2015 15:34:14 +0200
+
 apache2 (2.2.22-13+deb7u4) wheezy; urgency=medium
 
   * CVE-2013-5704: Fix handling of chunk trailers. A remote attacker could
diff -Nru apache2-2.2.22/debian/patches/DH-SSLCertificateFile.patch apache2-2.2.22/debian/patches/DH-SSLCertificateFile.patch
--- apache2-2.2.22/debian/patches/DH-SSLCertificateFile.patch	1970-01-01 01:00:00.000000000 +0100
+++ apache2-2.2.22/debian/patches/DH-SSLCertificateFile.patch	2015-06-03 15:33:45.000000000 +0200
@@ -0,0 +1,1373 @@
+# DP: backport support for adding DH parameters to the SSLCertificateFile
+
+--- a/docs/manual/mod/mod_ssl.html.en
++++ b/docs/manual/mod/mod_ssl.html.en
+@@ -388,12 +388,47 @@ SSLCertificateChainFile /usr/local/apach
+ <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_ssl</td></tr>
+ </table>
+ <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
+-two times (referencing different filenames) when both a RSA and a DSA based
+-server certificate is used in parallel.</p>
++This directive points to a file with certificate data in PEM format.
++At a minimum, the file must include an end-entity (leaf) certificate.
++The directive can be used up to three times (referencing different filenames)
++when an RSA, a DSA, and an ECC based server certificate is used in parallel.
++</p>
++
++<p>
++Custom DH parameters and an EC curve name for ephemeral keys,
++can be added to end of the first file configured using
++<code class="directive"><a href="#sslcertificatefile">SSLCertificateFile</a></code>.
++Such parameters can be generated using the commands
++<code>openssl dhparam</code> and <code>openssl ecparam</code>.
++The parameters can be added as-is to the end of the first
++certificate file. Only the first file can be used for custom
++parameters, as they are applied independently of the authentication
++algorithm type.
++</p>
++
++<p>
++Finally the the end-entity certificate's private key can also be
++added to the certificate file instead of using a separate
++<code class="directive"><a href="#sslcertificatekeyfile">SSLCertificateKeyFile</a></code>
++directive. This practice is highly discouraged. If the private
++key is encrypted, the pass phrase dialog is forced at startup time.
++</p>
++
++<div class="note">
++<h3>DH parameter interoperability with primes &gt; 1024 bit</h3>
++<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>
++</div>
++
+ <div class="example"><h3>Example</h3><p><code>
+ SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
+ </code></p></div>
+@@ -409,18 +444,22 @@ SSLCertificateFile /usr/local/apache2/co
+ <tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_ssl</td></tr>
+ </table>
+ <p>
+-This directive points to the PEM-encoded Private Key file for the
+-server. If the Private Key is not combined with the Certificate in the
+-<code class="directive">SSLCertificateFile</code>, use this additional directive to
+-point to the file with the stand-alone Private Key. When
+-<code class="directive">SSLCertificateFile</code> is used and the file
+-contains both the Certificate and the Private Key this directive need
+-not be used. But we strongly discourage this practice.  Instead we
+-recommend you to separate the Certificate and the Private Key. If the
+-contained Private Key is encrypted, the Pass Phrase dialog is forced
+-at startup time. This directive can be used up to two times
+-(referencing different filenames) when both a RSA and a DSA based
+-private key is used in parallel.</p>
++This directive points to the PEM-encoded private key file for the
++server. If the contained private key is encrypted, the pass phrase
++dialog is forced at startup time.</p>
++
++<p>
++The directive can be used up to three times (referencing different filenames)
++when an RSA, a DSA, and an ECC based private key is used in parallel. For each
++<code class="directive"><a href="#sslcertificatekeyfile">SSLCertificateKeyFile</a></code>
++directive, there must be a matching <code class="directive">SSLCertificateFile</code>
++directive.</p>
++
++<p>
++The private key may also be combined with the certificate in the file given by
++<code class="directive"><a href="#sslcertificatefile">SSLCertificateFile</a></code>, but this practice
++is highly discouraged.</p>
++
+ <div class="example"><h3>Example</h3><p><code>
+ SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.key
+ </code></p></div>
+@@ -1886,6 +1925,6 @@ SSLVerifyDepth 10
+ <div class="bottomlang">
+ <p><span>Available Languages: </span><a href="../en/mod/mod_ssl.html" title="English">&nbsp;en&nbsp;</a></p>
+ </div><div id="footer">
+-<p class="apache">Copyright 2012 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
++<p class="apache">Copyright 2015 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
+ <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div>
+ </body></html>
+\ No newline at end of file
+--- a/docs/manual/ssl/ssl_faq.html.en
++++ b/docs/manual/ssl/ssl_faq.html.en
+@@ -675,6 +675,7 @@ HTTPS to an Apache+mod_ssl server with M
+ <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>
+ 
+ <h3><a name="random" id="random">Why do I get lots of random SSL protocol 
+@@ -907,6 +908,40 @@ HTTPS to an Apache+mod_ssl server with N
+     implementation is correct, so when you encounter I/O errors with Netscape
+     Navigator it is usually caused by the configured certificates.</p>
+ 
++
++<h3><a name="javadh" id="javadh">Why do I get handshake failures with Java-based clients when using a certificate with more than 1024 bits?</a></h3>
++    <p>Beginning with version 2.2.30,
++    <code class="module"><a href="../mod/mod_ssl.html">mod_ssl</a></code> 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 <code class="directive"><a href="../mod/core.html#loglevel">LogLevel</a></code> <code>info</code>
++    or higher), you can either rearrange mod_ssl's cipher list with
++    <code class="directive"><a href="../mod/mod_ssl.html#sslciphersuite">SSLCipherSuite</a></code>
++    (possibly in conjunction with <code class="directive"><a href="../mod/mod_ssl.html#sslhonorcipherorder">SSLHonorCipherOrder</a></code>),
++    or you can use 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 1024</code>
++    command. Alternatively, you can use the following standard 1024-bit DH
++    parameters from <a href="http://www.ietf.org/rfc/rfc2409.txt">RFC 2409</a>,
++    section 6.2:</p>
++    <div class="example"><pre>-----BEGIN DH PARAMETERS-----
++MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
++Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
++/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
++-----END DH PARAMETERS-----</pre></div>
++    <p>Add the custom parameters including the "BEGIN DH PARAMETERS" and
++    "END DH PARAMETERS" lines to the end of the first certificate file
++    you have configured using the
++    <code class="directive"><a href="../mod/mod_ssl.html#sslcertificatefile">SSLCertificateFile</a></code> directive.</p>
++
++
+ </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+ <div class="section">
+ <h2><a name="support" id="support">mod_ssl Support</a></h2>
+@@ -1054,6 +1089,6 @@ the reason for my core dump?</a></h3>
+ <div class="bottomlang">
+ <p><span>Available Languages: </span><a href="../en/ssl/ssl_faq.html" title="English">&nbsp;en&nbsp;</a></p>
+ </div><div id="footer">
+-<p class="apache">Copyright 2012 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
++<p class="apache">Copyright 2015 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
+ <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div>
+ </body></html>
+\ No newline at end of file
+--- a/modules/ssl/mod_ssl.c
++++ b/modules/ssl/mod_ssl.c
+@@ -422,15 +422,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);
+--- a/modules/ssl/ssl_engine_config.c
++++ b/modules/ssl/ssl_engine_config.c
+@@ -76,8 +76,6 @@ SSLModConfigRec *ssl_config_global_creat
+     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);
+--- a/modules/ssl/ssl_engine_dh.c
++++ b/modules/ssl/ssl_engine_dh.c
+@@ -41,21 +41,9 @@
+ **         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[] = {
++static const unsigned char dh512_p[] = {
+     0x9F, 0xDB, 0x8B, 0x8A, 0x00, 0x45, 0x44, 0xF0, 0x04, 0x5F, 0x17, 0x37,
+     0xD0, 0xBA, 0x2E, 0x0B, 0x27, 0x4C, 0xDF, 0x1A, 0x9F, 0x58, 0x82, 0x18,
+     0xFB, 0x43, 0x53, 0x16, 0xA1, 0x6E, 0x37, 0x41, 0x71, 0xFD, 0x19, 0xD8,
+@@ -63,7 +51,7 @@ static unsigned char dh512_p[] = {
+     0x80, 0xA3, 0x03, 0x0C, 0x6E, 0x4C, 0x37, 0x57, 0xD0, 0x8F, 0x70, 0xE6,
+     0xAA, 0x87, 0x10, 0x33,
+ };
+-static unsigned char dh512_g[] = {
++static const unsigned char dh512_g[] = {
+     0x02,
+ };
+ 
+@@ -73,7 +61,23 @@ static DH *get_dh512(void)
+                                dh512_g, sizeof(dh512_g));
+ }
+ 
+-static unsigned char dh1024_p[] = {
++#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 const 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,
+     0xB8, 0x81, 0x74, 0xCB, 0x98, 0xBC, 0xE9, 0x51, 0x84, 0x9F, 0x91, 0x2E,
+@@ -86,7 +90,7 @@ static unsigned char dh1024_p[] = {
+     0x88, 0xAE, 0xAA, 0x74, 0x7D, 0xE0, 0xF4, 0xD6, 0xE2, 0xBD, 0x68, 0xB0,
+     0xE7, 0x39, 0x3E, 0x0F, 0x24, 0x21, 0x8E, 0xB3,
+ };
+-static unsigned char dh1024_g[] = {
++static const unsigned char dh1024_g[] = {
+     0x02,
+ };
+ 
+@@ -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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 "
++                         "%u 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 "
++                         "%u 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;
++
++    for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++)
++        if (nKeyLen >= dhparams[n].min)
++            return dhparams[n].dh;
+ 
+-    if (nKeyLen == 512)
+-        dh = get_dh512();
+-    else if (nKeyLen == 1024)
+-        dh = get_dh1024();
+-    else
+-        dh = get_dh1024();
+-    return 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_GetParamFromFile(char *file)
+     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
+ ##
+--- a/modules/ssl/ssl_engine_init.c
++++ b/modules/ssl/ssl_engine_init.c
+@@ -53,160 +53,6 @@ static void ssl_add_version_components(a
+ 
+ 
+ /*
+- * 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_ERR, 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_ERR, 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,7 +181,7 @@ int ssl_init_Module(apr_pool_t *p, apr_p
+      */
+     ssl_pphrase_Handle(base_server, ptemp);
+ 
+-    if (ssl_tmp_keys_init(base_server)) {
++    if (ssl_dh_InitParams(base_server)) {
+         return !OK;
+     }
+ 
+@@ -606,6 +452,9 @@ static void ssl_init_ctx_protocol(server
+      * 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
+     /*
+@@ -646,11 +495,7 @@ static void ssl_init_ctx_callbacks(serve
+ {
+     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);
+ }
+@@ -1040,10 +885,14 @@ static void ssl_init_server_certs(server
+     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
+@@ -1098,6 +947,46 @@ static void ssl_init_server_certs(server
+ #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,
+@@ -1468,7 +1357,7 @@ apr_status_t ssl_init_ModuleKill(void *d
+     /*
+      * Destroy the temporary keys and params
+      */
+-    ssl_tmp_keys_free(base_server);
++    ssl_dh_FreeParams();
+ 
+     /*
+      * Free the non-pool allocated structures
+--- a/modules/ssl/ssl_engine_kernel.c
++++ b/modules/ssl/ssl_engine_kernel.c
+@@ -1196,117 +1196,48 @@ 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;
++    int type;
+ 
+     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+-                  "handing out temporary %d bit DH key", keylen);
+-
+-    switch (keylen) {
+-      case 512:
+-        idx = SSL_TMP_KEY_DH_512;
+-        break;
+-
+-      case 1024:
+-      default:
+-        idx = SSL_TMP_KEY_DH_1024;
+-    }
++                  "handing out built-in DH parameters for %d-bit "
++                  "authenticated connection", keylen);
+ 
+-    return (DH *)mc->pTmpKeys[idx];
+-}
+-
+-#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");
++#ifdef SSL_CERT_SET_SERVER
++    /*
++     * When multiple certs/keys are configured for the SSL_CTX: make sure
++     * that we get the private key which is indeed used for the current
++     * SSL connection (available in OpenSSL 1.0.2 or later only)
++     */
++    SSL_set_current_cert(ssl, SSL_CERT_SET_SERVER);
++#endif
++    pkey = SSL_get_privatekey(ssl);
++    type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
+ 
+-    switch (keylen) {
+-      case 256:
+-      default:
+-        idx = SSL_TMP_KEY_EC_256;
++    /*
++     * 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 (EC_KEY *)mc->pTmpKeys[idx];
++    return ssl_dh_GetTmpParam(keylen);
+ }
+-#endif
+ 
+ /*
+  * This OpenSSL callback function is called when OpenSSL
+--- a/modules/ssl/ssl_private.h
++++ b/modules/ssl/ssl_private.h
+@@ -207,22 +207,6 @@ 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
+  */
+@@ -422,7 +406,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)
+@@ -624,11 +607,7 @@ int          ssl_hook_Upgrade(request_re
+ 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);
+@@ -703,8 +682,13 @@ int          ssl_init_ssl_connection(con
+ 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);
++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,
+--- a/modules/ssl/ssl_util_ssl.c
++++ b/modules/ssl/ssl_util_ssl.c
+@@ -550,8 +550,8 @@ int modssl_session_get_time(SSL_SESSION
+ #define SSLC_VERSION_NUMBER 0x0000
+ #endif
+ 
+-DH *modssl_dh_configure(unsigned char *p, int plen,
+-                        unsigned char *g, int glen)
++DH *modssl_dh_configure(const unsigned char *p, int plen,
++                        const unsigned char *g, int glen)
+ {
+     DH *dh;
+ 
+--- a/modules/ssl/ssl_util_ssl.h
++++ b/modules/ssl/ssl_util_ssl.h
+@@ -94,8 +94,8 @@ char       *SSL_SESSION_id2sz(unsigned c
+ /** util functions for OpenSSL+sslc compat */
+ int modssl_session_get_time(SSL_SESSION *session);
+ 
+-DH *modssl_dh_configure(unsigned char *p, int plen,
+-                        unsigned char *g, int glen);
++DH *modssl_dh_configure(const unsigned char *p, int plen,
++                        const unsigned char *g, int glen);
+ 
+ #endif /* __SSL_UTIL_SSL_H__ */
+ /** @} */
diff -Nru apache2-2.2.22/debian/patches/series apache2-2.2.22/debian/patches/series
--- apache2-2.2.22/debian/patches/series	2014-12-23 23:22:05.000000000 +0100
+++ apache2-2.2.22/debian/patches/series	2015-06-03 15:28:17.000000000 +0200
@@ -48,3 +48,4 @@
 CVE-2013-5704_trailers.patch
 SNI_case_insensitve.diff
 mod_ssl_SSL_CLIENT_S_DN_UID.diff
+DH-SSLCertificateFile.patch
