From ec1d54f40e7e8992bbcbc6cbad7afd88b03616c7 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 9 Jul 2018 16:27:04 +0200 Subject: [PATCH] proposal: Generalize KE methods --- src/libcharon/sa/ikev1/tasks/quick_mode.c | 4 +- src/libcharon/sa/ikev2/tasks/child_create.c | 6 +- src/libcharon/sa/ikev2/tasks/ike_init.c | 12 ++-- src/libstrongswan/crypto/proposal/proposal.c | 26 ++++---- src/libstrongswan/crypto/proposal/proposal.h | 19 +++--- .../tests/suites/test_proposal.c | 62 ++++++++++++++++--- 6 files changed, 91 insertions(+), 38 deletions(-) diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 8954b27553..dfc4e9c23d 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -796,13 +796,13 @@ static linked_list_t *get_proposals(private_quick_mode_t *this, { if (group != MODP_NONE) { - if (!proposal->has_ke_method(proposal, group)) + if (!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, group)) { list->remove_at(list, enumerator); proposal->destroy(proposal); continue; } - proposal->promote_ke_method(proposal, group); + proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, group); } proposal->set_spi(proposal, this->spi_i); } diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 64e8d41c53..9dd15ad058 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -316,7 +316,8 @@ static bool update_and_check_proposals(private_child_create_t *this) if (this->dh_group != MODP_NONE) { /* proposals that don't contain the selected group are * moved to the back */ - if (!proposal->promote_ke_method(proposal, this->dh_group)) + if (!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { this->proposals->remove_at(this->proposals, enumerator); other_dh_groups->insert_last(other_dh_groups, proposal); @@ -598,7 +599,8 @@ static status_t select_and_install(private_child_create_t *this, } this->child_sa->set_proposal(this->child_sa, this->proposal); - if (!this->proposal->has_ke_method(this->proposal, this->dh_group)) + if (!this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { uint16_t group; diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index 1c33a805cc..f71df314ee 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -332,7 +332,8 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) proposal->set_spi(proposal, id->get_initiator_spi(id)); } /* move the selected DH group to the front of the proposal */ - if (!proposal->promote_ke_method(proposal, this->dh_group)) + if (!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { /* the proposal does not include the group, move to the back */ proposal_list->remove_at(proposal_list, enumerator); other_dh_groups->insert_last(other_dh_groups, proposal); @@ -616,7 +617,8 @@ static void process_payloads(private_ike_init_t *this, message_t *message) } if (ke_payload && this->proposal && - this->proposal->has_ke_method(this->proposal, this->dh_group)) + this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { if (!this->initiator) { @@ -828,7 +830,8 @@ METHOD(task_t, build_r, status_t, } if (this->dh == NULL || - !this->proposal->has_ke_method(this->proposal, this->dh_group)) + !this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { uint16_t group; @@ -1063,7 +1066,8 @@ METHOD(task_t, process_i, status_t, } if (this->dh == NULL || - !this->proposal->has_ke_method(this->proposal, this->dh_group)) + !this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { DBG1(DBG_IKE, "peer DH group selection invalid"); return FAILED; diff --git a/src/libstrongswan/crypto/proposal/proposal.c b/src/libstrongswan/crypto/proposal/proposal.c index 097d0bc65e..a2c74e40f2 100644 --- a/src/libstrongswan/crypto/proposal/proposal.c +++ b/src/libstrongswan/crypto/proposal/proposal.c @@ -251,18 +251,18 @@ METHOD(proposal_t, get_algorithm, bool, return found; } -METHOD(proposal_t, has_ke_method, bool, - private_proposal_t *this, key_exchange_method_t ke) +METHOD(proposal_t, has_transform, bool, + private_proposal_t *this, transform_type_t type, uint16_t alg) { bool found = FALSE, any = FALSE; enumerator_t *enumerator; uint16_t current; - enumerator = create_enumerator(this, KEY_EXCHANGE_METHOD); + enumerator = create_enumerator(this, type); while (enumerator->enumerate(enumerator, ¤t, NULL)) { any = TRUE; - if (current == ke) + if (current == alg) { found = TRUE; break; @@ -270,15 +270,15 @@ METHOD(proposal_t, has_ke_method, bool, } enumerator->destroy(enumerator); - if (!any && ke == MODP_NONE) + if (!any && alg == 0) { found = TRUE; } return found; } -METHOD(proposal_t, promote_ke_method, bool, - private_proposal_t *this, key_exchange_method_t method) +METHOD(proposal_t, promote_transform, bool, + private_proposal_t *this, transform_type_t type, uint16_t alg) { enumerator_t *enumerator; entry_t *entry; @@ -287,8 +287,8 @@ METHOD(proposal_t, promote_ke_method, bool, enumerator = array_create_enumerator(this->transforms); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->type == KEY_EXCHANGE_METHOD && - entry->alg == method) + if (entry->type == type && + entry->alg == alg) { array_remove_at(this->transforms, enumerator); found = TRUE; @@ -299,8 +299,8 @@ METHOD(proposal_t, promote_ke_method, bool, if (found) { entry_t entry = { - .type = KEY_EXCHANGE_METHOD, - .alg = method, + .type = type, + .alg = alg, }; array_insert(this->transforms, ARRAY_HEAD, &entry); } @@ -942,8 +942,8 @@ proposal_t *proposal_create_v1(protocol_id_t protocol, uint8_t number, .add_algorithm = _add_algorithm, .create_enumerator = _create_enumerator, .get_algorithm = _get_algorithm, - .has_ke_method = _has_ke_method, - .promote_ke_method = _promote_ke_method, + .has_transform = _has_transform, + .promote_transform = _promote_transform, .select = _select_proposal, .matches = _matches, .get_protocol = _get_protocol, diff --git a/src/libstrongswan/crypto/proposal/proposal.h b/src/libstrongswan/crypto/proposal/proposal.h index b13f40c324..15db8dcaef 100644 --- a/src/libstrongswan/crypto/proposal/proposal.h +++ b/src/libstrongswan/crypto/proposal/proposal.h @@ -109,21 +109,26 @@ struct proposal_t { uint16_t *alg, uint16_t *key_size); /** - * Check if the proposal has a specific key exchange method. + * Check if the proposal has a specific transform. * - * @param method key exchange method to check for + * @param type kind of algorithm + * @param alg algorithm to check for (if 0, TRUE is returned if + * no transform of the given type is found) * @return TRUE if algorithm included */ - bool (*has_ke_method)(proposal_t *this, key_exchange_method_t method); + bool (*has_transform)(proposal_t *this, transform_type_t type, + uint16_t alg); /** - * Move the given key exchange method to the front of the list if it was - * contained in the proposal. + * Move the given transform to the front of the list if it was contained in + * the proposal. * - * @param method key exchange method to promote + * @param type kind of algorithm + * @param alg algorithm to promote * @return TRUE if algorithm included */ - bool (*promote_ke_method)(proposal_t *this, key_exchange_method_t method); + bool (*promote_transform)(proposal_t *this, transform_type_t type, + uint16_t alg); /** * Compare two proposals and select a matching subset. diff --git a/src/libstrongswan/tests/suites/test_proposal.c b/src/libstrongswan/tests/suites/test_proposal.c index 1d0003684b..b7497fd81e 100644 --- a/src/libstrongswan/tests/suites/test_proposal.c +++ b/src/libstrongswan/tests/suites/test_proposal.c @@ -274,38 +274,75 @@ START_TEST(test_select_proposal) } END_TEST -START_TEST(test_promote_ke_method) +START_TEST(test_has_transform) { proposal_t *proposal; proposal = proposal_create_from_string(PROTO_IKE, "aes128-sha256-modp3072-ecp256"); - ck_assert(proposal->promote_ke_method(proposal, ECP_256_BIT)); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_3072_BIT)); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + ECP_256_BIT)); + ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_2048_BIT)); + proposal->destroy(proposal); +} +END_TEST + +START_TEST(test_has_transform_none) +{ + proposal_t *proposal; + + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256"); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_NONE)); + proposal->destroy(proposal); + + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256-modp3072"); + ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_NONE)); + proposal->destroy(proposal); +} +END_TEST + +START_TEST(test_promote_transform) +{ + proposal_t *proposal; + + proposal = proposal_create_from_string(PROTO_IKE, + "aes128-sha256-modp3072-ecp256"); + ck_assert(proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + ECP_256_BIT)); assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256/MODP_3072"); proposal->destroy(proposal); } END_TEST -START_TEST(test_promote_ke_method_already_front) +START_TEST(test_promote_transform_already_front) { proposal_t *proposal; proposal = proposal_create_from_string(PROTO_IKE, "aes128-sha256-modp3072-ecp256"); - ck_assert(proposal->promote_ke_method(proposal, MODP_3072_BIT)); + ck_assert(proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_3072_BIT)); assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256"); proposal->destroy(proposal); } END_TEST -START_TEST(test_promote_ke_method_not_contained) +START_TEST(test_promote_transform_not_contained) { proposal_t *proposal; proposal = proposal_create_from_string(PROTO_IKE, "aes128-sha256-modp3072-ecp256"); - ck_assert(!proposal->promote_ke_method(proposal, MODP_2048_BIT)); + ck_assert(!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_2048_BIT)); assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256"); proposal->destroy(proposal); } @@ -474,10 +511,15 @@ Suite *proposal_suite_create() countof(select_proposal_data)); suite_add_tcase(s, tc); - tc = tcase_create("promote_ke_method"); - tcase_add_test(tc, test_promote_ke_method); - tcase_add_test(tc, test_promote_ke_method_already_front); - tcase_add_test(tc, test_promote_ke_method_not_contained); + tc = tcase_create("has_transform"); + tcase_add_test(tc, test_has_transform); + tcase_add_test(tc, test_has_transform_none); + suite_add_tcase(s, tc); + + tc = tcase_create("promote_transform"); + tcase_add_test(tc, test_promote_transform); + tcase_add_test(tc, test_promote_transform_already_front); + tcase_add_test(tc, test_promote_transform_not_contained); suite_add_tcase(s, tc); tc = tcase_create("unknown transform types"); -- 2.47.2