From 95d31cea2897eafc14a4b7dc87269ef4c6c70fed Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 12 Mar 2018 17:10:42 +0100 Subject: priorities: disable any key exchange methods if there is no TLS1.2 or earlier That is, because TLS1.2 has specific requirements in the ordering of curves/groups if certain ciphersuites (ECDHE/DHE) are present, and by being able to eliminate them early we simplify the negotiation for TLS1.3-only clients/servers. Relates #378 Signed-off-by: Nikos Mavrogiannopoulos --- lib/priority.c | 49 ++++++++++++++++++++++++++++++++++-------------- tests/tls13-cipher-neg.c | 4 ++-- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/lib/priority.c b/lib/priority.c index 8e2132ffea..65b3dd3d93 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -1172,8 +1172,10 @@ static int set_ciphersuite_list(gnutls_priority_t priority_cache) unsigned have_ec = 0; unsigned have_dh = 0; unsigned tls_sig_sem = 0; - const version_entry_st *tlsmax = NULL; + const version_entry_st *tlsmax = NULL, *vers; const version_entry_st *dtlsmax = NULL; + const version_entry_st *tlsmin = NULL; + const version_entry_st *dtlsmin = NULL; unsigned have_tls13 = 0; priority_cache->cs.size = 0; @@ -1182,23 +1184,42 @@ static int set_ciphersuite_list(gnutls_priority_t priority_cache) priority_cache->groups.have_ffdhe = 0; for (i = 0; i < priority_cache->protocol.algorithms; i++) { - if (priority_cache->protocol.priority[i] < GNUTLS_DTLS_VERSION_MIN) { - tlsmax = version_to_entry(priority_cache->protocol.priority[i]); - if (tlsmax) { - tls_sig_sem |= tlsmax->tls_sig_sem; - if (tlsmax->tls13_sem) - have_tls13 = 1; - } + vers = version_to_entry(priority_cache->protocol.priority[i]); + if (!vers) + continue; + + if (vers->transport == GNUTLS_STREAM) { /* TLS */ + tls_sig_sem |= vers->tls_sig_sem; + if (vers->tls13_sem) + have_tls13 = 1; + + if (tlsmax == NULL || vers->age > tlsmax->age) + tlsmax = vers; + if (tlsmin == NULL || vers->age < tlsmin->age) + tlsmin = vers; } else { /* dtls */ - dtlsmax = version_to_entry(priority_cache->protocol.priority[i]); - if (dtlsmax) { - tls_sig_sem |= dtlsmax->tls_sig_sem; - if (dtlsmax->tls13_sem) - have_tls13 = 1; - } + tls_sig_sem |= vers->tls_sig_sem; + if (vers->tls13_sem) + have_tls13 = 1; + + if (dtlsmax == NULL || vers->age > dtlsmax->age) + dtlsmax = vers; + if (dtlsmin == NULL || vers->age < dtlsmin->age) + dtlsmin = vers; } } + /* DTLS or TLS protocols must be present */ + if ((!tlsmax || !tlsmin) && (!dtlsmax || !dtlsmin)) + return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET); + + /* if we are have TLS1.3+ do not enable any key exchange algorithms, + * the protocol doesn't require any. */ + if (tlsmin && tlsmin->tls13_sem) { + if (!dtlsmin || (dtlsmin && dtlsmin->tls13_sem)) + priority_cache->_kx.algorithms = 0; + } + /* Add TLS 1.3 ciphersuites (no KX) */ for (j=0;j_cipher.algorithms;j++) { for (z=0;z_mac.algorithms;z++) { diff --git a/tests/tls13-cipher-neg.c b/tests/tls13-cipher-neg.c index ea9df13142..b2d402cb85 100644 --- a/tests/tls13-cipher-neg.c +++ b/tests/tls13-cipher-neg.c @@ -40,8 +40,8 @@ /* We remove the ECDHE and DHE key exchanges as they impose additional * rules in the sorting of groups. */ -#define SPRIO "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3:-ECDHE-RSA:-ECDHE-ECDSA:-DHE-RSA:-RSA:-DHE-DSS" -#define CPRIO "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:-ECDHE-RSA:-ECDHE-ECDSA:-DHE-RSA:-RSA:-DHE-DSS" +#define SPRIO "NORMAL:-VERS-ALL:+VERS-TLS1.3" +#define CPRIO "NORMAL:-VERS-ALL:+VERS-TLS1.3" test_case_st tests[] = { { -- cgit v1.2.1