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