]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/tests/suites/test_ike_rekey.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libcharon / tests / suites / test_ike_rekey.c
CommitLineData
b5695bbf
TB
1/*
2 * Copyright (C) 2016 Tobias Brunner
19ef2aec
TB
3 *
4 * Copyright (C) secunet Security Networks AG
b5695bbf
TB
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17#include "test_suite.h"
18
19#include <tests/utils/exchange_test_helper.h>
20#include <tests/utils/exchange_test_asserts.h>
7015994a 21#include <tests/utils/job_asserts.h>
b5695bbf
TB
22#include <tests/utils/sa_asserts.h>
23
24/**
498a46d2
TB
25 * Initiate rekeying the given IKE_SA.
26 */
27#define initiate_rekey(sa) ({ \
28 assert_hook_not_called(ike_rekey); \
29 call_ikesa(sa, rekey); \
30 assert_ike_sa_state(a, IKE_REKEYING); \
31 assert_hook(); \
32})
33
34/**
35 * Regular IKE_SA rekeying either initiated by the original initiator or
b5695bbf
TB
36 * responder of the IKE_SA.
37 */
38START_TEST(test_regular)
39{
40 ike_sa_t *a, *b, *new_sa;
41 status_t s;
42
43 if (_i)
44 { /* responder rekeys the IKE_SA */
45 exchange_test_helper->establish_sa(exchange_test_helper,
46 &b, &a, NULL);
47 }
48 else
49 { /* initiator rekeys the IKE_SA */
50 exchange_test_helper->establish_sa(exchange_test_helper,
51 &a, &b, NULL);
52 }
53 /* these should never get called as this results in a successful rekeying */
54 assert_hook_not_called(ike_updown);
55 assert_hook_not_called(child_updown);
56
498a46d2 57 initiate_rekey(a);
b5695bbf
TB
58
59 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
60 assert_hook_rekey(ike_rekey, 1, 3);
61 assert_no_notify(IN, REKEY_SA);
62 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
bb389973 63 assert_ike_sa_state(b, IKE_REKEYED);
b5695bbf
TB
64 assert_child_sa_count(b, 0);
65 new_sa = assert_ike_sa_checkout(3, 4, FALSE);
66 assert_ike_sa_state(new_sa, IKE_ESTABLISHED);
67 assert_child_sa_count(new_sa, 1);
68 assert_ike_sa_count(1);
69 assert_hook();
70
71 /* <-- CREATE_CHILD_SA { SA, Nr, KEr } */
72 assert_hook_rekey(ike_rekey, 1, 3);
73 assert_no_notify(IN, REKEY_SA);
74 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
75 assert_ike_sa_state(a, IKE_DELETING);
76 assert_child_sa_count(a, 0);
77 new_sa = assert_ike_sa_checkout(3, 4, TRUE);
78 assert_ike_sa_state(new_sa, IKE_ESTABLISHED);
79 assert_child_sa_count(new_sa, 1);
80 assert_ike_sa_count(2);
81 assert_hook();
82
83 /* we don't expect this hook to get called anymore */
84 assert_hook_not_called(ike_rekey);
85
86 /* INFORMATIONAL { D } --> */
87 assert_single_payload(IN, PLV2_DELETE);
88 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
89 ck_assert_int_eq(DESTROY_ME, s);
90 call_ikesa(b, destroy);
91 /* <-- INFORMATIONAL { } */
92 assert_message_empty(IN);
93 s = exchange_test_helper->process_message(exchange_test_helper, a, NULL);
94 ck_assert_int_eq(DESTROY_ME, s);
95 call_ikesa(a, destroy);
96
97 /* ike_rekey/ike_updown/child_updown */
98 assert_hook();
99 assert_hook();
100 assert_hook();
101
102 charon->ike_sa_manager->flush(charon->ike_sa_manager);
103}
104END_TEST
105
46cbdcac
TB
106/**
107 * IKE_SA rekeying where the responder does not agree with the DH group selected
108 * by the initiator, either initiated by the original initiator or responder of
109 * the IKE_SA.
110 */
111START_TEST(test_regular_ke_invalid)
112{
113 exchange_test_sa_conf_t conf = {
114 .initiator = {
115 .ike = "aes128-sha256-modp2048-modp3072",
116 },
117 .responder = {
118 .ike = "aes128-sha256-modp3072-modp2048",
119 },
120 };
121 ike_sa_t *a, *b, *sa;
122 status_t s;
123
124 lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
125 FALSE, lib->ns);
126 if (_i)
127 { /* responder rekeys the IKE_SA */
128 exchange_test_helper->establish_sa(exchange_test_helper,
129 &b, &a, &conf);
130 }
131 else
132 { /* initiator rekeys the IKE_SA */
133 exchange_test_helper->establish_sa(exchange_test_helper,
134 &a, &b, &conf);
135 }
136 /* these should never get called as this results in a successful rekeying */
137 assert_hook_not_called(ike_updown);
138 assert_hook_not_called(child_updown);
139
140 lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
141 TRUE, lib->ns);
576d9b90
TB
142 lib->settings->set_bool(lib->settings, "%s.prefer_previous_dh_group",
143 FALSE, lib->ns);
46cbdcac
TB
144
145 initiate_rekey(a);
146
147 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
148 assert_hook_not_called(ike_rekey);
149 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
150 assert_ike_sa_state(b, IKE_ESTABLISHED);
151 assert_child_sa_count(b, 1);
152 assert_ike_sa_count(0);
153
154 /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */
155 assert_single_notify(IN, INVALID_KE_PAYLOAD);
156 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
157 assert_ike_sa_state(a, IKE_REKEYING);
158 assert_child_sa_count(a, 1);
159 assert_ike_sa_count(0);
160 assert_hook();
161
162 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
163 assert_hook_rekey(ike_rekey, 1, 3);
164 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
165 assert_ike_sa_state(b, IKE_REKEYED);
166 assert_child_sa_count(b, 0);
167 sa = assert_ike_sa_checkout(3, 5, FALSE);
168 assert_ike_sa_state(sa, IKE_ESTABLISHED);
169 assert_child_sa_count(sa, 1);
170 assert_ike_sa_count(1);
171 assert_hook();
172
173 /* <-- CREATE_CHILD_SA { SA, Nr, KEr } */
174 assert_hook_rekey(ike_rekey, 1, 3);
175 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
176 assert_ike_sa_state(a, IKE_DELETING);
177 assert_child_sa_count(a, 0);
178 sa = assert_ike_sa_checkout(3, 5, TRUE);
179 assert_ike_sa_state(sa, IKE_ESTABLISHED);
180 assert_child_sa_count(sa, 1);
181 assert_ike_sa_count(2);
182 assert_hook();
183
184 /* we don't expect this hook to get called anymore */
185 assert_hook_not_called(ike_rekey);
186
187 /* INFORMATIONAL { D } --> */
188 assert_single_payload(IN, PLV2_DELETE);
189 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
190 ck_assert_int_eq(DESTROY_ME, s);
191 call_ikesa(b, destroy);
192 /* <-- INFORMATIONAL { } */
193 assert_message_empty(IN);
194 s = exchange_test_helper->process_message(exchange_test_helper, a, NULL);
195 ck_assert_int_eq(DESTROY_ME, s);
196 call_ikesa(a, destroy);
197
198 /* ike_rekey/ike_updown/child_updown */
199 assert_hook();
200 assert_hook();
201 assert_hook();
202
203 charon->ike_sa_manager->flush(charon->ike_sa_manager);
204}
205END_TEST
206
498a46d2
TB
207/**
208 * Both peers initiate the IKE_SA rekeying concurrently and should handle the
209 * collision properly depending on the nonces.
210 */
211START_TEST(test_collision)
212{
213 ike_sa_t *a, *b, *sa;
214 status_t status;
215
216 exchange_test_helper->establish_sa(exchange_test_helper,
217 &a, &b, NULL);
218
219 /* When rekeyings collide we get two IKE_SAs with a total of four nonces.
220 * The IKE_SA with the lowest nonce SHOULD be deleted by the peer that
221 * created that IKE_SA. The replaced IKE_SA is deleted by the peer that
222 * initiated the surviving SA.
223 * Four nonces and SPIs are needed (SPI 1 and 2 are used for the initial
224 * IKE_SA):
225 * N1/3 -----\ /----- N2/4
226 * \--/-----> N3/5
227 * N4/6 <-------/ /----- ...
228 * ... -----\
229 * We test this four times, each time a different nonce is the lowest.
230 */
231 struct {
232 /* Nonces used at each point */
233 u_char nonces[4];
234 /* SPIs of the deleted IKE_SAs (either redundant or replaced) */
235 uint32_t del_a_i, del_a_r;
236 uint32_t del_b_i, del_b_r;
237 /* SPIs of the kept IKE_SA */
238 uint32_t spi_i, spi_r;
239 } data[] = {
240 { { 0x00, 0xFF, 0xFF, 0xFF }, 3, 5, 1, 2, 4, 6 },
241 { { 0xFF, 0x00, 0xFF, 0xFF }, 1, 2, 4, 6, 3, 5 },
242 { { 0xFF, 0xFF, 0x00, 0xFF }, 3, 5, 1, 2, 4, 6 },
243 { { 0xFF, 0xFF, 0xFF, 0x00 }, 1, 2, 4, 6, 3, 5 },
244 };
245 /* these should never get called as this results in a successful rekeying */
246 assert_hook_not_called(ike_updown);
247 assert_hook_not_called(child_updown);
248
249 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
250 initiate_rekey(a);
251 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
252 initiate_rekey(b);
253
254 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
255 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
256 assert_hook_not_called(ike_rekey);
257 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
258 assert_ike_sa_state(b, IKE_REKEYING);
259 assert_child_sa_count(b, 1);
260 assert_ike_sa_count(0);
261 assert_hook();
262
263 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
264 exchange_test_helper->nonce_first_byte = data[_i].nonces[3];
265 assert_hook_not_called(ike_rekey);
266 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
267 assert_ike_sa_state(a, IKE_REKEYING);
268 assert_child_sa_count(a, 1);
269 assert_ike_sa_count(0);
270 assert_hook();
271
272 /* simplify next steps by checking in original IKE_SAs */
273 charon->ike_sa_manager->checkin(charon->ike_sa_manager, a);
274 charon->ike_sa_manager->checkin(charon->ike_sa_manager, b);
275 assert_ike_sa_count(2);
276
277 /* <-- CREATE_CHILD_SA { SA, Nr, KEr } */
278 assert_hook_rekey(ike_rekey, 1, data[_i].spi_i);
279 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
280 /* as original initiator a is initiator of both SAs it could delete */
281 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, TRUE);
282 assert_ike_sa_state(sa, IKE_DELETING);
283 assert_child_sa_count(sa, 0);
284 /* if b won it will delete the original SA a initiated */
285 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
286 data[_i].del_b_i == 1);
287 assert_ike_sa_state(sa, IKE_REKEYED);
288 assert_child_sa_count(sa, 0);
289 sa = assert_ike_sa_checkout(data[_i].spi_i, data[_i].spi_r,
290 data[_i].del_a_i == 1);
291 assert_ike_sa_state(sa, IKE_ESTABLISHED);
292 assert_child_sa_count(sa, 1);
293 assert_ike_sa_count(4);
294 assert_hook();
295
296 /* CREATE_CHILD_SA { SA, Nr, KEr } --> */
297 assert_hook_rekey(ike_rekey, 1, data[_i].spi_i);
298 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
299 /* if b wins it deletes the SA originally initiated by a */
300 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
301 data[_i].del_b_i != 1);
302 assert_ike_sa_state(sa, IKE_DELETING);
303 assert_child_sa_count(sa, 0);
304 /* a only deletes SAs for which b is responder */
305 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, FALSE);
306 assert_ike_sa_state(sa, IKE_REKEYED);
307 assert_child_sa_count(sa, 0);
308 sa = assert_ike_sa_checkout(data[_i].spi_i, data[_i].spi_r,
309 data[_i].del_b_i == 1);
310 assert_ike_sa_state(sa, IKE_ESTABLISHED);
311 assert_child_sa_count(sa, 1);
312 assert_ike_sa_count(6);
313 assert_hook();
314
315 /* we don't expect this hook to get called anymore */
316 assert_hook_not_called(ike_rekey);
317
318 /* INFORMATIONAL { D } --> */
319 assert_single_payload(IN, PLV2_DELETE);
320 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, FALSE);
321 status = exchange_test_helper->process_message(exchange_test_helper, sa,
322 NULL);
323 ck_assert_int_eq(DESTROY_ME, status);
324 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
325 assert_ike_sa_count(5);
326 /* <-- INFORMATIONAL { D } */
327 assert_single_payload(IN, PLV2_DELETE);
328 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
329 data[_i].del_b_i == 1);
330 status = exchange_test_helper->process_message(exchange_test_helper, sa,
331 NULL);
332 ck_assert_int_eq(DESTROY_ME, status);
333 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
334 assert_ike_sa_count(4);
335 /* <-- INFORMATIONAL { } */
336 assert_message_empty(IN);
337 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, TRUE);
338 status = exchange_test_helper->process_message(exchange_test_helper, sa,
339 NULL);
340 ck_assert_int_eq(DESTROY_ME, status);
341 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
342 assert_ike_sa_count(3);
343 /* INFORMATIONAL { } --> */
344 assert_message_empty(IN);
345 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
346 data[_i].del_b_i != 1);
347 status = exchange_test_helper->process_message(exchange_test_helper, sa,
348 NULL);
349 ck_assert_int_eq(DESTROY_ME, status);
350 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
351 assert_ike_sa_count(2);
352
353 /* ike_rekey/ike_updown/child_updown */
354 assert_hook();
355 assert_hook();
356 assert_hook();
357
358 charon->ike_sa_manager->flush(charon->ike_sa_manager);
359}
360END_TEST
361
46cbdcac
TB
362/**
363 * Both peers initiate the IKE_SA rekeying concurrently but the proposed DH
02b34840 364 * groups are not the same. After handling the INVALID_KE_PAYLOAD they should
46cbdcac
TB
365 * still handle the collision properly depending on the nonces.
366 */
367START_TEST(test_collision_ke_invalid)
368{
369 exchange_test_sa_conf_t conf = {
370 .initiator = {
371 .ike = "aes128-sha256-modp2048-modp3072",
372 },
373 .responder = {
374 .ike = "aes128-sha256-modp3072-modp2048",
375 },
376 };
377 ike_sa_t *a, *b, *sa;
378 status_t status;
379
380 lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
381 FALSE, lib->ns);
382
383 exchange_test_helper->establish_sa(exchange_test_helper,
384 &a, &b, &conf);
385
386 lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
387 TRUE, lib->ns);
576d9b90
TB
388 lib->settings->set_bool(lib->settings, "%s.prefer_previous_dh_group",
389 FALSE, lib->ns);
46cbdcac
TB
390
391 /* Six nonces and SPIs are needed (SPI 1 and 2 are used for the initial
392 * IKE_SA):
393 * N1/3 -----\ /----- N2/4
394 * \--/-----> N3/5
395 * N4/6 <-------/ /---- INVAL_KE
396 * INVAL_KE -----\ /
397 * <-----\--/
398 * N1/3 -----\ \------->
399 * \ /---- N2/4
400 * \--/----> N5/7
401 * N6/8 <--------/ /---- ...
402 * ... ------\
403 * We test this four times, each time a different nonce is the lowest.
404 */
405 struct {
406 /* Nonces used at each point */
407 u_char nonces[4];
408 /* SPIs of the deleted IKE_SAs (either redundant or replaced) */
409 uint32_t del_a_i, del_a_r;
410 uint32_t del_b_i, del_b_r;
411 /* SPIs of the kept IKE_SA */
412 uint32_t spi_i, spi_r;
413 } data[] = {
414 { { 0x00, 0xFF, 0xFF, 0xFF }, 3, 7, 1, 2, 4, 8 },
415 { { 0xFF, 0x00, 0xFF, 0xFF }, 1, 2, 4, 8, 3, 7 },
416 { { 0xFF, 0xFF, 0x00, 0xFF }, 3, 7, 1, 2, 4, 8 },
417 { { 0xFF, 0xFF, 0xFF, 0x00 }, 1, 2, 4, 8, 3, 7 },
418 };
419 /* these should never get called as this results in a successful rekeying */
420 assert_hook_not_called(ike_updown);
421 assert_hook_not_called(child_updown);
422
423 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
424 initiate_rekey(a);
425 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
426 initiate_rekey(b);
427
428 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
429 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
430 assert_hook_not_called(ike_rekey);
431 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
432 assert_ike_sa_state(b, IKE_REKEYING);
433 assert_child_sa_count(b, 1);
434 assert_ike_sa_count(0);
435 assert_hook();
436
437 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
438 exchange_test_helper->nonce_first_byte = data[_i].nonces[3];
439 assert_hook_not_called(ike_rekey);
440 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
441 assert_ike_sa_state(a, IKE_REKEYING);
442 assert_child_sa_count(a, 1);
443 assert_ike_sa_count(0);
444 assert_hook();
445
446 /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */
447 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
448 assert_hook_not_called(ike_rekey);
449 assert_single_notify(IN, INVALID_KE_PAYLOAD);
450 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
451 assert_ike_sa_state(a, IKE_REKEYING);
452 assert_child_sa_count(a, 1);
453 assert_ike_sa_count(0);
454 assert_hook();
455
456 /* CREATE_CHILD_SA { N(INVAL_KE) } --> */
457 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
458 assert_hook_not_called(child_rekey);
459 assert_single_notify(IN, INVALID_KE_PAYLOAD);
460 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
461 assert_ike_sa_state(b, IKE_REKEYING);
462 assert_child_sa_count(b, 1);
463 assert_ike_sa_count(0);
464 assert_hook();
465
466 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
467 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
468 assert_hook_not_called(ike_rekey);
469 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
470 assert_ike_sa_state(b, IKE_REKEYING);
471 assert_child_sa_count(b, 1);
472 assert_ike_sa_count(0);
473 assert_hook();
474
475 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
476 exchange_test_helper->nonce_first_byte = data[_i].nonces[3];
477 assert_hook_not_called(ike_rekey);
478 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
479 assert_ike_sa_state(a, IKE_REKEYING);
480 assert_child_sa_count(a, 1);
481 assert_ike_sa_count(0);
482 assert_hook();
483
484 /* simplify next steps by checking in original IKE_SAs */
485 charon->ike_sa_manager->checkin(charon->ike_sa_manager, a);
486 charon->ike_sa_manager->checkin(charon->ike_sa_manager, b);
487 assert_ike_sa_count(2);
488
489 /* <-- CREATE_CHILD_SA { SA, Nr, KEr } */
490 assert_hook_rekey(ike_rekey, 1, data[_i].spi_i);
491 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
492 /* as original initiator a is initiator of both SAs it could delete */
493 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, TRUE);
494 assert_ike_sa_state(sa, IKE_DELETING);
495 assert_child_sa_count(sa, 0);
496 /* if b won it will delete the original SA a initiated */
497 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
498 data[_i].del_b_i == 1);
499 assert_ike_sa_state(sa, IKE_REKEYED);
500 assert_child_sa_count(sa, 0);
501 sa = assert_ike_sa_checkout(data[_i].spi_i, data[_i].spi_r,
502 data[_i].del_a_i == 1);
503 assert_ike_sa_state(sa, IKE_ESTABLISHED);
504 assert_child_sa_count(sa, 1);
505 assert_ike_sa_count(4);
506 assert_hook();
507
508 /* CREATE_CHILD_SA { SA, Nr, KEr } --> */
509 assert_hook_rekey(ike_rekey, 1, data[_i].spi_i);
510 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
511 /* if b wins it deletes the SA originally initiated by a */
512 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
513 data[_i].del_b_i != 1);
514 assert_ike_sa_state(sa, IKE_DELETING);
515 assert_child_sa_count(sa, 0);
516 /* a only deletes SAs for which b is responder */
517 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, FALSE);
518 assert_ike_sa_state(sa, IKE_REKEYED);
519 assert_child_sa_count(sa, 0);
520 sa = assert_ike_sa_checkout(data[_i].spi_i, data[_i].spi_r,
521 data[_i].del_b_i == 1);
522 assert_ike_sa_state(sa, IKE_ESTABLISHED);
523 assert_child_sa_count(sa, 1);
524 assert_ike_sa_count(6);
525 assert_hook();
526
527 /* we don't expect this hook to get called anymore */
528 assert_hook_not_called(ike_rekey);
529
530 /* INFORMATIONAL { D } --> */
531 assert_single_payload(IN, PLV2_DELETE);
532 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, FALSE);
533 status = exchange_test_helper->process_message(exchange_test_helper, sa,
534 NULL);
535 ck_assert_int_eq(DESTROY_ME, status);
536 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
537 assert_ike_sa_count(5);
538 /* <-- INFORMATIONAL { D } */
539 assert_single_payload(IN, PLV2_DELETE);
540 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
541 data[_i].del_b_i == 1);
542 status = exchange_test_helper->process_message(exchange_test_helper, sa,
543 NULL);
544 ck_assert_int_eq(DESTROY_ME, status);
545 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
546 assert_ike_sa_count(4);
547 /* <-- INFORMATIONAL { } */
548 assert_message_empty(IN);
549 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, TRUE);
550 status = exchange_test_helper->process_message(exchange_test_helper, sa,
551 NULL);
552 ck_assert_int_eq(DESTROY_ME, status);
553 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
554 assert_ike_sa_count(3);
555 /* INFORMATIONAL { } --> */
556 assert_message_empty(IN);
557 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
558 data[_i].del_b_i != 1);
559 status = exchange_test_helper->process_message(exchange_test_helper, sa,
560 NULL);
561 ck_assert_int_eq(DESTROY_ME, status);
562 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
563 assert_ike_sa_count(2);
564
565 /* ike_rekey/ike_updown/child_updown */
566 assert_hook();
567 assert_hook();
568 assert_hook();
569
570 charon->ike_sa_manager->flush(charon->ike_sa_manager);
571}
572END_TEST
573
574/**
575 * This is like the collision above but one of the retries is delayed.
576 */
577START_TEST(test_collision_ke_invalid_delayed_retry)
578{
579 exchange_test_sa_conf_t conf = {
580 .initiator = {
581 .ike = "aes128-sha256-modp2048-modp3072",
582 },
583 .responder = {
584 .ike = "aes128-sha256-modp3072-modp2048",
585 },
586 };
587 ike_sa_t *a, *b, *sa;
588 message_t *msg;
589 status_t s;
590
591 lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
592 FALSE, lib->ns);
593
594 exchange_test_helper->establish_sa(exchange_test_helper,
595 &a, &b, &conf);
596
597 lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
598 TRUE, lib->ns);
576d9b90
TB
599 lib->settings->set_bool(lib->settings, "%s.prefer_previous_dh_group",
600 FALSE, lib->ns);
46cbdcac
TB
601
602 /* Five nonces and SPIs are needed (SPI 1 and 2 are used for the initial
603 * IKE_SA):
604 * N1/3 -----\ /----- N2/4
605 * \--/-----> N3/5
606 * N4/6 <-------/ /---- INVAL_KE
607 * INVAL_KE -----\ /
608 * <-----\--/
609 * N1/3 -----\ \------->
610 * <-----\--------- N2/4
611 * N5/7 -------\------->
612 * <-------\------- DELETE
613 * ... ------\ \----->
614 * /---- TEMP_FAIL
615 *
616 * We test this three times, each time a different nonce is the lowest.
617 */
618 struct {
619 /* Nonces used at each point */
620 u_char nonces[3];
621 } data[] = {
622 { { 0x00, 0xFF, 0xFF } },
623 { { 0xFF, 0x00, 0xFF } },
624 { { 0xFF, 0xFF, 0x00 } },
625 };
626 /* these should never get called as this results in a successful rekeying */
627 assert_hook_not_called(ike_updown);
628 assert_hook_not_called(child_updown);
629
630 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
631 initiate_rekey(a);
632 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
633 initiate_rekey(b);
634
635 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
636 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
637 assert_hook_not_called(ike_rekey);
638 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
639 assert_ike_sa_state(b, IKE_REKEYING);
640 assert_child_sa_count(b, 1);
641 assert_ike_sa_count(0);
642 assert_hook();
643
644 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
645 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
646 assert_hook_not_called(ike_rekey);
647 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
648 assert_ike_sa_state(a, IKE_REKEYING);
649 assert_child_sa_count(a, 1);
650 assert_ike_sa_count(0);
651 assert_hook();
652
653 /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */
654 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
655 assert_hook_not_called(ike_rekey);
656 assert_single_notify(IN, INVALID_KE_PAYLOAD);
657 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
658 assert_ike_sa_state(a, IKE_REKEYING);
659 assert_child_sa_count(a, 1);
660 assert_ike_sa_count(0);
661 assert_hook();
662
663 /* CREATE_CHILD_SA { N(INVAL_KE) } --> */
664 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
665 assert_hook_not_called(child_rekey);
666 assert_single_notify(IN, INVALID_KE_PAYLOAD);
667 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
668 assert_ike_sa_state(b, IKE_REKEYING);
669 assert_child_sa_count(b, 1);
670 assert_ike_sa_count(0);
671 assert_hook();
672
673 /* delay the CREATE_CHILD_SA request from a to b */
674 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
675
676 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
677 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
678 assert_hook_not_called(ike_rekey);
679 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
680 assert_ike_sa_state(a, IKE_REKEYING);
681 assert_child_sa_count(a, 1);
682 assert_ike_sa_count(0);
683 assert_hook();
684
685 /* CREATE_CHILD_SA { SA, Nr, KEr } --> */
686 assert_hook_rekey(ike_rekey, 1, 4);
687 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
688 assert_ike_sa_state(b, IKE_DELETING);
689 assert_child_sa_count(b, 0);
690 sa = assert_ike_sa_checkout(4, 7, TRUE);
691 assert_ike_sa_state(sa, IKE_ESTABLISHED);
692 assert_child_sa_count(sa, 1);
693 assert_ike_sa_count(1);
694 assert_hook();
695
696 /* CREATE_CHILD_SA { SA, Ni, KEi } --> (delayed) */
697 assert_single_notify(OUT, TEMPORARY_FAILURE);
698 exchange_test_helper->process_message(exchange_test_helper, b, msg);
699 assert_ike_sa_state(b, IKE_DELETING);
700
701 /* <-- INFORMATIONAL { D } */
702 assert_hook_rekey(ike_rekey, 1, 4);
703 assert_single_payload(IN, PLV2_DELETE);
704 s = exchange_test_helper->process_message(exchange_test_helper, a, NULL);
705 ck_assert_int_eq(DESTROY_ME, s);
706 call_ikesa(a, destroy);
707 sa = assert_ike_sa_checkout(4, 7, FALSE);
708 assert_ike_sa_state(sa, IKE_ESTABLISHED);
709 assert_child_sa_count(sa, 1);
710 assert_ike_sa_count(2);
711 assert_hook();
712
713 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
714 /* the SA is already gone */
715 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
716 msg->destroy(msg);
717
718 /* INFORMATIONAL { } --> */
719 assert_hook_not_called(ike_rekey);
720 assert_message_empty(IN);
721 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
722 ck_assert_int_eq(DESTROY_ME, s);
723 call_ikesa(b, destroy);
724 assert_hook();
725
726 /* ike_updown/child_updown */
727 assert_hook();
728 assert_hook();
729
730 charon->ike_sa_manager->flush(charon->ike_sa_manager);
731}
732END_TEST
733
2e33d1f9
TB
734/**
735 * This is like the rekey collision above, but one peer deletes the
736 * redundant/old SA before the other peer receives the CREATE_CHILD_SA
737 * response:
738 * Peer A Peer B
739 * rekey ----\ /---- rekey
740 * \-----/----> detect collision
741 * detect collision <---------/ /----
742 * -----------/---->
743 * handle delete <---------/------ delete redundant/old SA
744 * ---------/------>
745 * handle rekey <-------/
746 * delete SA ---------------->
747 * <----------------
748 *
749 * If peer B won the collision it deletes the old IKE_SA, in which case
750 * this situation is handled as if peer B was not aware of the collision (see
751 * below). That is, peer A finalizes the rekeying initiated by the peer and
752 * deletes the IKE_SA (it has no way of knowing whether the peer was aware of
753 * the collision or not). Peer B will expect the redundant IKE_SA to get
754 * deleted, but that will never happen if the response arrives after the SA is
755 * already gone. So a job should be queued that deletes it after a while.
756 *
757 * If peer B lost it will switch to the new IKE_SA and delete the redundant
758 * IKE_SA and expect a delete for the old IKE_SA. In this case peer A will
759 * simply retransmit until it receives a response to the rekey request, all the
760 * while ignoring the delete requests for the unknown IKE_SA. Afterwards,
761 * everything works as in a regular collision (however, until peer A receives
762 * the response it will not be able to receive any messages on the new IKE_SA).
763 */
764START_TEST(test_collision_delayed_response)
765{
766 ike_sa_t *a, *b, *sa;
767 message_t *msg, *d;
768 status_t s;
769
770 exchange_test_helper->establish_sa(exchange_test_helper,
771 &a, &b, NULL);
772
773 /* Four nonces and SPIs are needed (SPI 1 and 2 are used for the initial
774 * IKE_SA):
775 * N1/3 -----\ /----- N2/4
776 * \--/-----> N3/5
777 * N4/6 <-------/ /----- ...
778 * ... -----\
779 * We test this four times, each time a different nonce is the lowest.
780 */
781 struct {
782 /* Nonces used at each point */
783 u_char nonces[4];
784 /* SPIs of the deleted IKE_SAs (either redundant or replaced) */
785 uint32_t del_a_i, del_a_r;
786 uint32_t del_b_i, del_b_r;
787 /* SPIs of the kept IKE_SA */
788 uint32_t spi_i, spi_r;
789 } data[] = {
790 { { 0x00, 0xFF, 0xFF, 0xFF }, 3, 5, 1, 2, 4, 6 },
791 { { 0xFF, 0x00, 0xFF, 0xFF }, 1, 2, 4, 6, 3, 5 },
792 { { 0xFF, 0xFF, 0x00, 0xFF }, 3, 5, 1, 2, 4, 6 },
793 { { 0xFF, 0xFF, 0xFF, 0x00 }, 1, 2, 4, 6, 3, 5 },
794 };
795 /* these should never get called as this results in a successful rekeying */
796 assert_hook_not_called(ike_updown);
797 assert_hook_not_called(child_updown);
798
799 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
800 initiate_rekey(a);
801 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
802 initiate_rekey(b);
803
804 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
805 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
806 assert_hook_not_called(ike_rekey);
807 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
808 assert_ike_sa_state(b, IKE_REKEYING);
809 assert_child_sa_count(b, 1);
810 assert_ike_sa_count(0);
811 assert_hook();
812
813 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
814 exchange_test_helper->nonce_first_byte = data[_i].nonces[3];
815 assert_hook_not_called(ike_rekey);
816 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
817 assert_ike_sa_state(a, IKE_REKEYING);
818 assert_child_sa_count(a, 1);
819 assert_ike_sa_count(0);
820 assert_hook();
821
822 /* delay the CREATE_CHILD_SA response from b to a */
823 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
824
825 /* simplify next steps by checking in original IKE_SAs */
826 charon->ike_sa_manager->checkin(charon->ike_sa_manager, a);
827 charon->ike_sa_manager->checkin(charon->ike_sa_manager, b);
828 assert_ike_sa_count(2);
829
830 /* CREATE_CHILD_SA { SA, Nr, KEr } --> */
831 assert_hook_rekey(ike_rekey, 1, data[_i].spi_i);
832 /* besides the job that retransmits the delete, we expect a job that
833 * deletes the redundant IKE_SA if we expect the other to delete it */
834 assert_jobs_scheduled(data[_i].del_b_i == 1 ? 2 : 1);
835 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
836 /* if b wins it deletes the SA originally initiated by a */
837 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r,
838 data[_i].del_b_i != 1);
839 assert_ike_sa_state(sa, IKE_DELETING);
840 assert_child_sa_count(sa, 0);
841 /* a only deletes SAs for which b is responder */
842 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, FALSE);
843 assert_ike_sa_state(sa, IKE_REKEYED);
844 assert_child_sa_count(sa, 0);
845 sa = assert_ike_sa_checkout(data[_i].spi_i, data[_i].spi_r,
846 data[_i].del_b_i == 1);
847 assert_ike_sa_state(sa, IKE_ESTABLISHED);
848 assert_child_sa_count(sa, 1);
849 assert_ike_sa_count(4);
850 assert_scheduler();
851 assert_hook();
852
853 /* <-- INFORMATIONAL { D } */
854 if (data[_i].del_b_i == 1)
855 { /* b won, it deletes the replaced IKE_SA */
856 assert_hook_rekey(ike_rekey, 1, data[_i].spi_i);
857 assert_single_payload(IN, PLV2_DELETE);
858 s = exchange_test_helper->process_message(exchange_test_helper, a,
859 NULL);
860 ck_assert_int_eq(DESTROY_ME, s);
861 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, a);
862 sa = assert_ike_sa_checkout(data[_i].spi_i, data[_i].spi_r, FALSE);
863 assert_ike_sa_state(sa, IKE_ESTABLISHED);
864 assert_child_sa_count(sa, 1);
865 assert_ike_sa_count(4);
866 assert_hook();
867
868 /* INFORMATIONAL { } --> */
869 assert_hook_not_called(ike_rekey);
870 assert_message_empty(IN);
871 s = exchange_test_helper->process_message(exchange_test_helper, b,
872 NULL);
873 ck_assert_int_eq(DESTROY_ME, s);
874 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, b);
875 assert_ike_sa_count(3);
876 assert_hook();
877 /* the job will later remove this redundant IKE_SA on b */
878 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, FALSE);
879 assert_ike_sa_state(sa, IKE_REKEYED);
880 assert_sa_idle(sa);
881 /* <-- CREATE_CHILD_SA { SA, Nr, KEr } (delayed) */
882 /* the IKE_SA (a) does not exist anymore */
883 msg->destroy(msg);
884 }
885 else
886 { /* b lost, the delete is for the non-existing redundant IKE_SA */
887 d = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
888
889 /* <-- CREATE_CHILD_SA { SA, Nr, KEr } (delayed) */
890 assert_hook_rekey(ike_rekey, 1, data[_i].spi_i);
891 exchange_test_helper->process_message(exchange_test_helper, a, msg);
892 /* as original initiator a is initiator of both SAs it could delete */
893 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, TRUE);
894 assert_ike_sa_state(sa, IKE_DELETING);
895 assert_child_sa_count(sa, 0);
896 /* this is the redundant SA b is trying to delete */
897 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r, FALSE);
898 assert_ike_sa_state(sa, IKE_REKEYED);
899 assert_child_sa_count(sa, 0);
900 sa = assert_ike_sa_checkout(data[_i].spi_i, data[_i].spi_r,
901 data[_i].del_a_i == 1);
902 assert_ike_sa_state(sa, IKE_ESTABLISHED);
903 assert_child_sa_count(sa, 1);
904 assert_ike_sa_count(6);
905 assert_hook();
906
907 /* we don't expect this hook to get called anymore */
908 assert_hook_not_called(ike_rekey);
909
910 /* INFORMATIONAL { D } --> */
911 assert_single_payload(IN, PLV2_DELETE);
912 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, FALSE);
913 s = exchange_test_helper->process_message(exchange_test_helper, sa,
914 NULL);
915 ck_assert_int_eq(DESTROY_ME, s);
916 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
917 assert_ike_sa_count(5);
918 /* <-- INFORMATIONAL { } */
919 assert_message_empty(IN);
920 sa = assert_ike_sa_checkout(data[_i].del_a_i, data[_i].del_a_r, TRUE);
921 s = exchange_test_helper->process_message(exchange_test_helper, sa,
922 NULL);
923 ck_assert_int_eq(DESTROY_ME, s);
924 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
925 assert_ike_sa_count(4);
926
927 /* <-- INFORMATIONAL { D } (retransmit/delayed) */
928 assert_single_payload(IN, PLV2_DELETE);
929 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r, FALSE);
930 s = exchange_test_helper->process_message(exchange_test_helper, sa, d);
931 ck_assert_int_eq(DESTROY_ME, s);
932 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
933 assert_ike_sa_count(3);
934 /* INFORMATIONAL { } --> */
935 assert_message_empty(IN);
936 sa = assert_ike_sa_checkout(data[_i].del_b_i, data[_i].del_b_r, TRUE);
937 s = exchange_test_helper->process_message(exchange_test_helper, sa,
938 NULL);
939 ck_assert_int_eq(DESTROY_ME, s);
940 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
941 assert_ike_sa_count(2);
942 /* ike_rekey */
943 assert_hook();
944 }
945
946 /* ike_updown/child_updown */
947 assert_hook();
948 assert_hook();
949
950 charon->ike_sa_manager->flush(charon->ike_sa_manager);
951}
952END_TEST
953
566134b2
TB
954/**
955 * In this scenario one of the peers does not notice that there is a rekey
956 * collision because the other request is dropped:
957 *
958 * rekey ----\ /---- rekey
959 * \ /
960 * detect collision <-----\---/
961 * -------\-------->
962 * detect collision <-------\-------- delete old SA
963 * delete ---------\------>
964 * rekey done \-----> SA not found (or it never arrives)
965 */
966START_TEST(test_collision_dropped_request)
967{
968 ike_sa_t *a, *b, *sa;
969 message_t *msg;
970 status_t s;
971
972 exchange_test_helper->establish_sa(exchange_test_helper,
973 &a, &b, NULL);
974
975 /* Three nonces and SPIs are needed (SPI 1 and 2 are used for the initial
976 * CHILD_SA):
977 * N1/3 -----\ /----- N2/4
978 * N3/5 <-----\--/
979 * ... -----\ \-------> ...
980 * We test this three times, each time a different nonce is the lowest.
981 */
982 struct {
983 /* Nonces used at each point */
984 u_char nonces[3];
985 /* SPIs of the deleted IKE_SAs (either redundant or replaced) */
986 uint32_t del_a_i, del_a_r;
987 uint32_t del_b_i, del_b_r;
988 /* SPIs of the kept IKE_SA */
989 uint32_t spi_i, spi_r;
990 } data[] = {
991 { { 0x00, 0xFF, 0xFF }, 3, 5, 1, 2, 4, 6 },
992 { { 0xFF, 0x00, 0xFF }, 1, 2, 4, 6, 3, 5 },
993 { { 0xFF, 0xFF, 0x00 }, 3, 5, 1, 2, 4, 6 },
994 { { 0xFF, 0xFF, 0xFF }, 1, 2, 4, 6, 3, 5 },
995 };
996 /* these should never get called as this results in a successful rekeying */
997 assert_hook_not_called(ike_updown);
998 assert_hook_not_called(child_updown);
999
1000 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1001 initiate_rekey(a);
1002 /* drop the CREATE_CHILD_SA request from a to b */
1003 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1004 msg->destroy(msg);
1005 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1006 initiate_rekey(b);
1007
1008 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
1009 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
1010 assert_hook_not_called(ike_rekey);
1011 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1012 assert_ike_sa_state(a, IKE_REKEYING);
1013 assert_child_sa_count(a, 1);
1014 assert_ike_sa_count(0);
1015 assert_hook();
1016
1017 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
1018 assert_hook_rekey(ike_rekey, 1, 4);
1019 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1020 assert_ike_sa_state(b, IKE_DELETING);
1021 assert_child_sa_count(b, 0);
1022 sa = assert_ike_sa_checkout(4, 5, TRUE);
1023 assert_ike_sa_state(sa, IKE_ESTABLISHED);
1024 assert_child_sa_count(sa, 1);
1025 assert_ike_sa_count(1);
1026 assert_hook();
1027
1028 /* <-- INFORMATIONAL { D } */
1029 assert_hook_rekey(ike_rekey, 1, 4);
1030 assert_single_payload(IN, PLV2_DELETE);
1031 s = exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1032 ck_assert_int_eq(DESTROY_ME, s);
1033 call_ikesa(a, destroy);
1034 sa = assert_ike_sa_checkout(4, 5, FALSE);
1035 assert_ike_sa_state(sa, IKE_ESTABLISHED);
1036 assert_child_sa_count(sa, 1);
1037 assert_ike_sa_count(2);
1038 assert_hook();
1039
1040 /* INFORMATIONAL { } --> */
1041 assert_hook_not_called(ike_rekey);
1042 assert_message_empty(IN);
1043 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1044 ck_assert_int_eq(DESTROY_ME, s);
1045 call_ikesa(b, destroy);
1046 assert_hook();
1047
1048 /* ike_updown/child_updown */
1049 assert_hook();
1050 assert_hook();
1051
1052 charon->ike_sa_manager->flush(charon->ike_sa_manager);
1053}
1054END_TEST
1055
1056/**
1057 * In this scenario one of the peers does not notice that there is a rekey
1058 * collision because the other request is delayed:
1059 *
1060 * rekey ----\ /---- rekey
1061 * \ /
1062 * detect collision <-----\---/
1063 * -------\-------->
1064 * \ /---- delete old SA
1065 * \-/----> detect collision
1066 * detect collision <---------/ /---- TEMP_FAIL
1067 * delete -----------/---->
1068 * rekey done /
1069 * sa already gone <--------/
1070 */
1071START_TEST(test_collision_delayed_request)
1072{
1073 ike_sa_t *a, *b, *sa;
1074 message_t *msg;
1075 status_t s;
1076
1077 exchange_test_helper->establish_sa(exchange_test_helper,
1078 &a, &b, NULL);
1079
1080 /* Three nonces and SPIs are needed (SPI 1 and 2 are used for the initial
1081 * CHILD_SA):
1082 * N1/3 -----\ /----- N2/4
1083 * N3/5 <-----\--/
1084 * ... -----\ \-------> ...
1085 * We test this three times, each time a different nonce is the lowest.
1086 */
1087 struct {
1088 /* Nonces used at each point */
1089 u_char nonces[3];
1090 /* SPIs of the deleted IKE_SAs (either redundant or replaced) */
1091 uint32_t del_a_i, del_a_r;
1092 uint32_t del_b_i, del_b_r;
1093 /* SPIs of the kept IKE_SA */
1094 uint32_t spi_i, spi_r;
1095 } data[] = {
1096 { { 0x00, 0xFF, 0xFF }, 3, 5, 1, 2, 4, 6 },
1097 { { 0xFF, 0x00, 0xFF }, 1, 2, 4, 6, 3, 5 },
1098 { { 0xFF, 0xFF, 0x00 }, 3, 5, 1, 2, 4, 6 },
1099 { { 0xFF, 0xFF, 0xFF }, 1, 2, 4, 6, 3, 5 },
1100 };
1101 /* these should never get called as this results in a successful rekeying */
1102 assert_hook_not_called(ike_updown);
1103 assert_hook_not_called(child_updown);
1104
1105 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1106 initiate_rekey(a);
1107 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1108 initiate_rekey(b);
1109
1110 /* delay the CREATE_CHILD_SA request from a to b */
1111 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1112
1113 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
1114 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
1115 assert_hook_not_called(ike_rekey);
1116 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1117 assert_ike_sa_state(a, IKE_REKEYING);
1118 assert_child_sa_count(a, 1);
1119 assert_ike_sa_count(0);
1120 assert_hook();
1121
1122 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
1123 assert_hook_rekey(ike_rekey, 1, 4);
1124 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1125 assert_ike_sa_state(b, IKE_DELETING);
1126 assert_child_sa_count(b, 0);
1127 sa = assert_ike_sa_checkout(4, 5, TRUE);
1128 assert_ike_sa_state(sa, IKE_ESTABLISHED);
1129 assert_child_sa_count(sa, 1);
1130 assert_ike_sa_count(1);
1131 assert_hook();
1132
1133 /* CREATE_CHILD_SA { SA, Ni, KEi } --> (delayed) */
1134 assert_single_notify(OUT, TEMPORARY_FAILURE);
1135 exchange_test_helper->process_message(exchange_test_helper, b, msg);
1136 assert_ike_sa_state(b, IKE_DELETING);
1137
1138 /* <-- INFORMATIONAL { D } */
1139 assert_hook_rekey(ike_rekey, 1, 4);
1140 assert_single_payload(IN, PLV2_DELETE);
1141 s = exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1142 ck_assert_int_eq(DESTROY_ME, s);
1143 call_ikesa(a, destroy);
1144 sa = assert_ike_sa_checkout(4, 5, FALSE);
1145 assert_ike_sa_state(sa, IKE_ESTABLISHED);
1146 assert_child_sa_count(sa, 1);
1147 assert_ike_sa_count(2);
1148 assert_hook();
1149
1150 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1151 /* the SA is already gone */
1152 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1153 msg->destroy(msg);
1154
1155 /* INFORMATIONAL { } --> */
1156 assert_hook_not_called(ike_rekey);
1157 assert_message_empty(IN);
1158 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1159 ck_assert_int_eq(DESTROY_ME, s);
1160 call_ikesa(b, destroy);
1161 assert_hook();
1162
1163 /* ike_updown/child_updown */
1164 assert_hook();
1165 assert_hook();
1166
1167 charon->ike_sa_manager->flush(charon->ike_sa_manager);
1168}
1169END_TEST
1170
1171/**
1172 * In this scenario one of the peers does not notice that there is a rekey
1173 * collision and the delete arrives after the TEMPORARY_FAILURE notify:
1174 *
1175 * rekey ----\ /---- rekey
1176 * \ /
1177 * detect collision <-----\---/
1178 * -------\-------->
1179 * \ /---- delete old SA
1180 * \-/----> detect collision
1181 * no reschedule <---------/------ TEMP_FAIL
1182 * detect collision <--------/
1183 * delete ---------------->
1184 * rekey done
1185 */
1186START_TEST(test_collision_delayed_request_and_delete)
1187{
1188 ike_sa_t *a, *b, *sa;
1189 message_t *msg;
1190 status_t s;
1191
1192 exchange_test_helper->establish_sa(exchange_test_helper,
1193 &a, &b, NULL);
1194
1195 /* Three nonces and SPIs are needed (SPI 1 and 2 are used for the initial
1196 * CHILD_SA):
1197 * N1/3 -----\ /----- N2/4
1198 * N3/5 <-----\--/
1199 * ... -----\ \-------> ...
1200 * We test this three times, each time a different nonce is the lowest.
1201 */
1202 struct {
1203 /* Nonces used at each point */
1204 u_char nonces[3];
1205 /* SPIs of the deleted IKE_SAs (either redundant or replaced) */
1206 uint32_t del_a_i, del_a_r;
1207 uint32_t del_b_i, del_b_r;
1208 /* SPIs of the kept IKE_SA */
1209 uint32_t spi_i, spi_r;
1210 } data[] = {
1211 { { 0x00, 0xFF, 0xFF }, 3, 5, 1, 2, 4, 6 },
1212 { { 0xFF, 0x00, 0xFF }, 1, 2, 4, 6, 3, 5 },
1213 { { 0xFF, 0xFF, 0x00 }, 3, 5, 1, 2, 4, 6 },
1214 { { 0xFF, 0xFF, 0xFF }, 1, 2, 4, 6, 3, 5 },
1215 };
1216 /* these should never get called as this results in a successful rekeying */
1217 assert_hook_not_called(ike_updown);
1218 assert_hook_not_called(child_updown);
1219
1220 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1221 initiate_rekey(a);
1222 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1223 initiate_rekey(b);
1224
1225 /* delay the CREATE_CHILD_SA request from a to b */
1226 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1227
1228 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
1229 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
1230 assert_hook_not_called(ike_rekey);
1231 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1232 assert_ike_sa_state(a, IKE_REKEYING);
1233 assert_child_sa_count(a, 1);
1234 assert_ike_sa_count(0);
1235 assert_hook();
1236
1237 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
1238 assert_hook_rekey(ike_rekey, 1, 4);
1239 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1240 assert_ike_sa_state(b, IKE_DELETING);
1241 assert_child_sa_count(b, 0);
1242 sa = assert_ike_sa_checkout(4, 5, TRUE);
1243 assert_ike_sa_state(sa, IKE_ESTABLISHED);
1244 assert_child_sa_count(sa, 1);
1245 assert_ike_sa_count(1);
1246 assert_hook();
1247
1248 /* CREATE_CHILD_SA { SA, Ni, KEi } --> (delayed) */
1249 assert_single_notify(OUT, TEMPORARY_FAILURE);
1250 exchange_test_helper->process_message(exchange_test_helper, b, msg);
1251 assert_ike_sa_state(b, IKE_DELETING);
1252
1253 /* delay the INFORMATIONAL request from b to a */
1254 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1255
1256 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1257 assert_hook_rekey(ike_rekey, 1, 4);
1258 assert_no_jobs_scheduled();
1259 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1260 assert_ike_sa_state(a, IKE_REKEYED);
1261 assert_child_sa_count(a, 0);
1262 sa = assert_ike_sa_checkout(4, 5, FALSE);
1263 assert_ike_sa_state(sa, IKE_ESTABLISHED);
1264 assert_child_sa_count(sa, 1);
1265 assert_ike_sa_count(2);
1266 assert_scheduler();
1267 assert_hook();
1268
1269 /* <-- INFORMATIONAL { D } (delayed) */
1270 assert_single_payload(IN, PLV2_DELETE);
1271 s = exchange_test_helper->process_message(exchange_test_helper, a, msg);
1272 ck_assert_int_eq(DESTROY_ME, s);
1273 call_ikesa(a, destroy);
1274
1275 /* INFORMATIONAL { } --> */
1276 assert_hook_not_called(ike_rekey);
1277 assert_message_empty(IN);
1278 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1279 ck_assert_int_eq(DESTROY_ME, s);
1280 call_ikesa(b, destroy);
1281 assert_hook();
1282
1283 /* ike_updown/child_updown */
1284 assert_hook();
1285 assert_hook();
1286
1287 charon->ike_sa_manager->flush(charon->ike_sa_manager);
1288}
1289END_TEST
1290
7015994a
TB
1291/**
1292 * One of the hosts initiates a DELETE of the IKE_SA the other peer is
1293 * concurrently trying to rekey.
1294 *
1295 * rekey ----\ /---- delete
1296 * \-----/----> detect collision
1297 * detect collision <---------/ /---- TEMP_FAIL
1298 * delete ----\ /
1299 * \----/----->
1300 * sa already gone <--------/
1301 */
1302START_TEST(test_collision_delete)
1303{
1304 ike_sa_t *a, *b;
1305 message_t *msg;
1306 status_t s;
1307
1308 if (_i)
1309 { /* responder rekeys the IKE_SA */
1310 exchange_test_helper->establish_sa(exchange_test_helper,
1311 &b, &a, NULL);
1312 }
1313 else
1314 { /* initiator rekeys the IKE_SA */
1315 exchange_test_helper->establish_sa(exchange_test_helper,
1316 &a, &b, NULL);
1317 }
1318 /* this should never get called as this does not result in a successful
1319 * rekeying on either side */
1320 assert_hook_not_called(ike_rekey);
1321
1322 initiate_rekey(a);
a79d5103 1323 call_ikesa(b, delete, FALSE);
7015994a
TB
1324 assert_ike_sa_state(b, IKE_DELETING);
1325
1326 /* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that
1327 * it is currently trying to close, it SHOULD reply with TEMPORARY_FAILURE.
1328 */
1329
1330 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
1331 assert_hook_not_called(ike_updown);
1332 assert_single_notify(OUT, TEMPORARY_FAILURE);
1333 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1334 assert_ike_sa_state(b, IKE_DELETING);
1335 assert_ike_sa_count(0);
1336 assert_hook();
1337
1338 /* RFC 7296, 2.25.2: If a peer receives a request to close an IKE SA that
1339 * it is currently rekeying, it SHOULD reply as usual, and forget its own
1340 * rekeying request.
1341 */
1342
1343 /* <-- INFORMATIONAL { D } */
1344 assert_hook_updown(ike_updown, FALSE);
1345 assert_hook_updown(child_updown, FALSE);
1346 assert_single_payload(IN, PLV2_DELETE);
1347 assert_message_empty(OUT);
1348 s = exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1349 ck_assert_int_eq(DESTROY_ME, s);
1350 call_ikesa(a, destroy);
1351 assert_hook();
1352 assert_hook();
1353
1354 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1355 /* the SA is already gone */
1356 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1357 msg->destroy(msg);
1358
1359 /* INFORMATIONAL { } --> */
1360 assert_hook_updown(ike_updown, FALSE);
1361 assert_hook_updown(child_updown, FALSE);
1362 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1363 ck_assert_int_eq(DESTROY_ME, s);
1364 call_ikesa(b, destroy);
1365 assert_hook();
1366 assert_hook();
1367
1368 /* ike_rekey */
1369 assert_hook();
1370}
1371END_TEST
1372
1373/**
1374 * One of the hosts initiates a DELETE of the IKE_SA the other peer is
1375 * concurrently trying to rekey. However, the delete request is delayed or
1376 * dropped, so the peer doing the rekeying is unaware of the collision.
1377 *
1378 * rekey ----\ /---- delete
1379 * \-----/----> detect collision
1380 * reschedule <---------/------ TEMP_FAIL
1381 * <--------/
1382 * delete ---------------->
1383 */
1384START_TEST(test_collision_delete_drop_delete)
1385{
1386 ike_sa_t *a, *b;
1387 message_t *msg;
1388 status_t s;
1389
1390 if (_i)
1391 { /* responder rekeys the IKE_SA */
1392 exchange_test_helper->establish_sa(exchange_test_helper,
1393 &b, &a, NULL);
1394 }
1395 else
1396 { /* initiator rekeys the IKE_SA */
1397 exchange_test_helper->establish_sa(exchange_test_helper,
1398 &a, &b, NULL);
1399 }
1400 /* this should never get called as this does not result in a successful
1401 * rekeying on either side */
1402 assert_hook_not_called(ike_rekey);
1403
1404 initiate_rekey(a);
a79d5103 1405 call_ikesa(b, delete, FALSE);
7015994a
TB
1406 assert_ike_sa_state(b, IKE_DELETING);
1407
1408 /* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that
1409 * it is currently trying to close, it SHOULD reply with TEMPORARY_FAILURE.
1410 */
1411
1412 /* CREATE_CHILD_SA { SA, Ni, KEi } --> */
1413 assert_hook_not_called(ike_updown);
1414 assert_single_notify(OUT, TEMPORARY_FAILURE);
1415 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1416 assert_ike_sa_state(b, IKE_DELETING);
1417 assert_ike_sa_count(0);
1418 assert_hook();
1419
1420 /* delay the DELETE request */
1421 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1422
1423 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1424 assert_hook_not_called(ike_updown);
1425 assert_hook_not_called(child_updown);
1426 /* we expect a job to retry the rekeying is scheduled */
1427 assert_jobs_scheduled(1);
1428 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1429 assert_ike_sa_state(a, IKE_ESTABLISHED);
1430 assert_scheduler();
1431 assert_hook();
1432 assert_hook();
1433
1434 /* <-- INFORMATIONAL { D } (delayed) */
1435 assert_hook_updown(ike_updown, FALSE);
1436 assert_hook_updown(child_updown, FALSE);
1437 assert_single_payload(IN, PLV2_DELETE);
1438 assert_message_empty(OUT);
1439 s = exchange_test_helper->process_message(exchange_test_helper, a, msg);
1440 ck_assert_int_eq(DESTROY_ME, s);
1441 call_ikesa(a, destroy);
1442 assert_hook();
1443 assert_hook();
1444
1445 /* INFORMATIONAL { } --> */
1446 assert_hook_updown(ike_updown, FALSE);
1447 assert_hook_updown(child_updown, FALSE);
1448 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1449 ck_assert_int_eq(DESTROY_ME, s);
1450 call_ikesa(b, destroy);
1451 assert_hook();
1452 assert_hook();
1453
1454 /* ike_rekey */
1455 assert_hook();
1456}
1457END_TEST
1458
b5695bbf
TB
1459Suite *ike_rekey_suite_create()
1460{
1461 Suite *s;
1462 TCase *tc;
1463
1464 s = suite_create("ike rekey");
1465
1466 tc = tcase_create("regular");
1467 tcase_add_loop_test(tc, test_regular, 0, 2);
46cbdcac 1468 tcase_add_loop_test(tc, test_regular_ke_invalid, 0, 2);
b5695bbf
TB
1469 suite_add_tcase(s, tc);
1470
498a46d2
TB
1471 tc = tcase_create("collisions rekey");
1472 tcase_add_loop_test(tc, test_collision, 0, 4);
46cbdcac
TB
1473 tcase_add_loop_test(tc, test_collision_ke_invalid, 0, 4);
1474 tcase_add_loop_test(tc, test_collision_ke_invalid_delayed_retry, 0, 3);
2e33d1f9 1475 tcase_add_loop_test(tc, test_collision_delayed_response, 0, 4);
566134b2
TB
1476 tcase_add_loop_test(tc, test_collision_dropped_request, 0, 3);
1477 tcase_add_loop_test(tc, test_collision_delayed_request, 0, 3);
1478 tcase_add_loop_test(tc, test_collision_delayed_request_and_delete, 0, 3);
498a46d2
TB
1479 suite_add_tcase(s, tc);
1480
7015994a
TB
1481 tc = tcase_create("collisions delete");
1482 tcase_add_loop_test(tc, test_collision_delete, 0, 2);
1483 tcase_add_loop_test(tc, test_collision_delete_drop_delete, 0, 2);
1484 suite_add_tcase(s, tc);
1485
b5695bbf
TB
1486 return s;
1487}