summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhil Pennock <pdp@exim.org>2012-06-01 05:52:31 -0400
committerPhil Pennock <pdp@exim.org>2012-06-01 05:52:31 -0400
commit54c90be16587ca315041c964e251f07fc2bcf0e9 (patch)
tree5ceb2487ddd6f8cf06f564e0da4deb0497430c1f /src
parent12f6998964d44c0a40783162fc37eabe770f4382 (diff)
tls_dh_min_bits smtp transport option
Could not find an API for use with OpenSSL, so GnuTLS only
Diffstat (limited to 'src')
-rw-r--r--src/src/buildconfig.c11
-rw-r--r--src/src/config.h.defaults3
-rw-r--r--src/src/functions.h2
-rw-r--r--src/src/tls-gnu.c15
-rw-r--r--src/src/tls-openssl.c4
-rw-r--r--src/src/transports/smtp.c9
-rw-r--r--src/src/transports/smtp.h3
7 files changed, 34 insertions, 13 deletions
diff --git a/src/src/buildconfig.c b/src/src/buildconfig.c
index 62114fc09..f3390cb75 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 92a4cd348..f02aef12c 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 fa9d5585e..2758a4aec 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 c8bf634bc..cf315b6d1 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 22c0730c3..fdcb95ef2 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 f9f225fca..b3856f553 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 621cb6ba9..17b75cf3b 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;