From: Tobias Brunner Date: Mon, 9 Jul 2018 14:27:04 +0000 (+0200) Subject: proposal: Generalize KE methods X-Git-Tag: 5.9.7dr2~1^2~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3bebf5bf8d20d708ab52c4812af17b4169818806;p=thirdparty%2Fstrongswan.git proposal: Generalize KE methods --- diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 84c4d79556..78cc46f103 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -797,13 +797,13 @@ static linked_list_t *get_proposals(private_quick_mode_t *this, { if (group != KE_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 ddc0df798b..5230b30bd5 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -328,7 +328,8 @@ static bool update_and_check_proposals(private_child_create_t *this) if (this->dh_group != KE_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); @@ -554,7 +555,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 f5c5482876..c9241f7abe 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -333,7 +333,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); @@ -617,7 +618,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) { @@ -829,7 +831,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; @@ -1064,7 +1067,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 3ecba9fb29..1ad04db4e4 100644 --- a/src/libstrongswan/crypto/proposal/proposal.c +++ b/src/libstrongswan/crypto/proposal/proposal.c @@ -252,34 +252,37 @@ 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) { - found = TRUE; - break; + any = TRUE; + if (alg && current == alg) + { + found = TRUE; + break; + } } } enumerator->destroy(enumerator); - if (!any && ke == KE_NONE) + if (!any && !alg) { 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; @@ -288,8 +291,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; @@ -300,8 +303,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); } @@ -943,8 +946,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 5d23167966..29fda8b8b4 100644 --- a/src/libstrongswan/crypto/proposal/proposal.h +++ b/src/libstrongswan/crypto/proposal/proposal.h @@ -110,21 +110,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 7827b1bccc..c42f9e4a66 100644 --- a/src/libstrongswan/tests/suites/test_proposal.c +++ b/src/libstrongswan/tests/suites/test_proposal.c @@ -301,38 +301,89 @@ 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, + KE_NONE)); + proposal->destroy(proposal); + + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256-none"); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + KE_NONE)); + proposal->destroy(proposal); + + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256-modp3072"); + ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + KE_NONE)); + proposal->destroy(proposal); + + /* while actually contained in the proposal, KE_NONE is 0 so we expect + * has_transform() to return FALSE if there are other algorithms */ + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256-modp3072-none"); + ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + KE_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); } @@ -505,10 +556,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");