]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
tls-crypto: Add support to configure DH groups to use
authorPascal Knecht <pascal.knecht@hsr.ch>
Sat, 26 Sep 2020 20:19:16 +0000 (22:19 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 12 Feb 2021 13:35:23 +0000 (14:35 +0100)
And add new test cases to test TLS 1.3 connections for each supported DH
group.

src/libtls/tests/suites/test_socket.c
src/libtls/tls_crypto.c
src/libtls/tls_crypto.h

index 5682dad88cfdfa717d9c90f7c497fa0f41bab007..c183df5ecaf37c0e10db6b68600d1d2dae681a5d 100644 (file)
@@ -444,6 +444,49 @@ static void test_tls(tls_version_t version, uint16_t port, bool cauth, u_int i)
        free(config);
 }
 
+/**
+ * TLS curve test wrapper function
+ */
+static void test_tls_curves(tls_version_t version, uint16_t port, bool cauth,
+                                                       u_int i)
+{
+       echo_server_config_t *config;
+       diffie_hellman_group_t *groups;
+       char curve[128];
+       int count;
+
+       INIT(config,
+               .version = version,
+               .addr = "127.0.0.1",
+               .port = port,
+               .cauth = cauth,
+               .data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08),
+       );
+
+       start_echo_server(config);
+
+       count = tls_crypto_get_supported_groups(&groups);
+       ck_assert(i < count);
+       snprintf(curve, sizeof(curve), "%N", diffie_hellman_group_names_short,
+                        groups[i]);
+       lib->settings->set_str(lib->settings, "%s.tls.curve", curve, lib->ns);
+
+       run_echo_client(config);
+
+       free(groups);
+
+       shutdown(config->fd, SHUT_RDWR);
+       close(config->fd);
+
+       free(config);
+}
+
+START_TEST(test_tls13_curves)
+{
+       test_tls_curves(TLS_1_3, 5668, FALSE, _i);
+}
+END_TEST
+
 START_TEST(test_tls13)
 {
        test_tls(TLS_1_3, 5669, FALSE, _i);
@@ -503,6 +546,12 @@ Suite *socket_suite_create()
 
        s = suite_create("socket");
 
+       tc = tcase_create("TLS 1.3/curves");
+       tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
+       tcase_add_loop_test(tc, test_tls13_curves, 0,
+                                               tls_crypto_get_supported_groups(NULL));
+       suite_add_tcase(s, tc);
+
        tc = tcase_create("TLS 1.3/anon");
        tcase_add_checked_fixture(tc, setup_creds, teardown_creds);
        add_tls_test(test_tls13, TLS_1_3);
index 16aed5c8ca08efc07cb8a0b7f80e3cbfb1f764b8..7c43a570c65db7176cecc78cb05a33cb97e262b7 100644 (file)
@@ -1091,6 +1091,35 @@ static void filter_specific_config_suites(private_tls_crypto_t *this,
        }
 }
 
+/**
+ * Filter key exchange curves by curve user config
+ */
+static bool filter_curve_config(tls_named_group_t curve)
+{
+       enumerator_t *enumerator;
+       char *token, *config;
+
+       config = lib->settings->get_str(lib->settings, "%s.tls.curve", NULL, lib->ns);
+       if (config)
+       {
+               enumerator = enumerator_create_token(config, ",", " ");
+               while (enumerator->enumerate(enumerator, &token))
+               {
+                       const proposal_token_t *tok;
+
+                       tok = lib->proposal->get_token(lib->proposal, token);
+                       if (tok != NULL && tok->type == DIFFIE_HELLMAN_GROUP &&
+                               curve == tls_ec_group_to_curve(tok->algorithm))
+                       {
+                               enumerator->destroy(enumerator);
+                               return TRUE;
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       return !config;
+}
+
 /**
  * Filter out unsupported suites on given suite array
  */
@@ -1524,29 +1553,52 @@ static struct {
 CALLBACK(group_filter, bool,
        void *null, enumerator_t *orig, va_list args)
 {
-       diffie_hellman_group_t group, *out;
-       tls_named_group_t *curve;
+       diffie_hellman_group_t group, *group_out;
+       tls_named_group_t curve, *curve_out;
        char *plugin;
-       int i;
 
-       VA_ARGS_VGET(args, out, curve);
+       VA_ARGS_VGET(args, group_out, curve_out);
 
        while (orig->enumerate(orig, &group, &plugin))
        {
-               for (i = 0; i < countof(curves); i++)
+               curve = tls_ec_group_to_curve(group);
+               if (curve)
                {
-                       if (curves[i].group == group)
+                       if (group_out)
                        {
-                               if (out)
-                               {
-                                       *out = curves[i].group;
-                               }
-                               if (curve)
-                               {
-                                       *curve = curves[i].curve;
-                               }
-                               return TRUE;
+                               *group_out = group;
+                       }
+                       if (curve_out)
+                       {
+                               *curve_out = curve;
+                       }
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+CALLBACK(config_filter, bool,
+       void *null, enumerator_t *orig, va_list args)
+{
+       diffie_hellman_group_t group, *group_out;
+       tls_named_group_t curve, *curve_out;
+
+       VA_ARGS_VGET(args, group_out, curve_out);
+
+       while (orig->enumerate(orig, &group, &curve))
+       {
+               if (filter_curve_config(curve))
+               {
+                       if (group_out)
+                       {
+                               *group_out = group;
                        }
+                       if (curve_out)
+                       {
+                               *curve_out = curve;
+                       }
+                       return TRUE;
                }
        }
        return FALSE;
@@ -1556,8 +1608,10 @@ METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*,
        private_tls_crypto_t *this)
 {
        return enumerator_create_filter(
-                                                       lib->crypto->create_dh_enumerator(lib->crypto),
-                                                       group_filter, NULL, NULL);
+                                                       enumerator_create_filter(
+                                                               lib->crypto->create_dh_enumerator(lib->crypto),
+                                                               group_filter, NULL, NULL),
+                                                       config_filter, NULL, NULL);
 }
 
 METHOD(tls_crypto_t, set_protection, void,
@@ -2320,6 +2374,38 @@ int tls_crypto_get_supported_suites(bool null, tls_version_t version,
        return count;
 }
 
+/**
+ * See header.
+ */
+int tls_crypto_get_supported_groups(diffie_hellman_group_t **out)
+{
+       enumerator_t *enumerator;
+       diffie_hellman_group_t groups[countof(curves)];
+       diffie_hellman_group_t group;
+       tls_named_group_t curve;
+       int count = 0, i;
+
+       enumerator = enumerator_create_filter(
+                                                       lib->crypto->create_dh_enumerator(lib->crypto),
+                                                       group_filter, NULL, NULL);
+
+       while (enumerator->enumerate(enumerator, &group, &curve))
+       {
+               groups[count++] = group;
+       }
+       enumerator->destroy(enumerator);
+
+       if (out)
+       {
+               *out = calloc(count, sizeof(diffie_hellman_group_t));
+               for (i = 0; i < count; i++)
+               {
+                       (*out)[i] = groups[i];
+               }
+       }
+       return count;
+}
+
 /**
  * See header.
  */
index 784f6616761bb7c57ed04fa1eff4fd8b8f9194d1..3d230e919206cc74529614fa900e879925a1ba22 100644 (file)
@@ -669,6 +669,14 @@ tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache);
 int tls_crypto_get_supported_suites(bool null, tls_version_t version,
                                                                        tls_cipher_suite_t **suites);
 
+/**
+ * Get a list of all supported TLS DH groups.
+ *
+ * @param groups               pointer to allocated DH group array, to free(), or NULL
+ * @return                             number of curves supported
+ */
+int tls_crypto_get_supported_groups(diffie_hellman_group_t **groups);
+
 /**
  * Get the TLS curve of a given EC DH group
  *