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