From: Tobias Brunner Date: Tue, 2 Apr 2019 14:44:44 +0000 (+0200) Subject: unit-tests: Add unit tests for childless IKE_SA initiation X-Git-Tag: 5.8.0rc1~24^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbb0feeea95bf04e27867b60312ad49782390be5;p=thirdparty%2Fstrongswan.git unit-tests: Add unit tests for childless IKE_SA initiation --- diff --git a/src/libcharon/tests/Makefile.am b/src/libcharon/tests/Makefile.am index 101b534f03..1d925019cf 100644 --- a/src/libcharon/tests/Makefile.am +++ b/src/libcharon/tests/Makefile.am @@ -31,6 +31,7 @@ exchange_tests_SOURCES = \ suites/test_ike_delete.c \ suites/test_ike_mid_sync.c \ suites/test_ike_rekey.c \ + suites/test_childless.c \ utils/exchange_test_asserts.h utils/exchange_test_asserts.c \ utils/exchange_test_helper.h utils/exchange_test_helper.c \ utils/job_asserts.h \ diff --git a/src/libcharon/tests/exchange_tests.h b/src/libcharon/tests/exchange_tests.h index 6b35ea5e53..491c25cd93 100644 --- a/src/libcharon/tests/exchange_tests.h +++ b/src/libcharon/tests/exchange_tests.h @@ -19,3 +19,4 @@ TEST_SUITE(ike_rekey_suite_create) TEST_SUITE(child_create_suite_create) TEST_SUITE(child_delete_suite_create) TEST_SUITE(child_rekey_suite_create) +TEST_SUITE(childless_suite_create) diff --git a/src/libcharon/tests/suites/test_childless.c b/src/libcharon/tests/suites/test_childless.c new file mode 100644 index 0000000000..6ac02aad81 --- /dev/null +++ b/src/libcharon/tests/suites/test_childless.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2019 Tobias Brunner + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "test_suite.h" + +#include +#include +#include +#include + +/** + * Childless initiation of the IKE_SA. The first CHILD_SA is automatically + * initiated in a separate CREATE_CHILD_SA exchange including DH. + */ +START_TEST(test_regular) +{ + exchange_test_sa_conf_t conf = { + .initiator = { + .childless = CHILDLESS_FORCE, + .esp = "aes128-sha256-modp3072", + }, + .responder = { + .esp = "aes128-sha256-modp3072", + }, + }; + ike_sa_t *a, *b; + ike_sa_id_t *id_a, *id_b; + child_cfg_t *child_cfg; + + child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b, + &conf); + id_a = a->get_id(a); + id_b = b->get_id(b); + + call_ikesa(a, initiate, child_cfg, 0, NULL, NULL); + + /* IKE_SA_INIT --> */ + id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a)); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + /* <-- IKE_SA_INIT */ + assert_notify(IN, CHILDLESS_IKEV2_SUPPORTED); + id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b)); + exchange_test_helper->process_message(exchange_test_helper, a, NULL); + + /* IKE_AUTH --> */ + assert_hook_not_called(child_updown); + assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION); + assert_no_payload(IN, PLV2_TS_INITIATOR); + assert_no_payload(IN, PLV2_TS_RESPONDER); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + + /* <-- IKE_AUTH */ + assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION); + assert_no_payload(IN, PLV2_TS_INITIATOR); + assert_no_payload(IN, PLV2_TS_RESPONDER); + exchange_test_helper->process_message(exchange_test_helper, a, NULL); + assert_child_sa_count(a, 0); + assert_child_sa_count(b, 0); + assert_hook(); + + /* CREATE_CHILD_SA { SA, Ni, KEi, TSi, TSr } --> */ + assert_hook_called(child_updown); + assert_payload(IN, PLV2_KEY_EXCHANGE); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + assert_child_sa_count(b, 1); + assert_hook(); + + /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */ + assert_hook_called(child_updown); + assert_payload(IN, PLV2_KEY_EXCHANGE); + exchange_test_helper->process_message(exchange_test_helper, a, NULL); + assert_child_sa_count(a, 1); + assert_hook(); + + assert_sa_idle(a); + assert_sa_idle(b); + + call_ikesa(a, destroy); + call_ikesa(b, destroy); +} +END_TEST + +/** + * Childless initiation of the IKE_SA, no CHILD_SA created automatically. + * It's created with a separate initiation and exchange afterwards. + */ +START_TEST(test_regular_manual) +{ + exchange_test_sa_conf_t conf = { + .initiator = { + .esp = "aes128-sha256-modp3072", + }, + .responder = { + .esp = "aes128-sha256-modp3072", + }, + }; + ike_sa_t *a, *b; + ike_sa_id_t *id_a, *id_b; + child_cfg_t *child_cfg; + + child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b, + &conf); + id_a = a->get_id(a); + id_b = b->get_id(b); + + call_ikesa(a, initiate, NULL, 0, NULL, NULL); + + /* IKE_SA_INIT --> */ + id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a)); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + /* <-- IKE_SA_INIT */ + assert_notify(IN, CHILDLESS_IKEV2_SUPPORTED); + id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b)); + exchange_test_helper->process_message(exchange_test_helper, a, NULL); + + /* IKE_AUTH --> */ + assert_hook_not_called(child_updown); + assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION); + assert_no_payload(IN, PLV2_TS_INITIATOR); + assert_no_payload(IN, PLV2_TS_RESPONDER); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + + /* <-- IKE_AUTH */ + assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION); + assert_no_payload(IN, PLV2_TS_INITIATOR); + assert_no_payload(IN, PLV2_TS_RESPONDER); + exchange_test_helper->process_message(exchange_test_helper, a, NULL); + assert_child_sa_count(a, 0); + assert_child_sa_count(b, 0); + assert_hook(); + + assert_sa_idle(a); + assert_sa_idle(b); + + call_ikesa(a, initiate, child_cfg, 0, NULL, NULL); + + /* CREATE_CHILD_SA { SA, Ni, KEi, TSi, TSr } --> */ + assert_hook_called(child_updown); + assert_payload(IN, PLV2_KEY_EXCHANGE); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + assert_child_sa_count(b, 1); + assert_hook(); + + /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */ + assert_hook_called(child_updown); + assert_payload(IN, PLV2_KEY_EXCHANGE); + exchange_test_helper->process_message(exchange_test_helper, a, NULL); + assert_child_sa_count(a, 1); + assert_hook(); + + assert_sa_idle(a); + assert_sa_idle(b); + + call_ikesa(a, destroy); + call_ikesa(b, destroy); +} +END_TEST + +/** + * The initiator aborts the initiation once it notices the responder does not + * support childless IKE_SAs. + */ +START_TEST(test_failure_init) +{ + exchange_test_sa_conf_t conf = { + .initiator = { + .childless = CHILDLESS_FORCE, + }, + .responder = { + .childless = CHILDLESS_NEVER, + }, + }; + ike_sa_t *a, *b; + ike_sa_id_t *id_a, *id_b; + child_cfg_t *child_cfg; + status_t status; + + child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b, + &conf); + id_a = a->get_id(a); + id_b = b->get_id(b); + + call_ikesa(a, initiate, child_cfg, 0, NULL, NULL); + + /* IKE_SA_INIT --> */ + id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a)); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + /* <-- IKE_SA_INIT */ + assert_no_notify(IN, CHILDLESS_IKEV2_SUPPORTED); + id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b)); + status = exchange_test_helper->process_message(exchange_test_helper, a, + NULL); + ck_assert_int_eq(DESTROY_ME, status); + + call_ikesa(a, destroy); + call_ikesa(b, destroy); +} +END_TEST + +/** + * The responder aborts the initiation once it notices the initiator does not + * create a childless IKE_SA. + */ +START_TEST(test_failure_resp) +{ + exchange_test_sa_conf_t conf = { + .initiator = { + .childless = CHILDLESS_NEVER, + }, + .responder = { + .childless = CHILDLESS_FORCE, + }, + }; + ike_sa_t *a, *b; + ike_sa_id_t *id_a, *id_b; + child_cfg_t *child_cfg; + status_t status; + + child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b, + &conf); + id_a = a->get_id(a); + id_b = b->get_id(b); + + call_ikesa(a, initiate, child_cfg, 0, NULL, NULL); + + /* IKE_SA_INIT --> */ + id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a)); + exchange_test_helper->process_message(exchange_test_helper, b, NULL); + /* <-- IKE_SA_INIT */ + assert_notify(IN, CHILDLESS_IKEV2_SUPPORTED); + id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b)); + exchange_test_helper->process_message(exchange_test_helper, a, NULL); + + /* IKE_AUTH --> */ + assert_hook_not_called(child_updown); + assert_payload(IN, PLV2_SECURITY_ASSOCIATION); + assert_payload(IN, PLV2_TS_INITIATOR); + assert_payload(IN, PLV2_TS_RESPONDER); + status = exchange_test_helper->process_message(exchange_test_helper, b, + NULL); + ck_assert_int_eq(DESTROY_ME, status); + assert_hook(); + + /* <-- IKE_AUTH */ + assert_hook_not_called(child_updown); + assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION); + assert_no_payload(IN, PLV2_TS_INITIATOR); + assert_no_payload(IN, PLV2_TS_RESPONDER); + assert_notify(IN, INVALID_SYNTAX); + status = exchange_test_helper->process_message(exchange_test_helper, a, + NULL); + ck_assert_int_eq(DESTROY_ME, status); + assert_hook(); + + assert_sa_idle(a); + assert_sa_idle(b); + + call_ikesa(a, destroy); + call_ikesa(b, destroy); +} +END_TEST + +Suite *childless_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("childless"); + + tc = tcase_create("initiation"); + tcase_add_test(tc, test_regular); + tcase_add_test(tc, test_regular_manual); + suite_add_tcase(s, tc); + + tc = tcase_create("failure"); + tcase_add_test(tc, test_failure_init); + tcase_add_test(tc, test_failure_resp); + suite_add_tcase(s, tc); + + return s; +}