changeset 932:083549518c3c

Forward Secrecy EC Perdition 2.1 can not use or offer cipher suites with forward secrecy. Please include attached patch in the package or in the upstream mercurial. The patch originates from Daniel Kahn Gillmor and was posted to the perdition mailing list in spring. I extended the patch to also support EC-DHE ciphers. It applies cleanly on 1.19rc5 as well as 2.1-2. Maybe the used EC curve should be made configurable. See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765867#5 Signed-off-by: Simon Horman <horms@verge.net.au>
author Matthias Hunstock <atze_80@web.de>
date Sat, 13 Jun 2015 08:59:05 +0900
parents 94e84696af2d
children 30672d224854
files etc/perdition/perdition.conf perdition/options.c perdition/options.h perdition/perdition.8 perdition/perdition.c perdition/ssl.c perdition/ssl.h
diffstat 7 files changed, 107 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/etc/perdition/perdition.conf	Thu Sep 11 12:40:38 2014 +0900
+++ b/etc/perdition/perdition.conf	Sat Jun 13 08:59:05 2015 +0900
@@ -358,6 +358,11 @@
 # (default "/etc/perdition/perdition.crt.pem")
 #ssl_cert_file /etc/perdition/perdition.crt.pem
 
+# ssl_dh_params_file FILENAME:
+# Diffie-Hellman parameters to use when offering EDH ciphersuites to clients.
+# (default is to look for the DH params in the ssl_cert_file)
+#ssl_dh_params_file /etc/perdition/perdition.crt.pem
+
 # ssl_cert_accept_self_signed:
 # Accept self-signed certificates.
 #ssl_cert_accept_self_signed
--- a/perdition/options.c	Thu Sep 11 12:40:38 2014 +0900
+++ b/perdition/options.c	Sat Jun 13 08:59:05 2015 +0900
@@ -464,6 +464,8 @@
       TAG_SSL_CA_ACCEPT_SELF_SIGNED, NULL, NULL},
     {"ssl_cert_file",               '\0', POPT_ARG_STRING, NULL,
       TAG_SSL_CERT_FILE, NULL, NULL},
+    {"ssl_dh_params_file",          '\0', POPT_ARG_STRING, NULL,
+      TAG_SSL_DH_PARAMS_FILE, NULL, NULL},
     {"ssl_cert_accept_expired",     '\0', POPT_ARG_NONE,   NULL,
       TAG_SSL_CERT_ACCEPT_EXPIRED, NULL, NULL},
     {"ssl_cert_accept_not_yet_valid", '\0', POPT_ARG_NONE, NULL,
@@ -594,6 +596,7 @@
     opt_i(&(opt.ssl_ca_accept_self_signed), DEFAULT_SSL_CA_ACCEPT_SELF_SIGNED, 
 		    &i, 0, OPT_NOT_SET);
     opt_p(&(opt.ssl_cert_file), DEFAULT_SSL_CERT_FILE, &i, 0, OPT_NOT_SET);
+    opt_p(&(opt.ssl_dh_params_file), DEFAULT_SSL_DH_PARAMS_FILE, &i, 0, OPT_NOT_SET);
     opt_i(&(opt.ssl_cert_accept_expired), DEFAULT_SSL_CERT_ACCEPT_EXPIRED, 
 	       	    &i, 0, OPT_NOT_SET);
     opt_i(&(opt.ssl_cert_accept_not_yet_valid), 
@@ -920,6 +923,14 @@
 	NO_SSL_OPT("ssl_cert_file");
 #endif /* WITH_SSL_SUPPORT */
         break; 
+      case TAG_SSL_DH_PARAMS_FILE:
+#ifdef WITH_SSL_SUPPORT
+        opt_p(&(opt.ssl_dh_params_file), optarg, &(opt.ssl_mask), 
+			MASK_SSL_DH_PARAMS_FILE, f);
+#else /* WITH_SSL_SUPPORT */
+	NO_SSL_OPT("ssl_dh_params_file");
+#endif /* WITH_SSL_SUPPORT */
+        break; 
       case TAG_SSL_CERT_ACCEPT_EXPIRED:
 #ifdef WITH_SSL_SUPPORT
         opt_i(&(opt.ssl_cert_accept_expired), 1, &(opt.ssl_mask),
@@ -1755,6 +1766,7 @@
     OPT_STR(RECOMMENDED_SSL_CA_FILE),
     OPT_STR(DEFAULT_SSL_CA_PATH),
     OPT_STR(DEFAULT_SSL_CERT_FILE),
+    OPT_STR(DEFAULT_SSL_DH_PARAMS_FILE),
     DEFAULT_SSL_CERT_VERIFY_DEPTH,
     OPT_STR(DEFAULT_SSL_KEY_FILE),
     OPT_STR(DEFAULT_SSL_LISTEN_CIPHERS),
--- a/perdition/options.h	Thu Sep 11 12:40:38 2014 +0900
+++ b/perdition/options.h	Sat Jun 13 08:59:05 2015 +0900
@@ -167,6 +167,7 @@
 #define DEFAULT_SSL_CA_ACCEPT_SELF_SIGNED    0
 #define DEFAULT_SSL_CERT_FILE                PERDITION_SYSCONFDIR \
 					     "/perdition.crt.pem"
+#define DEFAULT_SSL_DH_PARAMS_FILE           NULL
 #define DEFAULT_SSL_CERT_ACCEPT_EXPIRED      0
 #define DEFAULT_SSL_CERT_ACCEPT_SELF_SIGNED  0
 #define DEFAULT_SSL_CERT_ACCEPT_NOT_YET_VALID 0
@@ -236,6 +237,7 @@
   char            *ssl_ca_path;
   int             ssl_ca_accept_self_signed;
   char            *ssl_cert_file;
+  char            *ssl_dh_params_file;
   int             ssl_cert_accept_self_signed;
   int             ssl_cert_accept_expired;
   int             ssl_cert_accept_not_yet_valid;
@@ -317,6 +319,7 @@
 #define MASK_SSL_NO_CN_VERIFY                  (flag_t) 0x00004000
 #define MASK_SSL_PASSPHRASE_FD                 (flag_t) 0x00008000
 #define MASK_SSL_PASSPHRASE_FILE               (flag_t) 0x00010000
+#define MASK_SSL_DH_PARAMS_FILE                (flag_t) 0x00020000
 #endif /* WITH_SSL_SUPPORT */
 
 /* 
@@ -355,6 +358,7 @@
 #define TAG_MANAGESIEVE_CAPABILITY             (int) 155
 #define TAG_POP_CAPABILITY                     (int) 156
 #define TAG_TCP_KEEPALIVE                      (int) 157
+#define TAG_SSL_DH_PARAMS_FILE                 (int) 158
 
 /*Flag values for options()*/
 #define OPT_ERR         (flag_t) 0x1  /*Print error to stderr, enable help*/
--- a/perdition/perdition.8	Thu Sep 11 12:40:38 2014 +0900
+++ b/perdition/perdition.8	Sat Jun 13 08:59:05 2015 +0900
@@ -571,6 +571,12 @@
 .br
 (default "/etc/perdition/perdition.crt.pem")
 .TP 
+.B \-\-ssl_dh_params_file FILENAME:
+Diffie-Hellman parameters to use when offering EDH ciphersuites to clients.
+Should be in PEM format.
+.br
+(default: look for DH parameters in ssl_cert_file)
+.TP 
 .B \-\-ssl_cert_accept_self_signed:
 Accept self-signed certificates.
 Used for SSL or TLS outgoing connections.
--- a/perdition/perdition.c	Thu Sep 11 12:40:38 2014 +0900
+++ b/perdition/perdition.c	Sat Jun 13 08:59:05 2015 +0900
@@ -509,8 +509,8 @@
   if(opt.ssl_mode & SSL_LISTEN_MASK) {
     ssl_ctx = perdition_ssl_ctx(opt.ssl_ca_file, opt.ssl_ca_path,
 				opt.ssl_cert_file, opt.ssl_key_file,
-				opt.ssl_ca_chain_file, opt.ssl_listen_ciphers,
-				PERDITION_SSL_SERVER);
+				opt.ssl_ca_chain_file, opt.ssl_dh_params_file,
+				opt.ssl_listen_ciphers, PERDITION_SSL_SERVER);
     if(!ssl_ctx) {
       PERDITION_DEBUG_SSL_ERR("perdition_ssl_ctx");
       VANESSA_LOGGER_ERR("Fatal error establishing SSL context for listening");
--- a/perdition/ssl.c	Thu Sep 11 12:40:38 2014 +0900
+++ b/perdition/ssl.c	Sat Jun 13 08:59:05 2015 +0900
@@ -166,6 +166,11 @@
  *               concatenation of the various PEM-encoded CA Certificate 
  *               files, usually in certificate chain order.  
  *               Overrides ca_pat and ca_file
+ *      dh_params_file: Diffie-Hellman parameters to use as a server
+ *               May be NULL if not a server, if the DH params are
+ *               appended to the cert file, or if EDH ciphersuites are
+ *               not desired.  Should be the path to a PEM file that
+ *               contains DH PARAMETERS
  *      ciphers: cipher list to use as per ciphers(1). 
  *               May be NULL in which case openssl's default is used.
  *      flag: PERDITION_SSL_CLIENT or PERDITION_SSL_SERVER
@@ -488,9 +493,14 @@
 
 SSL_CTX *perdition_ssl_ctx(const char *ca_file, const char *ca_path, 
 		const char *cert, const char *privkey, 
-		const char *ca_chain_file, const char *ciphers, flag_t flag)
+		const char *ca_chain_file, const char *dh_params_file,
+		const char *ciphers, flag_t flag)
 {
 	SSL_CTX *ssl_ctx, *out = NULL;
+	const char *dhfile = NULL;
+	FILE* dhfp = NULL;
+	DH* dh = NULL;
+	EC_KEY* ecdh = NULL;
 	const char *use_ca_file = NULL;
 	const char *use_ca_path = NULL;
 	struct passwd_cb_data pw_data;
@@ -533,6 +543,65 @@
 	}
 
 	/*
+	 * Load the Diffie-Hellman parameters:
+	 */
+	if (flag & PERDITION_SSL_SERVER &&
+		(dh_params_file || cert)) {
+		dhfile = (dh_params_file ? dh_params_file : cert);
+		dhfp = fopen(dhfile, "r");
+		if (dhfp == NULL) {
+			if (dh_params_file) {
+				VANESSA_LOGGER_ERR_UNSAFE
+					("Error opening Diffie-Hellman parameters file \"%s\"", dhfile);
+				SSL_CTX_free(ssl_ctx);
+				return NULL;
+			} else {
+				VANESSA_LOGGER_DEBUG_UNSAFE("could not open cert file for reading DH params \"%s\"", dhfile);
+			}
+		} else {
+			dh = PEM_read_DHparams(dhfp, NULL, NULL, NULL);
+			fclose(dhfp);
+			if (dh == NULL) {
+				if (dh_params_file) {
+					PERDITION_DEBUG_SSL_ERR("PEM_read_DHparams");
+					VANESSA_LOGGER_ERR_UNSAFE
+						("Error reading Diffie-Hellman parameters from file \"%s\"", dhfile);
+					SSL_CTX_free(ssl_ctx);
+					return NULL;
+				} else {
+					VANESSA_LOGGER_ERR_UNSAFE("could not read DH params from cert file \"%s\"", dhfile);
+				}
+			} else {
+				if (1 != SSL_CTX_set_tmp_dh(ssl_ctx, dh)) {
+					PERDITION_DEBUG_SSL_ERR("SSL_CTX_set_tmp_dh");
+					VANESSA_LOGGER_ERR_UNSAFE
+					("Error loading Diffie-Hellman parameters: \"%s\"", dhfile);
+				} else {
+					VANESSA_LOGGER_INFO_UNSAFE
+					("Loaded Diffie-Hellman parameters: \"%s\"", dhfile);
+				}
+				DH_free(dh);
+			}
+		}
+	}		  
+
+
+	/*
+	 * Load the EC Diffie-Hellman parameters:
+	 */
+	if (flag & PERDITION_SSL_SERVER) {
+		EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
+		if (!ecdh) {
+			VANESSA_LOGGER_ERR("Error generating ECDH parameters");
+		} else {
+			if (!SSL_CTX_set_tmp_ecdh (ssl_ctx, ecdh)) {
+				VANESSA_LOGGER_ERR("Error setting ECDH parameters");
+		 	}
+			EC_KEY_free (ecdh);
+		}
+	}
+
+	/*
 	 * Set the available ciphers
 	 */
 	if(ciphers && SSL_CTX_set_cipher_list(ssl_ctx, ciphers) < 0) {
@@ -1154,7 +1223,7 @@
 	io_t *new_io;
 
 	ssl_ctx = perdition_ssl_ctx(ca_file, ca_path, NULL, NULL, NULL,
-			ciphers, PERDITION_SSL_CLIENT);
+			NULL, ciphers, PERDITION_SSL_CLIENT);
 	if (!ssl_ctx) {
 		PERDITION_DEBUG_SSL_ERR("perdition_ssl_ctx");
 		io_destroy(io);
--- a/perdition/ssl.h	Thu Sep 11 12:40:38 2014 +0900
+++ b/perdition/ssl.h	Sat Jun 13 08:59:05 2015 +0900
@@ -62,6 +62,11 @@
  *               the root CA certificate. Such a file is simply the
  *               concatenation of the various PEM-encoded CA Certificate 
  *               files, usually in certificate chain order.  
+ *      dh_params_file: Diffie-Hellman parameters to use as a server
+ *               May be NULL if not a server, if the DH params are
+ *               appended to the cert file, or if EDH ciphersuites are
+ *               not desired.  Should be the path to a PEM file that
+ *               contains DH PARAMETERS
  *      ciphers: cipher list to use as per ciphers(1). 
  *               May be NULL in which case openssl's default is used.
  *      flag: PERDITION_SSL_CLIENT or PERDITION_SSL_SERVER
@@ -79,7 +84,8 @@
 
 SSL_CTX *perdition_ssl_ctx(const char *ca_file, const char *ca_path,
 		const char *cert, const char *privkey, 
-		const char *ca_chain_file, const char *ciphers, flag_t flag);
+		const char *ca_chain_file, const char *dh_params_file,
+		const char *ciphers, flag_t flag);
 
 
 /**********************************************************************