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