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