summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-03-12 17:10:42 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2018-03-23 20:51:34 +0100
commit95d31cea2897eafc14a4b7dc87269ef4c6c70fed (patch)
tree891be1c710f3f79d12d5d5a300de5ab489c31b11
parent3495f992b8b4cd50f1136edcc2f66b53e701980d (diff)
downloadgnutls-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.c49
-rw-r--r--tests/tls13-cipher-neg.c4
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[] = {
{