summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2023-04-01 23:05:00 +0000
committerDaiki Ueno <ueno@gnu.org>2023-04-01 23:05:00 +0000
commit1fd97c0b7fe75bc46b768af8ce018425ebeab151 (patch)
treef7f2681f3ef0a6af8ec6148ef260ef151775d0d8
parentb3fe5c229474a4dd0e74e955afb6bdc5d54c462d (diff)
parentb6b71c8b70061eb5a489443ba82c90df948da95b (diff)
downloadgnutls-1fd97c0b7fe75bc46b768af8ce018425ebeab151.tar.gz
Merge branch 'dev0' into 'master'
added clientHello extension permutation Closes #1465 See merge request gnutls/gnutls!1737
-rw-r--r--lib/gnutls_int.h3
-rw-r--r--lib/hello_ext.c49
-rw-r--r--lib/priority.c5
-rw-r--r--lib/priority_options.gperf1
-rw-r--r--tests/tls13-early-data.c4
-rw-r--r--tests/tls13/prf-early.c4
-rw-r--r--tests/tls13/prf.c5
7 files changed, 64 insertions, 7 deletions
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index d4b2e280e0..a3ee5e6f20 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -948,6 +948,9 @@ struct gnutls_priority_st {
/* to disable record padding */
bool no_extensions;
+ /* to disable extensions shuffling */
+ bool no_exts_shuffle;
+
safe_renegotiation_t sr;
bool min_record_version;
bool server_precedence;
diff --git a/lib/hello_ext.c b/lib/hello_ext.c
index 6870db8a81..a15e91876a 100644
--- a/lib/hello_ext.c
+++ b/lib/hello_ext.c
@@ -408,6 +408,30 @@ int hello_ext_send(void *_ctx, gnutls_buffer_st * buf)
return 0;
}
+static inline void swap_exts(extensions_t * exts1, extensions_t * exts2)
+{
+ extensions_t temp = *exts1;
+ *exts1 = *exts2;
+ *exts2 = temp;
+}
+
+static
+int shuffle_exts(extensions_t * exts, size_t size)
+{
+ /* generating random permutation of extensions */
+ extensions_t rnd_n;
+ for (size_t i = size - 1; i > 0; i--) {
+ int ret = gnutls_rnd(GNUTLS_RND_RANDOM, (void *)&rnd_n,
+ sizeof(extensions_t));
+ if (ret < 0)
+ return ret;
+ extensions_t j = rnd_n % (i + 1);
+ swap_exts(&exts[i], &exts[j]);
+ }
+
+ return 0;
+}
+
int
_gnutls_gen_hello_extensions(gnutls_session_t session,
gnutls_buffer_st * buf,
@@ -446,9 +470,32 @@ _gnutls_gen_hello_extensions(gnutls_session_t session,
ret - 4);
}
+ /* To shuffle extension sending order */
+ extensions_t shuffled_exts[MAX_EXT_TYPES];
+
+ /* Initializing extensions array */
+ for (i = 0; i < MAX_EXT_TYPES; i++) {
+ shuffled_exts[i] = i;
+ }
+
+ /* ordering dumbfw and pre_shared_key as last extensions */
+ swap_exts(&shuffled_exts[MAX_EXT_TYPES - 2],
+ &shuffled_exts[GNUTLS_EXTENSION_DUMBFW]);
+ swap_exts(&shuffled_exts[MAX_EXT_TYPES - 1],
+ &shuffled_exts[GNUTLS_EXTENSION_PRE_SHARED_KEY]);
+
+ if (session->internals.priorities->no_exts_shuffle == 1)
+ goto next;
+
+ ret = shuffle_exts(shuffled_exts, MAX_EXT_TYPES - 2);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ next:
/* hello_ext_send() ensures we don't send duplicates, in case
* of overridden extensions */
- for (i = 0; i < MAX_EXT_TYPES; i++) {
+ for (size_t r = 0; r < MAX_EXT_TYPES; r++) {
+ i = shuffled_exts[r];
if (!extfunc[i])
continue;
diff --git a/lib/priority.c b/lib/priority.c
index 4b5eb7c77d..966de4d83d 100644
--- a/lib/priority.c
+++ b/lib/priority.c
@@ -1081,6 +1081,11 @@ static void disable_tls13_compat_mode(gnutls_priority_t c)
c->tls13_compat_mode = false;
}
+static void enable_no_exts_shuffle(gnutls_priority_t c)
+{
+ c->no_exts_shuffle = 1;
+}
+
static void dummy_func(gnutls_priority_t c)
{
}
diff --git a/lib/priority_options.gperf b/lib/priority_options.gperf
index 11bcc6e88e..d69c3b4b11 100644
--- a/lib/priority_options.gperf
+++ b/lib/priority_options.gperf
@@ -43,3 +43,4 @@ NEW_PADDING, dummy_func
DEBUG_ALLOW_KEY_USAGE_VIOLATIONS, enable_server_key_usage_violations
ALLOW_SMALL_RECORDS, enable_allow_small_records
DISABLE_TLS13_COMPAT_MODE, disable_tls13_compat_mode
+NO_EXTS_SHUFFLE, enable_no_exts_shuffle
diff --git a/tests/tls13-early-data.c b/tests/tls13-early-data.c
index b89fe75367..d7ed79b3bf 100644
--- a/tests/tls13-early-data.c
+++ b/tests/tls13-early-data.c
@@ -91,8 +91,8 @@ extern unsigned int _gnutls_global_version;
* selected during the initial handshake, not the resuming handshakes.
*/
# define SESSIONS 3
-# define TLS13_AES_128_GCM "NONE:+VERS-TLS1.3:+AES-128-GCM:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1"
-# define TLS13_CHACHA20_POLY1305 "NONE:+VERS-TLS1.3:+CHACHA20-POLY1305:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1"
+# define TLS13_AES_128_GCM "NONE:+VERS-TLS1.3:+AES-128-GCM:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1:%NO_EXTS_SHUFFLE"
+# define TLS13_CHACHA20_POLY1305 "NONE:+VERS-TLS1.3:+CHACHA20-POLY1305:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1:%NO_EXTS_SHUFFLE"
static const
gnutls_datum_t hrnd = { (void *)
diff --git a/tests/tls13/prf-early.c b/tests/tls13/prf-early.c
index a21bc1c7a4..0df9a18abd 100644
--- a/tests/tls13/prf-early.c
+++ b/tests/tls13/prf-early.c
@@ -183,9 +183,9 @@ static void client(int sds[])
*/
gnutls_init(&session, GNUTLS_CLIENT);
- /* Use default priorities */
+ /* Use default priorities, sets %NO_EXTS_SHUFFLE */
ret = gnutls_priority_set_direct(session,
- "NONE:+VERS-TLS1.3:+AES-256-GCM:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1",
+ "NONE:+VERS-TLS1.3:+AES-256-GCM:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1:%NO_EXTS_SHUFFLE",
&err);
if (ret < 0) {
fail("client: priority set failed (%s): %s\n",
diff --git a/tests/tls13/prf.c b/tests/tls13/prf.c
index 1cd3f9e5ec..003ed69b01 100644
--- a/tests/tls13/prf.c
+++ b/tests/tls13/prf.c
@@ -196,10 +196,11 @@ static void client(int fd)
*/
gnutls_init(&session, GNUTLS_CLIENT);
- /* Use default priorities */
+ /* Use default priorities, sets %NO_EXTS_SHUFFLE */
ret = gnutls_priority_set_direct(session,
- "NONE:+VERS-TLS1.3:+AES-256-GCM:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1",
+ "NONE:+VERS-TLS1.3:+AES-256-GCM:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1:%NO_EXTS_SHUFFLE",
&err);
+
if (ret < 0) {
fail("client: priority set failed (%s): %s\n",
gnutls_strerror(ret), err);