diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index bb7ad8768..4c29af1ef 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -536,11 +536,12 @@ METHOD(auth_cfg_t, add_pubkey_constraints, void, private_auth_cfg_t *this, char* constraints, bool ike) { enumerator_t *enumerator; - bool is_ike = FALSE, ike_added = FALSE; + bool ike_added = FALSE; key_type_t expected_type = -1; auth_rule_t expected_strength = AUTH_RULE_MAX; + signature_params_t *params; int strength; - char *token; + char *token, *key_token = NULL; auth_rule_t type; void *value; @@ -589,72 +590,108 @@ METHOD(auth_cfg_t, add_pubkey_constraints, void, } if (streq(token, "rsa") || streq(token, "ike:rsa")) { + key_token = token; + expected_type = KEY_RSA; + expected_strength = AUTH_RULE_RSA_STRENGTH; + continue; + } + if (streq(token, "rsa/pss") || streq(token, "ike:rsa/pss")) + { + key_token = token; expected_type = KEY_RSA; expected_strength = AUTH_RULE_RSA_STRENGTH; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "ecdsa") || streq(token, "ike:ecdsa")) { + key_token = token; expected_type = KEY_ECDSA; expected_strength = AUTH_RULE_ECDSA_STRENGTH; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "ed25519") || streq(token, "ike:ed25519")) { + key_token = token; expected_type = KEY_ED25519; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "ed448") || streq(token, "ike:ed448")) { + key_token = token; expected_type = KEY_ED448; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "bliss") || streq(token, "ike:bliss")) { + key_token = token; expected_type = KEY_BLISS; expected_strength = AUTH_RULE_BLISS_STRENGTH; - is_ike = strpfx(token, "ike:"); continue; } if (streq(token, "pubkey") || streq(token, "ike:pubkey")) { + key_token = token; expected_type = KEY_ANY; - is_ike = strpfx(token, "ike:"); continue; } - if (is_ike && !ike) + if (key_token && strpfx(key_token, "ike:") && !ike) { continue; } - for (i = 0; i < countof(schemes); i++) - { - if (streq(schemes[i].name, token)) + if (key_token && streq(key_token + strlen(key_token) - 3, "pss")) + { /* these are not added automatically with 'pubkey' */ + hash_algorithm_t hash; + if (enum_from_name(hash_algorithm_short_names, token, &hash)) { - if (expected_type == KEY_ANY || expected_type == schemes[i].key) + rsa_pss_params_t pss = { + .hash = hash, + .mgf1_hash = hash, + .salt_len = RSA_PSS_SALT_LEN_DEFAULT, + }; + signature_params_t pss_params = { + .scheme = SIGN_RSA_EMSA_PSS, + .params = &pss, + }; + params = signature_params_clone(&pss_params); + if (strpfx(key_token, "ike:")) { - signature_params_t *params; - - INIT(params, - .scheme = schemes[i].scheme, - ); - if (is_ike) - { - add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params); - ike_added = TRUE; - } - else - { - add(this, AUTH_RULE_SIGNATURE_SCHEME, params); - } + add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params); + ike_added = TRUE; + } + else + { + add(this, AUTH_RULE_SIGNATURE_SCHEME, params); } found = TRUE; } } + else + { + for (i = 0; i < countof(schemes); i++) + { + if (streq(schemes[i].name, token)) + { + if (expected_type == KEY_ANY || + expected_type == schemes[i].key) + { + INIT(params, + .scheme = schemes[i].scheme, + ); + if (strpfx(key_token, "ike:")) + { + add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params); + ike_added = TRUE; + } + else + { + add(this, AUTH_RULE_SIGNATURE_SCHEME, params); + } + } + found = TRUE; + } + } + } if (!found) { DBG1(DBG_CFG, "ignoring invalid auth token: '%s'", token); diff --git a/src/libstrongswan/tests/suites/test_auth_cfg.c b/src/libstrongswan/tests/suites/test_auth_cfg.c index 3e30e0d0a..0c5baaf6b 100644 --- a/src/libstrongswan/tests/suites/test_auth_cfg.c +++ b/src/libstrongswan/tests/suites/test_auth_cfg.c @@ -106,6 +106,76 @@ START_TEST(test_ike_contraints_fallback) } END_TEST +typedef union { + rsa_pss_params_t pss; +} signature_param_types_t; + +struct { + char *constraints; + signature_scheme_t sig[5]; + signature_param_types_t p[5]; +} sig_constraints_params_tests[] = { + { "rsa/pss-sha256", { SIGN_RSA_EMSA_PSS, 0 }, { + { .pss = { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, }}}}, + { "rsa/pss-sha256-sha384", { SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PSS, 0 }, { + { .pss = { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, }}, + { .pss = { .hash = HASH_SHA384, .mgf1_hash = HASH_SHA384, .salt_len = HASH_SIZE_SHA384, }}}}, + { "rsa/pss-sha256-rsa-sha256", { SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PKCS1_SHA2_256, 0 }, { + { .pss = { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, }}}}, + { "rsa-sha256-rsa/pss-sha256", { SIGN_RSA_EMSA_PKCS1_SHA2_256, SIGN_RSA_EMSA_PSS, 0 }, { + {}, + { .pss = { .hash = HASH_SHA256, .mgf1_hash = HASH_SHA256, .salt_len = HASH_SIZE_SHA256, }}}}, + { "rsa/pss", { 0 }, {}}, +}; + +static void check_sig_constraints_params(auth_cfg_t *cfg, auth_rule_t type, + signature_scheme_t scheme[], + signature_param_types_t p[]) +{ + enumerator_t *enumerator; + auth_rule_t t; + signature_params_t *value; + int i = 0; + + enumerator = cfg->create_enumerator(cfg); + while (enumerator->enumerate(enumerator, &t, &value)) + { + if (t == type) + { + if (scheme[i] == SIGN_RSA_EMSA_PSS) + { + signature_params_t expected = { + .scheme = scheme[i], + .params = &p[i].pss, + }; + ck_assert(signature_params_equal(value, &expected)); + } + else + { + ck_assert(scheme[i]); + ck_assert(!value->params); + ck_assert_int_eq(scheme[i], value->scheme); + } + i++; + } + } + enumerator->destroy(enumerator); + ck_assert(!scheme[i]); +} + +START_TEST(test_sig_contraints_params) +{ + auth_cfg_t *cfg; + + cfg = auth_cfg_create(); + cfg->add_pubkey_constraints(cfg, sig_constraints_params_tests[_i].constraints, TRUE); + check_sig_constraints_params(cfg, AUTH_RULE_IKE_SIGNATURE_SCHEME, + sig_constraints_params_tests[_i].sig, + sig_constraints_params_tests[_i].p); + cfg->destroy(cfg); +} +END_TEST + Suite *auth_cfg_suite_create() { Suite *s; @@ -118,5 +188,9 @@ Suite *auth_cfg_suite_create() tcase_add_loop_test(tc, test_ike_contraints_fallback, 0, countof(sig_constraints_tests)); suite_add_tcase(s, tc); + tc = tcase_create("add_pubkey_constraints parameters"); + tcase_add_loop_test(tc, test_sig_contraints_params, 0, countof(sig_constraints_params_tests)); + suite_add_tcase(s, tc); + return s; }