Gitweb:
http://git.exim.org/exim.git/commitdiff/54c90be16587ca315041c964e251f07fc2bcf0e9
Commit: 54c90be16587ca315041c964e251f07fc2bcf0e9
Parent: 12f6998964d44c0a40783162fc37eabe770f4382
Author: Phil Pennock <pdp@???>
AuthorDate: Fri Jun 1 05:52:31 2012 -0400
Committer: Phil Pennock <pdp@???>
CommitDate: Fri Jun 1 05:52:31 2012 -0400
tls_dh_min_bits smtp transport option
Could not find an API for use with OpenSSL, so GnuTLS only
---
doc/doc-docbook/spec.xfpt | 20 ++++++++++++++++++++
doc/doc-txt/ChangeLog | 3 +++
doc/doc-txt/NewStuff | 11 +++++++++++
doc/doc-txt/OptionLists.txt | 2 ++
src/src/buildconfig.c | 11 ++++++-----
src/src/config.h.defaults | 3 ++-
src/src/functions.h | 2 +-
src/src/tls-gnu.c | 15 +++++++++++++--
src/src/tls-openssl.c | 4 +++-
src/src/transports/smtp.c | 9 +++++++--
src/src/transports/smtp.h | 3 ++-
11 files changed, 70 insertions(+), 13 deletions(-)
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 61cdc1e..78d5b0b 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -22451,6 +22451,19 @@ This option specifies a certificate revocation list. The expanded value must
be the name of a file that contains a CRL in PEM format.
+.new
+.option tls_dh_min_bits smtp integer 1024
+.cindex "TLS" "Diffie-Hellman minimum acceptable size"
+When establishing a TLS session, if a ciphersuite which uses Diffie-Hellman
+key agreement is negotiated, the server will provide a large prime number
+for use. This option establishes the minimum acceptable size of that number.
+If the parameter offered by the server is too small, then the TLS handshake
+will fail.
+
+Only supported when using GnuTLS.
+.wen
+
+
.option tls_privatekey smtp string&!! unset
.cindex "TLS" "client private key, location of"
.vindex "&$host$&"
@@ -25004,6 +25017,13 @@ option).
The &%tls_require_ciphers%& options operate differently, as described in the
sections &<<SECTreqciphssl>>& and &<<SECTreqciphgnu>>&.
.next
+.new
+The &%tls_dh_min_bits%& SMTP transport option is only honoured by GnuTLS.
+When using OpenSSL, this option is ignored.
+(If an API is found to let OpenSSL be configured in this way,
+let the Exim Maintainers know and we'll likely use it).
+.wen
+.next
Some other recently added features may only be available in one or the other.
This should be documented with the feature. If the documentation does not
explicitly state that the feature is infeasible in the other TLS
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 533ce50..635533f 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -9,6 +9,9 @@ PP/01 Add -bI: framework, and -bI:sieve for querying sieve capabilities.
PP/02 Make -n do something, by making it not do something.
When combined with -bP, the name of an option is not output.
+PP/03 Added tls_dh_min_bits SMTP transport driver option, only honoured
+ by GnuTLS.
+
Exim version 4.80
-----------------
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 5088a24..be8285b 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -20,6 +20,17 @@ Version 4.81
For instance, "exim -n -bP pid_file_path" should just emit a pathname
followed by a newline, and no other text.
+ 3. When built with SUPPORT_TLS and USE_GNUTLS, the SMTP transport driver now
+ has a "tls_dh_min_bits" option, to set the minimum acceptable number of
+ bits in the Diffie-Hellman prime offered by a server (in DH ciphersuites)
+ acceptable for security. (Option accepted but ignored if using OpenSSL).
+ Defaults to 1024, the old value. May be lowered only to 512, or raised as
+ far as you like. Raising this may hinder TLS interoperability with other
+ sites and is not currently recommended. Lowering this will permit you to
+ establish a TLS session which is not as secure as you might like.
+
+ Unless you really know what you are doing, leave it alone.
+
Version 4.80
------------
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 45b7997..b8e8599 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -548,6 +548,7 @@ tls_advertise_hosts host list * main
tls_certificate string* unset main 3.20
unset smtp 3.20
tls_dh_max_bits integer 2236 main 4.80
+tls_dh_min_bits integer 1024 smtp 4.81
tls_dhparam string* unset main 3.20
tls_on_connect_ports string unset main 4.43
tls_privatekey string* unset main 3.20
@@ -623,6 +624,7 @@ provide compatibility with Sendmail.
-bh Test incoming SMTP call, omitting callouts
-bhc Test incoming SMTP call, with callouts
-bi * Run <command>bi_command</command>
+-bI:help Show list of accepted -bI:<tag> options
-bm Accept message on standard input
-bmalware + Invoke configured malware scanning against supplied filename
-bnq Don't qualify addresses in locally submitted messages
diff --git a/src/src/buildconfig.c b/src/src/buildconfig.c
index 62114fc..f3390cb 100644
--- a/src/src/buildconfig.c
+++ b/src/src/buildconfig.c
@@ -847,16 +847,17 @@ else if (isgroup)
}
/* how many bits Exim, as a client, demands must be in D-H */
- /* as of GnuTLS 2.12.x, we ask for "normal" for D-H PK; before that, we
- specify the number of bits. We've stuck with the historical value, but
- it can be overridden. */
- else if ((strcmp(name, "EXIM_CLIENT_DH_MIN_BITS") == 0) ||
+ /* 1024 is a historical figure; some sites actually use lower, so we
+ permit the value to be lowered "dangerously" low, but not "insanely"
+ low. Though actually, 1024 is becoming "dangerous". */
+ else if ((strcmp(name, "EXIM_CLIENT_DH_MIN_MIN_BITS") == 0) ||
+ (strcmp(name, "EXIM_CLIENT_DH_DEFAULT_MIN_BITS") == 0) ||
(strcmp(name, "EXIM_SERVER_DH_BITS_PRE2_12") == 0))
{
long nv;
char *end;
nv = strtol(value, &end, 10);
- if (end != value && *end == '\0' && nv >= 1000 && nv < 50000)
+ if (end != value && *end == '\0' && nv >= 512 && nv < 500000)
{
fprintf(new, "%s\n", value);
}
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index 92a4cd3..f02aef1 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -49,7 +49,8 @@ it's a default value. */
#define EXIMDB_LOCK_TIMEOUT 60
#define EXIMDB_LOCKFILE_MODE 0640
#define EXIMDB_MODE 0640
-#define EXIM_CLIENT_DH_MIN_BITS
+#define EXIM_CLIENT_DH_MIN_MIN_BITS 512
+#define EXIM_CLIENT_DH_DEFAULT_MIN_BITS 1024
#define EXIM_GNUTLS_LIBRARY_LOG_LEVEL
#define EXIM_SERVER_DH_BITS_PRE2_12
#define EXIM_PERL
diff --git a/src/src/functions.h b/src/src/functions.h
index fa9d558..2758a4a 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -27,7 +27,7 @@ extern const char *
std_dh_prime_named(const uschar *);
extern int tls_client_start(int, host_item *, address_item *, uschar *,
uschar *, uschar *, uschar *, uschar *, uschar *, uschar *,
- int);
+ int, int);
extern void tls_close(BOOL);
extern int tls_feof(void);
extern int tls_ferror(void);
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index c8bf634..cf315b6 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -1536,6 +1536,7 @@ Arguments:
verify_certs file for certificate verify
verify_crl CRL for verify
require_ciphers list of allowed ciphers or NULL
+ dh_min_bits minimum number of bits acceptable in server's DH prime
timeout startup timeout
Returns: OK/DEFER/FAIL (because using common functions),
@@ -1547,7 +1548,7 @@ tls_client_start(int fd, host_item *host,
address_item *addr ARG_UNUSED, uschar *dhparam ARG_UNUSED,
uschar *certificate, uschar *privatekey, uschar *sni,
uschar *verify_certs, uschar *verify_crl,
- uschar *require_ciphers, int timeout)
+ uschar *require_ciphers, int dh_min_bits, int timeout)
{
int rc;
const char *error;
@@ -1559,7 +1560,17 @@ rc = tls_init(host, certificate, privatekey,
sni, verify_certs, verify_crl, require_ciphers, &state);
if (rc != OK) return rc;
-gnutls_dh_set_prime_bits(state->session, EXIM_CLIENT_DH_MIN_BITS);
+if (dh_min_bits < EXIM_CLIENT_DH_MIN_MIN_BITS)
+ {
+ DEBUG(D_tls)
+ debug_printf("WARNING: tls_dh_min_bits far too low, clamping %d up to %d\n",
+ dh_min_bits, EXIM_CLIENT_DH_MIN_MIN_BITS);
+ dh_min_bits = EXIM_CLIENT_DH_MIN_MIN_BITS;
+ }
+
+DEBUG(D_tls) debug_printf("Setting D-H prime minimum acceptable bits to %d\n",
+ dh_min_bits);
+gnutls_dh_set_prime_bits(state->session, dh_min_bits);
if (verify_certs == NULL)
{
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 22c0730..fdcb95e 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -1233,6 +1233,8 @@ Argument:
verify_certs file for certificate verify
crl file containing CRL
require_ciphers list of allowed ciphers
+ dh_min_bits minimum number of bits acceptable in server's DH prime
+ (unused in OpenSSL)
timeout startup timeout
Returns: OK on success
@@ -1244,7 +1246,7 @@ int
tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
uschar *certificate, uschar *privatekey, uschar *sni,
uschar *verify_certs, uschar *crl,
- uschar *require_ciphers, int timeout)
+ uschar *require_ciphers, int dh_min_bits ARG_UNUSED, int timeout)
{
static uschar txt[256];
uschar *expciphers;
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index f9f225f..b3856f5 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -129,6 +129,8 @@ optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, tls_certificate) },
{ "tls_crl", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_crl) },
+ { "tls_dh_min_bits", opt_int,
+ (void *)offsetof(smtp_transport_options_block, tls_dh_min_bits) },
{ "tls_privatekey", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_privatekey) },
{ "tls_require_ciphers", opt_stringptr,
@@ -195,9 +197,11 @@ smtp_transport_options_block smtp_transport_option_defaults = {
NULL, /* gnutls_require_kx */
NULL, /* gnutls_require_mac */
NULL, /* gnutls_require_proto */
+ NULL, /* tls_sni */
NULL, /* tls_verify_certificates */
- TRUE, /* tls_tempfail_tryclear */
- NULL /* tls_sni */
+ EXIM_CLIENT_DH_DEFAULT_MIN_BITS,
+ /* tls_dh_min_bits */
+ TRUE /* tls_tempfail_tryclear */
#endif
#ifndef DISABLE_DKIM
,NULL, /* dkim_canon */
@@ -1136,6 +1140,7 @@ if (tls_offered && !suppress_tls &&
ob->tls_verify_certificates,
ob->tls_crl,
ob->tls_require_ciphers,
+ ob->tls_dh_min_bits,
ob->command_timeout);
/* TLS negotiation failed; give an error. From outside, this function may
diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h
index 621cb6b..17b75cf 100644
--- a/src/src/transports/smtp.h
+++ b/src/src/transports/smtp.h
@@ -52,9 +52,10 @@ typedef struct {
uschar *gnutls_require_kx;
uschar *gnutls_require_mac;
uschar *gnutls_require_proto;
+ uschar *tls_sni;
uschar *tls_verify_certificates;
+ int tls_dh_min_bits;
BOOL tls_tempfail_tryclear;
- uschar *tls_sni;
#endif
#ifndef DISABLE_DKIM
uschar *dkim_domain;