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);
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);
}
}
+/**
+ * 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
*/
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;
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,
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.
*/