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