]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
proposal: Generalize DH methods
authorTobias Brunner <tobias@strongswan.org>
Mon, 9 Jul 2018 14:27:04 +0000 (16:27 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 14 May 2019 08:53:14 +0000 (10:53 +0200)
src/libcharon/config/child_cfg.c
src/libcharon/sa/ikev1/tasks/quick_mode.c
src/libcharon/sa/ikev2/tasks/child_create.c
src/libcharon/sa/ikev2/tasks/ike_init.c
src/libstrongswan/crypto/proposal/proposal.c
src/libstrongswan/crypto/proposal/proposal.h
src/libstrongswan/tests/suites/test_proposal.c

index 73cb02bd9a4f57ebc0194bf3ec931e4c41569e8b..1e3d2e1dff81255f04938a4c4ac4f1e959ed9397 100644 (file)
@@ -217,7 +217,7 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*,
                current = current->clone(current);
                if (strip_dh)
                {
-                       current->strip_dh(current, MODP_NONE);
+                       current->strip_transform(current, DIFFIE_HELLMAN_GROUP, MODP_NONE);
                }
                if (proposals->find_first(proposals, match_proposal, NULL, current))
                {
@@ -256,7 +256,7 @@ METHOD(child_cfg_t, select_proposal, proposal_t*,
                proposal = proposal->clone(proposal);
                if (strip_dh)
                {
-                       proposal->strip_dh(proposal, MODP_NONE);
+                       proposal->strip_transform(proposal, DIFFIE_HELLMAN_GROUP, MODP_NONE);
                }
                if (prefer_self)
                {
@@ -271,7 +271,7 @@ METHOD(child_cfg_t, select_proposal, proposal_t*,
                        match = match->clone(match);
                        if (strip_dh)
                        {
-                               match->strip_dh(match, MODP_NONE);
+                               match->strip_transform(match, DIFFIE_HELLMAN_GROUP, MODP_NONE);
                        }
                        selected = proposal->select(proposal, match, prefer_self, private);
                        match->destroy(match);
index 3309a5ddc123ce5af0fee6e1f197cce8dbb38118..1b941589df7d8a883f74fedcbffe693739cab604 100644 (file)
@@ -796,13 +796,13 @@ static linked_list_t *get_proposals(private_quick_mode_t *this,
        {
                if (group != MODP_NONE)
                {
-                       if (!proposal->has_dh_group(proposal, group))
+                       if (!proposal->has_transform(proposal, DIFFIE_HELLMAN_GROUP, group))
                        {
                                list->remove_at(list, enumerator);
                                proposal->destroy(proposal);
                                continue;
                        }
-                       proposal->strip_dh(proposal, group);
+                       proposal->strip_transform(proposal, DIFFIE_HELLMAN_GROUP, group);
                }
                proposal->set_spi(proposal, this->spi_i);
        }
index ad015358142cfcd3476f8b1634e16050d07b543f..9901e8507843ea7f839216369d4b327cc75ad45f 100644 (file)
@@ -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_dh_group(proposal, this->dh_group))
+                       if (!proposal->promote_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                                        this->dh_group))
                        {
                                this->proposals->remove_at(this->proposals, enumerator);
                                other_dh_groups->insert_last(other_dh_groups, proposal);
@@ -586,7 +587,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_dh_group(this->proposal, this->dh_group))
+       if (!this->proposal->has_transform(this->proposal, DIFFIE_HELLMAN_GROUP,
+                                                                          this->dh_group))
        {
                uint16_t group;
 
index 00ec9f45647059cbf5eb0c2a92df1f81329688fb..8d0d863a1a955510de12d11676c920d143b9b25d 100644 (file)
@@ -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_dh_group(proposal, this->dh_group))
+                       if (!proposal->promote_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                                        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);
@@ -610,7 +611,8 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
        }
 
        if (ke_payload && this->proposal &&
-               this->proposal->has_dh_group(this->proposal, this->dh_group))
+               this->proposal->has_transform(this->proposal, DIFFIE_HELLMAN_GROUP,
+                                                                         this->dh_group))
        {
                if (!this->initiator)
                {
@@ -822,7 +824,8 @@ METHOD(task_t, build_r, status_t,
        }
 
        if (this->dh == NULL ||
-               !this->proposal->has_dh_group(this->proposal, this->dh_group))
+               !this->proposal->has_transform(this->proposal, DIFFIE_HELLMAN_GROUP,
+                                                                          this->dh_group))
        {
                uint16_t group;
 
@@ -1057,7 +1060,8 @@ METHOD(task_t, process_i, status_t,
        }
 
        if (this->dh == NULL ||
-               !this->proposal->has_dh_group(this->proposal, this->dh_group))
+               !this->proposal->has_transform(this->proposal, DIFFIE_HELLMAN_GROUP,
+                                                                          this->dh_group))
        {
                DBG1(DBG_IKE, "peer DH group selection invalid");
                return FAILED;
index 3ca78c92f5d247fafcd31c0ff6c2d885402f19fa..60bd2cd36759f85408a09e936ea67400038cd90d 100644 (file)
@@ -246,18 +246,18 @@ METHOD(proposal_t, get_algorithm, bool,
        return found;
 }
 
-METHOD(proposal_t, has_dh_group, bool,
-       private_proposal_t *this, diffie_hellman_group_t group)
+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, DIFFIE_HELLMAN_GROUP);
+       enumerator = create_enumerator(this, type);
        while (enumerator->enumerate(enumerator, &current, NULL))
        {
                any = TRUE;
-               if (current == group)
+               if (current == alg)
                {
                        found = TRUE;
                        break;
@@ -265,15 +265,15 @@ METHOD(proposal_t, has_dh_group, bool,
        }
        enumerator->destroy(enumerator);
 
-       if (!any && group == MODP_NONE)
+       if (!any && alg == 0)
        {
                found = TRUE;
        }
        return found;
 }
 
-METHOD(proposal_t, promote_dh_group, bool,
-       private_proposal_t *this, diffie_hellman_group_t group)
+METHOD(proposal_t, promote_transform, bool,
+       private_proposal_t *this, transform_type_t type, uint16_t alg)
 {
        enumerator_t *enumerator;
        entry_t *entry;
@@ -282,8 +282,8 @@ METHOD(proposal_t, promote_dh_group, bool,
        enumerator = array_create_enumerator(this->transforms);
        while (enumerator->enumerate(enumerator, &entry))
        {
-               if (entry->type == DIFFIE_HELLMAN_GROUP &&
-                       entry->alg == group)
+               if (entry->type == type &&
+                       entry->alg == alg)
                {
                        array_remove_at(this->transforms, enumerator);
                        found = TRUE;
@@ -294,16 +294,16 @@ METHOD(proposal_t, promote_dh_group, bool,
        if (found)
        {
                entry_t entry = {
-                       .type = DIFFIE_HELLMAN_GROUP,
-                       .alg = group,
+                       .type = type,
+                       .alg = alg,
                };
                array_insert(this->transforms, ARRAY_HEAD, &entry);
        }
        return found;
 }
 
-METHOD(proposal_t, strip_dh, void,
-       private_proposal_t *this, diffie_hellman_group_t keep)
+METHOD(proposal_t, strip_transform, void,
+       private_proposal_t *this, transform_type_t type, uint16_t keep)
 {
        enumerator_t *enumerator;
        entry_t *entry;
@@ -312,7 +312,7 @@ METHOD(proposal_t, strip_dh, void,
        enumerator = array_create_enumerator(this->transforms);
        while (enumerator->enumerate(enumerator, &entry))
        {
-               if (entry->type == DIFFIE_HELLMAN_GROUP)
+               if (entry->type == type)
                {
                        if (entry->alg != keep)
                        {
@@ -327,9 +327,9 @@ METHOD(proposal_t, strip_dh, void,
        enumerator->destroy(enumerator);
        array_compress(this->transforms);
 
-       if (keep == MODP_NONE || !found)
+       if (keep == 0 || !found)
        {
-               remove_type(this, DIFFIE_HELLMAN_GROUP);
+               remove_type(this, type);
                array_compress(this->types);
        }
 }
@@ -952,9 +952,9 @@ proposal_t *proposal_create(protocol_id_t protocol, u_int number)
                        .add_algorithm = _add_algorithm,
                        .create_enumerator = _create_enumerator,
                        .get_algorithm = _get_algorithm,
-                       .has_dh_group = _has_dh_group,
-                       .promote_dh_group = _promote_dh_group,
-                       .strip_dh = _strip_dh,
+                       .has_transform = _has_transform,
+                       .promote_transform = _promote_transform,
+                       .strip_transform = _strip_transform,
                        .select = _select_proposal,
                        .matches = _matches,
                        .get_protocol = _get_protocol,
index 3383243264fb9e7849a1ddd1ea31bf1d98402440..f3e1b49ce731f172fc3f63007a0de5090a22d5ed 100644 (file)
@@ -102,28 +102,36 @@ struct proposal_t {
                                                   uint16_t *alg, uint16_t *key_size);
 
        /**
-        * Check if the proposal has a specific DH group.
+        * Check if the proposal has a specific transform.
         *
-        * @param group                 group 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_dh_group)(proposal_t *this, diffie_hellman_group_t group);
+       bool (*has_transform)(proposal_t *this, transform_type_t type,
+                                                 uint16_t alg);
 
        /**
-        * Move the given DH group to the front of the list if it was contained in
+        * Move the given transform to the front of the list if it was contained in
         * the proposal.
         *
-        * @param group                 group to promote
+        * @param type                  kind of algorithm
+        * @param alg                   algorithm to promote
         * @return                              TRUE if algorithm included
         */
-       bool (*promote_dh_group)(proposal_t *this, diffie_hellman_group_t group);
+       bool (*promote_transform)(proposal_t *this, transform_type_t type,
+                                                         uint16_t alg);
 
        /**
-        * Strip DH groups from proposal to use it without PFS.
+        * Strip transforms from proposal (e.g. for DH groups to use it without PFS
+        * or during IKE_AUTH).
         *
-        * @param keep                  group to keep (MODP_NONE to remove all)
+        * @param type                  kind of algorithm
+        * @param keep                  algorithm to keep (0 to remove all)
         */
-       void (*strip_dh)(proposal_t *this, diffie_hellman_group_t keep);
+       void (*strip_transform)(proposal_t *this, transform_type_t type,
+                                                       uint16_t keep);
 
        /**
         * Compare two proposal, and select a matching subset.
index 099cd19c7fe4d2d2e536e344aa899e7f2b11b4dc..ff49c3863e1dfbc54746593e3d39a4d55fc7b2d1 100644 (file)
@@ -187,43 +187,140 @@ START_TEST(test_matches)
 }
 END_TEST
 
-START_TEST(test_promote_dh_group)
+START_TEST(test_has_transform)
 {
        proposal_t *proposal;
 
        proposal = proposal_create_from_string(PROTO_IKE,
                                                                                   "aes128-sha256-modp3072-ecp256");
-       ck_assert(proposal->promote_dh_group(proposal, ECP_256_BIT));
+       ck_assert(proposal->has_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                         MODP_3072_BIT));
+       ck_assert(proposal->has_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                         ECP_256_BIT));
+       ck_assert(!proposal->has_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                          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, DIFFIE_HELLMAN_GROUP,
+                                                                         MODP_NONE));
+       proposal->destroy(proposal);
+
+       proposal = proposal_create_from_string(PROTO_ESP,
+                                                                                  "aes128-sha256-modp3072");
+       ck_assert(!proposal->has_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                          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, DIFFIE_HELLMAN_GROUP,
+                                                                                 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_dh_group_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_dh_group(proposal, MODP_3072_BIT));
+       ck_assert(proposal->promote_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                                 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_dh_group_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_dh_group(proposal, MODP_2048_BIT));
+       ck_assert(!proposal->promote_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                                  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);
 }
 END_TEST
 
+START_TEST(test_promote_transform_qske)
+{
+       proposal_t *proposal;
+
+       proposal = proposal_create_from_string(PROTO_IKE,
+                                                                                  "aes128-sha256-ecp256-qskenewhope1-qskenewhope5");
+       ck_assert(proposal->promote_transform(proposal, QSKE_MECHANISM,
+                                                                                 QSKE_NEWHOPE_L5));
+       assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256/QSKE_NEWHOPE_L5/QSKE_NEWHOPE_L1");
+       proposal->destroy(proposal);
+}
+END_TEST
+
+START_TEST(test_strip_transform)
+{
+       proposal_t *proposal;
+
+       proposal = proposal_create_from_string(PROTO_ESP,
+                                                                                  "aes128-sha256-modp3072-ecp256");
+       proposal->strip_transform(proposal, DIFFIE_HELLMAN_GROUP, MODP_NONE);
+       ck_assert(proposal->has_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                         MODP_NONE));
+       assert_proposal_eq(proposal, "ESP:AES_CBC_128/HMAC_SHA2_256_128/NO_EXT_SEQ");
+       proposal->destroy(proposal);
+}
+END_TEST
+
+START_TEST(test_strip_transform_keep)
+{
+       proposal_t *proposal;
+
+       proposal = proposal_create_from_string(PROTO_ESP,
+                                                                                  "aes128-sha256-modp3072-ecp256");
+       proposal->strip_transform(proposal, DIFFIE_HELLMAN_GROUP, MODP_3072_BIT);
+       ck_assert(proposal->has_transform(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                         MODP_3072_BIT));
+       assert_proposal_eq(proposal, "ESP:AES_CBC_128/HMAC_SHA2_256_128/MODP_3072/NO_EXT_SEQ");
+       proposal->destroy(proposal);
+}
+END_TEST
+
+START_TEST(test_strip_transform_qske)
+{
+       proposal_t *proposal;
+
+       proposal = proposal_create_from_string(PROTO_ESP,
+                                                                                  "aes128-sha256-qskenewhope1-qskenewhope5");
+       proposal->strip_transform(proposal, QSKE_MECHANISM, QSKE_NEWHOPE_L5);
+       ck_assert(proposal->has_transform(proposal, QSKE_MECHANISM,
+                                                                         QSKE_NEWHOPE_L5));
+       proposal->strip_transform(proposal, QSKE_MECHANISM, QSKE_NONE);
+       ck_assert(!proposal->has_transform(proposal, QSKE_MECHANISM,
+                                                                         QSKE_NEWHOPE_L5));
+       ck_assert(proposal->has_transform(proposal, QSKE_MECHANISM,
+                                                                         QSKE_NONE));
+       assert_proposal_eq(proposal, "ESP:AES_CBC_128/HMAC_SHA2_256_128/NO_EXT_SEQ");
+       proposal->destroy(proposal);
+}
+END_TEST
+
 START_TEST(test_unknown_transform_types_print)
 {
        proposal_t *proposal;
@@ -344,10 +441,22 @@ Suite *proposal_suite_create()
        tcase_add_loop_test(tc, test_matches, 0, countof(select_data));
        suite_add_tcase(s, tc);
 
-       tc = tcase_create("promote_dh_group");
-       tcase_add_test(tc, test_promote_dh_group);
-       tcase_add_test(tc, test_promote_dh_group_already_front);
-       tcase_add_test(tc, test_promote_dh_group_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);
+       tcase_add_test(tc, test_promote_transform_qske);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("strip_transform");
+       tcase_add_test(tc, test_strip_transform);
+       tcase_add_test(tc, test_strip_transform_keep);
+       tcase_add_test(tc, test_strip_transform_qske);
        suite_add_tcase(s, tc);
 
        tc = tcase_create("unknown transform types");