[exim] Exim, GnuTLS 3.1.7 and up, DH TLS

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: Exim Users
Subject: [exim] Exim, GnuTLS 3.1.7 and up, DH TLS
Folks,

If you're not comfortable with TLS and Exim configuration, please stop
reading now.

Viktor Duchovni from the Postfix folks and I have been picking over a
TLS interop issue. I don't currently have time to set up a test
scenario: I'm wondering if anyone here is using Exim built with GnuTLS
3.1.7 or newer and can check something?

There's a claim that Exim as a client, in a setup, was demanding
Diffie-Hellman parameters of 2048 bits of the client. I'm not seeing
how any current setup should achieve this, but perhaps I'm being blind
and need help getting a smacking to see reality once more.

This affects Exim as a TLS *client*, thus the tls_require_ciphers and
tls_dh_min_bits options on an SMTP transport (*not* in the main section
of the configuration).

When negotiating session keys (for Perfect Forward Secrecy), Exim can
use Ephemeral Diffie-Hellman if the TLS library can. For GnuTLS, after
initialising the library with the GnuTLS Priority String (from
tls_require_ciphers), Exim calls:

gnutls_dh_set_prime_bits(state->session, dh_min_bits);

The idea here is that the TLS session should error out if the number of
bits in the DH parameters are less than the value in dh_min_bits (which
corresponds to the tls_dh_min_bits option, after ensuring it's at least
EXIM_CLIENT_DH_MIN_MIN_BITS in value, which defaults to 1024).

Historically, this was hard-coded at 1024; Exim 4.80 onwards make this a
user-configurable option.

In the GnuTLS git tree, lib/gnutls_ui.c:gnutls_dh_set_prime_bits()
function comment, I now find this text:
- ----------------------------8< cut here >8------------------------------
* Note that since 3.1.7 this function is deprecated. The minimum
* number of bits is set by the priority string level.
- ----------------------------8< cut here >8------------------------------
(it's followed by a warning about ordering constraints, but Exim is
calling in the correct order).

So one reading of that comment suggests that if Exim users upgrade
GnuTLS to 3.1.7 or newer, then the interop work to try to keep TLS from
breaking is ignored, and values from the Priority String are used
instead.

That said, the code, in my brief reading, suggests that the
gnutls_set_prime_bits() value _is_ still honoured.

- ----------------------------8< cut here >8------------------------------
static inline int
_gnutls_dh_get_min_prime_bits (gnutls_session_t session)
{
  if (session->internals.priorities.dh_prime_bits != 0)
    return session->internals.priorities.dh_prime_bits;
  else
    return gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, session->internals.priorities.level);
}
- ----------------------------8< cut here >8------------------------------


If anyone here *does* see Exim/GnuTLS rejecting server TLS sessions
which offer TLS of too small a size, can you see if adjusting
tls_require_ciphers on the SMTP Transport fixes things?

*If* we weren't calling gnutls_dh_set_prime_bits(), then it seems that
with a "NORMAL" priority string, as a client we'd be demanding 2432
bits, and that specifying "WEAK" would be required.

But I'm not seeing any combination of Exim or current GnuTLS git head
settings that could result in the reported behaviour, *unless* the
client explicitly set tls_dh_min_bits on their SMTP Transport, in which
case they got exactly the brokenness which they've explicitly asked for.

Is anyone seeing brokenness in Exim's behaviour here?

- -Phil