]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
key_share: treat X25519 and X448 as same PK type when advertising
authorDaiki Ueno <ueno@gnu.org>
Fri, 25 Jun 2021 06:39:12 +0000 (08:39 +0200)
committerDaiki Ueno <ueno@gnu.org>
Fri, 25 Jun 2021 07:33:23 +0000 (09:33 +0200)
Previously, if both X25519 and X448 groups were enabled in the
priority string, the client sent both algorithms in a key_share
extension, while it was only capable of handling one algorithm from
the same (Edwards curve) category.  This adds an extra check so the
client should send either X25519 or X448.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
lib/ext/key_share.c
tests/tls13/key_share.c

index a8c4bb5cff5d93af203cac0fd601e2814e7d89ef..a4db3af950e00511ba189c2fa147c8e69e603819 100644 (file)
@@ -656,6 +656,18 @@ key_share_recv_params(gnutls_session_t session,
        return 0;
 }
 
+static inline bool
+pk_type_is_ecdhx(gnutls_pk_algorithm_t pk)
+{
+       return pk == GNUTLS_PK_ECDH_X25519 || pk == GNUTLS_PK_ECDH_X448;
+}
+
+static inline bool
+pk_type_equal(gnutls_pk_algorithm_t a, gnutls_pk_algorithm_t b)
+{
+       return a == b || (pk_type_is_ecdhx(a) && pk_type_is_ecdhx(b));
+}
+
 /* returns data_size or a negative number on failure
  */
 static int
@@ -710,12 +722,18 @@ key_share_send_params(gnutls_session_t session,
                        /* generate key shares for out top-(max_groups) groups
                         * if they are of different PK type. */
                        for (i = 0; i < session->internals.priorities->groups.size; i++) {
+                               unsigned int j;
+
                                group = session->internals.priorities->groups.entry[i];
 
-                               if (generated == 1 && group->pk == selected_groups[0])
-                                       continue;
-                               else if (generated == 2 && (group->pk == selected_groups[1] || group->pk == selected_groups[0]))
+                               for (j = 0; j < generated; j++) {
+                                       if (pk_type_equal(group->pk, selected_groups[j])) {
+                                               break;
+                                       }
+                               }
+                               if (j < generated) {
                                        continue;
+                               }
 
                                selected_groups[generated] = group->pk;
 
index 7f8f6295cea3fb47f5f2fad80ccbdaec706dc605..816a7d9b58ffdff78e9a1e4017d7b9a4e65428fe 100644 (file)
@@ -124,6 +124,7 @@ unsigned int tls_id_to_group[] = {
        [23] = GNUTLS_GROUP_SECP256R1,
        [24] = GNUTLS_GROUP_SECP384R1,
        [29] = GNUTLS_GROUP_X25519,
+       [30] = GNUTLS_GROUP_X448,
        [0x100] = GNUTLS_GROUP_FFDHE2048,
        [0x101] = GNUTLS_GROUP_FFDHE3072
 };
@@ -315,11 +316,13 @@ void doit(void)
        start("two groups: default secp256r1", "NORMAL:-VERS-ALL:+VERS-TLS1.3", GNUTLS_KEY_SHARE_TOP2, GNUTLS_GROUP_SECP256R1, 2);
        start("two groups: secp256r1", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-X25519:+GROUP-FFDHE2048", GNUTLS_KEY_SHARE_TOP2, GNUTLS_GROUP_SECP256R1, 2);
        start("two groups: x25519", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-FFDHE2048", GNUTLS_KEY_SHARE_TOP2, GNUTLS_GROUP_X25519, 2);
+       start("two groups: x448", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X448:+GROUP-X25519:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-FFDHE2048", GNUTLS_KEY_SHARE_TOP2, GNUTLS_GROUP_X448, 2);
        start("two groups: ffdhe2048", "NORMAL:-KX-ALL:+DHE-RSA:+ECDHE-RSA:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-X25519:+GROUP-FFDHE3072", GNUTLS_KEY_SHARE_TOP2, GNUTLS_GROUP_FFDHE2048, 2);
 
        start("three groups: default secp256r1", "NORMAL:-VERS-ALL:+VERS-TLS1.3", GNUTLS_KEY_SHARE_TOP3, GNUTLS_GROUP_SECP256R1, 3);
        start("three groups: secp256r1", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-X25519:+GROUP-FFDHE2048", GNUTLS_KEY_SHARE_TOP3, GNUTLS_GROUP_SECP256R1, 3);
        start("three groups: x25519", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-FFDHE2048", GNUTLS_KEY_SHARE_TOP3, GNUTLS_GROUP_X25519, 3);
+       start("three groups: x448", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X448:+GROUP-X25519:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-FFDHE2048", GNUTLS_KEY_SHARE_TOP3, GNUTLS_GROUP_X448, 3);
        start("three groups: ffdhe2048", "NORMAL:-KX-ALL:+DHE-RSA:+ECDHE-RSA:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-X25519:+GROUP-FFDHE3072", GNUTLS_KEY_SHARE_TOP3, GNUTLS_GROUP_FFDHE2048, 3);
 
        /* test default behavior */