From 9dc803d7f1dc0e03a16256ca1e65c365446cffe5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 16 Jul 2018 15:50:56 +0200 Subject: [PATCH] wip: unit-tests: Add QSKE exchange tests --- src/libcharon/tests/suites/test_ike_rekey.c | 126 ++++++++++++++---- .../tests/utils/exchange_test_helper.c | 11 ++ 2 files changed, 111 insertions(+), 26 deletions(-) diff --git a/src/libcharon/tests/suites/test_ike_rekey.c b/src/libcharon/tests/suites/test_ike_rekey.c index 5960e989df..ccf91ce2d5 100644 --- a/src/libcharon/tests/suites/test_ike_rekey.c +++ b/src/libcharon/tests/suites/test_ike_rekey.c @@ -30,11 +30,23 @@ assert_hook(); \ }) +/** + * Default config for QSKE tests + */ +static exchange_test_sa_conf_t qske_conf = { + .initiator = { + .ike = "aes256-sha256-modp3072-qskenewhope5", + }, + .responder = { + .ike = "aes256-sha256-modp3072-qskenewhope5", + }, +}; + /** * Regular IKE_SA rekeying either initiated by the original initiator or * responder of the IKE_SA. */ -START_TEST(test_regular) +static void _test_regular(int _i, bool qske, exchange_test_sa_conf_t *conf) { ike_sa_t *a, *b, *new_sa; status_t s; @@ -42,12 +54,12 @@ START_TEST(test_regular) if (_i) { /* responder rekeys the IKE_SA */ exchange_test_helper->establish_sa(exchange_test_helper, - &b, &a, NULL); + &b, &a, conf); } else { /* initiator rekeys the IKE_SA */ exchange_test_helper->establish_sa(exchange_test_helper, - &a, &b, NULL); + &a, &b, conf); } /* these should never get called as this results in a successful rekeying */ assert_hook_not_called(ike_updown); @@ -55,7 +67,7 @@ START_TEST(test_regular) initiate_rekey(a); - /* CREATE_CHILD_SA { SA, Ni, KEi } --> */ + /* CREATE_CHILD_SA { SA, Ni, KEi, [QSKEi] } --> */ assert_hook_rekey(ike_rekey, 1, 3); assert_no_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, b, NULL); @@ -67,7 +79,7 @@ START_TEST(test_regular) assert_ike_sa_count(1); assert_hook(); - /* <-- CREATE_CHILD_SA { SA, Nr, KEr } */ + /* <-- CREATE_CHILD_SA { SA, Nr, KEr, [QSKEr] } */ assert_hook_rekey(ike_rekey, 1, 3); assert_no_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, a, NULL); @@ -79,6 +91,7 @@ START_TEST(test_regular) assert_ike_sa_count(2); assert_hook(); + /* we don't expect this hook to get called anymore */ assert_hook_not_called(ike_rekey); @@ -100,6 +113,17 @@ START_TEST(test_regular) charon->ike_sa_manager->flush(charon->ike_sa_manager); } + +START_TEST(test_regular) +{ + _test_regular(_i, FALSE, NULL); +} +END_TEST + +START_TEST(test_regular_qske) +{ + _test_regular(_i, TRUE, &qske_conf); +} END_TEST /** @@ -107,16 +131,9 @@ END_TEST * by the initiator, either initiated by the original initiator or responder of * the IKE_SA. */ -START_TEST(test_regular_ke_invalid) +static void _test_regular_ke_invalid(int _i, bool qske, + exchange_test_sa_conf_t *conf) { - exchange_test_sa_conf_t conf = { - .initiator = { - .ike = "aes128-sha256-modp2048-modp3072", - }, - .responder = { - .ike = "aes128-sha256-modp3072-modp2048", - }, - }; ike_sa_t *a, *b, *sa; status_t s; @@ -125,12 +142,12 @@ START_TEST(test_regular_ke_invalid) if (_i) { /* responder rekeys the IKE_SA */ exchange_test_helper->establish_sa(exchange_test_helper, - &b, &a, &conf); + &b, &a, conf); } else { /* initiator rekeys the IKE_SA */ exchange_test_helper->establish_sa(exchange_test_helper, - &a, &b, &conf); + &a, &b, conf); } /* these should never get called as this results in a successful rekeying */ assert_hook_not_called(ike_updown); @@ -140,6 +157,8 @@ START_TEST(test_regular_ke_invalid) TRUE, lib->ns); lib->settings->set_bool(lib->settings, "%s.prefer_previous_dh_group", FALSE, lib->ns); + lib->settings->set_bool(lib->settings, "%s.prefer_previous_qske_mechanism", + FALSE, lib->ns); initiate_rekey(a); @@ -151,14 +170,14 @@ START_TEST(test_regular_ke_invalid) assert_ike_sa_count(0); /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */ - assert_single_notify(IN, INVALID_KE_PAYLOAD); + assert_single_notify(IN, qske ? INVALID_QSKE_PAYLOAD : INVALID_KE_PAYLOAD); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_ike_sa_state(a, IKE_REKEYING); assert_child_sa_count(a, 1); assert_ike_sa_count(0); assert_hook(); - /* CREATE_CHILD_SA { SA, Ni, KEi } --> */ + /* CREATE_CHILD_SA { SA, Ni, KEi, [QSKEi] } --> */ assert_hook_rekey(ike_rekey, 1, 3); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_ike_sa_state(b, IKE_REKEYED); @@ -169,7 +188,7 @@ START_TEST(test_regular_ke_invalid) assert_ike_sa_count(1); assert_hook(); - /* <-- CREATE_CHILD_SA { SA, Nr, KEr } */ + /* <-- CREATE_CHILD_SA { SA, Nr, KEr, [QSKEr] } */ assert_hook_rekey(ike_rekey, 1, 3); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_ike_sa_state(a, IKE_DELETING); @@ -201,19 +220,60 @@ START_TEST(test_regular_ke_invalid) charon->ike_sa_manager->flush(charon->ike_sa_manager); } + +START_TEST(test_regular_ke_invalid) +{ + exchange_test_sa_conf_t conf = { + .initiator = { + .ike = "aes128-sha256-modp2048-modp3072", + }, + .responder = { + .ike = "aes128-sha256-modp3072-modp2048", + }, + }; + _test_regular_ke_invalid(_i, FALSE, &conf); +} +END_TEST + +START_TEST(test_regular_ke_invalid_qske) +{ + exchange_test_sa_conf_t conf = { + .initiator = { + .ike = "aes128-sha256-modp2048-modp3072-qskenewhope5", + }, + .responder = { + .ike = "aes128-sha256-modp3072-modp2048-qskenewhope5", + }, + }; + _test_regular_ke_invalid(_i, FALSE, &conf); +} +END_TEST + +START_TEST(test_regular_qske_invalid) +{ + exchange_test_sa_conf_t conf = { + .initiator = { + .ike = "aes128-sha256-modp3072-qskenewhope1-qskenewhope5", + }, + .responder = { + .ike = "aes128-sha256-modp3072-qskenewhope5-qskenewhope1", + }, + }; + _test_regular_ke_invalid(_i, TRUE, &conf); +} END_TEST /** * Both peers initiate the IKE_SA rekeying concurrently and should handle the * collision properly depending on the nonces. */ -START_TEST(test_collision) +static void _test_collision(int _i, bool qske, exchange_test_sa_conf_t *conf) { ike_sa_t *a, *b, *sa; status_t status; exchange_test_helper->establish_sa(exchange_test_helper, - &a, &b, NULL); + &a, &b, conf); /* When rekeyings collide we get two IKE_SAs with a total of four nonces. * The IKE_SA with the lowest nonce SHOULD be deleted by the peer that @@ -250,18 +310,17 @@ START_TEST(test_collision) exchange_test_helper->nonce_first_byte = data[_i].nonces[1]; initiate_rekey(b); + assert_hook_not_called(ike_rekey); + /* CREATE_CHILD_SA { SA, Ni, KEi } --> */ exchange_test_helper->nonce_first_byte = data[_i].nonces[2]; - assert_hook_not_called(ike_rekey); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_ike_sa_state(b, IKE_REKEYING); assert_child_sa_count(b, 1); assert_ike_sa_count(0); - assert_hook(); /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */ exchange_test_helper->nonce_first_byte = data[_i].nonces[3]; - assert_hook_not_called(ike_rekey); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_ike_sa_state(a, IKE_REKEYING); assert_child_sa_count(a, 1); @@ -273,7 +332,7 @@ START_TEST(test_collision) charon->ike_sa_manager->checkin(charon->ike_sa_manager, b); assert_ike_sa_count(2); - /* <-- CREATE_CHILD_SA { SA, Nr, KEr } */ + /* <-- CREATE_CHILD_SA { SA, Nr, KEr, [QSKEi] } */ assert_hook_rekey(ike_rekey, 1, data[_i].spi_i); exchange_test_helper->process_message(exchange_test_helper, a, NULL); /* as original initiator a is initiator of both SAs it could delete */ @@ -292,7 +351,7 @@ START_TEST(test_collision) assert_ike_sa_count(4); assert_hook(); - /* CREATE_CHILD_SA { SA, Nr, KEr } --> */ + /* CREATE_CHILD_SA { SA, Nr, KEr, [QSKEr] } --> */ assert_hook_rekey(ike_rekey, 1, data[_i].spi_i); exchange_test_helper->process_message(exchange_test_helper, b, NULL); /* if b wins it deletes the SA originally initiated by a */ @@ -356,6 +415,17 @@ START_TEST(test_collision) charon->ike_sa_manager->flush(charon->ike_sa_manager); } + +START_TEST(test_collision) +{ + _test_collision(_i, FALSE, NULL); +} +END_TEST + +START_TEST(test_collision_qske) +{ + _test_collision(_i, TRUE, &qske_conf); +} END_TEST /** @@ -1464,11 +1534,15 @@ Suite *ike_rekey_suite_create() tc = tcase_create("regular"); tcase_add_loop_test(tc, test_regular, 0, 2); + tcase_add_loop_test(tc, test_regular_qske, 0, 2); tcase_add_loop_test(tc, test_regular_ke_invalid, 0, 2); + tcase_add_loop_test(tc, test_regular_ke_invalid_qske, 0, 2); + tcase_add_loop_test(tc, test_regular_qske_invalid, 0, 2); suite_add_tcase(s, tc); tc = tcase_create("collisions rekey"); tcase_add_loop_test(tc, test_collision, 0, 4); + tcase_add_loop_test(tc, test_collision_qske, 0, 4); tcase_add_loop_test(tc, test_collision_ke_invalid, 0, 4); tcase_add_loop_test(tc, test_collision_ke_invalid_delayed_retry, 0, 3); tcase_add_loop_test(tc, test_collision_delayed_response, 0, 4); diff --git a/src/libcharon/tests/utils/exchange_test_helper.c b/src/libcharon/tests/utils/exchange_test_helper.c index b924646781..a574e6158c 100644 --- a/src/libcharon/tests/utils/exchange_test_helper.c +++ b/src/libcharon/tests/utils/exchange_test_helper.c @@ -262,6 +262,7 @@ METHOD(exchange_test_helper_t, establish_sa, void, ike_sa_id_t *id_i, *id_r; ike_sa_t *sa_i, *sa_r; child_cfg_t *child_i; + proposal_t *proposal; child_i = create_sa(this, init, resp, conf); @@ -279,6 +280,16 @@ METHOD(exchange_test_helper_t, establish_sa, void, /* <-- IKE_SA_INIT */ id_i->set_responder_spi(id_i, id_r->get_responder_spi(id_r)); process_message(this, sa_i, NULL); + + proposal = sa_i->get_proposal(sa_i); + if (proposal->get_algorithm(proposal, QSKE_MECHANISM, NULL, NULL)) + { + /* IKE_AUX --> */ + process_message(this, sa_r, NULL); + /* <-- IKE_AUX */ + process_message(this, sa_i, NULL); + } + /* IKE_AUTH --> */ process_message(this, sa_r, NULL); /* <-- IKE_AUTH */ -- 2.47.2