diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-03-12 17:10:42 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-03-23 20:51:34 +0100 |
commit | 95d31cea2897eafc14a4b7dc87269ef4c6c70fed (patch) | |
tree | 891be1c710f3f79d12d5d5a300de5ab489c31b11 | |
parent | 3495f992b8b4cd50f1136edcc2f66b53e701980d (diff) | |
download | gnutls-95d31cea2897eafc14a4b7dc87269ef4c6c70fed.tar.gz |
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 <nmav@redhat.com>
-rw-r--r-- | lib/priority.c | 49 | ||||
-rw-r--r-- | 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<priority_cache->_cipher.algorithms;j++) { for (z=0;z<priority_cache->_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[] = { { |