diff -ru httpd-2.2.29.orig/modules/ssl/mod_ssl.c httpd-2.2.29.new/modules/ssl/mod_ssl.c
--- httpd-2.2.29.orig/modules/ssl/mod_ssl.c	2013-11-11 09:00:57.000000000 -0500
+++ httpd-2.2.29.new/modules/ssl/mod_ssl.c	2015-05-31 18:48:52.000000000 -0400
@@ -111,6 +111,9 @@
     SSL_CMD_SRV(CertificateKeyFile, TAKE1,
                 "SSL Server Private Key file "
                 "(`/path/to/file' - PEM or DER encoded)")
+    SSL_CMD_SRV(DHParametersFile, TAKE1,
+                "SSL Server Diffie-Hellman parameters file "
+                "(`/path/to/file' - PEM or DER encoded)")
     SSL_CMD_SRV(CertificateChainFile, TAKE1,
                 "SSL Server CA Certificate Chain file "
                 "(`/path/to/file' - PEM encoded)")
diff -ru httpd-2.2.29.orig/modules/ssl/ssl_engine_config.c httpd-2.2.29.new/modules/ssl/ssl_engine_config.c
--- httpd-2.2.29.orig/modules/ssl/ssl_engine_config.c	2013-11-11 09:05:50.000000000 -0500
+++ httpd-2.2.29.new/modules/ssl/ssl_engine_config.c	2015-05-31 20:48:14.000000000 -0400
@@ -72,6 +72,7 @@
     mc->tVHostKeys             = apr_hash_make(pool);
     mc->tPrivateKey            = apr_hash_make(pool);
     mc->tPublicCert            = apr_hash_make(pool);
+    mc->tDHParams              = apr_hash_make(pool);
 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
     mc->szCryptoDevice         = NULL;
 #endif
@@ -158,6 +159,9 @@
     mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks));
 
     /* mctx->pks->... certs/keys are set during module init */
+
+    mctx->pks->dhparams_file = NULL;
+    mctx->pks->dhparams     = NULL;
 }
 
 static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
@@ -256,6 +260,7 @@
 
     cfgMergeString(pks->ca_name_path);
     cfgMergeString(pks->ca_name_file);
+    cfgMergeString(pks->dhparams_file);
 }
 
 /*
@@ -831,6 +836,22 @@
 
     return NULL;
 }
+
+const char *ssl_cmd_SSLDHParametersFile(cmd_parms *cmd,
+                                        void *dcfg,
+                                        const char *arg)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+    const char *err;
+
+    if ((err = ssl_cmd_check_file(cmd, &arg))) {
+        return err;
+    }
+
+    sc->server->pks->dhparams_file = arg;
+
+    return NULL;
+}
 
 const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
                                           void *dcfg,
diff -ru httpd-2.2.29.orig/modules/ssl/ssl_engine_init.c httpd-2.2.29.new/modules/ssl/ssl_engine_init.c
--- httpd-2.2.29.orig/modules/ssl/ssl_engine_init.c	2014-07-16 02:04:38.000000000 -0400
+++ httpd-2.2.29.new/modules/ssl/ssl_engine_init.c	2015-05-31 19:02:02.000000000 -0400
@@ -872,6 +872,42 @@
     }
 }
 
+static int ssl_server_import_dhparams(server_rec *s,
+                                      modssl_ctx_t *mctx,
+                                      const char *id)
+{
+    SSLModConfigRec *mc = myModConfig(s);
+    ssl_asn1_t *asn1;
+    MODSSL_D2I_DHparams_CONST unsigned char *ptr;
+    DH *dhparams = NULL;
+
+    if (!(asn1 = ssl_asn1_table_get(mc->tDHParams, id))) {
+        return FALSE;
+    }
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+                 "Configuring server Diffie-Hellman parameters");
+
+    ptr = asn1->cpData;
+    if (!(dhparams = d2i_DHparams(NULL, &ptr, asn1->nData))) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                "Unable to import server Diffie-Hellman parameters");
+        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+        ssl_die();
+    }
+
+    if (SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams) <= 0) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                "Unable to configure server Diffie-Hellman parameters");
+        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+        ssl_die();
+    }
+
+    mctx->pks->dhparams = dhparams;
+
+    return TRUE;
+}
+
 static int ssl_server_import_cert(server_rec *s,
                                   modssl_ctx_t *mctx,
                                   const char *id,
@@ -1038,7 +1074,7 @@
                                   apr_pool_t *ptemp,
                                   modssl_ctx_t *mctx)
 {
-    const char *rsa_id, *dsa_id;
+    const char *rsa_id, *dsa_id, *dh_id;
 #ifndef OPENSSL_NO_EC
     const char *ecc_id;
 #endif
@@ -1051,12 +1087,14 @@
 
     rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
     dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
+    dh_id = apr_pstrcat(ptemp, vhost_id, ":", "DH", NULL);
 #ifndef OPENSSL_NO_EC
     ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC);
 #endif
 
     have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
     have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
+    (void)ssl_server_import_dhparams(s, mctx, dh_id);
 #ifndef OPENSSL_NO_EC
     have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC);
 #endif
@@ -1553,6 +1591,7 @@
         MODSSL_CFG_ITEM_FREE(EVP_PKEY_free,
                              mctx->pks->keys[i]);
     }
+    MODSSL_CFG_ITEM_FREE(DH_free, mctx->pks->dhparams);
 }
 
 apr_status_t ssl_init_ModuleKill(void *data)
diff -ru httpd-2.2.29.orig/modules/ssl/ssl_engine_pphrase.c httpd-2.2.29.new/modules/ssl/ssl_engine_pphrase.c
--- httpd-2.2.29.orig/modules/ssl/ssl_engine_pphrase.c	2009-09-16 16:06:05.000000000 -0400
+++ httpd-2.2.29.new/modules/ssl/ssl_engine_pphrase.c	2015-05-31 19:06:26.000000000 -0400
@@ -144,6 +144,7 @@
     unsigned char *ucp;
     long int length;
     X509 *pX509Cert;
+    DH *pDHParams;
     BOOL bReadable;
     apr_array_header_t *aPassPhrase;
     int nPassPhrase;
@@ -517,6 +518,45 @@
              */
             EVP_PKEY_free(pPrivateKey);
         }
+
+       /*
+        * Read in Diffie-Hellman parameters file if such a file is
+        * specified.
+        */
+       if (sc->server->pks->dhparams_file) {
+            apr_cpystrn(szPath, sc->server->pks->dhparams_file, sizeof(szPath));
+            if ((rv = exists_and_readable(szPath, p, NULL)) != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+                             "Init: Can't open server Diffie-Hellman parameters file %s",
+                             szPath);
+                ssl_die();
+            }
+            if ((pDHParams = SSL_read_DHparams(szPath, NULL, NULL)) == NULL) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                        "Init: Unable to read server Diffie-Hellman parameters from file %s", szPath);
+                ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+                ssl_die();
+            }
+
+            /*
+             * Insert the DH params into global module configuration
+             * to let it survive the processing between the 1st Apache
+             * API init round (where we operate here) and the 2nd
+             * Apache init round (where it will be actually used to
+             * configure mod_ssl's per-server configuration
+             * structures).
+             */
+            cp = asn1_table_vhost_key(mc, p, cpVHostID, "DH");
+            length = i2d_DHparams(pDHParams, NULL);
+            ucp = ssl_asn1_table_set(mc->tDHParams, cp, length);
+            (void)i2d_DHparams(pDHParams, &ucp); /* 2nd arg increments */
+
+            /*
+             * Free the DH structure
+             */
+            DH_free(pDHParams);
+       }
+
     }
 
     /*
diff -ru httpd-2.2.29.orig/modules/ssl/ssl_private.h httpd-2.2.29.new/modules/ssl/ssl_private.h
--- httpd-2.2.29.orig/modules/ssl/ssl_private.h	2013-11-11 09:00:57.000000000 -0500
+++ httpd-2.2.29.new/modules/ssl/ssl_private.h	2015-05-31 19:09:39.000000000 -0400
@@ -434,6 +434,7 @@
     void           *pTmpKeys[SSL_TMP_KEY_MAX];
     apr_hash_t     *tPublicCert;
     apr_hash_t     *tPrivateKey;
+    apr_hash_t     *tDHParams;
 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
     const char     *szCryptoDevice;
 #endif
@@ -450,8 +451,10 @@
      */
     const char  *cert_files[SSL_AIDX_MAX];
     const char  *key_files[SSL_AIDX_MAX];
+    const char  *dhparams_file;
     X509        *certs[SSL_AIDX_MAX];
     EVP_PKEY    *keys[SSL_AIDX_MAX];
+    DH          *dhparams;
 
     /** Certificates which specify the set of CA names which should be
      * sent in the CertificateRequest message: */
@@ -577,6 +580,7 @@
 const char  *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
 const char  *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
+const char  *ssl_cmd_SSLDHParametersFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *);
diff -ru httpd-2.2.29.orig/modules/ssl/ssl_toolkit_compat.h httpd-2.2.29.new/modules/ssl/ssl_toolkit_compat.h
--- httpd-2.2.29.orig/modules/ssl/ssl_toolkit_compat.h	2013-11-11 09:00:57.000000000 -0500
+++ httpd-2.2.29.new/modules/ssl/ssl_toolkit_compat.h	2015-05-31 19:13:08.000000000 -0400
@@ -108,9 +108,11 @@
 #if (OPENSSL_VERSION_NUMBER >= 0x00908000)
 # define MODSSL_D2I_PrivateKey_CONST const
 # define MODSSL_D2I_X509_CONST const
+# define MODSSL_D2I_DHparams_CONST const
 #else
 # define MODSSL_D2I_PrivateKey_CONST
 # define MODSSL_D2I_X509_CONST
+# define MODSSL_D2I_DHparams_CONST
 #endif
 
 #if (OPENSSL_VERSION_NUMBER >= 0x00909000)
@@ -125,8 +127,10 @@
 
 #if (OPENSSL_VERSION_NUMBER < 0x00904000)
 #define modssl_PEM_read_bio_X509(b, x, cb, arg) PEM_read_bio_X509(b, x, cb)
+#define modssl_PEM_read_bio_DHparams(b, x, cb, arg) PEM_read_bio_DHparams(b, x, cb)
 #else
 #define modssl_PEM_read_bio_X509(b, x, cb, arg) PEM_read_bio_X509(b, x, cb, arg)
+#define modssl_PEM_read_bio_DHparams(b, x, cb, arg) PEM_read_bio_DHparams(b, x, cb, arg)
 #endif
 
 #define modssl_PEM_X509_INFO_read_bio PEM_X509_INFO_read_bio 
diff -ru httpd-2.2.29.orig/modules/ssl/ssl_util_ssl.c httpd-2.2.29.new/modules/ssl/ssl_util_ssl.c
--- httpd-2.2.29.orig/modules/ssl/ssl_util_ssl.c	2012-08-17 13:30:46.000000000 -0400
+++ httpd-2.2.29.new/modules/ssl/ssl_util_ssl.c	2015-05-31 19:23:15.000000000 -0400
@@ -115,6 +115,47 @@
     return rc;
 }
 
+DH *SSL_read_DHparams(char* filename, DH **DHparams, modssl_read_bio_cb_fn *cb)
+{
+    DH  *rc;
+    BIO *bioS;
+    BIO *bioF;
+
+    /* 1. try PEM (= DER+Base64+headers) */
+    if ((bioS=BIO_new_file(filename, "r")) == NULL)
+        return NULL;
+    rc = modssl_PEM_read_bio_DHparams (bioS, DHparams, cb, NULL);
+    BIO_free(bioS);
+
+    if (rc == NULL) {
+        /* 2. try DER+Base64 */
+        if ((bioS=BIO_new_file(filename, "r")) == NULL)
+            return NULL;
+
+        if ((bioF = BIO_new(BIO_f_base64())) == NULL) {
+            BIO_free(bioS);
+            return NULL;
+        }
+        bioS = BIO_push(bioF, bioS);
+        rc = d2i_DHparams_bio(bioS, NULL);
+        BIO_free_all(bioS);
+
+        if (rc == NULL) {
+            /* 3. try plain DER */
+            if ((bioS=BIO_new_file(filename, "r")) == NULL)
+                return NULL;
+            rc = d2i_DHparams_bio(bioS, NULL);
+            BIO_free(bioS);
+        }
+    }
+    if (rc != NULL && DHparams != NULL) {
+        if (*DHparams != NULL)
+            DH_free(*DHparams);
+        *DHparams = rc;
+    }
+    return rc;
+}
+
 #if SSL_LIBRARY_VERSION <= 0x00904100
 static EVP_PKEY *d2i_PrivateKey_bio(BIO *bio, EVP_PKEY **key)
 {
