# Taken from: # http://bugs.exim.org/show_bug.cgi?id=1397 # http://bugs.exim.org/attachment.cgi?id=661 diff -urN exim-4.82_RC3.orig/src/globals.c exim-4.82_RC3.ecdh/src/globals.c --- exim-4.82_RC3.orig/src/globals.c 2013-10-09 22:47:52.000000000 +0200 +++ exim-4.82_RC3.ecdh/src/globals.c 2013-10-15 00:53:16.000000000 +0200 @@ -137,6 +137,7 @@ bit-count as "NORMAL" (2432) and Thunderbird dropping connection. */ int tls_dh_max_bits = 2236; uschar *tls_dhparam = NULL; +uschar *tls_eccurve = NULL; #if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS) uschar *tls_ocsp_file = NULL; #endif diff -urN exim-4.82_RC3.orig/src/globals.h exim-4.82_RC3.ecdh/src/globals.h --- exim-4.82_RC3.orig/src/globals.h 2013-10-09 22:47:52.000000000 +0200 +++ exim-4.82_RC3.ecdh/src/globals.h 2013-10-15 00:52:25.000000000 +0200 @@ -105,6 +105,7 @@ extern uschar *tls_crl; /* CRL File */ extern int tls_dh_max_bits; /* don't accept higher lib suggestions */ extern uschar *tls_dhparam; /* DH param file */ +extern uschar *tls_eccurve; /* EC curve */ #if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS) extern uschar *tls_ocsp_file; /* OCSP stapling proof file */ #endif diff -urN exim-4.82_RC3.orig/src/readconf.c exim-4.82_RC3.ecdh/src/readconf.c --- exim-4.82_RC3.orig/src/readconf.c 2013-10-09 22:47:52.000000000 +0200 +++ exim-4.82_RC3.ecdh/src/readconf.c 2013-10-15 00:53:58.000000000 +0200 @@ -433,6 +433,7 @@ { "tls_crl", opt_stringptr, &tls_crl }, { "tls_dh_max_bits", opt_int, &tls_dh_max_bits }, { "tls_dhparam", opt_stringptr, &tls_dhparam }, + { "tls_eccurve", opt_stringptr, &tls_eccurve }, # if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS) { "tls_ocsp_file", opt_stringptr, &tls_ocsp_file }, # endif diff -urN exim-4.82_RC3.orig/src/tls-openssl.c exim-4.82_RC3.ecdh/src/tls-openssl.c --- exim-4.82_RC3.orig/src/tls-openssl.c 2013-10-09 22:47:52.000000000 +0200 +++ exim-4.82_RC3.ecdh/src/tls-openssl.c 2013-10-15 00:51:20.000000000 +0200 @@ -446,7 +446,57 @@ return TRUE; } +#if !defined(OPENSSL_NO_ECDH) +static BOOL +init_ecdh(SSL_CTX *sctx, host_item *host) +{ +EC_KEY *ecdh; +int nid; +# if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10002000L +/* check if OpenSSL >= 1.0.2 auto ECDH temp key parameter selection should be used */ +if (Ustrcmp(tls_eccurve, "auto") == 0) + { + DEBUG(D_tls) debug_printf("ECDH temp key parameter settings: OpenSSL 1.2+ autoselection\n"); + SSL_CTX_set_ecdh_auto(sctx, 1); + return TRUE; + } +# endif + +if (tls_eccurve == NULL) + { + DEBUG(D_tls) + debug_printf("ECDH curve (default): prime256v1\n", tls_eccurve); + nid = NID_X9_62_prime256v1; + } +else + { + /* search curve name */ + DEBUG(D_tls) + debug_printf("ECDH curve: %s\n", tls_eccurve); + nid = OBJ_sn2nid((uschar *)tls_eccurve); + if (nid == 0) + { + tls_error(string_sprintf("Unkown curve name tls_eccurve \"%s\"", tls_eccurve), + host, NULL); + return FALSE; + } + } + +ecdh = EC_KEY_new_by_curve_name(nid); +if (ecdh == NULL) + { + tls_error("Unable to create ec curve", + host, NULL); + return FALSE; + } + +SSL_CTX_set_tmp_ecdh(sctx, ecdh); +EC_KEY_free(ecdh); + +return TRUE; +} +#endif #ifdef EXPERIMENTAL_OCSP @@ -1066,6 +1116,11 @@ rc = tls_expand_session_files(*ctxp, cbinfo); if (rc != OK) return rc; +#if !defined(OPENSSL_NO_ECDH) +/* Initialize ECDH temp key parameter selection */ +if (!init_ecdh(*ctxp, host)) return DEFER; +#endif + /* If we need to handle SNI, do so */ #ifdef EXIM_HAVE_OPENSSL_TLSEXT if (host == NULL) /* server */