ike: Reuse interface ID during CHILD_SA rekeyings
[strongswan.git] / src / libcharon / sa / ikev2 / tasks / child_create.c
1 /*
2 * Copyright (C) 2008-2019 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * HSR Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include "child_create.h"
19
20 #include <daemon.h>
21 #include <sa/ikev2/keymat_v2.h>
22 #include <crypto/diffie_hellman.h>
23 #include <credentials/certificates/x509.h>
24 #include <encoding/payloads/sa_payload.h>
25 #include <encoding/payloads/ke_payload.h>
26 #include <encoding/payloads/ts_payload.h>
27 #include <encoding/payloads/nonce_payload.h>
28 #include <encoding/payloads/notify_payload.h>
29 #include <encoding/payloads/delete_payload.h>
30 #include <processing/jobs/delete_ike_sa_job.h>
31 #include <processing/jobs/inactivity_job.h>
32 #include <processing/jobs/initiate_tasks_job.h>
33
34 typedef struct private_child_create_t private_child_create_t;
35
36 /**
37 * Private members of a child_create_t task.
38 */
39 struct private_child_create_t {
40
41 /**
42 * Public methods and task_t interface.
43 */
44 child_create_t public;
45
46 /**
47 * Assigned IKE_SA.
48 */
49 ike_sa_t *ike_sa;
50
51 /**
52 * Are we the initiator?
53 */
54 bool initiator;
55
56 /**
57 * nonce chosen by us
58 */
59 chunk_t my_nonce;
60
61 /**
62 * nonce chosen by peer
63 */
64 chunk_t other_nonce;
65
66 /**
67 * nonce generator
68 */
69 nonce_gen_t *nonceg;
70
71 /**
72 * config to create the CHILD_SA from
73 */
74 child_cfg_t *config;
75
76 /**
77 * list of proposal candidates
78 */
79 linked_list_t *proposals;
80
81 /**
82 * selected proposal to use for CHILD_SA
83 */
84 proposal_t *proposal;
85
86 /**
87 * traffic selectors for initiators side
88 */
89 linked_list_t *tsi;
90
91 /**
92 * traffic selectors for responders side
93 */
94 linked_list_t *tsr;
95
96 /**
97 * source of triggering packet
98 */
99 traffic_selector_t *packet_tsi;
100
101 /**
102 * destination of triggering packet
103 */
104 traffic_selector_t *packet_tsr;
105
106 /**
107 * optional diffie hellman exchange
108 */
109 diffie_hellman_t *dh;
110
111 /**
112 * Applying DH public value failed?
113 */
114 bool dh_failed;
115
116 /**
117 * group used for DH exchange
118 */
119 diffie_hellman_group_t dh_group;
120
121 /**
122 * IKE_SAs keymat
123 */
124 keymat_v2_t *keymat;
125
126 /**
127 * mode the new CHILD_SA uses (transport/tunnel/beet)
128 */
129 ipsec_mode_t mode;
130
131 /**
132 * peer accepts TFC padding for this SA
133 */
134 bool tfcv3;
135
136 /**
137 * IPComp transform to use
138 */
139 ipcomp_transform_t ipcomp;
140
141 /**
142 * IPComp transform proposed or accepted by the other peer
143 */
144 ipcomp_transform_t ipcomp_received;
145
146 /**
147 * IPsec protocol
148 */
149 protocol_id_t proto;
150
151 /**
152 * Own allocated SPI
153 */
154 uint32_t my_spi;
155
156 /**
157 * SPI received in proposal
158 */
159 uint32_t other_spi;
160
161 /**
162 * Own allocated Compression Parameter Index (CPI)
163 */
164 uint16_t my_cpi;
165
166 /**
167 * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
168 */
169 uint16_t other_cpi;
170
171 /**
172 * reqid to use if we are rekeying
173 */
174 uint32_t reqid;
175
176 /**
177 * Explicit inbound mark value
178 */
179 uint32_t mark_in;
180
181 /**
182 * Explicit outbound mark value
183 */
184 uint32_t mark_out;
185
186 /**
187 * Explicit inbound interface ID to use, if any
188 */
189 uint32_t if_id_in;
190
191 /**
192 * Explicit outbound interface ID to use, if any
193 */
194 uint32_t if_id_out;
195
196 /**
197 * CHILD_SA which gets established
198 */
199 child_sa_t *child_sa;
200
201 /**
202 * successfully established the CHILD?
203 */
204 bool established;
205
206 /**
207 * whether the CHILD_SA rekeys an existing one
208 */
209 bool rekey;
210
211 /**
212 * whether we are retrying with another DH group
213 */
214 bool retry;
215 };
216
217 /**
218 * Schedule a retry if creating the CHILD_SA temporary failed
219 */
220 static void schedule_delayed_retry(private_child_create_t *this)
221 {
222 child_create_t *task;
223 uint32_t retry;
224
225 retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
226
227 task = child_create_create(this->ike_sa,
228 this->config->get_ref(this->config), FALSE,
229 this->packet_tsi, this->packet_tsr);
230 task->use_reqid(task, this->reqid);
231 DBG1(DBG_IKE, "creating CHILD_SA failed, trying again in %d seconds",
232 retry);
233 this->ike_sa->queue_task_delayed(this->ike_sa, (task_t*)task, retry);
234 }
235
236 /**
237 * get the nonce from a message
238 */
239 static status_t get_nonce(message_t *message, chunk_t *nonce)
240 {
241 nonce_payload_t *payload;
242
243 payload = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
244 if (payload == NULL)
245 {
246 return FAILED;
247 }
248 *nonce = payload->get_nonce(payload);
249 return NEED_MORE;
250 }
251
252 /**
253 * generate a new nonce to include in a CREATE_CHILD_SA message
254 */
255 static bool generate_nonce(private_child_create_t *this)
256 {
257 this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
258 if (!this->nonceg)
259 {
260 DBG1(DBG_IKE, "no nonce generator found to create nonce");
261 return FALSE;
262 }
263 if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
264 &this->my_nonce))
265 {
266 DBG1(DBG_IKE, "nonce allocation failed");
267 return FALSE;
268 }
269 return TRUE;
270 }
271
272 /**
273 * Check a list of traffic selectors if any selector belongs to host
274 */
275 static bool ts_list_is_host(linked_list_t *list, host_t *host)
276 {
277 traffic_selector_t *ts;
278 bool is_host = TRUE;
279 enumerator_t *enumerator = list->create_enumerator(list);
280
281 while (is_host && enumerator->enumerate(enumerator, (void**)&ts))
282 {
283 is_host = is_host && ts->is_host(ts, host);
284 }
285 enumerator->destroy(enumerator);
286 return is_host;
287 }
288
289 /**
290 * Allocate local SPI
291 */
292 static bool allocate_spi(private_child_create_t *this)
293 {
294 proposal_t *proposal;
295
296 if (this->initiator)
297 {
298 this->proto = PROTO_ESP;
299 /* we just get a SPI for the first protocol. TODO: If we ever support
300 * proposal lists with mixed protocols, we'd need multiple SPIs */
301 if (this->proposals->get_first(this->proposals,
302 (void**)&proposal) == SUCCESS)
303 {
304 this->proto = proposal->get_protocol(proposal);
305 }
306 }
307 else
308 {
309 this->proto = this->proposal->get_protocol(this->proposal);
310 }
311 this->my_spi = this->child_sa->alloc_spi(this->child_sa, this->proto);
312 return this->my_spi != 0;
313 }
314
315 /**
316 * Update the proposals with the allocated SPIs as initiator and check the DH
317 * group and promote it if necessary
318 */
319 static bool update_and_check_proposals(private_child_create_t *this)
320 {
321 enumerator_t *enumerator;
322 proposal_t *proposal;
323 linked_list_t *other_dh_groups;
324 bool found = FALSE;
325
326 other_dh_groups = linked_list_create();
327 enumerator = this->proposals->create_enumerator(this->proposals);
328 while (enumerator->enumerate(enumerator, &proposal))
329 {
330 proposal->set_spi(proposal, this->my_spi);
331
332 /* move the selected DH group to the front, if any */
333 if (this->dh_group != MODP_NONE)
334 { /* proposals that don't contain the selected group are
335 * moved to the back */
336 if (!proposal->promote_dh_group(proposal, this->dh_group))
337 {
338 this->proposals->remove_at(this->proposals, enumerator);
339 other_dh_groups->insert_last(other_dh_groups, proposal);
340 }
341 else
342 {
343 found = TRUE;
344 }
345 }
346 }
347 enumerator->destroy(enumerator);
348 enumerator = other_dh_groups->create_enumerator(other_dh_groups);
349 while (enumerator->enumerate(enumerator, (void**)&proposal))
350 { /* no need to remove from the list as we destroy it anyway*/
351 this->proposals->insert_last(this->proposals, proposal);
352 }
353 enumerator->destroy(enumerator);
354 other_dh_groups->destroy(other_dh_groups);
355
356 return this->dh_group == MODP_NONE || found;
357 }
358
359 /**
360 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
361 */
362 static void schedule_inactivity_timeout(private_child_create_t *this)
363 {
364 uint32_t timeout, id;
365 bool close_ike;
366
367 timeout = this->config->get_inactivity(this->config);
368 if (timeout)
369 {
370 close_ike = lib->settings->get_bool(lib->settings,
371 "%s.inactivity_close_ike", FALSE, lib->ns);
372 id = this->child_sa->get_unique_id(this->child_sa);
373 lib->scheduler->schedule_job(lib->scheduler, (job_t*)
374 inactivity_job_create(id, timeout, close_ike), timeout);
375 }
376 }
377
378 /**
379 * Check if we have a an address pool configured
380 */
381 static bool have_pool(ike_sa_t *ike_sa)
382 {
383 enumerator_t *enumerator;
384 peer_cfg_t *peer_cfg;
385 char *pool;
386 bool found = FALSE;
387
388 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
389 if (peer_cfg)
390 {
391 enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
392 if (enumerator->enumerate(enumerator, &pool))
393 {
394 found = TRUE;
395 }
396 enumerator->destroy(enumerator);
397 }
398 return found;
399 }
400
401 /**
402 * Get hosts to use for dynamic traffic selectors
403 */
404 static linked_list_t *get_dynamic_hosts(ike_sa_t *ike_sa, bool local)
405 {
406 enumerator_t *enumerator;
407 linked_list_t *list;
408 host_t *host;
409
410 list = linked_list_create();
411 enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
412 while (enumerator->enumerate(enumerator, &host))
413 {
414 list->insert_last(list, host);
415 }
416 enumerator->destroy(enumerator);
417
418 if (list->get_count(list) == 0)
419 { /* no virtual IPs assigned */
420 if (local)
421 {
422 host = ike_sa->get_my_host(ike_sa);
423 list->insert_last(list, host);
424 }
425 else if (!have_pool(ike_sa))
426 { /* use host only if we don't have a pool configured */
427 host = ike_sa->get_other_host(ike_sa);
428 list->insert_last(list, host);
429 }
430 }
431 return list;
432 }
433
434 /**
435 * Substitute any host address with NATed address in traffic selector
436 */
437 static linked_list_t* get_transport_nat_ts(private_child_create_t *this,
438 bool local, linked_list_t *in)
439 {
440 enumerator_t *enumerator;
441 linked_list_t *out;
442 traffic_selector_t *ts;
443 host_t *ike, *first = NULL;
444 uint8_t mask;
445
446 if (local)
447 {
448 ike = this->ike_sa->get_my_host(this->ike_sa);
449 }
450 else
451 {
452 ike = this->ike_sa->get_other_host(this->ike_sa);
453 }
454
455 out = linked_list_create();
456
457 enumerator = in->create_enumerator(in);
458 while (enumerator->enumerate(enumerator, &ts))
459 {
460 /* require that all selectors match the first "host" selector */
461 if (ts->is_host(ts, first))
462 {
463 if (!first)
464 {
465 ts->to_subnet(ts, &first, &mask);
466 }
467 ts = ts->clone(ts);
468 ts->set_address(ts, ike);
469 out->insert_last(out, ts);
470 }
471 }
472 enumerator->destroy(enumerator);
473 DESTROY_IF(first);
474
475 return out;
476 }
477
478 /**
479 * Narrow received traffic selectors with configuration
480 */
481 static linked_list_t* narrow_ts(private_child_create_t *this, bool local,
482 linked_list_t *in)
483 {
484 linked_list_t *hosts, *nat, *ts;
485 ike_condition_t cond;
486
487 cond = local ? COND_NAT_HERE : COND_NAT_THERE;
488 hosts = get_dynamic_hosts(this->ike_sa, local);
489
490 if (this->mode == MODE_TRANSPORT &&
491 this->ike_sa->has_condition(this->ike_sa, cond))
492 {
493 nat = get_transport_nat_ts(this, local, in);
494 ts = this->config->get_traffic_selectors(this->config, local, nat,
495 hosts, TRUE);
496 nat->destroy_offset(nat, offsetof(traffic_selector_t, destroy));
497 }
498 else
499 {
500 ts = this->config->get_traffic_selectors(this->config, local, in,
501 hosts, TRUE);
502 }
503
504 hosts->destroy(hosts);
505
506 return ts;
507 }
508
509 /**
510 * Install a CHILD_SA for usage, return value:
511 * - FAILED: no acceptable proposal
512 * - INVALID_ARG: diffie hellman group unacceptable
513 * - NOT_FOUND: TS unacceptable
514 */
515 static status_t select_and_install(private_child_create_t *this,
516 bool no_dh, bool ike_auth)
517 {
518 status_t status, status_i, status_o;
519 child_sa_outbound_state_t out_state;
520 chunk_t nonce_i, nonce_r;
521 chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
522 chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
523 linked_list_t *my_ts, *other_ts;
524 host_t *me, *other;
525 bool private, prefer_configured;
526
527 if (this->proposals == NULL)
528 {
529 DBG1(DBG_IKE, "SA payload missing in message");
530 return FAILED;
531 }
532 if (this->tsi == NULL || this->tsr == NULL)
533 {
534 DBG1(DBG_IKE, "TS payloads missing in message");
535 return NOT_FOUND;
536 }
537
538 me = this->ike_sa->get_my_host(this->ike_sa);
539 other = this->ike_sa->get_other_host(this->ike_sa);
540
541 private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
542 prefer_configured = lib->settings->get_bool(lib->settings,
543 "%s.prefer_configured_proposals", TRUE, lib->ns);
544 this->proposal = this->config->select_proposal(this->config,
545 this->proposals, no_dh, private, prefer_configured);
546 if (this->proposal == NULL)
547 {
548 DBG1(DBG_IKE, "no acceptable proposal found");
549 charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD,
550 this->proposals);
551 return FAILED;
552 }
553 this->other_spi = this->proposal->get_spi(this->proposal);
554
555 if (!this->initiator)
556 {
557 if (!allocate_spi(this))
558 {
559 /* responder has no SPI allocated yet */
560 DBG1(DBG_IKE, "allocating SPI failed");
561 return FAILED;
562 }
563 this->proposal->set_spi(this->proposal, this->my_spi);
564 }
565 this->child_sa->set_proposal(this->child_sa, this->proposal);
566
567 if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
568 {
569 uint16_t group;
570
571 if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
572 &group, NULL))
573 {
574 DBG1(DBG_IKE, "DH group %N unacceptable, requesting %N",
575 diffie_hellman_group_names, this->dh_group,
576 diffie_hellman_group_names, group);
577 this->dh_group = group;
578 return INVALID_ARG;
579 }
580 /* the selected proposal does not use a DH group */
581 DBG1(DBG_IKE, "ignoring KE exchange, agreed on a non-PFS proposal");
582 DESTROY_IF(this->dh);
583 this->dh = NULL;
584 this->dh_group = MODP_NONE;
585 }
586
587 if (this->initiator)
588 {
589 nonce_i = this->my_nonce;
590 nonce_r = this->other_nonce;
591 my_ts = narrow_ts(this, TRUE, this->tsi);
592 other_ts = narrow_ts(this, FALSE, this->tsr);
593 }
594 else
595 {
596 nonce_r = this->my_nonce;
597 nonce_i = this->other_nonce;
598 my_ts = narrow_ts(this, TRUE, this->tsr);
599 other_ts = narrow_ts(this, FALSE, this->tsi);
600 }
601
602 if (this->initiator)
603 {
604 if (ike_auth)
605 {
606 charon->bus->narrow(charon->bus, this->child_sa,
607 NARROW_INITIATOR_POST_NOAUTH, my_ts, other_ts);
608 }
609 else
610 {
611 charon->bus->narrow(charon->bus, this->child_sa,
612 NARROW_INITIATOR_POST_AUTH, my_ts, other_ts);
613 }
614 }
615 else
616 {
617 charon->bus->narrow(charon->bus, this->child_sa,
618 NARROW_RESPONDER, my_ts, other_ts);
619 }
620
621 if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
622 {
623 charon->bus->alert(charon->bus, ALERT_TS_MISMATCH, this->tsi, this->tsr);
624 my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
625 other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
626 DBG1(DBG_IKE, "no acceptable traffic selectors found");
627 return NOT_FOUND;
628 }
629
630 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
631 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
632 if (this->initiator)
633 {
634 this->tsi = my_ts;
635 this->tsr = other_ts;
636 }
637 else
638 {
639 this->tsr = my_ts;
640 this->tsi = other_ts;
641 }
642
643 if (!this->initiator)
644 {
645 /* check if requested mode is acceptable, downgrade if required */
646 switch (this->mode)
647 {
648 case MODE_TRANSPORT:
649 if (!this->config->has_option(this->config, OPT_PROXY_MODE) &&
650 (!ts_list_is_host(this->tsi, other) ||
651 !ts_list_is_host(this->tsr, me))
652 )
653 {
654 this->mode = MODE_TUNNEL;
655 DBG1(DBG_IKE, "not using transport mode, not host-to-host");
656 }
657 if (this->config->get_mode(this->config) != MODE_TRANSPORT)
658 {
659 this->mode = MODE_TUNNEL;
660 }
661 break;
662 case MODE_BEET:
663 if (!ts_list_is_host(this->tsi, NULL) ||
664 !ts_list_is_host(this->tsr, NULL))
665 {
666 this->mode = MODE_TUNNEL;
667 DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
668 }
669 if (this->config->get_mode(this->config) != MODE_BEET)
670 {
671 this->mode = MODE_TUNNEL;
672 }
673 break;
674 default:
675 break;
676 }
677 /* use a copy of the traffic selectors, as the POST hook should not
678 * change payloads */
679 my_ts = this->tsr->clone_offset(this->tsr,
680 offsetof(traffic_selector_t, clone));
681 other_ts = this->tsi->clone_offset(this->tsi,
682 offsetof(traffic_selector_t, clone));
683 charon->bus->narrow(charon->bus, this->child_sa,
684 NARROW_RESPONDER_POST, my_ts, other_ts);
685
686 if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
687 {
688 my_ts->destroy_offset(my_ts,
689 offsetof(traffic_selector_t, destroy));
690 other_ts->destroy_offset(other_ts,
691 offsetof(traffic_selector_t, destroy));
692 return NOT_FOUND;
693 }
694 }
695
696 this->child_sa->set_policies(this->child_sa, my_ts, other_ts);
697 if (!this->initiator)
698 {
699 my_ts->destroy_offset(my_ts,
700 offsetof(traffic_selector_t, destroy));
701 other_ts->destroy_offset(other_ts,
702 offsetof(traffic_selector_t, destroy));
703 }
704
705 this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
706 this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
707 this->child_sa->set_mode(this->child_sa, this->mode);
708 this->child_sa->set_protocol(this->child_sa,
709 this->proposal->get_protocol(this->proposal));
710
711 if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
712 {
713 this->my_cpi = this->other_cpi = 0;
714 this->ipcomp = IPCOMP_NONE;
715 }
716 status_i = status_o = FAILED;
717 if (this->keymat->derive_child_keys(this->keymat, this->proposal,
718 this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
719 {
720 if (this->initiator)
721 {
722 status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
723 this->my_spi, this->my_cpi, this->initiator,
724 TRUE, this->tfcv3);
725 }
726 else
727 {
728 status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
729 this->my_spi, this->my_cpi, this->initiator,
730 TRUE, this->tfcv3);
731 }
732 if (this->rekey)
733 { /* during rekeyings we install the outbound SA and/or policies
734 * separately: as responder when we receive the delete for the old
735 * SA, as initiator pretty much immediately in the ike-rekey task,
736 * unless there was a rekey collision that we lost */
737 if (this->initiator)
738 {
739 status_o = this->child_sa->register_outbound(this->child_sa,
740 encr_i, integ_i, this->other_spi, this->other_cpi,
741 this->tfcv3);
742 }
743 else
744 {
745 status_o = this->child_sa->register_outbound(this->child_sa,
746 encr_r, integ_r, this->other_spi, this->other_cpi,
747 this->tfcv3);
748 }
749 }
750 else if (this->initiator)
751 {
752 status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
753 this->other_spi, this->other_cpi, this->initiator,
754 FALSE, this->tfcv3);
755 }
756 else
757 {
758 status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
759 this->other_spi, this->other_cpi, this->initiator,
760 FALSE, this->tfcv3);
761 }
762 }
763
764 if (status_i != SUCCESS || status_o != SUCCESS)
765 {
766 DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
767 (status_i != SUCCESS) ? "inbound " : "",
768 (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
769 (status_o != SUCCESS) ? "outbound " : "");
770 charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED,
771 this->child_sa);
772 status = FAILED;
773 }
774 else
775 {
776 status = this->child_sa->install_policies(this->child_sa);
777
778 if (status != SUCCESS)
779 {
780 DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
781 charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_POLICY_FAILED,
782 this->child_sa);
783 status = NOT_FOUND;
784 }
785 else
786 {
787 charon->bus->child_derived_keys(charon->bus, this->child_sa,
788 this->initiator, encr_i, encr_r,
789 integ_i, integ_r);
790 }
791 }
792 chunk_clear(&integ_i);
793 chunk_clear(&integ_r);
794 chunk_clear(&encr_i);
795 chunk_clear(&encr_r);
796
797 if (status != SUCCESS)
798 {
799 return status;
800 }
801
802 charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
803 this->dh, nonce_i, nonce_r);
804
805 my_ts = linked_list_create_from_enumerator(
806 this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
807 other_ts = linked_list_create_from_enumerator(
808 this->child_sa->create_ts_enumerator(this->child_sa, FALSE));
809 out_state = this->child_sa->get_outbound_state(this->child_sa);
810
811 DBG0(DBG_IKE, "%sCHILD_SA %s{%d} established "
812 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
813 (out_state == CHILD_OUTBOUND_INSTALLED) ? "" : "inbound ",
814 this->child_sa->get_name(this->child_sa),
815 this->child_sa->get_unique_id(this->child_sa),
816 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
817 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
818 my_ts, other_ts);
819
820 my_ts->destroy(my_ts);
821 other_ts->destroy(other_ts);
822
823 this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
824 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
825 this->established = TRUE;
826
827 schedule_inactivity_timeout(this);
828 return SUCCESS;
829 }
830
831 /**
832 * build the payloads for the message
833 */
834 static bool build_payloads(private_child_create_t *this, message_t *message)
835 {
836 sa_payload_t *sa_payload;
837 nonce_payload_t *nonce_payload;
838 ke_payload_t *ke_payload;
839 ts_payload_t *ts_payload;
840 kernel_feature_t features;
841
842 /* add SA payload */
843 if (this->initiator)
844 {
845 sa_payload = sa_payload_create_from_proposals_v2(this->proposals);
846 }
847 else
848 {
849 sa_payload = sa_payload_create_from_proposal_v2(this->proposal);
850 }
851 message->add_payload(message, (payload_t*)sa_payload);
852
853 /* add nonce payload if not in IKE_AUTH */
854 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
855 {
856 nonce_payload = nonce_payload_create(PLV2_NONCE);
857 nonce_payload->set_nonce(nonce_payload, this->my_nonce);
858 message->add_payload(message, (payload_t*)nonce_payload);
859 }
860
861 /* diffie hellman exchange, if PFS enabled */
862 if (this->dh)
863 {
864 ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
865 this->dh);
866 if (!ke_payload)
867 {
868 DBG1(DBG_IKE, "creating KE payload failed");
869 return FALSE;
870 }
871 message->add_payload(message, (payload_t*)ke_payload);
872 }
873
874 /* add TSi/TSr payloads */
875 ts_payload = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
876 message->add_payload(message, (payload_t*)ts_payload);
877 ts_payload = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
878 message->add_payload(message, (payload_t*)ts_payload);
879
880 /* add a notify if we are not in tunnel mode */
881 switch (this->mode)
882 {
883 case MODE_TRANSPORT:
884 message->add_notify(message, FALSE, USE_TRANSPORT_MODE, chunk_empty);
885 break;
886 case MODE_BEET:
887 message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
888 break;
889 default:
890 break;
891 }
892
893 features = charon->kernel->get_features(charon->kernel);
894 if (!(features & KERNEL_ESP_V3_TFC))
895 {
896 message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED,
897 chunk_empty);
898 }
899 return TRUE;
900 }
901
902 /**
903 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
904 */
905 static void add_ipcomp_notify(private_child_create_t *this,
906 message_t *message, uint8_t ipcomp)
907 {
908 this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
909 if (this->my_cpi)
910 {
911 this->ipcomp = ipcomp;
912 message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
913 chunk_cata("cc", chunk_from_thing(this->my_cpi),
914 chunk_from_thing(ipcomp)));
915 }
916 else
917 {
918 DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
919 }
920 }
921
922 /**
923 * handle a received notify payload
924 */
925 static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
926 {
927 switch (notify->get_notify_type(notify))
928 {
929 case USE_TRANSPORT_MODE:
930 this->mode = MODE_TRANSPORT;
931 break;
932 case USE_BEET_MODE:
933 if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN))
934 { /* handle private use notify only if we know its meaning */
935 this->mode = MODE_BEET;
936 }
937 else
938 {
939 DBG1(DBG_IKE, "received a notify strongSwan uses for BEET "
940 "mode, but peer implementation unknown, skipped");
941 }
942 break;
943 case IPCOMP_SUPPORTED:
944 {
945 ipcomp_transform_t ipcomp;
946 uint16_t cpi;
947 chunk_t data;
948
949 data = notify->get_notification_data(notify);
950 cpi = *(uint16_t*)data.ptr;
951 ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
952 switch (ipcomp)
953 {
954 case IPCOMP_DEFLATE:
955 this->other_cpi = cpi;
956 this->ipcomp_received = ipcomp;
957 break;
958 case IPCOMP_LZS:
959 case IPCOMP_LZJH:
960 default:
961 DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
962 "transform ID we don't support %N",
963 ipcomp_transform_names, ipcomp);
964 break;
965 }
966 break;
967 }
968 case ESP_TFC_PADDING_NOT_SUPPORTED:
969 DBG1(DBG_IKE, "received %N, not using ESPv3 TFC padding",
970 notify_type_names, notify->get_notify_type(notify));
971 this->tfcv3 = FALSE;
972 break;
973 default:
974 break;
975 }
976 }
977
978 /**
979 * Read payloads from message
980 */
981 static void process_payloads(private_child_create_t *this, message_t *message)
982 {
983 enumerator_t *enumerator;
984 payload_t *payload;
985 sa_payload_t *sa_payload;
986 ke_payload_t *ke_payload;
987 ts_payload_t *ts_payload;
988
989 /* defaults to TUNNEL mode */
990 this->mode = MODE_TUNNEL;
991
992 enumerator = message->create_payload_enumerator(message);
993 while (enumerator->enumerate(enumerator, &payload))
994 {
995 switch (payload->get_type(payload))
996 {
997 case PLV2_SECURITY_ASSOCIATION:
998 sa_payload = (sa_payload_t*)payload;
999 this->proposals = sa_payload->get_proposals(sa_payload);
1000 break;
1001 case PLV2_KEY_EXCHANGE:
1002 ke_payload = (ke_payload_t*)payload;
1003 if (!this->initiator)
1004 {
1005 this->dh_group = ke_payload->get_dh_group_number(ke_payload);
1006 this->dh = this->keymat->keymat.create_dh(
1007 &this->keymat->keymat, this->dh_group);
1008 }
1009 else if (this->dh)
1010 {
1011 this->dh_failed = this->dh->get_dh_group(this->dh) !=
1012 ke_payload->get_dh_group_number(ke_payload);
1013 }
1014 if (this->dh && !this->dh_failed)
1015 {
1016 this->dh_failed = !this->dh->set_other_public_value(this->dh,
1017 ke_payload->get_key_exchange_data(ke_payload));
1018 }
1019 break;
1020 case PLV2_TS_INITIATOR:
1021 ts_payload = (ts_payload_t*)payload;
1022 this->tsi = ts_payload->get_traffic_selectors(ts_payload);
1023 break;
1024 case PLV2_TS_RESPONDER:
1025 ts_payload = (ts_payload_t*)payload;
1026 this->tsr = ts_payload->get_traffic_selectors(ts_payload);
1027 break;
1028 case PLV2_NOTIFY:
1029 handle_notify(this, (notify_payload_t*)payload);
1030 break;
1031 default:
1032 break;
1033 }
1034 }
1035 enumerator->destroy(enumerator);
1036 }
1037
1038 METHOD(task_t, build_i, status_t,
1039 private_child_create_t *this, message_t *message)
1040 {
1041 enumerator_t *enumerator;
1042 host_t *vip;
1043 peer_cfg_t *peer_cfg;
1044 linked_list_t *list;
1045
1046 switch (message->get_exchange_type(message))
1047 {
1048 case IKE_SA_INIT:
1049 return get_nonce(message, &this->my_nonce);
1050 case CREATE_CHILD_SA:
1051 if (!generate_nonce(this))
1052 {
1053 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1054 chunk_empty);
1055 return SUCCESS;
1056 }
1057 if (!this->retry && this->dh_group == MODP_NONE)
1058 { /* during a rekeying the group might already be set */
1059 this->dh_group = this->config->get_dh_group(this->config);
1060 }
1061 break;
1062 case IKE_AUTH:
1063 if (message->get_message_id(message) != 1)
1064 {
1065 /* send only in the first request, not in subsequent rounds */
1066 return NEED_MORE;
1067 }
1068 break;
1069 default:
1070 break;
1071 }
1072
1073 /* check if we want a virtual IP, but don't have one */
1074 list = linked_list_create();
1075 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1076 if (!this->rekey)
1077 {
1078 enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
1079 while (enumerator->enumerate(enumerator, &vip))
1080 {
1081 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
1082 vip = host_create_any(vip->get_family(vip));
1083 list->insert_last(list, vip);
1084 }
1085 enumerator->destroy(enumerator);
1086 }
1087 if (list->get_count(list))
1088 {
1089 this->tsi = this->config->get_traffic_selectors(this->config,
1090 TRUE, NULL, list, TRUE);
1091 list->destroy_offset(list, offsetof(host_t, destroy));
1092 }
1093 else
1094 { /* no virtual IPs configured */
1095 list->destroy(list);
1096 list = get_dynamic_hosts(this->ike_sa, TRUE);
1097 this->tsi = this->config->get_traffic_selectors(this->config,
1098 TRUE, NULL, list, TRUE);
1099 list->destroy(list);
1100 }
1101 list = get_dynamic_hosts(this->ike_sa, FALSE);
1102 this->tsr = this->config->get_traffic_selectors(this->config,
1103 FALSE, NULL, list, TRUE);
1104 list->destroy(list);
1105
1106 if (this->packet_tsi)
1107 {
1108 this->tsi->insert_first(this->tsi,
1109 this->packet_tsi->clone(this->packet_tsi));
1110 }
1111 if (this->packet_tsr)
1112 {
1113 this->tsr->insert_first(this->tsr,
1114 this->packet_tsr->clone(this->packet_tsr));
1115 }
1116 this->proposals = this->config->get_proposals(this->config,
1117 this->dh_group == MODP_NONE);
1118 this->mode = this->config->get_mode(this->config);
1119
1120 this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
1121 this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
1122 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
1123 this->mark_in, this->mark_out, this->if_id_in, this->if_id_out);
1124
1125 if (this->reqid)
1126 {
1127 DBG0(DBG_IKE, "establishing CHILD_SA %s{%d} reqid %d",
1128 this->child_sa->get_name(this->child_sa),
1129 this->child_sa->get_unique_id(this->child_sa), this->reqid);
1130 }
1131 else
1132 {
1133 DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
1134 this->child_sa->get_name(this->child_sa),
1135 this->child_sa->get_unique_id(this->child_sa));
1136 }
1137
1138 if (!allocate_spi(this))
1139 {
1140 DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
1141 return FAILED;
1142 }
1143
1144 if (!update_and_check_proposals(this))
1145 {
1146 DBG1(DBG_IKE, "requested DH group %N not contained in any of our "
1147 "proposals",
1148 diffie_hellman_group_names, this->dh_group);
1149 return FAILED;
1150 }
1151
1152 if (this->dh_group != MODP_NONE)
1153 {
1154 this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
1155 this->dh_group);
1156 }
1157
1158 if (this->config->has_option(this->config, OPT_IPCOMP))
1159 {
1160 /* IPCOMP_DEFLATE is the only transform we support at the moment */
1161 add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
1162 }
1163
1164 if (message->get_exchange_type(message) == IKE_AUTH)
1165 {
1166 charon->bus->narrow(charon->bus, this->child_sa,
1167 NARROW_INITIATOR_PRE_NOAUTH, this->tsi, this->tsr);
1168 }
1169 else
1170 {
1171 charon->bus->narrow(charon->bus, this->child_sa,
1172 NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr);
1173 }
1174
1175 if (!build_payloads(this, message))
1176 {
1177 return FAILED;
1178 }
1179
1180 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1181 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1182 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1183 this->tsi = NULL;
1184 this->tsr = NULL;
1185 this->proposals = NULL;
1186
1187 return NEED_MORE;
1188 }
1189
1190 METHOD(task_t, process_r, status_t,
1191 private_child_create_t *this, message_t *message)
1192 {
1193 switch (message->get_exchange_type(message))
1194 {
1195 case IKE_SA_INIT:
1196 return get_nonce(message, &this->other_nonce);
1197 case CREATE_CHILD_SA:
1198 get_nonce(message, &this->other_nonce);
1199 break;
1200 case IKE_AUTH:
1201 if (message->get_message_id(message) != 1)
1202 {
1203 /* only handle first AUTH payload, not additional rounds */
1204 return NEED_MORE;
1205 }
1206 default:
1207 break;
1208 }
1209
1210 process_payloads(this, message);
1211
1212 return NEED_MORE;
1213 }
1214
1215 /**
1216 * handle CHILD_SA setup failure
1217 */
1218 static void handle_child_sa_failure(private_child_create_t *this,
1219 message_t *message)
1220 {
1221 bool is_first;
1222
1223 is_first = message->get_exchange_type(message) == IKE_AUTH;
1224 if (is_first &&
1225 lib->settings->get_bool(lib->settings,
1226 "%s.close_ike_on_child_failure", FALSE, lib->ns))
1227 {
1228 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
1229 * first */
1230 DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
1231 lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
1232 delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
1233 100);
1234 }
1235 else
1236 {
1237 DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
1238 charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE,
1239 is_first);
1240 }
1241 }
1242
1243 /**
1244 * Substitute transport mode NAT selectors, if applicable
1245 */
1246 static linked_list_t* get_ts_if_nat_transport(private_child_create_t *this,
1247 bool local, linked_list_t *in)
1248 {
1249 linked_list_t *out = NULL;
1250 ike_condition_t cond;
1251
1252 if (this->mode == MODE_TRANSPORT)
1253 {
1254 cond = local ? COND_NAT_HERE : COND_NAT_THERE;
1255 if (this->ike_sa->has_condition(this->ike_sa, cond))
1256 {
1257 out = get_transport_nat_ts(this, local, in);
1258 if (out->get_count(out) == 0)
1259 {
1260 out->destroy(out);
1261 out = NULL;
1262 }
1263 }
1264 }
1265 return out;
1266 }
1267
1268 /**
1269 * Select a matching CHILD config as responder
1270 */
1271 static child_cfg_t* select_child_cfg(private_child_create_t *this)
1272 {
1273 peer_cfg_t *peer_cfg;
1274 child_cfg_t *child_cfg = NULL;;
1275
1276 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1277 if (peer_cfg && this->tsi && this->tsr)
1278 {
1279 linked_list_t *listr, *listi, *tsr, *tsi;
1280
1281 tsr = get_ts_if_nat_transport(this, TRUE, this->tsr);
1282 tsi = get_ts_if_nat_transport(this, FALSE, this->tsi);
1283
1284 listr = get_dynamic_hosts(this->ike_sa, TRUE);
1285 listi = get_dynamic_hosts(this->ike_sa, FALSE);
1286 child_cfg = peer_cfg->select_child_cfg(peer_cfg,
1287 tsr ?: this->tsr, tsi ?: this->tsi,
1288 listr, listi);
1289 if ((tsi || tsr) && child_cfg &&
1290 child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
1291 {
1292 /* found a CHILD config, but it doesn't use transport mode */
1293 child_cfg->destroy(child_cfg);
1294 child_cfg = NULL;
1295 }
1296 if (!child_cfg && (tsi || tsr))
1297 {
1298 /* no match for the substituted NAT selectors, try it without */
1299 child_cfg = peer_cfg->select_child_cfg(peer_cfg,
1300 this->tsr, this->tsi, listr, listi);
1301 }
1302 listr->destroy(listr);
1303 listi->destroy(listi);
1304 DESTROY_OFFSET_IF(tsi, offsetof(traffic_selector_t, destroy));
1305 DESTROY_OFFSET_IF(tsr, offsetof(traffic_selector_t, destroy));
1306 }
1307
1308 return child_cfg;
1309 }
1310
1311 METHOD(task_t, build_r, status_t,
1312 private_child_create_t *this, message_t *message)
1313 {
1314 payload_t *payload;
1315 enumerator_t *enumerator;
1316 bool no_dh = TRUE, ike_auth = FALSE;
1317
1318 switch (message->get_exchange_type(message))
1319 {
1320 case IKE_SA_INIT:
1321 return get_nonce(message, &this->my_nonce);
1322 case CREATE_CHILD_SA:
1323 if (!generate_nonce(this))
1324 {
1325 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1326 chunk_empty);
1327 return SUCCESS;
1328 }
1329 if (this->dh_failed)
1330 {
1331 DBG1(DBG_IKE, "applying DH public value failed");
1332 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1333 chunk_empty);
1334 return SUCCESS;
1335 }
1336 no_dh = FALSE;
1337 break;
1338 case IKE_AUTH:
1339 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1340 { /* wait until all authentication round completed */
1341 return NEED_MORE;
1342 }
1343 if (this->ike_sa->has_condition(this->ike_sa, COND_REDIRECTED))
1344 { /* no CHILD_SA is created for redirected SAs */
1345 return SUCCESS;
1346 }
1347 ike_auth = TRUE;
1348 default:
1349 break;
1350 }
1351
1352 if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
1353 {
1354 DBG1(DBG_IKE, "unable to create CHILD_SA while rekeying IKE_SA");
1355 message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
1356 return SUCCESS;
1357 }
1358 if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
1359 {
1360 DBG1(DBG_IKE, "unable to create CHILD_SA while deleting IKE_SA");
1361 message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
1362 return SUCCESS;
1363 }
1364
1365 if (this->config == NULL)
1366 {
1367 this->config = select_child_cfg(this);
1368 }
1369 if (this->config == NULL)
1370 {
1371 DBG1(DBG_IKE, "traffic selectors %#R === %#R unacceptable",
1372 this->tsr, this->tsi);
1373 charon->bus->alert(charon->bus, ALERT_TS_MISMATCH, this->tsi, this->tsr);
1374 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
1375 handle_child_sa_failure(this, message);
1376 return SUCCESS;
1377 }
1378
1379 /* check if ike_config_t included non-critical error notifies */
1380 enumerator = message->create_payload_enumerator(message);
1381 while (enumerator->enumerate(enumerator, &payload))
1382 {
1383 if (payload->get_type(payload) == PLV2_NOTIFY)
1384 {
1385 notify_payload_t *notify = (notify_payload_t*)payload;
1386
1387 switch (notify->get_notify_type(notify))
1388 {
1389 case INTERNAL_ADDRESS_FAILURE:
1390 case FAILED_CP_REQUIRED:
1391 {
1392 DBG1(DBG_IKE,"configuration payload negotiation "
1393 "failed, no CHILD_SA built");
1394 enumerator->destroy(enumerator);
1395 handle_child_sa_failure(this, message);
1396 return SUCCESS;
1397 }
1398 default:
1399 break;
1400 }
1401 }
1402 }
1403 enumerator->destroy(enumerator);
1404
1405 this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
1406 this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
1407 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
1408 this->mark_in, this->mark_out, this->if_id_in, this->if_id_out);
1409
1410 if (this->ipcomp_received != IPCOMP_NONE)
1411 {
1412 if (this->config->has_option(this->config, OPT_IPCOMP))
1413 {
1414 add_ipcomp_notify(this, message, this->ipcomp_received);
1415 }
1416 else
1417 {
1418 DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
1419 notify_type_names, IPCOMP_SUPPORTED);
1420 }
1421 }
1422
1423 switch (select_and_install(this, no_dh, ike_auth))
1424 {
1425 case SUCCESS:
1426 break;
1427 case NOT_FOUND:
1428 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
1429 handle_child_sa_failure(this, message);
1430 return SUCCESS;
1431 case INVALID_ARG:
1432 {
1433 uint16_t group = htons(this->dh_group);
1434 message->add_notify(message, FALSE, INVALID_KE_PAYLOAD,
1435 chunk_from_thing(group));
1436 return SUCCESS;
1437 }
1438 case FAILED:
1439 default:
1440 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
1441 handle_child_sa_failure(this, message);
1442 return SUCCESS;
1443 }
1444
1445 if (!build_payloads(this, message))
1446 {
1447 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
1448 handle_child_sa_failure(this, message);
1449 return SUCCESS;
1450 }
1451
1452 if (!this->rekey)
1453 { /* invoke the child_up() hook if we are not rekeying */
1454 charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1455 }
1456 return SUCCESS;
1457 }
1458
1459 /**
1460 * Raise alerts for received notify errors
1461 */
1462 static void raise_alerts(private_child_create_t *this, notify_type_t type)
1463 {
1464 linked_list_t *list;
1465
1466 switch (type)
1467 {
1468 case NO_PROPOSAL_CHOSEN:
1469 list = this->config->get_proposals(this->config, FALSE);
1470 charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD, list);
1471 list->destroy_offset(list, offsetof(proposal_t, destroy));
1472 break;
1473 default:
1474 break;
1475 }
1476 }
1477
1478 METHOD(task_t, build_i_delete, status_t,
1479 private_child_create_t *this, message_t *message)
1480 {
1481 message->set_exchange_type(message, INFORMATIONAL);
1482 if (this->my_spi && this->proto)
1483 {
1484 delete_payload_t *del;
1485
1486 del = delete_payload_create(PLV2_DELETE, this->proto);
1487 del->add_spi(del, this->my_spi);
1488 message->add_payload(message, (payload_t*)del);
1489
1490 DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x",
1491 protocol_id_names, this->proto, ntohl(this->my_spi));
1492 }
1493 return NEED_MORE;
1494 }
1495
1496 /**
1497 * Change task to delete the failed CHILD_SA as initiator
1498 */
1499 static status_t delete_failed_sa(private_child_create_t *this)
1500 {
1501 if (this->my_spi && this->proto)
1502 {
1503 this->public.task.build = _build_i_delete;
1504 this->public.task.process = (void*)return_success;
1505 return NEED_MORE;
1506 }
1507 return SUCCESS;
1508 }
1509
1510 METHOD(task_t, process_i, status_t,
1511 private_child_create_t *this, message_t *message)
1512 {
1513 enumerator_t *enumerator;
1514 payload_t *payload;
1515 bool no_dh = TRUE, ike_auth = FALSE;
1516
1517 switch (message->get_exchange_type(message))
1518 {
1519 case IKE_SA_INIT:
1520 return get_nonce(message, &this->other_nonce);
1521 case CREATE_CHILD_SA:
1522 get_nonce(message, &this->other_nonce);
1523 no_dh = FALSE;
1524 break;
1525 case IKE_AUTH:
1526 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1527 { /* wait until all authentication round completed */
1528 return NEED_MORE;
1529 }
1530 ike_auth = TRUE;
1531 default:
1532 break;
1533 }
1534
1535 /* check for erroneous notifies */
1536 enumerator = message->create_payload_enumerator(message);
1537 while (enumerator->enumerate(enumerator, &payload))
1538 {
1539 if (payload->get_type(payload) == PLV2_NOTIFY)
1540 {
1541 notify_payload_t *notify = (notify_payload_t*)payload;
1542 notify_type_t type = notify->get_notify_type(notify);
1543
1544 switch (type)
1545 {
1546 /* handle notify errors related to CHILD_SA only */
1547 case NO_PROPOSAL_CHOSEN:
1548 case SINGLE_PAIR_REQUIRED:
1549 case NO_ADDITIONAL_SAS:
1550 case INTERNAL_ADDRESS_FAILURE:
1551 case FAILED_CP_REQUIRED:
1552 case TS_UNACCEPTABLE:
1553 case INVALID_SELECTORS:
1554 {
1555 DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
1556 notify_type_names, type);
1557 enumerator->destroy(enumerator);
1558 raise_alerts(this, type);
1559 handle_child_sa_failure(this, message);
1560 /* an error in CHILD_SA creation is not critical */
1561 return SUCCESS;
1562 }
1563 case TEMPORARY_FAILURE:
1564 {
1565 DBG1(DBG_IKE, "received %N notify, will retry later",
1566 notify_type_names, type);
1567 enumerator->destroy(enumerator);
1568 if (!this->rekey)
1569 { /* the rekey task will retry itself if necessary */
1570 schedule_delayed_retry(this);
1571 }
1572 return SUCCESS;
1573 }
1574 case INVALID_KE_PAYLOAD:
1575 {
1576 chunk_t data;
1577 uint16_t group = MODP_NONE;
1578
1579 data = notify->get_notification_data(notify);
1580 if (data.len == sizeof(group))
1581 {
1582 memcpy(&group, data.ptr, data.len);
1583 group = ntohs(group);
1584 }
1585 if (this->retry)
1586 {
1587 DBG1(DBG_IKE, "already retried with DH group %N, "
1588 "ignore requested %N", diffie_hellman_group_names,
1589 this->dh_group, diffie_hellman_group_names, group);
1590 handle_child_sa_failure(this, message);
1591 /* an error in CHILD_SA creation is not critical */
1592 return SUCCESS;
1593 }
1594 DBG1(DBG_IKE, "peer didn't accept DH group %N, "
1595 "it requested %N", diffie_hellman_group_names,
1596 this->dh_group, diffie_hellman_group_names, group);
1597 this->retry = TRUE;
1598 this->dh_group = group;
1599 this->child_sa->set_state(this->child_sa, CHILD_RETRYING);
1600 this->public.task.migrate(&this->public.task, this->ike_sa);
1601 enumerator->destroy(enumerator);
1602 return NEED_MORE;
1603 }
1604 default:
1605 {
1606 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
1607 { /* handle notifies if not handled in IKE_AUTH */
1608 if (type <= 16383)
1609 {
1610 DBG1(DBG_IKE, "received %N notify error",
1611 notify_type_names, type);
1612 enumerator->destroy(enumerator);
1613 return SUCCESS;
1614 }
1615 DBG2(DBG_IKE, "received %N notify",
1616 notify_type_names, type);
1617 }
1618 break;
1619 }
1620 }
1621 }
1622 }
1623 enumerator->destroy(enumerator);
1624
1625 process_payloads(this, message);
1626
1627 if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
1628 {
1629 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify without requesting"
1630 " one, no CHILD_SA built");
1631 handle_child_sa_failure(this, message);
1632 return delete_failed_sa(this);
1633 }
1634 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
1635 {
1636 DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
1637 "IPComp is disabled");
1638 this->ipcomp = IPCOMP_NONE;
1639 }
1640 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
1641 {
1642 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1643 "no CHILD_SA built");
1644 handle_child_sa_failure(this, message);
1645 return delete_failed_sa(this);
1646 }
1647
1648 if (this->dh_failed)
1649 {
1650 DBG1(DBG_IKE, "applying DH public value failed");
1651 handle_child_sa_failure(this, message);
1652 return delete_failed_sa(this);
1653 }
1654
1655 if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
1656 {
1657 if (!this->rekey)
1658 { /* invoke the child_up() hook if we are not rekeying */
1659 charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1660 }
1661 }
1662 else
1663 {
1664 handle_child_sa_failure(this, message);
1665 return delete_failed_sa(this);
1666 }
1667 return SUCCESS;
1668 }
1669
1670 METHOD(child_create_t, use_reqid, void,
1671 private_child_create_t *this, uint32_t reqid)
1672 {
1673 this->reqid = reqid;
1674 }
1675
1676 METHOD(child_create_t, use_marks, void,
1677 private_child_create_t *this, uint32_t in, uint32_t out)
1678 {
1679 this->mark_in = in;
1680 this->mark_out = out;
1681 }
1682
1683 METHOD(child_create_t, use_if_ids, void,
1684 private_child_create_t *this, uint32_t in, uint32_t out)
1685 {
1686 this->if_id_in = in;
1687 this->if_id_out = out;
1688 }
1689
1690 METHOD(child_create_t, use_dh_group, void,
1691 private_child_create_t *this, diffie_hellman_group_t dh_group)
1692 {
1693 this->dh_group = dh_group;
1694 }
1695
1696 METHOD(child_create_t, get_child, child_sa_t*,
1697 private_child_create_t *this)
1698 {
1699 return this->child_sa;
1700 }
1701
1702 METHOD(child_create_t, set_config, void,
1703 private_child_create_t *this, child_cfg_t *cfg)
1704 {
1705 DESTROY_IF(this->config);
1706 this->config = cfg;
1707 }
1708
1709 METHOD(child_create_t, get_lower_nonce, chunk_t,
1710 private_child_create_t *this)
1711 {
1712 if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
1713 min(this->my_nonce.len, this->other_nonce.len)) < 0)
1714 {
1715 return this->my_nonce;
1716 }
1717 else
1718 {
1719 return this->other_nonce;
1720 }
1721 }
1722
1723 METHOD(task_t, get_type, task_type_t,
1724 private_child_create_t *this)
1725 {
1726 return TASK_CHILD_CREATE;
1727 }
1728
1729 METHOD(task_t, migrate, void,
1730 private_child_create_t *this, ike_sa_t *ike_sa)
1731 {
1732 chunk_free(&this->my_nonce);
1733 chunk_free(&this->other_nonce);
1734 if (this->tsr)
1735 {
1736 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1737 }
1738 if (this->tsi)
1739 {
1740 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1741 }
1742 DESTROY_IF(this->child_sa);
1743 DESTROY_IF(this->proposal);
1744 DESTROY_IF(this->nonceg);
1745 DESTROY_IF(this->dh);
1746 this->dh_failed = FALSE;
1747 if (this->proposals)
1748 {
1749 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1750 }
1751
1752 this->ike_sa = ike_sa;
1753 this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
1754 this->proposal = NULL;
1755 this->proposals = NULL;
1756 this->tsi = NULL;
1757 this->tsr = NULL;
1758 this->dh = NULL;
1759 this->nonceg = NULL;
1760 this->child_sa = NULL;
1761 this->mode = MODE_TUNNEL;
1762 this->ipcomp = IPCOMP_NONE;
1763 this->ipcomp_received = IPCOMP_NONE;
1764 this->other_cpi = 0;
1765 this->reqid = 0;
1766 this->mark_in = 0;
1767 this->mark_out = 0;
1768 this->if_id_in = 0;
1769 this->if_id_out = 0;
1770 this->established = FALSE;
1771 }
1772
1773 METHOD(task_t, destroy, void,
1774 private_child_create_t *this)
1775 {
1776 chunk_free(&this->my_nonce);
1777 chunk_free(&this->other_nonce);
1778 if (this->tsr)
1779 {
1780 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1781 }
1782 if (this->tsi)
1783 {
1784 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1785 }
1786 if (!this->established)
1787 {
1788 DESTROY_IF(this->child_sa);
1789 }
1790 DESTROY_IF(this->packet_tsi);
1791 DESTROY_IF(this->packet_tsr);
1792 DESTROY_IF(this->proposal);
1793 DESTROY_IF(this->dh);
1794 if (this->proposals)
1795 {
1796 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1797 }
1798 DESTROY_IF(this->config);
1799 DESTROY_IF(this->nonceg);
1800 free(this);
1801 }
1802
1803 /*
1804 * Described in header.
1805 */
1806 child_create_t *child_create_create(ike_sa_t *ike_sa,
1807 child_cfg_t *config, bool rekey,
1808 traffic_selector_t *tsi, traffic_selector_t *tsr)
1809 {
1810 private_child_create_t *this;
1811
1812 INIT(this,
1813 .public = {
1814 .get_child = _get_child,
1815 .set_config = _set_config,
1816 .get_lower_nonce = _get_lower_nonce,
1817 .use_reqid = _use_reqid,
1818 .use_marks = _use_marks,
1819 .use_if_ids = _use_if_ids,
1820 .use_dh_group = _use_dh_group,
1821 .task = {
1822 .get_type = _get_type,
1823 .migrate = _migrate,
1824 .destroy = _destroy,
1825 },
1826 },
1827 .ike_sa = ike_sa,
1828 .config = config,
1829 .packet_tsi = tsi ? tsi->clone(tsi) : NULL,
1830 .packet_tsr = tsr ? tsr->clone(tsr) : NULL,
1831 .dh_group = MODP_NONE,
1832 .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
1833 .mode = MODE_TUNNEL,
1834 .tfcv3 = TRUE,
1835 .ipcomp = IPCOMP_NONE,
1836 .ipcomp_received = IPCOMP_NONE,
1837 .rekey = rekey,
1838 .retry = FALSE,
1839 );
1840
1841 if (config)
1842 {
1843 this->public.task.build = _build_i;
1844 this->public.task.process = _process_i;
1845 this->initiator = TRUE;
1846 }
1847 else
1848 {
1849 this->public.task.build = _build_r;
1850 this->public.task.process = _process_r;
1851 this->initiator = FALSE;
1852 }
1853 return &this->public;
1854 }