/* 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;
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,
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;
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)
{
}
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
* 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 *)
*/
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_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);