child-rekey: Don't install outbound SA in case of lost collisions
[strongswan.git] / src / libcharon / tests / suites / test_child_rekey.c
1 /*
2 * Copyright (C) 2016-2017 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <daemon.h>
19 #include <tests/utils/exchange_test_helper.h>
20 #include <tests/utils/exchange_test_asserts.h>
21 #include <tests/utils/job_asserts.h>
22 #include <tests/utils/sa_asserts.h>
23
24 /**
25 * Initiate rekeying the CHILD_SA with the given SPI on the given IKE_SA.
26 */
27 #define initiate_rekey(sa, spi) ({ \
28 assert_hook_not_called(child_updown); \
29 assert_hook_not_called(child_rekey); \
30 call_ikesa(sa, rekey_child_sa, PROTO_ESP, spi); \
31 assert_child_sa_state(sa, spi, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); \
32 assert_hook(); \
33 assert_hook(); \
34 })
35
36 /**
37 * Destroy a rekeyed CHILD_SA that was kept around to accept inbound traffic.
38 * Simulates the job that's scheduled to do this.
39 */
40 #define destroy_rekeyed(sa, spi) ({ \
41 assert_hook_not_called(child_updown); \
42 assert_hook_not_called(child_rekey); \
43 assert_no_jobs_scheduled(); \
44 assert_child_sa_state(sa, spi, CHILD_DELETING, CHILD_OUTBOUND_NONE); \
45 call_ikesa(sa, delete_child_sa, PROTO_ESP, spi, FALSE); \
46 assert_child_sa_not_exists(sa, spi); \
47 assert_scheduler(); \
48 assert_hook(); \
49 assert_hook(); \
50 })
51
52 /**
53 * Regular CHILD_SA rekey either initiated by the original initiator or
54 * responder of the IKE_SA.
55 */
56 START_TEST(test_regular)
57 {
58 ike_sa_t *a, *b;
59 uint32_t spi_a = _i+1, spi_b = 2-_i;
60
61 if (_i)
62 { /* responder rekeys the CHILD_SA (SPI 2) */
63 exchange_test_helper->establish_sa(exchange_test_helper,
64 &b, &a, NULL);
65 }
66 else
67 { /* initiator rekeys the CHILD_SA (SPI 1) */
68 exchange_test_helper->establish_sa(exchange_test_helper,
69 &a, &b, NULL);
70 }
71 initiate_rekey(a, spi_a);
72 assert_ipsec_sas_installed(a, spi_a, spi_b);
73
74 /* this should never get called as this results in a successful rekeying */
75 assert_hook_not_called(child_updown);
76
77 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
78 assert_hook_called(child_rekey);
79 assert_notify(IN, REKEY_SA);
80 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
81 assert_child_sa_state(b, spi_b, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
82 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
83 assert_ipsec_sas_installed(b, spi_a, spi_b, 4);
84 assert_hook();
85
86 /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */
87 assert_hook_called(child_rekey);
88 assert_no_notify(IN, REKEY_SA);
89 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
90 assert_child_sa_state(a, spi_a, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
91 assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
92 assert_ipsec_sas_installed(a, spi_a, spi_b, 3, 4);
93 assert_hook();
94
95 /* INFORMATIONAL { D } --> */
96 assert_hook_not_called(child_rekey);
97 assert_jobs_scheduled(1);
98 assert_single_payload(IN, PLV2_DELETE);
99 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
100 assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_NONE);
101 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
102 assert_child_sa_count(b, 2);
103 assert_ipsec_sas_installed(b, spi_b, 3, 4);
104 assert_scheduler();
105 assert_hook();
106 /* <-- INFORMATIONAL { D } */
107 assert_hook_not_called(child_rekey);
108 assert_jobs_scheduled(1);
109 assert_single_payload(IN, PLV2_DELETE);
110 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
111 assert_child_sa_state(a, spi_a, CHILD_DELETING, CHILD_OUTBOUND_NONE);
112 assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
113 assert_child_sa_count(a, 2);
114 assert_ipsec_sas_installed(a, spi_a, 3, 4);
115 assert_scheduler();
116 assert_hook();
117
118 /* simulate the execution of the scheduled jobs */
119 destroy_rekeyed(a, spi_a);
120 assert_child_sa_count(a, 1);
121 assert_ipsec_sas_installed(a, 3, 4);
122 destroy_rekeyed(b, spi_b);
123 assert_child_sa_count(b, 1);
124 assert_ipsec_sas_installed(a, 3, 4);
125
126 /* child_updown */
127 assert_hook();
128
129 call_ikesa(a, destroy);
130 call_ikesa(b, destroy);
131 }
132 END_TEST
133
134 /**
135 * CHILD_SA rekey where the responder does not agree with the DH group selected
136 * by the initiator, either initiated by the original initiator or responder of
137 * the IKE_SA.
138 */
139 START_TEST(test_regular_ke_invalid)
140 {
141 exchange_test_sa_conf_t conf = {
142 .initiator = {
143 .esp = "aes128-sha256-modp2048-modp3072",
144 },
145 .responder = {
146 .esp = "aes128-sha256-modp3072-modp2048",
147 },
148 };
149 ike_sa_t *a, *b;
150 uint32_t spi_a = _i+1, spi_b = 2-_i;
151
152 if (_i)
153 { /* responder rekeys the CHILD_SA (SPI 2) */
154 exchange_test_helper->establish_sa(exchange_test_helper,
155 &b, &a, &conf);
156 }
157 else
158 { /* initiator rekeys the CHILD_SA (SPI 1) */
159 exchange_test_helper->establish_sa(exchange_test_helper,
160 &a, &b, &conf);
161 }
162 initiate_rekey(a, spi_a);
163 assert_ipsec_sas_installed(a, spi_a, spi_b);
164
165 /* this should never get called as this results in a successful rekeying */
166 assert_hook_not_called(child_updown);
167
168 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
169 assert_hook_not_called(child_rekey);
170 assert_notify(IN, REKEY_SA);
171 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
172 assert_child_sa_state(b, spi_b, CHILD_INSTALLED);
173 assert_child_sa_count(b, 1);
174 assert_ipsec_sas_installed(b, spi_a, spi_b);
175 assert_hook();
176
177 /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */
178 assert_hook_not_called(child_rekey);
179 assert_single_notify(IN, INVALID_KE_PAYLOAD);
180 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
181 assert_child_sa_state(a, spi_a, CHILD_REKEYING);
182 assert_child_sa_count(a, 1);
183 assert_ipsec_sas_installed(a, spi_a, spi_b);
184 assert_hook();
185
186 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
187 assert_hook_called(child_rekey);
188 assert_notify(IN, REKEY_SA);
189 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
190 assert_child_sa_state(b, spi_b, CHILD_REKEYED);
191 assert_child_sa_state(b, 6, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
192 assert_ipsec_sas_installed(b, spi_a, spi_b, 6);
193 assert_hook();
194
195 /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */
196 assert_hook_called(child_rekey);
197 assert_no_notify(IN, REKEY_SA);
198 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
199 assert_child_sa_state(a, spi_a, CHILD_DELETING);
200 assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
201 assert_ipsec_sas_installed(a, spi_a, spi_b, 5, 6);
202 assert_hook();
203
204 /* INFORMATIONAL { D } --> */
205 assert_hook_not_called(child_rekey);
206 assert_single_payload(IN, PLV2_DELETE);
207 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
208 assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_NONE);
209 assert_child_sa_state(b, 6, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
210 assert_child_sa_count(b, 2);
211 assert_ipsec_sas_installed(b, spi_b, 5, 6);
212 assert_hook();
213 /* <-- INFORMATIONAL { D } */
214 assert_hook_not_called(child_rekey);
215 assert_single_payload(IN, PLV2_DELETE);
216 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
217 assert_child_sa_state(a, spi_a, CHILD_DELETING, CHILD_OUTBOUND_NONE);
218 assert_child_sa_state(a, 5, CHILD_INSTALLED);
219 assert_child_sa_count(a, 2);
220 assert_ipsec_sas_installed(a, spi_a, 5, 6);
221 assert_hook();
222
223 /* simulate the execution of the scheduled jobs */
224 destroy_rekeyed(a, spi_a);
225 assert_child_sa_count(a, 1);
226 assert_ipsec_sas_installed(a, 5, 6);
227 destroy_rekeyed(b, spi_b);
228 assert_child_sa_count(b, 1);
229 assert_ipsec_sas_installed(b, 5, 6);
230
231 /* child_updown */
232 assert_hook();
233
234 call_ikesa(a, destroy);
235 call_ikesa(b, destroy);
236 }
237 END_TEST
238
239 /**
240 * Check that the responder ignores soft expires while waiting for the delete
241 * after a rekeying.
242 */
243 START_TEST(test_regular_responder_ignore_soft_expire)
244 {
245 ike_sa_t *a, *b;
246
247 exchange_test_helper->establish_sa(exchange_test_helper,
248 &a, &b, NULL);
249 initiate_rekey(a, 1);
250 assert_ipsec_sas_installed(a, 1, 2);
251
252 /* this should never get called as this results in a successful rekeying */
253 assert_hook_not_called(child_updown);
254
255 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
256 assert_hook_called(child_rekey);
257 assert_notify(IN, REKEY_SA);
258 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
259 assert_child_sa_state(b, 2, CHILD_REKEYED);
260 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
261 assert_ipsec_sas_installed(b, 1, 2, 4);
262 assert_hook();
263
264 /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */
265 assert_hook_called(child_rekey);
266 assert_no_notify(IN, REKEY_SA);
267 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
268 assert_child_sa_state(a, 1, CHILD_DELETING);
269 assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
270 assert_ipsec_sas_installed(a, 1, 2, 3, 4);
271 assert_hook();
272
273 /* we don't expect this to get called anymore */
274 assert_hook_not_called(child_rekey);
275 /* this should not produce a message, if it does there won't be a delete
276 * payload below */
277 call_ikesa(b, rekey_child_sa, PROTO_ESP, 2);
278 assert_child_sa_state(b, 2, CHILD_REKEYED);
279
280 /* INFORMATIONAL { D } --> */
281 assert_jobs_scheduled(1);
282 assert_single_payload(IN, PLV2_DELETE);
283 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
284 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE);
285 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
286 assert_child_sa_count(b, 2);
287 assert_ipsec_sas_installed(b, 2, 3, 4);
288 assert_scheduler();
289 /* <-- INFORMATIONAL { D } */
290 assert_jobs_scheduled(1);
291 assert_single_payload(IN, PLV2_DELETE);
292 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
293 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
294 assert_child_sa_state(a, 3, CHILD_INSTALLED);
295 assert_child_sa_count(a, 2);
296 assert_ipsec_sas_installed(a, 1, 3, 4);
297 assert_scheduler();
298
299 /* simulate the execution of the scheduled jobs */
300 destroy_rekeyed(a, 1);
301 assert_child_sa_count(a, 1);
302 assert_ipsec_sas_installed(a, 3, 4);
303 destroy_rekeyed(b, 2);
304 assert_child_sa_count(b, 1);
305 assert_ipsec_sas_installed(b, 3, 4);
306
307 /* child_rekey/child_updown */
308 assert_hook();
309 assert_hook();
310
311 call_ikesa(a, destroy);
312 call_ikesa(b, destroy);
313 }
314 END_TEST
315
316 /**
317 * Check that the responder handles hard expires properly while waiting for the
318 * delete after a rekeying (e.g. if the initiator of the rekeying fails to
319 * delete the CHILD_SA for some reason).
320 */
321 START_TEST(test_regular_responder_handle_hard_expire)
322 {
323 ike_sa_t *a, *b;
324
325 exchange_test_helper->establish_sa(exchange_test_helper,
326 &a, &b, NULL);
327 initiate_rekey(a, 1);
328 assert_ipsec_sas_installed(a, 1, 2);
329
330 /* this should never get called as this results in a successful rekeying */
331 assert_hook_not_called(child_updown);
332
333 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
334 assert_hook_called(child_rekey);
335 assert_notify(IN, REKEY_SA);
336 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
337 assert_child_sa_state(b, 2, CHILD_REKEYED);
338 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
339 assert_ipsec_sas_installed(b, 1, 2, 4);
340 assert_hook();
341
342 /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */
343 assert_hook_called(child_rekey);
344 assert_no_notify(IN, REKEY_SA);
345 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
346 assert_child_sa_state(a, 1, CHILD_DELETING);
347 assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
348 assert_ipsec_sas_installed(a, 1, 2, 3, 4);
349 assert_hook();
350
351 /* we don't expect this to get called anymore */
352 assert_hook_not_called(child_rekey);
353 /* this is similar to a regular delete collision */
354 assert_single_payload(OUT, PLV2_DELETE);
355 call_ikesa(b, delete_child_sa, PROTO_ESP, 2, TRUE);
356 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
357 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
358 /* since the SAs expired they would not actually be installed in the kernel
359 * anymore and since we have not yet installed a new outbound SA this
360 * will result in dropped packets and possibly acquires */
361 assert_ipsec_sas_installed(b, 1, 2, 4);
362
363 /* INFORMATIONAL { D } --> */
364 assert_single_payload(IN, PLV2_DELETE);
365 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
366 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
367 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
368 assert_ipsec_sas_installed(b, 1, 2, 4);
369 /* <-- INFORMATIONAL { D } */
370 assert_single_payload(IN, PLV2_DELETE);
371 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
372 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
373 assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
374 assert_ipsec_sas_installed(a, 1, 2, 3, 4);
375 /* <-- INFORMATIONAL { } */
376 assert_jobs_scheduled(1);
377 assert_message_empty(IN);
378 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
379 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
380 assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
381 assert_child_sa_count(a, 2);
382 assert_ipsec_sas_installed(a, 1, 3, 4);
383 assert_scheduler();
384 /* INFORMATIONAL { } --> */
385 assert_jobs_scheduled(1);
386 assert_message_empty(IN);
387 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
388 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE);
389 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
390 assert_child_sa_count(b, 2);
391 assert_ipsec_sas_installed(b, 2, 3, 4);
392 assert_scheduler();
393
394 /* simulate the execution of the scheduled jobs */
395 destroy_rekeyed(a, 1);
396 assert_child_sa_count(a, 1);
397 assert_ipsec_sas_installed(a, 3, 4);
398 destroy_rekeyed(b, 2);
399 assert_child_sa_count(b, 1);
400 assert_ipsec_sas_installed(b, 3, 4);
401
402 /* child_rekey/child_updown */
403 assert_hook();
404 assert_hook();
405
406 call_ikesa(a, destroy);
407 call_ikesa(b, destroy);
408 }
409 END_TEST
410
411 /**
412 * Both peers initiate the CHILD_SA reekying concurrently and should handle
413 * the collision properly depending on the nonces.
414 */
415 START_TEST(test_collision)
416 {
417 ike_sa_t *a, *b;
418
419 exchange_test_helper->establish_sa(exchange_test_helper,
420 &a, &b, NULL);
421
422 /* When rekeyings collide we get two CHILD_SAs with a total of four nonces.
423 * The CHILD_SA with the lowest nonce SHOULD be deleted by the peer that
424 * created that CHILD_SA. The replaced CHILD_SA is deleted by the peer that
425 * initiated the surviving SA.
426 * Four nonces and SPIs are needed (SPI 1 and 2 are used for the initial
427 * CHILD_SA):
428 * N1/3 -----\ /----- N2/4
429 * \--/-----> N3/5
430 * N4/6 <-------/ /----- ...
431 * ... -----\
432 * We test this four times, each time a different nonce is the lowest.
433 */
434 struct {
435 /* Nonces used at each point */
436 u_char nonces[4];
437 /* SPIs of the deleted CHILD_SA (either redundant or replaced) */
438 uint32_t spi_del_a, spi_del_b;
439 /* SPIs of the kept CHILD_SA */
440 uint32_t spi_a, spi_b;
441 } data[] = {
442 { { 0x00, 0xFF, 0xFF, 0xFF }, 3, 2, 6, 4 },
443 { { 0xFF, 0x00, 0xFF, 0xFF }, 1, 4, 3, 5 },
444 { { 0xFF, 0xFF, 0x00, 0xFF }, 3, 2, 6, 4 },
445 { { 0xFF, 0xFF, 0xFF, 0x00 }, 1, 4, 3, 5 },
446 };
447
448 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
449 initiate_rekey(a, 1);
450 assert_ipsec_sas_installed(a, 1, 2);
451 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
452 initiate_rekey(b, 2);
453 assert_ipsec_sas_installed(b, 1, 2);
454
455 /* this should never get called as this results in a successful rekeying */
456 assert_hook_not_called(child_updown);
457
458 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
459 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
460 assert_hook_rekey(child_rekey, 2, 5);
461 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
462 assert_child_sa_state(b, 2, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
463 assert_child_sa_state(b, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
464 assert_ipsec_sas_installed(b, 1, 2, 5);
465 assert_hook();
466 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
467 exchange_test_helper->nonce_first_byte = data[_i].nonces[3];
468 assert_hook_rekey(child_rekey, 1, 6);
469 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
470 assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
471 assert_child_sa_state(a, 6, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
472 assert_ipsec_sas_installed(a, 1, 2, 6);
473 assert_hook();
474
475 /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */
476 if (data[_i].spi_del_a == 1)
477 { /* currently we call this again if we keep our own replacement as we
478 * already called it above */
479 assert_hook_rekey(child_rekey, 1, data[_i].spi_a);
480 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
481 assert_hook();
482 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED,
483 CHILD_OUTBOUND_REGISTERED);
484 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
485 CHILD_OUTBOUND_INSTALLED);
486 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
487 CHILD_OUTBOUND_INSTALLED);
488 assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
489 }
490 else
491 {
492 assert_hook_not_called(child_rekey);
493 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
494 assert_hook();
495 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED,
496 CHILD_OUTBOUND_INSTALLED);
497 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
498 CHILD_OUTBOUND_REGISTERED);
499 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
500 CHILD_OUTBOUND_REGISTERED);
501 assert_ipsec_sas_installed(a, 1, 2, 3, 6);
502 }
503 /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
504 if (data[_i].spi_del_b == 2)
505 {
506 assert_hook_rekey(child_rekey, 2, data[_i].spi_b);
507 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
508 assert_hook();
509 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
510 CHILD_OUTBOUND_REGISTERED);
511 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
512 CHILD_OUTBOUND_INSTALLED);
513 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
514 CHILD_OUTBOUND_INSTALLED);
515 assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
516 }
517 else
518 {
519 assert_hook_not_called(child_rekey);
520 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
521 assert_hook();
522 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
523 CHILD_OUTBOUND_INSTALLED);
524 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
525 CHILD_OUTBOUND_REGISTERED);
526 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
527 CHILD_OUTBOUND_REGISTERED);
528 assert_ipsec_sas_installed(b, 1, 2, 4, 5);
529 }
530
531 /* we don't expect this hook to get called anymore */
532 assert_hook_not_called(child_rekey);
533 /* INFORMATIONAL { D } --> */
534 assert_jobs_scheduled(1);
535 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
536 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
537 data[_i].spi_del_b == 2 ? CHILD_OUTBOUND_INSTALLED
538 : CHILD_OUTBOUND_REGISTERED);
539 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
540 CHILD_OUTBOUND_NONE);
541 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
542 CHILD_OUTBOUND_INSTALLED);
543 assert_child_sa_count(b, 3);
544 if (data[_i].spi_del_b == 2)
545 {
546 assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
547 }
548 else
549 {
550 assert_ipsec_sas_installed(b, 2, 3, 4, 5);
551 }
552 assert_scheduler();
553 /* <-- INFORMATIONAL { D } */
554 assert_jobs_scheduled(1);
555 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
556 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
557 data[_i].spi_del_a == 1 ? CHILD_OUTBOUND_INSTALLED
558 : CHILD_OUTBOUND_REGISTERED);
559 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
560 CHILD_OUTBOUND_NONE);
561 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
562 CHILD_OUTBOUND_INSTALLED);
563 assert_child_sa_count(a, 3);
564 if (data[_i].spi_del_a == 1)
565 {
566 assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
567 }
568 else
569 {
570 assert_ipsec_sas_installed(a, 1, 3, 4, 6);
571 }
572 assert_scheduler();
573 /* <-- INFORMATIONAL { D } */
574 assert_jobs_scheduled(1);
575 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
576 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
577 CHILD_OUTBOUND_NONE);
578 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
579 CHILD_OUTBOUND_NONE);
580 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
581 CHILD_OUTBOUND_INSTALLED);
582 assert_child_sa_count(a, 3);
583 assert_ipsec_sas_installed(a, 1, 3, 6,
584 data[_i].spi_del_a == 1 ? 5 : 4);
585 assert_scheduler();
586 /* INFORMATIONAL { D } --> */
587 assert_jobs_scheduled(1);
588 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
589 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
590 CHILD_OUTBOUND_NONE);
591 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
592 CHILD_OUTBOUND_NONE);
593 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
594 CHILD_OUTBOUND_INSTALLED);
595 assert_child_sa_count(b, 3);
596 assert_ipsec_sas_installed(b, 2, 4, 5,
597 data[_i].spi_del_b == 2 ? 6 : 3);
598 assert_scheduler();
599
600 /* simulate the execution of the scheduled jobs */
601 destroy_rekeyed(a, data[_i].spi_del_a);
602 destroy_rekeyed(a, data[_i].spi_del_b);
603 assert_child_sa_count(a, 1);
604 assert_ipsec_sas_installed(a, data[_i].spi_a, data[_i].spi_b);
605 destroy_rekeyed(b, data[_i].spi_del_a);
606 destroy_rekeyed(b, data[_i].spi_del_b);
607 assert_child_sa_count(b, 1);
608 assert_ipsec_sas_installed(b, data[_i].spi_a, data[_i].spi_b);
609
610 /* child_rekey/child_updown */
611 assert_hook();
612 assert_hook();
613
614 call_ikesa(a, destroy);
615 call_ikesa(b, destroy);
616 }
617 END_TEST
618
619 /**
620 * This is like the rekey collision above, but one peer deletes the
621 * redundant/old SA before the other peer receives the CREATE_CHILD_SA
622 * response:
623 *
624 * rekey ----\ /---- rekey
625 * \-----/----> detect collision
626 * detect collision <---------/ /----
627 * ----\ /
628 * \----/----->
629 * handle delete <--------/------- delete SA
630 * --------/------->
631 * handle rekey <------/
632 * delete SA ---------------->
633 * <----------------
634 */
635 START_TEST(test_collision_delayed_response)
636 {
637 ike_sa_t *a, *b;
638 message_t *msg;
639
640 exchange_test_helper->establish_sa(exchange_test_helper,
641 &a, &b, NULL);
642
643 /* Four nonces and SPIs are needed (SPI 1 and 2 are used for the initial
644 * CHILD_SA):
645 * N1/3 -----\ /----- N2/4
646 * \--/-----> N3/5
647 * N4/6 <-------/ /----- ...
648 * ... -----\
649 * We test this four times, each time a different nonce is the lowest.
650 */
651 struct {
652 /* Nonces used at each point */
653 u_char nonces[4];
654 /* SPIs of the deleted CHILD_SA (either redundant or replaced) */
655 uint32_t spi_del_a, spi_del_b;
656 /* SPIs of the kept CHILD_SA */
657 uint32_t spi_a, spi_b;
658 } data[] = {
659 { { 0x00, 0xFF, 0xFF, 0xFF }, 3, 2, 6, 4 },
660 { { 0xFF, 0x00, 0xFF, 0xFF }, 1, 4, 3, 5 },
661 { { 0xFF, 0xFF, 0x00, 0xFF }, 3, 2, 6, 4 },
662 { { 0xFF, 0xFF, 0xFF, 0x00 }, 1, 4, 3, 5 },
663 };
664
665 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
666 initiate_rekey(a, 1);
667 assert_ipsec_sas_installed(a, 1, 2);
668 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
669 initiate_rekey(b, 2);
670 assert_ipsec_sas_installed(b, 1, 2);
671
672 /* this should never get called as this results in a successful rekeying */
673 assert_hook_not_called(child_updown);
674
675 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
676 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
677 assert_hook_rekey(child_rekey, 2, 5);
678 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
679 assert_child_sa_state(b, 2, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
680 assert_child_sa_state(b, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
681 assert_ipsec_sas_installed(b, 1, 2, 5);
682 assert_hook();
683 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
684 exchange_test_helper->nonce_first_byte = data[_i].nonces[3];
685 assert_hook_rekey(child_rekey, 1, 6);
686 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
687 assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
688 assert_child_sa_state(a, 6, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
689 assert_ipsec_sas_installed(a, 1, 2, 6);
690 assert_hook();
691
692 /* delay the CREATE_CHILD_SA response from b to a */
693 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
694
695 /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
696 if (data[_i].spi_del_b == 2)
697 {
698 assert_hook_rekey(child_rekey, 2, data[_i].spi_b);
699 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
700 assert_hook();
701 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
702 CHILD_OUTBOUND_REGISTERED);
703 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
704 CHILD_OUTBOUND_INSTALLED);
705 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
706 CHILD_OUTBOUND_INSTALLED);
707 assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
708 }
709 else
710 {
711 assert_hook_not_called(child_rekey);
712 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
713 assert_hook();
714 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
715 CHILD_OUTBOUND_INSTALLED);
716 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
717 CHILD_OUTBOUND_REGISTERED);
718 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
719 CHILD_OUTBOUND_REGISTERED);
720 assert_ipsec_sas_installed(b, 1, 2, 4, 5);
721 }
722
723 /* <-- INFORMATIONAL { D } */
724 assert_hook_not_called(child_rekey);
725 assert_jobs_scheduled(1);
726 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
727 if (data[_i].spi_del_b == 2)
728 {
729 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
730 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
731 CHILD_OUTBOUND_INSTALLED);
732 assert_ipsec_sas_installed(a, 1, 4, 6);
733 }
734 else
735 {
736 assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
737 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
738 CHILD_OUTBOUND_NONE);
739 assert_ipsec_sas_installed(a, 1, 2, 6);
740 }
741 assert_child_sa_count(a, 2);
742 assert_scheduler();
743 /* INFORMATIONAL { D } --> */
744 assert_jobs_scheduled(1);
745 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
746 if (data[_i].spi_del_b == 2)
747 {
748 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
749 CHILD_OUTBOUND_REGISTERED);
750 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
751 CHILD_OUTBOUND_INSTALLED);
752 assert_ipsec_sas_installed(b, 2, 4, 5, 6);
753 }
754 else
755 {
756 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
757 CHILD_OUTBOUND_INSTALLED);
758 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
759 CHILD_OUTBOUND_REGISTERED);
760 assert_ipsec_sas_installed(b, 1, 2, 4, 5);
761 }
762 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
763 CHILD_OUTBOUND_NONE);
764 assert_child_sa_count(b, 3);
765 assert_scheduler();
766 assert_hook();
767
768 /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } (delayed) */
769 if (data[_i].spi_del_a == 1)
770 {
771 assert_hook_rekey(child_rekey, 1, data[_i].spi_a);
772 exchange_test_helper->process_message(exchange_test_helper, a, msg);
773 assert_hook();
774 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
775 CHILD_OUTBOUND_INSTALLED);
776 assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
777 }
778 else
779 {
780 assert_hook_not_called(child_rekey);
781 exchange_test_helper->process_message(exchange_test_helper, a, msg);
782 assert_hook();
783 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
784 CHILD_OUTBOUND_REGISTERED);
785 assert_ipsec_sas_installed(a, 1, 3, 4, 6);
786 }
787 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
788 CHILD_OUTBOUND_NONE);
789 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
790 CHILD_OUTBOUND_INSTALLED);
791 assert_child_sa_count(a, 3);
792
793 /* we don't expect this hook to get called anymore */
794 assert_hook_not_called(child_rekey);
795 /* INFORMATIONAL { D } --> */
796 assert_jobs_scheduled(1);
797 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
798 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
799 CHILD_OUTBOUND_NONE);
800 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
801 CHILD_OUTBOUND_NONE);
802 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
803 CHILD_OUTBOUND_INSTALLED);
804 assert_ipsec_sas_installed(b, 2, 4, 5,
805 data[_i].spi_del_b == 2 ? 6 : 3);
806 assert_child_sa_count(b, 3);
807 assert_scheduler();
808 /* <-- INFORMATIONAL { D } */
809 assert_jobs_scheduled(1);
810 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
811 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
812 CHILD_OUTBOUND_NONE);
813 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
814 CHILD_OUTBOUND_NONE);
815 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
816 CHILD_OUTBOUND_INSTALLED);
817 assert_child_sa_count(a, 3);
818 assert_ipsec_sas_installed(a, 1, 3, 6,
819 data[_i].spi_del_a == 1 ? 5 : 4);
820 assert_scheduler();
821
822 /* simulate the execution of the scheduled jobs */
823 destroy_rekeyed(a, data[_i].spi_del_a);
824 destroy_rekeyed(a, data[_i].spi_del_b);
825 assert_child_sa_count(a, 1);
826 assert_ipsec_sas_installed(a, data[_i].spi_a, data[_i].spi_b);
827 destroy_rekeyed(b, data[_i].spi_del_a);
828 destroy_rekeyed(b, data[_i].spi_del_b);
829 assert_child_sa_count(b, 1);
830 assert_ipsec_sas_installed(b, data[_i].spi_a, data[_i].spi_b);
831
832 /* child_rekey/child_updown */
833 assert_hook();
834 assert_hook();
835
836 call_ikesa(a, destroy);
837 call_ikesa(b, destroy);
838 }
839 END_TEST
840
841 /**
842 * In this scenario one of the peers does not notice that there is a
843 * rekey collision:
844 *
845 * rekey ----\ /---- rekey
846 * \ /
847 * detect collision <-----\---/
848 * -------\-------->
849 * \ /---- delete old SA
850 * \-/----> detect collision
851 * detect collision <---------/ /---- TEMP_FAIL
852 * delete -----------/---->
853 * aborts rekeying <---------/
854 */
855 START_TEST(test_collision_delayed_request)
856 {
857 ike_sa_t *a, *b;
858 message_t *msg;
859
860 exchange_test_helper->establish_sa(exchange_test_helper,
861 &a, &b, NULL);
862
863 /* Three nonces and SPIs are needed (SPI 1 and 2 are used for the initial
864 * CHILD_SA):
865 * N1/3 -----\ /----- N2/4
866 * N3/5 <-----\--/
867 * ... -----\ \-------> ...
868 * We test this three times, each time a different nonce is the lowest.
869 */
870 struct {
871 /* Nonces used at each point */
872 u_char nonces[3];
873 } data[] = {
874 { { 0x00, 0xFF, 0xFF } },
875 { { 0xFF, 0x00, 0xFF } },
876 { { 0xFF, 0xFF, 0x00 } },
877 };
878
879 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
880 initiate_rekey(a, 1);
881 assert_ipsec_sas_installed(a, 1, 2);
882 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
883 initiate_rekey(b, 2);
884 assert_ipsec_sas_installed(b, 1, 2);
885
886 /* delay the CREATE_CHILD_SA request from a to b */
887 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
888
889 /* this should never get called as this results in a successful rekeying */
890 assert_hook_not_called(child_updown);
891
892 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
893 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
894 assert_hook_rekey(child_rekey, 1, 5);
895 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
896 assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
897 assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
898 assert_ipsec_sas_installed(a, 1, 2, 5);
899 assert_hook();
900 /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
901 assert_hook_rekey(child_rekey, 2, 4);
902 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
903 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
904 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
905 assert_ipsec_sas_installed(b, 1, 2, 4, 5);
906 assert_hook();
907
908 /* we don't expect this hook to get called anymore */
909 assert_hook_not_called(child_rekey);
910
911 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> (delayed) */
912 assert_single_notify(OUT, TEMPORARY_FAILURE);
913 exchange_test_helper->process_message(exchange_test_helper, b, msg);
914 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
915 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
916
917 /* <-- INFORMATIONAL { D } */
918 assert_jobs_scheduled(1);
919 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
920 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
921 assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
922 assert_child_sa_count(a, 2);
923 assert_ipsec_sas_installed(a, 1, 4, 5);
924 assert_scheduler();
925
926 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
927 assert_no_jobs_scheduled();
928 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
929 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
930 assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
931 assert_child_sa_count(a, 2);
932 assert_ipsec_sas_installed(a, 1, 4, 5);
933 assert_scheduler();
934
935 /* INFORMATIONAL { D } --> */
936 assert_jobs_scheduled(1);
937 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
938 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE);
939 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
940 assert_child_sa_count(b, 2);
941 assert_ipsec_sas_installed(b, 2, 4, 5);
942 assert_scheduler();
943
944 /* simulate the execution of the scheduled jobs */
945 destroy_rekeyed(a, 1);
946 assert_child_sa_count(a, 1);
947 assert_ipsec_sas_installed(a, 4, 5);
948 destroy_rekeyed(b, 2);
949 assert_child_sa_count(b, 1);
950 assert_ipsec_sas_installed(b, 4, 5);
951
952 /* child_rekey/child_updown */
953 assert_hook();
954 assert_hook();
955
956 assert_sa_idle(a);
957 assert_sa_idle(b);
958
959 call_ikesa(a, destroy);
960 call_ikesa(b, destroy);
961 }
962 END_TEST
963
964 /**
965 * Similar to above one peer fails to notice the collision but the
966 * CREATE_CHILD_SA request is even more delayed:
967 *
968 * rekey ----\ /---- rekey
969 * \ /
970 * detect collision <-----\---/
971 * -------\-------->
972 * detect collision <-------\-------- delete old SA
973 * delete ---------\------>
974 * \----->
975 * /---- CHILD_SA_NOT_FOUND
976 * aborts rekeying <----------/
977 */
978 START_TEST(test_collision_delayed_request_more)
979 {
980 ike_sa_t *a, *b;
981 message_t *msg;
982
983 exchange_test_helper->establish_sa(exchange_test_helper,
984 &a, &b, NULL);
985
986 /* Three nonces and SPIs are needed (SPI 1 and 2 are used for the initial
987 * CHILD_SA):
988 * N1/3 -----\ /----- N2/4
989 * N3/5 <-----\--/
990 * ... -----\ \-------> ...
991 * We test this three times, each time a different nonce is the lowest.
992 */
993 struct {
994 /* Nonces used at each point */
995 u_char nonces[3];
996 } data[] = {
997 { { 0x00, 0xFF, 0xFF } },
998 { { 0xFF, 0x00, 0xFF } },
999 { { 0xFF, 0xFF, 0x00 } },
1000 };
1001
1002 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1003 initiate_rekey(a, 1);
1004 assert_ipsec_sas_installed(a, 1, 2);
1005 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1006 initiate_rekey(b, 2);
1007 assert_ipsec_sas_installed(b, 1, 2);
1008
1009 /* delay the CREATE_CHILD_SA request from a to b */
1010 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1011
1012 /* this should never get called as this results in a successful rekeying */
1013 assert_hook_not_called(child_updown);
1014
1015 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
1016 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
1017 assert_hook_rekey(child_rekey, 1, 5);
1018 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1019 assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
1020 assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
1021 assert_ipsec_sas_installed(a, 1, 2, 5);
1022 assert_hook();
1023 /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
1024 assert_hook_rekey(child_rekey, 2, 4);
1025 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1026 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1027 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1028 assert_ipsec_sas_installed(b, 1, 2, 4, 5);
1029 assert_hook();
1030
1031 /* we don't expect this hook to get called anymore */
1032 assert_hook_not_called(child_rekey);
1033
1034 /* <-- INFORMATIONAL { D } */
1035 assert_jobs_scheduled(1);
1036 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1037 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
1038 assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1039 assert_child_sa_count(a, 2);
1040 assert_ipsec_sas_installed(a, 1, 4, 5);
1041 assert_scheduler();
1042 /* INFORMATIONAL { D } --> */
1043 assert_jobs_scheduled(1);
1044 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1045 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE);
1046 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1047 assert_child_sa_count(b, 2);
1048 assert_ipsec_sas_installed(b, 2, 4, 5);
1049 assert_scheduler();
1050
1051 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1052 assert_single_notify(OUT, CHILD_SA_NOT_FOUND);
1053 exchange_test_helper->process_message(exchange_test_helper, b, msg);
1054 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE);
1055 assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1056 assert_child_sa_count(b, 2);
1057 assert_ipsec_sas_installed(b, 2, 4, 5);
1058 /* <-- CREATE_CHILD_SA { N(NO_CHILD_SA) } */
1059 assert_no_jobs_scheduled();
1060 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1061 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
1062 assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1063 assert_child_sa_count(a, 2);
1064 assert_ipsec_sas_installed(a, 1, 4, 5);
1065 assert_scheduler();
1066
1067 /* simulate the execution of the scheduled jobs */
1068 destroy_rekeyed(a, 1);
1069 assert_child_sa_count(a, 1);
1070 assert_ipsec_sas_installed(a, 4, 5);
1071 destroy_rekeyed(b, 2);
1072 assert_child_sa_count(b, 1);
1073 assert_ipsec_sas_installed(b, 4, 5);
1074
1075 /* child_rekey/child_updown */
1076 assert_hook();
1077 assert_hook();
1078
1079 assert_sa_idle(a);
1080 assert_sa_idle(b);
1081
1082 call_ikesa(a, destroy);
1083 call_ikesa(b, destroy);
1084 }
1085 END_TEST
1086
1087 /**
1088 * Both peers initiate the CHILD_SA reekying concurrently but the proposed DH
1089 * groups are not the same after handling the INVALID_KE_PAYLOAD they should
1090 * still handle the collision properly depending on the nonces.
1091 */
1092 START_TEST(test_collision_ke_invalid)
1093 {
1094 exchange_test_sa_conf_t conf = {
1095 .initiator = {
1096 .esp = "aes128-sha256-modp2048-modp3072",
1097 },
1098 .responder = {
1099 .esp = "aes128-sha256-modp3072-modp2048",
1100 },
1101 };
1102 ike_sa_t *a, *b;
1103
1104 exchange_test_helper->establish_sa(exchange_test_helper,
1105 &a, &b, &conf);
1106
1107 /* Eight nonces and SPIs are needed (SPI 1 and 2 are used for the initial
1108 * CHILD_SA):
1109 * N1/3 -----\ /----- N2/4
1110 * \--/-----> N3/5
1111 * N4/6 <-------/ /---- INVAL_KE
1112 * INVAL_KE -----\ /
1113 * <-----\--/
1114 * N5/7 -----\ \------->
1115 * \ /---- N6/8
1116 * \--/----> N7/9
1117 * N8/10 <--------/ /---- ...
1118 * ... ------\
1119 *
1120 * We test this four times, each time a different nonce is the lowest.
1121 */
1122 struct {
1123 /* Nonces used at each point */
1124 u_char nonces[4];
1125 /* SPIs of the deleted CHILD_SA (either redundant or replaced) */
1126 uint32_t spi_del_a, spi_del_b;
1127 /* SPIs of the kept CHILD_SA */
1128 uint32_t spi_a, spi_b;
1129 } data[] = {
1130 { { 0x00, 0xFF, 0xFF, 0xFF }, 7, 2,10, 8 },
1131 { { 0xFF, 0x00, 0xFF, 0xFF }, 1, 8, 7, 9 },
1132 { { 0xFF, 0xFF, 0x00, 0xFF }, 7, 2,10, 8 },
1133 { { 0xFF, 0xFF, 0xFF, 0x00 }, 1, 8, 7, 9 },
1134 };
1135
1136 /* make sure the nonces of the first try don't affect the retries */
1137 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1138 initiate_rekey(a, 1);
1139 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1140 initiate_rekey(b, 2);
1141
1142 /* this should never get called as this results in a successful rekeying */
1143 assert_hook_not_called(child_updown);
1144
1145 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1146 assert_hook_not_called(child_rekey);
1147 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1148 assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1149 assert_child_sa_count(b, 1);
1150 assert_hook();
1151 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
1152 assert_hook_not_called(child_rekey);
1153 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1154 assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1155 assert_child_sa_count(a, 1);
1156 assert_hook();
1157
1158 /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */
1159 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1160 assert_hook_not_called(child_rekey);
1161 assert_single_notify(IN, INVALID_KE_PAYLOAD);
1162 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1163 assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1164 assert_child_sa_count(a, 1);
1165 assert_hook();
1166 /* CREATE_CHILD_SA { N(INVAL_KE) } --> */
1167 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1168 assert_hook_not_called(child_rekey);
1169 assert_single_notify(IN, INVALID_KE_PAYLOAD);
1170 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1171 assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1172 assert_child_sa_count(b, 1);
1173 assert_hook();
1174
1175 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1176 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
1177 assert_hook_rekey(child_rekey, 2, 9);
1178 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1179 assert_child_sa_state(b, 2, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
1180 assert_child_sa_state(b, 9, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
1181 assert_hook();
1182 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
1183 exchange_test_helper->nonce_first_byte = data[_i].nonces[3];
1184 assert_hook_rekey(child_rekey, 1, 10);
1185 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1186 assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
1187 assert_child_sa_state(a,10, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
1188 assert_hook();
1189
1190 /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */
1191 if (data[_i].spi_del_a == 1)
1192 { /* currently we call this again if we keep our own replacement as we
1193 * already called it above */
1194 assert_hook_rekey(child_rekey, 1, data[_i].spi_a);
1195 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1196 assert_hook();
1197 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED,
1198 CHILD_OUTBOUND_REGISTERED);
1199 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
1200 CHILD_OUTBOUND_INSTALLED);
1201 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
1202 CHILD_OUTBOUND_INSTALLED);
1203 }
1204 else
1205 {
1206 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1207 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED,
1208 CHILD_OUTBOUND_INSTALLED);
1209 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
1210 CHILD_OUTBOUND_REGISTERED);
1211 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
1212 CHILD_OUTBOUND_REGISTERED);
1213 }
1214 /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
1215 if (data[_i].spi_del_b == 2)
1216 {
1217 assert_hook_rekey(child_rekey, 2, data[_i].spi_b);
1218 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1219 assert_hook();
1220 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
1221 CHILD_OUTBOUND_REGISTERED);
1222 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
1223 CHILD_OUTBOUND_INSTALLED);
1224 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
1225 CHILD_OUTBOUND_INSTALLED);
1226 }
1227 else
1228 {
1229 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1230 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED,
1231 CHILD_OUTBOUND_INSTALLED);
1232 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
1233 CHILD_OUTBOUND_REGISTERED);
1234 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
1235 CHILD_OUTBOUND_REGISTERED);
1236 }
1237
1238
1239 /* we don't expect this hook to get called anymore */
1240 assert_hook_not_called(child_rekey);
1241 /* INFORMATIONAL { D } --> */
1242 assert_jobs_scheduled(1);
1243 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1244 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
1245 data[_i].spi_del_b == 2 ? CHILD_OUTBOUND_INSTALLED
1246 : CHILD_OUTBOUND_REGISTERED);
1247 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
1248 CHILD_OUTBOUND_NONE);
1249 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
1250 CHILD_OUTBOUND_INSTALLED);
1251 assert_child_sa_count(b, 3);
1252 assert_scheduler();
1253 /* <-- INFORMATIONAL { D } */
1254 assert_jobs_scheduled(1);
1255 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1256 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
1257 data[_i].spi_del_a == 1 ? CHILD_OUTBOUND_INSTALLED
1258 : CHILD_OUTBOUND_REGISTERED);
1259 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
1260 CHILD_OUTBOUND_NONE);
1261 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
1262 CHILD_OUTBOUND_INSTALLED);
1263 assert_child_sa_count(a, 3);
1264 assert_scheduler();
1265 /* <-- INFORMATIONAL { D } */
1266 assert_jobs_scheduled(1);
1267 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1268 assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
1269 CHILD_OUTBOUND_NONE);
1270 assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
1271 CHILD_OUTBOUND_NONE);
1272 assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
1273 CHILD_OUTBOUND_INSTALLED);
1274 assert_child_sa_count(a, 3);
1275 assert_scheduler();
1276 /* INFORMATIONAL { D } --> */
1277 assert_jobs_scheduled(1);
1278 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1279 assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
1280 CHILD_OUTBOUND_NONE);
1281 assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
1282 CHILD_OUTBOUND_NONE);
1283 assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
1284 CHILD_OUTBOUND_INSTALLED);
1285 assert_child_sa_count(b, 3);
1286 assert_scheduler();
1287
1288 /* simulate the execution of the scheduled jobs */
1289 destroy_rekeyed(a, data[_i].spi_del_a);
1290 destroy_rekeyed(a, data[_i].spi_del_b);
1291 assert_child_sa_count(a, 1);
1292 assert_ipsec_sas_installed(a, data[_i].spi_a, data[_i].spi_b);
1293 destroy_rekeyed(b, data[_i].spi_del_a);
1294 destroy_rekeyed(b, data[_i].spi_del_b);
1295 assert_child_sa_count(b, 1);
1296 assert_ipsec_sas_installed(b, data[_i].spi_a, data[_i].spi_b);
1297
1298 /* child_rekey/child_updown */
1299 assert_hook();
1300 assert_hook();
1301
1302 assert_sa_idle(a);
1303 assert_sa_idle(b);
1304
1305 call_ikesa(a, destroy);
1306 call_ikesa(b, destroy);
1307 }
1308 END_TEST
1309
1310 /**
1311 * This is a variation of the above but with the retry by one peer delayed so
1312 * that to the other peer it looks like there is no collision.
1313 */
1314 START_TEST(test_collision_ke_invalid_delayed_retry)
1315 {
1316 exchange_test_sa_conf_t conf = {
1317 .initiator = {
1318 .esp = "aes128-sha256-modp2048-modp3072",
1319 },
1320 .responder = {
1321 .esp = "aes128-sha256-modp3072-modp2048",
1322 },
1323 };
1324 ike_sa_t *a, *b;
1325 message_t *msg;
1326
1327 exchange_test_helper->establish_sa(exchange_test_helper,
1328 &a, &b, &conf);
1329
1330 /* Seven nonces and SPIs are needed (SPI 1 and 2 are used for the initial
1331 * CHILD_SA):
1332 * N1/3 -----\ /----- N2/4
1333 * \--/-----> N3/5
1334 * N4/6 <-------/ /---- INVAL_KE
1335 * INVAL_KE -----\ /
1336 * <-----\--/
1337 * N5/7 -----\ \------->
1338 * <-----\--------- N6/8
1339 * N7/9 -------\------->
1340 * <-------\------- DELETE
1341 * ... ------\ \----->
1342 * /---- TEMP_FAIL
1343 *
1344 * We test this three times, each time a different nonce is the lowest.
1345 */
1346 struct {
1347 /* Nonces used at each point */
1348 u_char nonces[3];
1349 } data[] = {
1350 { { 0x00, 0xFF, 0xFF } },
1351 { { 0xFF, 0x00, 0xFF } },
1352 { { 0xFF, 0xFF, 0x00 } },
1353 };
1354
1355 /* make sure the nonces of the first try don't affect the retries */
1356 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1357 initiate_rekey(a, 1);
1358 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1359 initiate_rekey(b, 2);
1360
1361 /* this should never get called as this results in a successful rekeying */
1362 assert_hook_not_called(child_updown);
1363
1364 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1365 assert_hook_not_called(child_rekey);
1366 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1367 assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1368 assert_child_sa_count(b, 1);
1369 assert_hook();
1370 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
1371 assert_hook_not_called(child_rekey);
1372 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1373 assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1374 assert_child_sa_count(a, 1);
1375 assert_hook();
1376
1377 /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */
1378 exchange_test_helper->nonce_first_byte = data[_i].nonces[0];
1379 assert_hook_not_called(child_rekey);
1380 assert_single_notify(IN, INVALID_KE_PAYLOAD);
1381 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1382 assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1383 assert_child_sa_count(a, 1);
1384 assert_hook();
1385 /* CREATE_CHILD_SA { N(INVAL_KE) } --> */
1386 exchange_test_helper->nonce_first_byte = data[_i].nonces[1];
1387 assert_hook_not_called(child_rekey);
1388 assert_single_notify(IN, INVALID_KE_PAYLOAD);
1389 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1390 assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1391 assert_child_sa_count(b, 1);
1392 assert_hook();
1393
1394 /* delay the CREATE_CHILD_SA request from a to b */
1395 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1396
1397 /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */
1398 exchange_test_helper->nonce_first_byte = data[_i].nonces[2];
1399 assert_hook_rekey(child_rekey, 1, 9);
1400 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1401 assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED);
1402 assert_child_sa_state(a, 9, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED);
1403 assert_hook();
1404 /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
1405 assert_hook_rekey(child_rekey, 2, 8);
1406 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1407 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1408 assert_child_sa_state(b, 8, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1409 assert_hook();
1410
1411 /* we don't expect this hook to get called anymore */
1412 assert_hook_not_called(child_rekey);
1413
1414 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> (delayed) */
1415 assert_single_notify(OUT, TEMPORARY_FAILURE);
1416 exchange_test_helper->process_message(exchange_test_helper, b, msg);
1417 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1418 assert_child_sa_state(b, 8, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1419
1420 /* <-- INFORMATIONAL { D } */
1421 assert_jobs_scheduled(1);
1422 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1423 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
1424 assert_child_sa_state(a, 9, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1425 assert_child_sa_count(a, 2);
1426 assert_scheduler();
1427
1428 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1429 assert_no_jobs_scheduled();
1430 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1431 assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE);
1432 assert_child_sa_state(a, 9, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1433 assert_child_sa_count(a, 2);
1434 assert_scheduler();
1435
1436 /* INFORMATIONAL { D } --> */
1437 assert_jobs_scheduled(1);
1438 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1439 assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE);
1440 assert_child_sa_state(b, 8, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1441 assert_child_sa_count(b, 2);
1442 assert_scheduler();
1443
1444 /* simulate the execution of the scheduled jobs */
1445 destroy_rekeyed(a, 1);
1446 assert_child_sa_count(a, 1);
1447 assert_ipsec_sas_installed(a, 8, 9);
1448 destroy_rekeyed(b, 2);
1449 assert_child_sa_count(b, 1);
1450 assert_ipsec_sas_installed(b, 8, 9);
1451
1452 /* child_rekey/child_updown */
1453 assert_hook();
1454 assert_hook();
1455
1456 assert_sa_idle(a);
1457 assert_sa_idle(b);
1458
1459 call_ikesa(a, destroy);
1460 call_ikesa(b, destroy);
1461 }
1462 END_TEST
1463
1464 /**
1465 * One of the hosts initiates a DELETE of the CHILD_SA the other peer is
1466 * concurrently trying to rekey.
1467 *
1468 * rekey ----\ /---- delete
1469 * \-----/----> detect collision
1470 * detect collision <---------/ /---- TEMP_FAIL
1471 * delete ----\ /
1472 * \----/----->
1473 * aborts rekeying <--------/
1474 */
1475 START_TEST(test_collision_delete)
1476 {
1477 ike_sa_t *a, *b;
1478 uint32_t spi_a = _i+1, spi_b = 2-_i;
1479
1480 if (_i)
1481 { /* responder rekeys the CHILD_SA (SPI 2) */
1482 exchange_test_helper->establish_sa(exchange_test_helper,
1483 &b, &a, NULL);
1484 }
1485 else
1486 { /* initiator rekeys the CHILD_SA (SPI 1) */
1487 exchange_test_helper->establish_sa(exchange_test_helper,
1488 &a, &b, NULL);
1489 }
1490 initiate_rekey(a, spi_a);
1491 call_ikesa(b, delete_child_sa, PROTO_ESP, spi_b, FALSE);
1492 assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1493
1494 /* this should never get called as there is no successful rekeying on
1495 * either side */
1496 assert_hook_not_called(child_rekey);
1497
1498 /* RFC 7296, 2.25.1: If a peer receives a request to rekey a CHILD_SA that
1499 * it is currently trying to close, it SHOULD reply with TEMPORARY_FAILURE.
1500 */
1501
1502 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1503 assert_hook_not_called(child_updown);
1504 assert_notify(IN, REKEY_SA);
1505 assert_single_notify(OUT, TEMPORARY_FAILURE);
1506 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1507 assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1508 assert_hook();
1509
1510 /* RFC 7296, 2.25.1: If a peer receives a request to delete a CHILD_SA that
1511 * it is currently trying to rekey, it SHOULD reply as usual, with a DELETE
1512 * payload.
1513 */
1514
1515 /* <-- INFORMATIONAL { D } */
1516 assert_hook_updown(child_updown, FALSE);
1517 assert_single_payload(IN, PLV2_DELETE);
1518 assert_single_payload(OUT, PLV2_DELETE);
1519 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1520 assert_child_sa_count(a, 0);
1521 assert_hook();
1522
1523 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1524 assert_hook_not_called(child_updown);
1525 /* we don't expect a job to retry the rekeying */
1526 assert_no_jobs_scheduled();
1527 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1528 assert_scheduler();
1529 assert_hook();
1530
1531 /* INFORMATIONAL { D } --> */
1532 assert_hook_updown(child_updown, FALSE);
1533 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1534 assert_child_sa_count(b, 0);
1535 assert_hook();
1536
1537 /* child_rekey */
1538 assert_hook();
1539
1540 assert_sa_idle(a);
1541 assert_sa_idle(b);
1542
1543 call_ikesa(a, destroy);
1544 call_ikesa(b, destroy);
1545 }
1546 END_TEST
1547
1548 /**
1549 * One of the hosts initiates a DELETE of the CHILD_SA the other peer is
1550 * concurrently trying to rekey. However, the delete request is delayed or
1551 * dropped, so the peer doing the rekeying is unaware of the collision.
1552 *
1553 * rekey ----\ /---- delete
1554 * \-----/----> detect collision
1555 * reschedule <---------/------ TEMP_FAIL
1556 * <--------/
1557 * delete ---------------->
1558 *
1559 * The job will not find the SA to retry rekeying.
1560 */
1561 START_TEST(test_collision_delete_drop_delete)
1562 {
1563 ike_sa_t *a, *b;
1564 message_t *msg;
1565 uint32_t spi_a = _i+1, spi_b = 2-_i;
1566
1567 if (_i)
1568 { /* responder rekeys the CHILD_SA (SPI 2) */
1569 exchange_test_helper->establish_sa(exchange_test_helper,
1570 &b, &a, NULL);
1571 }
1572 else
1573 { /* initiator rekeys the CHILD_SA (SPI 1) */
1574 exchange_test_helper->establish_sa(exchange_test_helper,
1575 &a, &b, NULL);
1576 }
1577 initiate_rekey(a, spi_a);
1578 call_ikesa(b, delete_child_sa, PROTO_ESP, spi_b, FALSE);
1579 assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1580
1581 /* this should never get called as there is no successful rekeying on
1582 * either side */
1583 assert_hook_not_called(child_rekey);
1584
1585 /* RFC 7296, 2.25.1: If a peer receives a request to rekey a CHILD_SA that
1586 * it is currently trying to close, it SHOULD reply with TEMPORARY_FAILURE.
1587 */
1588
1589 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1590 assert_hook_not_called(child_updown);
1591 assert_notify(IN, REKEY_SA);
1592 assert_single_notify(OUT, TEMPORARY_FAILURE);
1593 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1594 assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1595 assert_hook();
1596
1597 /* delay the DELETE request */
1598 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1599
1600 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1601 assert_hook_not_called(child_updown);
1602 /* we expect a job to retry the rekeying is scheduled */
1603 assert_jobs_scheduled(1);
1604 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1605 assert_child_sa_state(a, spi_a, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1606 assert_scheduler();
1607 assert_hook();
1608
1609 /* <-- INFORMATIONAL { D } (delayed) */
1610 assert_hook_updown(child_updown, FALSE);
1611 assert_single_payload(IN, PLV2_DELETE);
1612 assert_single_payload(OUT, PLV2_DELETE);
1613 exchange_test_helper->process_message(exchange_test_helper, a, msg);
1614 assert_child_sa_count(a, 0);
1615 assert_hook();
1616
1617 /* INFORMATIONAL { D } --> */
1618 assert_hook_updown(child_updown, FALSE);
1619 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1620 assert_child_sa_count(b, 0);
1621 assert_hook();
1622
1623 /* child_rekey */
1624 assert_hook();
1625
1626 assert_sa_idle(a);
1627 assert_sa_idle(b);
1628
1629 call_ikesa(a, destroy);
1630 call_ikesa(b, destroy);
1631 }
1632 END_TEST
1633
1634 /**
1635 * One of the hosts initiates a DELETE of the CHILD_SA the other peer is
1636 * concurrently trying to rekey. However, the rekey request is delayed or
1637 * dropped, so the peer doing the deleting is unaware of the collision.
1638 *
1639 * rekey ----\ /---- delete
1640 * detect collision <----\-----/
1641 * delete ------\--------->
1642 * \-------->
1643 * /---- CHILD_SA_NOT_FOUND
1644 * aborts rekeying <----------/
1645 */
1646 START_TEST(test_collision_delete_drop_rekey)
1647 {
1648 ike_sa_t *a, *b;
1649 message_t *msg;
1650 uint32_t spi_a = _i+1, spi_b = 2-_i;
1651
1652 if (_i)
1653 { /* responder rekeys the CHILD_SA (SPI 2) */
1654 exchange_test_helper->establish_sa(exchange_test_helper,
1655 &b, &a, NULL);
1656 }
1657 else
1658 { /* initiator rekeys the CHILD_SA (SPI 1) */
1659 exchange_test_helper->establish_sa(exchange_test_helper,
1660 &a, &b, NULL);
1661 }
1662 initiate_rekey(a, spi_a);
1663 call_ikesa(b, delete_child_sa, PROTO_ESP, spi_b, FALSE);
1664 assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED);
1665
1666 /* this should never get called as there is no successful rekeying on
1667 * either side */
1668 assert_hook_not_called(child_rekey);
1669
1670 /* delay the CREATE_CHILD_SA request */
1671 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1672
1673 /* RFC 7296, 2.25.1: If a peer receives a request to delete a CHILD_SA that
1674 * it is currently trying to rekey, it SHOULD reply as usual, with a DELETE
1675 * payload.
1676 */
1677
1678 /* <-- INFORMATIONAL { D } */
1679 assert_hook_updown(child_updown, FALSE);
1680 assert_single_payload(IN, PLV2_DELETE);
1681 assert_single_payload(OUT, PLV2_DELETE);
1682 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1683 assert_child_sa_count(a, 0);
1684 assert_hook();
1685
1686 /* INFORMATIONAL { D } --> */
1687 assert_hook_updown(child_updown, FALSE);
1688 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1689 assert_child_sa_count(b, 0);
1690 assert_hook();
1691
1692 /* RFC 7296, 2.25.1: If a peer receives a to rekey a Child SA that does not
1693 * exist, it SHOULD reply with CHILD_SA_NOT_FOUND.
1694 */
1695
1696 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> (delayed) */
1697 assert_hook_not_called(child_updown);
1698 assert_notify(IN, REKEY_SA);
1699 assert_single_notify(OUT, CHILD_SA_NOT_FOUND);
1700 exchange_test_helper->process_message(exchange_test_helper, b, msg);
1701 assert_hook();
1702
1703 /* <-- CREATE_CHILD_SA { N(NO_CHILD_SA) } */
1704 assert_hook_not_called(child_updown);
1705 /* no jobs or tasks should get scheduled/queued */
1706 assert_no_jobs_scheduled();
1707 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1708 assert_scheduler();
1709 assert_hook();
1710
1711 /* child_rekey */
1712 assert_hook();
1713
1714 assert_sa_idle(a);
1715 assert_sa_idle(b);
1716
1717 call_ikesa(a, destroy);
1718 call_ikesa(b, destroy);
1719 }
1720 END_TEST
1721
1722 /**
1723 * FIXME: Not sure what we can do about the following:
1724 *
1725 * One of the hosts initiates a rekeying of a CHILD_SA and after responding to
1726 * it the other peer deletes the new SA. However, the rekey response is
1727 * delayed or dropped, so the peer doing the rekeying receives a delete for an
1728 * unknown CHILD_SA and then has a rekeyed CHILD_SA that should not exist.
1729 *
1730 * rekey ---------------->
1731 * /---- rekey
1732 * unknown SA <----------/----- delete new SA
1733 * ----------/----->
1734 * <--------/
1735 *
1736 * The peers' states are now out of sync.
1737 *
1738 * Perhaps the rekey initiator could keep track of deletes for non-existing SAs
1739 * while rekeying and then check against the SPIs when handling the
1740 * CREATE_CHILD_SA response.
1741 */
1742
1743
1744 /**
1745 * One of the hosts initiates a rekey of the IKE_SA of the CHILD_SA the other
1746 * peer is concurrently trying to rekey.
1747 *
1748 * rekey ----\ /---- rekey IKE
1749 * \-----/----> detect collision
1750 * detect collision <---------/ /---- TEMP_FAIL
1751 * TEMP_FAIL ----\ /
1752 * \----/----->
1753 * <--------/
1754 */
1755 START_TEST(test_collision_ike_rekey)
1756 {
1757 ike_sa_t *a, *b;
1758 uint32_t spi_a = _i+1;
1759
1760 if (_i)
1761 { /* responder rekeys the CHILD_SA (SPI 2) */
1762 exchange_test_helper->establish_sa(exchange_test_helper,
1763 &b, &a, NULL);
1764 }
1765 else
1766 { /* initiator rekeys the CHILD_SA (SPI 1) */
1767 exchange_test_helper->establish_sa(exchange_test_helper,
1768 &a, &b, NULL);
1769 }
1770 initiate_rekey(a, spi_a);
1771 call_ikesa(b, rekey);
1772 assert_ike_sa_state(b, IKE_REKEYING);
1773
1774 /* these should never get called as there is no successful rekeying on
1775 * either side */
1776 assert_hook_not_called(ike_rekey);
1777 assert_hook_not_called(child_rekey);
1778
1779 /* RFC 7296, 2.25.2: If a peer receives a request to rekey a CHILD_SA when
1780 * it is currently rekeying the IKE SA, it SHOULD reply with
1781 * TEMPORARY_FAILURE.
1782 */
1783
1784 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1785 assert_single_notify(OUT, TEMPORARY_FAILURE);
1786 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1787 assert_ike_sa_state(b, IKE_REKEYING);
1788
1789 /* RFC 7296, 2.25.1: If a peer receives a request to rekey the IKE SA, and
1790 * it is currently, rekeying, or closing a Child SA of that IKE SA, it
1791 * SHOULD reply with TEMPORARY_FAILURE.
1792 */
1793
1794 /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
1795 assert_single_notify(OUT, TEMPORARY_FAILURE);
1796 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1797 assert_child_sa_state(a, spi_a, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED);
1798
1799 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1800 /* we expect a job to retry the rekeying is scheduled */
1801 assert_jobs_scheduled(1);
1802 exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1803 assert_child_sa_state(a, spi_a, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED);
1804 assert_scheduler();
1805
1806 /* CREATE_CHILD_SA { N(TEMP_FAIL) } --> */
1807 /* we expect a job to retry the rekeying is scheduled */
1808 assert_jobs_scheduled(1);
1809 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1810 assert_ike_sa_state(b, IKE_ESTABLISHED);
1811 assert_scheduler();
1812
1813 /* ike_rekey/child_rekey */
1814 assert_hook();
1815 assert_hook();
1816
1817 assert_sa_idle(a);
1818 assert_sa_idle(b);
1819
1820 call_ikesa(a, destroy);
1821 call_ikesa(b, destroy);
1822 }
1823 END_TEST
1824
1825 /**
1826 * One of the hosts initiates a delete of the IKE_SA of the CHILD_SA the other
1827 * peer is concurrently trying to rekey.
1828 *
1829 * rekey ----\ /---- delete IKE
1830 * \-----/----> detect collision
1831 * <---------/ /---- TEMP_FAIL
1832 * delete ----\ /
1833 * \----/----->
1834 * sa already gone <--------/
1835 */
1836 START_TEST(test_collision_ike_delete)
1837 {
1838 ike_sa_t *a, *b;
1839 uint32_t spi_a = _i+1;
1840 message_t *msg;
1841 status_t s;
1842
1843 if (_i)
1844 { /* responder rekeys the CHILD_SA (SPI 2) */
1845 exchange_test_helper->establish_sa(exchange_test_helper,
1846 &b, &a, NULL);
1847 }
1848 else
1849 { /* initiator rekeys the CHILD_SA (SPI 1) */
1850 exchange_test_helper->establish_sa(exchange_test_helper,
1851 &a, &b, NULL);
1852 }
1853 initiate_rekey(a, spi_a);
1854 call_ikesa(b, delete);
1855 assert_ike_sa_state(b, IKE_DELETING);
1856
1857 /* this should never get called as there is no successful rekeying on
1858 * either side */
1859 assert_hook_not_called(child_rekey);
1860
1861 /* RFC 7296, 2.25.2 does not explicitly state what the behavior SHOULD be if
1862 * a peer receives a request to rekey a CHILD_SA when it is currently
1863 * closing the IKE SA. We expect a TEMPORARY_FAILURE notify.
1864 */
1865
1866 /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */
1867 assert_single_notify(OUT, TEMPORARY_FAILURE);
1868 exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1869 assert_ike_sa_state(b, IKE_DELETING);
1870
1871 /* RFC 7296, 2.25.1 does not explicitly state what the behavior SHOULD be if
1872 * a peer receives a request to close the IKE SA if it is currently rekeying
1873 * a Child SA of that IKE SA. Let's just close the IKE_SA and forget the
1874 * rekeying.
1875 */
1876
1877 /* <-- INFORMATIONAL { D } */
1878 assert_hook_updown(ike_updown, FALSE);
1879 assert_hook_updown(child_updown, FALSE);
1880 assert_message_empty(OUT);
1881 s = exchange_test_helper->process_message(exchange_test_helper, a, NULL);
1882 ck_assert_int_eq(DESTROY_ME, s);
1883 call_ikesa(a, destroy);
1884 assert_hook();
1885 assert_hook();
1886
1887 /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */
1888 /* the SA is already gone */
1889 msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender);
1890 msg->destroy(msg);
1891
1892 /* INFORMATIONAL { } --> */
1893 assert_hook_updown(ike_updown, FALSE);
1894 assert_hook_updown(child_updown, FALSE);
1895 s = exchange_test_helper->process_message(exchange_test_helper, b, NULL);
1896 ck_assert_int_eq(DESTROY_ME, s);
1897 call_ikesa(b, destroy);
1898 assert_hook();
1899 assert_hook();
1900
1901 /* child_rekey */
1902 assert_hook();
1903 }
1904 END_TEST
1905
1906 Suite *child_rekey_suite_create()
1907 {
1908 Suite *s;
1909 TCase *tc;
1910
1911 s = suite_create("child rekey");
1912
1913 tc = tcase_create("regular");
1914 tcase_add_loop_test(tc, test_regular, 0, 2);
1915 tcase_add_loop_test(tc, test_regular_ke_invalid, 0, 2);
1916 tcase_add_test(tc, test_regular_responder_ignore_soft_expire);
1917 tcase_add_test(tc, test_regular_responder_handle_hard_expire);
1918 suite_add_tcase(s, tc);
1919
1920 tc = tcase_create("collisions rekey");
1921 tcase_add_loop_test(tc, test_collision, 0, 4);
1922 tcase_add_loop_test(tc, test_collision_delayed_response, 0, 4);
1923 tcase_add_loop_test(tc, test_collision_delayed_request, 0, 3);
1924 tcase_add_loop_test(tc, test_collision_delayed_request_more, 0, 3);
1925 tcase_add_loop_test(tc, test_collision_ke_invalid, 0, 4);
1926 tcase_add_loop_test(tc, test_collision_ke_invalid_delayed_retry, 0, 3);
1927 suite_add_tcase(s, tc);
1928
1929 tc = tcase_create("collisions delete");
1930 tcase_add_loop_test(tc, test_collision_delete, 0, 2);
1931 tcase_add_loop_test(tc, test_collision_delete_drop_delete, 0, 2);
1932 tcase_add_loop_test(tc, test_collision_delete_drop_rekey, 0, 2);
1933 suite_add_tcase(s, tc);
1934
1935 tc = tcase_create("collisions ike rekey");
1936 tcase_add_loop_test(tc, test_collision_ike_rekey, 0, 2);
1937 suite_add_tcase(s, tc);
1938
1939 tc = tcase_create("collisions ike delete");
1940 tcase_add_loop_test(tc, test_collision_ike_delete, 0, 2);
1941 suite_add_tcase(s, tc);
1942
1943 return s;
1944 }