libtls: As client, reject DH exchanges using primes smaller than 1024 bit
authorMartin Willi <martin@revosec.ch>
Wed, 20 May 2015 08:56:23 +0000 (10:56 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 26 May 2015 09:36:24 +0000 (11:36 +0200)
While the server signs the ephemeral DH parameters, it can be tricked to its
lowest supported DH group by a man-in-the-middle:

  https://weakdh.org/imperfect-forward-secrecy.pdf

While we at least use 2048-bit DH groups as server, the client accepts any
DH prime the server sends. If it supports export ciphers, only a 512-bit prime
may be used.

As TLS does not define nor negotiate a DH group for cipher suites, the client
actually must accept what the server offers. To avoid downgrades to weak
DH groups, we must reject what we consider insecure. We set this limit to
1024-bit primes. While this breaks compatibility with TLS servers using weaker
primes, this is what we expect servers at least use. Most browser vendors use
the same limit in a similar fix.

src/libtls/tls_peer.c

index 86b94ab..000dda4 100644 (file)
@@ -354,6 +354,13 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this,
                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                return NEED_MORE;
        }
+       /* reject (export) DH groups using primes smaller than 1024 bit */
+       if (prime.len < 1024 / 8)
+       {
+               DBG1(DBG_TLS, "short DH prime received (%zu bytes)", prime.len);
+               this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               return NEED_MORE;
+       }
        public = find_public_key(this);
        if (!public)
        {