diff options
author | Daiki Ueno <ueno@gnu.org> | 2023-04-01 23:05:00 +0000 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2023-04-01 23:05:00 +0000 |
commit | 1fd97c0b7fe75bc46b768af8ce018425ebeab151 (patch) | |
tree | f7f2681f3ef0a6af8ec6148ef260ef151775d0d8 | |
parent | b3fe5c229474a4dd0e74e955afb6bdc5d54c462d (diff) | |
parent | b6b71c8b70061eb5a489443ba82c90df948da95b (diff) | |
download | gnutls-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.h | 3 | ||||
-rw-r--r-- | lib/hello_ext.c | 49 | ||||
-rw-r--r-- | lib/priority.c | 5 | ||||
-rw-r--r-- | lib/priority_options.gperf | 1 | ||||
-rw-r--r-- | tests/tls13-early-data.c | 4 | ||||
-rw-r--r-- | tests/tls13/prf-early.c | 4 | ||||
-rw-r--r-- | tests/tls13/prf.c | 5 |
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); |