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