From 9205812071bcd7bcf098efd80b82ec2bc1a62da4 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Mon, 8 Feb 2016 15:52:25 +0100
Subject: [PATCH] Add server support for DHE ciphers

Similar patch was provided by Vitezslav Cizek <vcizek@suse.com>

Heavily modified by Rob Crittenden <rcritten@redhat.com>

https://fedorahosted.org/mod_nss/ticket/15
---
 configure.ac        |  9 +++++++++
 docs/mod_nss.html   | 40 +++++++++++++++++++++++++++++++++++++++-
 mod_nss.h           |  3 +++
 nss_engine_cipher.c | 20 +++++++++++++++++++-
 nss_engine_cipher.h |  2 ++
 nss_engine_init.c   | 15 +++++++++++++++
 6 files changed, 87 insertions(+), 2 deletions(-)

Index: mod_nss-1.0.8/docs/mod_nss.html
===================================================================
--- mod_nss-1.0.8.orig/docs/mod_nss.html	2016-03-18 14:48:47.718852738 +0100
+++ mod_nss-1.0.8/docs/mod_nss.html	2016-03-21 13:01:46.378528024 +0100
@@ -511,7 +511,7 @@ All ciphers are disabled by default. The
 enabled because
 <a href="#SSLv2">SSLv2</a> is not allowed in mod_nss.<br>
 <br>
-Available ciphers are:<br>
+Available RSA ciphers are:<br>
 <br>
 <table style="width: 70%; text-align: left;" border="1" cellpadding="2"
  cellspacing="2">
@@ -718,6 +718,43 @@ definition<br>
     </tr>
   </tbody>
 </table>
+<br>The available server-side DHE ciphers are:<br>
+<br>
+<table style="width: 70%; text-align: left;" border="1" cellpadding="2" cellspacing="2">
+<tbody><tr><td style="vertical-align: top; font-weight: bold;">Cipher Name<br>
+      </td><td style="vertical-align: top; font-weight: bold;">NSS Cipher definition<br>
+      </td><td style="vertical-align: top; font-weight: bold;">Protocol<br>
+      </td></tr><tr><td style="vertical-align: top;">dhe_rsa_des_sha<br>
+      </td><td style="vertical-align: top;">TLS_DHE_RSA_WITH_DES_CBC_SHA<br>
+</td><td style="vertical-align: top;">SSLv3/TLSv1.0/TLSv1.1/TLSv1.2<br>
+      </td></tr><tr><td style="vertical-align: top;">dhe_rsa_3des_sha<br>
+      </td><td style="vertical-align: top;">TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA<br>
+      </td><td style="vertical-align: top;">TLSv1.0/TLSv1.1/TLSv1.2</td></tr><tr><td style="vertical-align: top;">dhe_rsa_aes_128_sha<br>
+      </td><td style="vertical-align: top;">TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA<br>
+      </td><td style="vertical-align: top;">TLSv1.0/TLSv1.1/TLSv1.2</td></tr><tr><td style="vertical-align: top;">dhe_rsa_aes_256_sha<br>
+      </td><td style="vertical-align: top;">TLS_DHE_RSA_WITH_AES_256_CBC_SHA<br>
+      </td><td style="vertical-align: top;">TLSv1.0/TLSv1.1/TLSv1.2</td></tr><tr><td style="vertical-align: top;">dhe_rsa_camellia_128_sha<br>
+</td><td style="vertical-align: top;">TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA<br>
+      </td><td style="vertical-align: top;">TLSv1.0/TLSv1.1/TLSv1.2</td></tr><tr><td style="vertical-align: top;">dhe_rsa_camellia_256_sha<br>
+</td><td style="vertical-align: top;">TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA<br>
+      </td><td style="vertical-align: top;">TLSv1.0/TLSv1.1/TLSv1.2</td></tr><tr><td style="vertical-align: top;">dhe_rsa_aes_128_sha_256<br>
+</td><td style="vertical-align: top;">TLS_DHE_RSA_WITH_AES_128_CBC_SHA256<br>
+      </td><td style="vertical-align: top;">TLSv1.2</td></tr><tr>
+    <td valign="top">dhe_rsa_aes_256_sha_256<br>
+    </td>
+    <td valign="top">TLS_DHE_RSA_WITH_AES_256_CBC_SHA256<br>
+    </td>
+    <td valign="top">TLSv1.2</td>
+  </tr>
+  <tr>
+    <td valign="top">dhe_rsa_aes_128_gcm_sha_256<br>
+    </td>
+    <td valign="top">TLS_DHE_RSA_WITH_AES_128_GCM_SHA256<br>
+    </td>
+    <td valign="top">TLSv1.2</td>
+  </tr>
+</tbody>
+</table>
 <br>
 Additionally there are a number of ECC ciphers:<br>
 <br>
Index: mod_nss-1.0.8/nss_engine_init.c
===================================================================
--- mod_nss-1.0.8.orig/nss_engine_init.c	2016-03-18 14:48:47.725852854 +0100
+++ mod_nss-1.0.8/nss_engine_init.c	2016-03-21 11:33:35.142204451 +0100
@@ -46,6 +46,7 @@ cipher_properties ciphers_def[ciphernum]
     {"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA, 0, SSL3 | TLS},
     {"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA, 0, SSL3 | TLS},
     {"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA, 0, SSL3 | TLS},
+    {"dhe_rsa_des_sha", TLS_DHE_RSA_WITH_DES_CBC_SHA, 0, SSL3 | TLS},
     {"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5, 0, SSL3 | TLS},
     {"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0, SSL3 | TLS},
     {"rsa_null_md5", SSL_RSA_WITH_NULL_MD5, 0, SSL3 | TLS},
@@ -63,6 +64,14 @@ cipher_properties ciphers_def[ciphernum]
     {"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA, 0, SSL3 | TLS},
     {"rsa_aes_256_sha256", TLS_RSA_WITH_AES_256_CBC_SHA256, 0, TLS},
     {"rsa_camellia_256_sha", TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, 0, TLS},
+    {"dhe_rsa_3des_sha", TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0, TLS},
+    {"dhe_rsa_aes_128_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 0, TLS},
+    {"dhe_rsa_aes_256_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 0, TLS},
+    {"dhe_rsa_camellia_128_sha", TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, 0, TLS},
+    {"dhe_rsa_camellia_256_sha", TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, 0, TLS},
+    {"dhe_rsa_aes_128_sha_256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 0, TLS},
+    {"dhe_rsa_aes_256_sha_256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 0, TLS},
+    {"dhe_rsa_aes_128_gcm_sha_256", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0, TLS},
 
 #ifdef NSS_ENABLE_ECC
     /* ECC ciphers.*/
@@ -845,6 +854,16 @@ static void nss_init_ctx_protocol(server
     } else {
         mctx->tls = tls;
     }
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+        "Enabling DHE key exchange");
+    if (SSL_OptionSet(mctx->model, SSL_ENABLE_SERVER_DHE,
+        PR_TRUE) != SECSuccess) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                "Unable to enable DHE key exchange");
+        nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
+        nss_die();
+    }
 }
 
 static void nss_init_ctx_session_cache(server_rec *s,
@@ -1082,6 +1101,10 @@ static void nss_init_ctx_cipher_suite(se
 
     /* Finally actually enable the selected ciphers */
     for (i=0; i<ciphernum;i++) {
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+            "%sable cipher: %s",
+            cipher_state[i] == 1 ? "En" : "Dis",
+            ciphers_def[i].name);
         SSL_CipherPrefSet(mctx->model, ciphers_def[i].num, cipher_state[i]);
     }
 }
Index: mod_nss-1.0.8/mod_nss.h
===================================================================
--- mod_nss-1.0.8.orig/mod_nss.h	2016-03-18 14:48:47.725852854 +0100
+++ mod_nss-1.0.8/mod_nss.h	2016-03-18 15:42:38.468872877 +0100
@@ -380,9 +380,9 @@ enum sslversion { SSL2=1, SSL3=2, TLS=4}
 
 /* the table itself is defined in nss_engine_init.c */
 #ifdef NSS_ENABLE_ECC
-#define ciphernum 50
+#define ciphernum 59
 #else
-#define ciphernum 19
+#define ciphernum 28
 #endif
 
 /*
@@ -425,6 +425,7 @@ const char *nss_cmd_NSSSessionCacheSize(
 const char *nss_cmd_NSSPassPhraseDialog(cmd_parms *cmd, void *dcfg, const char *arg);
 const char *nss_cmd_NSSPassPhraseHelper(cmd_parms *cmd, void *dcfg, const char *arg);
 const char *nss_cmd_NSSRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
+const char *nss_cmd_NSSServerDHE(cmd_parms *cmd, void *dcfg, int flag);
 const char *nss_cmd_NSSUserName(cmd_parms *cmd, void *dcfg, const char *arg);
 const char *nss_cmd_NSSOptions(cmd_parms *, void *, const char *);
 const char *nss_cmd_NSSRequireSSL(cmd_parms *cmd, void *dcfg);
