From: Jeremy Harris Date: Tue, 26 May 2015 15:36:08 +0000 (+0100) Subject: Add tls_eccurve main config option. Bug 1397 X-Git-Tag: exim-4_86_RC3~8 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/10ca4f1ca3116f346dcc19645b59c443e57d26a8 Add tls_eccurve main config option. Bug 1397 Patch from Suse, massaged by JH --- diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index d44349c20..50dfaf1fd 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -13436,6 +13436,7 @@ listed in more than one group. .row &%tls_crl%& "certificate revocation list" .row &%tls_dh_max_bits%& "clamp D-H bit count suggestion" .row &%tls_dhparam%& "DH parameters for server" +.row &%tls_eccurve%& "EC curve selection for server" .row &%tls_ocsp_file%& "location of server certificate status proof" .row &%tls_on_connect_ports%& "specify SSMTP (SMTPS) ports" .row &%tls_privatekey%& "location of server private key" @@ -16627,7 +16628,22 @@ prior to the 4.80 release, as Debian used to patch Exim to raise the minimum acceptable bound from 1024 to 2048. +.option tls_eccurve main string&!! prime256v1 +.cindex TLS "EC cryptography" +If built with a recent-enough version of OpenSSL, +this option selects a EC curve for use by Exim. + +Curve names of the form &'prime256v1'& are accepted. +For even more-recent library versions, names of the form &'P-512'& +are also accepted, plus the special value &'auto'& +which tell the library to choose. + +If the option is set to an empty string, no EC curves will be enabled. + + .option tls_ocsp_file main string&!! unset +.cindex TLS "certificate status" +.cindex TLS "OCSP proof file" This option must if set expand to the absolute path to a file which contains a current status proof for the server's certificate, as obtained from the @@ -16635,6 +16651,8 @@ Certificate Authority. .option tls_on_connect_ports main "string list" unset +.cindex SSMTP +.cindex SMTPS This option specifies a list of incoming SSMTP (aka SMTPS) ports that should operate the obsolete SSMTP (SMTPS) protocol, where a TLS session is immediately set up without waiting for the client to issue a STARTTLS command. For diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index e10a32b3f..010c90d15 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -37,6 +37,8 @@ Version 4.86 12. A non-SMTP authenticator using information from TLS client certificates. +13. Main option "tls_eccurve" for selecting an Elliptic Curve for TLS. + Version 4.85 ------------ diff --git a/src/src/globals.c b/src/src/globals.c index cb1e8de39..63674e51c 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -156,6 +156,7 @@ that's the interop problem which has been observed: GnuTLS suggesting a higher bit-count as "NORMAL" (2432) and Thunderbird dropping connection. */ int tls_dh_max_bits = 2236; uschar *tls_dhparam = NULL; +uschar *tls_eccurve = US"prime256v1"; #ifndef DISABLE_OCSP uschar *tls_ocsp_file = NULL; #endif diff --git a/src/src/globals.h b/src/src/globals.h index 18dcf2fd0..36c25906e 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -118,6 +118,7 @@ extern uschar *tls_channelbinding_b64; /* string of base64 channel binding */ 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 */ #ifndef DISABLE_OCSP extern uschar *tls_ocsp_file; /* OCSP stapling proof file */ #endif diff --git a/src/src/readconf.c b/src/src/readconf.c index a36fdd3b7..8b43c7a9f 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -448,6 +448,7 @@ static optionlist optionlist_config[] = { { "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 }, # ifndef DISABLE_OCSP { "tls_ocsp_file", opt_stringptr, &tls_ocsp_file }, # endif diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 21e086e65..e1dcd77bc 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -22,6 +22,9 @@ functions from the OpenSSL library. */ #include #include #include +#ifndef OPENSSL_NO_ECDH +# include +#endif #ifndef DISABLE_OCSP # include #endif @@ -59,6 +62,16 @@ functions from the OpenSSL library. */ && (OPENSSL_VERSION_NUMBER & 0x0000ff000L) >= 0x000002000L # define EXIM_HAVE_OPENSSL_CHECKHOST # endif + +# if !defined(OPENSSL_NO_ECDH) +# if OPENSSL_VERSION_NUMBER >= 0x0090800fL +# define EXIM_HAVE_ECDH +# endif +# if OPENSSL_VERSION_NUMBER >= 0x10002000L +# define EXIM_HAVE_OPENSSL_ECDH_AUTO +# define EXIM_HAVE_OPENSSL_EC_NIST2NID +# endif +# endif #endif #if !defined(EXIM_HAVE_OPENSSL_TLSEXT) && !defined(DISABLE_OCSP) @@ -644,42 +657,74 @@ Returns: TRUE if OK (nothing to set up, or setup worked) */ static BOOL -init_ecdh(SSL_CTX *sctx, host_item *host) +init_ecdh(SSL_CTX * sctx, host_item * host) { +EC_KEY * ecdh; +uschar * exp_curve; +int nid; +BOOL rv; + +#ifdef OPENSSL_NO_ECDH +return TRUE; +#else + if (host) /* No ECDH setup for clients, only for servers */ return TRUE; -#ifndef SSL_CTX_set_tmp_ecdh -/* No elliptic curve API in OpenSSL, skip it */ +# ifndef EXIM_HAVE_ECDH DEBUG(D_tls) debug_printf("No OpenSSL API to define ECDH parameters, skipping\n"); return TRUE; -#else -# ifndef NID_X9_62_prime256v1 -/* For now, stick to NIST P-256 to get "something" running. -If that's not available, bail */ -DEBUG(D_tls) - debug_printf("NIST P-256 EC curve not available, skipping ECDH setup\n"); -return TRUE; # else + +if (!expand_check(tls_eccurve, US"tls_eccurve", &exp_curve)) + return FALSE; +if (!exp_curve || !*exp_curve) + return TRUE; + +# ifdef EXIM_HAVE_OPENSSL_ECDH_AUTO +/* check if new enough library to support auto ECDH temp key parameter selection */ +if (Ustrcmp(exp_curve, "auto") == 0) { - EC_KEY * ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - BOOL rv; + 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 - /* The "tmp" in the name here refers to setting a tempoary key - not to the stability of the interface. */ +DEBUG(D_tls) debug_printf("ECDH: curve '%s'\n", exp_curve); +if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef +# ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID + && (nid = EC_curve_nist2nid(CCS exp_curve)) == NID_undef +# endif + ) + { + tls_error(string_sprintf("Unknown curve name tls_eccurve '%s'", + exp_curve), + host, NULL); + return FALSE; + } - if ((rv = SSL_CTX_set_tmp_ecdh(sctx, ecdh) != 0)) - { - DEBUG(D_tls) debug_printf("ECDH: enable NIST P-256 curve\n"); - } - else - tls_error(US"Error enabling NIST P-256 curve", host, NULL); - EC_KEY_free(ecdh); - return rv; +if (!(ecdh = EC_KEY_new_by_curve_name(nid))) + { + tls_error("Unable to create ec curve", host, NULL); + return FALSE; } -# endif -#endif + +/* The "tmp" in the name here refers to setting a temporary key +not to the stability of the interface. */ + +if ((rv = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0)) + tls_error(string_sprintf("Error enabling '%s' curve", exp_curve), host, NULL); +else + DEBUG(D_tls) debug_printf("ECDH: enabled '%s' curve\n", exp_curve); + +EC_KEY_free(ecdh); +return !rv; + +# endif /*EXIM_HAVE_ECDH*/ +#endif /*OPENSSL_NO_ECDH*/ } @@ -1321,6 +1366,7 @@ else DEBUG(D_tls) debug_printf("no SSL CTX options to set\n"); /* Initialize with DH parameters if supplied */ +/* Initialize ECDH temp key parameter selection */ if ( !init_dh(*ctxp, dhparam, host) || !init_ecdh(*ctxp, host)