From: Pascal Knecht Date: Sat, 26 Sep 2020 20:19:16 +0000 (+0200) Subject: tls-crypto: Add support to configure DH groups to use X-Git-Tag: 5.9.2rc1~23^2~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e53bee9dbea3c0d64253914da1d4b36165dce595;p=thirdparty%2Fstrongswan.git tls-crypto: Add support to configure DH groups to use And add new test cases to test TLS 1.3 connections for each supported DH group. --- diff --git a/src/libtls/tests/suites/test_socket.c b/src/libtls/tests/suites/test_socket.c index 5682dad88c..c183df5eca 100644 --- a/src/libtls/tests/suites/test_socket.c +++ b/src/libtls/tests/suites/test_socket.c @@ -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); diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index 16aed5c8ca..7c43a570c6 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -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. */ diff --git a/src/libtls/tls_crypto.h b/src/libtls/tls_crypto.h index 784f661676..3d230e9192 100644 --- a/src/libtls/tls_crypto.h +++ b/src/libtls/tls_crypto.h @@ -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 *