summaryrefslogtreecommitdiff
path: root/lib/hello_ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hello_ext.c')
-rw-r--r--lib/hello_ext.c49
1 files changed, 48 insertions, 1 deletions
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;