Description: Allow custom DH and ECDH parameters.
 The parameters used for DH and ECDH are hard-coded by default, and
 the 1024-bit modulus used by default for DH may be too weak to
 provide effective forward secrecy for years to come.  Following the
 behavior of Apache 2.4.7, allow the administrator to specify custom
 parameters by including them in the SSLCertificateFile.
Origin: backport, subset of https://svn.apache.org/r1527295
Bug: https://bz.apache.org/bugzilla/show_bug.cgi?id=49559
Bug-Debian: http://bugs.debian.org/780398

--- apache2-2.2.22.orig/modules/ssl/ssl_engine_init.c
+++ apache2-2.2.22/modules/ssl/ssl_engine_init.c
@@ -1040,10 +1040,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;
 #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 +1102,33 @@ 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]);
+    }
+#endif
 }
 
 static void ssl_init_proxy_certs(server_rec *s,
--- apache2-2.2.22.orig/modules/ssl/ssl_private.h
+++ apache2-2.2.22/modules/ssl/ssl_private.h
@@ -705,6 +705,9 @@ void         ssl_pphrase_Handle(server_r
 /**  Diffie-Hellman Parameter Support  */
 DH           *ssl_dh_GetTmpParam(int);
 DH           *ssl_dh_GetParamFromFile(char *);
+#ifndef OPENSSL_NO_EC
+EC_GROUP     *ssl_ec_GetParamFromFile(const char *);
+#endif
 
 unsigned char *ssl_asn1_table_set(apr_hash_t *table,
                                   const char *key,
--- apache2-2.2.22.orig/modules/ssl/ssl_util_ssl.c
+++ apache2-2.2.22/modules/ssl/ssl_util_ssl.c
@@ -451,6 +451,26 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t
 
 /*  _________________________________________________________________
 **
+**  Custom (EC)DH parameter support
+**  _________________________________________________________________
+*/
+
+#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
+
+/*  _________________________________________________________________
+**
 **  Extra Server Certificate Chain Support
 **  _________________________________________________________________
 */
--- apache2-2.2.22.orig/docs/manual/mod/mod_ssl.html.en
+++ apache2-2.2.22/docs/manual/mod/mod_ssl.html.en
@@ -388,12 +388,19 @@ 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 the file with the PEM-encoded certificate,
+optionally also the corresponding private key, and - beginning with
+version 2.5.0-dev as of 2013-09-29 - 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>
+
 <div class="example"><h3>Example</h3><p><code>
 SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
 </code></p></div>
