Removed strayed code fragment
[strongswan.git] / src / charon / 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 * IPComp transform to use
121 */
122 ipcomp_transform_t ipcomp;
123
124 /**
125 * IPComp transform proposed or accepted by the other peer
126 */
127 ipcomp_transform_t ipcomp_received;
128
129 /**
130 * Own allocated SPI
131 */
132 u_int32_t my_spi;
133
134 /**
135 * SPI received in proposal
136 */
137 u_int32_t other_spi;
138
139 /**
140 * Own allocated Compression Parameter Index (CPI)
141 */
142 u_int16_t my_cpi;
143
144 /**
145 * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
146 */
147 u_int16_t other_cpi;
148
149 /**
150 * reqid to use if we are rekeying
151 */
152 u_int32_t reqid;
153
154 /**
155 * CHILD_SA which gets established
156 */
157 child_sa_t *child_sa;
158
159 /**
160 * successfully established the CHILD?
161 */
162 bool established;
163
164 /**
165 * whether the CHILD_SA rekeys an existing one
166 */
167 bool rekey;
168 };
169
170 /**
171 * get the nonce from a message
172 */
173 static status_t get_nonce(message_t *message, chunk_t *nonce)
174 {
175 nonce_payload_t *payload;
176
177 payload = (nonce_payload_t*)message->get_payload(message, NONCE);
178 if (payload == NULL)
179 {
180 return FAILED;
181 }
182 *nonce = payload->get_nonce(payload);
183 return NEED_MORE;
184 }
185
186 /**
187 * generate a new nonce to include in a CREATE_CHILD_SA message
188 */
189 static status_t generate_nonce(chunk_t *nonce)
190 {
191 rng_t *rng;
192
193 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
194 if (!rng)
195 {
196 DBG1(DBG_IKE, "error generating nonce value, no RNG found");
197 return FAILED;
198 }
199 rng->allocate_bytes(rng, NONCE_SIZE, nonce);
200 rng->destroy(rng);
201 return SUCCESS;
202 }
203
204 /**
205 * Check a list of traffic selectors if any selector belongs to host
206 */
207 static bool ts_list_is_host(linked_list_t *list, host_t *host)
208 {
209 traffic_selector_t *ts;
210 bool is_host = TRUE;
211 iterator_t *iterator = list->create_iterator(list, TRUE);
212
213 while (is_host && iterator->iterate(iterator, (void**)&ts))
214 {
215 is_host = is_host && ts->is_host(ts, host);
216 }
217 iterator->destroy(iterator);
218 return is_host;
219 }
220
221 /**
222 * Allocate SPIs and update proposals
223 */
224 static bool allocate_spi(private_child_create_t *this)
225 {
226 enumerator_t *enumerator;
227 proposal_t *proposal;
228
229 /* TODO: allocate additional SPI for AH if we have such proposals */
230 this->my_spi = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP);
231 if (this->my_spi)
232 {
233 if (this->initiator)
234 {
235 enumerator = this->proposals->create_enumerator(this->proposals);
236 while (enumerator->enumerate(enumerator, &proposal))
237 {
238 proposal->set_spi(proposal, this->my_spi);
239 }
240 enumerator->destroy(enumerator);
241 }
242 else
243 {
244 this->proposal->set_spi(this->proposal, this->my_spi);
245 }
246 return TRUE;
247 }
248 return FALSE;
249 }
250
251 /**
252 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
253 */
254 static void schedule_inactivity_timeout(private_child_create_t *this)
255 {
256 u_int32_t timeout;
257 bool close_ike;
258
259 timeout = this->config->get_inactivity(this->config);
260 if (timeout)
261 {
262 close_ike = lib->settings->get_bool(lib->settings,
263 "charon.inactivity_close_ike", FALSE);
264 charon->scheduler->schedule_job(charon->scheduler, (job_t*)
265 inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
266 timeout, close_ike), timeout);
267 }
268 }
269
270 /**
271 * Install a CHILD_SA for usage, return value:
272 * - FAILED: no acceptable proposal
273 * - INVALID_ARG: diffie hellman group inacceptable
274 * - NOT_FOUND: TS inacceptable
275 */
276 static status_t select_and_install(private_child_create_t *this, bool no_dh)
277 {
278 status_t status, status_i, status_o;
279 chunk_t nonce_i, nonce_r;
280 chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
281 chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
282 linked_list_t *my_ts, *other_ts;
283 host_t *me, *other, *other_vip, *my_vip;
284 bool private;
285
286 if (this->proposals == NULL)
287 {
288 DBG1(DBG_IKE, "SA payload missing in message");
289 return FAILED;
290 }
291 if (this->tsi == NULL || this->tsr == NULL)
292 {
293 DBG1(DBG_IKE, "TS payloads missing in message");
294 return NOT_FOUND;
295 }
296
297 me = this->ike_sa->get_my_host(this->ike_sa);
298 other = this->ike_sa->get_other_host(this->ike_sa);
299 my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
300 other_vip = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
301
302 private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
303 this->proposal = this->config->select_proposal(this->config,
304 this->proposals, no_dh, private);
305 if (this->proposal == NULL)
306 {
307 DBG1(DBG_IKE, "no acceptable proposal found");
308 return FAILED;
309 }
310 this->other_spi = this->proposal->get_spi(this->proposal);
311
312 if (!this->initiator && !allocate_spi(this))
313 { /* responder has no SPI allocated yet */
314 DBG1(DBG_IKE, "allocating SPI failed");
315 return FAILED;
316 }
317 this->child_sa->set_proposal(this->child_sa, this->proposal);
318
319 if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
320 {
321 u_int16_t group;
322
323 if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
324 &group, NULL))
325 {
326 DBG1(DBG_IKE, "DH group %N inacceptable, requesting %N",
327 diffie_hellman_group_names, this->dh_group,
328 diffie_hellman_group_names, group);
329 this->dh_group = group;
330 return INVALID_ARG;
331 }
332 else
333 {
334 DBG1(DBG_IKE, "no acceptable proposal found");
335 return FAILED;
336 }
337 }
338
339 if (my_vip == NULL)
340 {
341 my_vip = me;
342 }
343 if (other_vip == NULL)
344 {
345 other_vip = other;
346 }
347
348 if (this->initiator)
349 {
350 nonce_i = this->my_nonce;
351 nonce_r = this->other_nonce;
352 my_ts = this->tsi;
353 other_ts = this->tsr;
354 }
355 else
356 {
357 nonce_r = this->my_nonce;
358 nonce_i = this->other_nonce;
359 my_ts = this->tsr;
360 other_ts = this->tsi;
361 }
362 my_ts = this->config->get_traffic_selectors(this->config, TRUE, my_ts,
363 my_vip);
364 other_ts = this->config->get_traffic_selectors(this->config, FALSE, other_ts,
365 other_vip);
366
367 if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
368 {
369 my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
370 other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
371 DBG1(DBG_IKE, "no acceptable traffic selectors found");
372 return NOT_FOUND;
373 }
374
375 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
376 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
377 if (this->initiator)
378 {
379 this->tsi = my_ts;
380 this->tsr = other_ts;
381 }
382 else
383 {
384 this->tsr = my_ts;
385 this->tsi = other_ts;
386 }
387
388 if (!this->initiator)
389 {
390 /* check if requested mode is acceptable, downgrade if required */
391 switch (this->mode)
392 {
393 case MODE_TRANSPORT:
394 if (!this->config->use_proxy_mode(this->config) &&
395 (!ts_list_is_host(this->tsi, other) ||
396 !ts_list_is_host(this->tsr, me))
397 )
398 {
399 this->mode = MODE_TUNNEL;
400 DBG1(DBG_IKE, "not using transport mode, not host-to-host");
401 }
402 else if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
403 {
404 this->mode = MODE_TUNNEL;
405 DBG1(DBG_IKE, "not using transport mode, connection NATed");
406 }
407 break;
408 case MODE_BEET:
409 if (!ts_list_is_host(this->tsi, NULL) ||
410 !ts_list_is_host(this->tsr, NULL))
411 {
412 this->mode = MODE_TUNNEL;
413 DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
414 }
415 break;
416 default:
417 break;
418 }
419 }
420
421 /* check for any certificate-based IP address block constraints */
422 if (this->mode == MODE_BEET || this->mode == MODE_TUNNEL)
423 {
424 auth_cfg_t *auth;
425 enumerator_t *auth_enum;
426 certificate_t *cert = NULL;
427
428 auth_enum = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, FALSE);
429 while (auth_enum->enumerate(auth_enum, &auth))
430 {
431 cert = auth->get(auth, AUTH_HELPER_SUBJECT_CERT);
432 if (cert)
433 {
434 break;
435 }
436 }
437 auth_enum->destroy(auth_enum);
438
439 if (cert && cert->get_type(cert) == CERT_X509)
440 {
441 x509_t *x509 = (x509_t*)cert;
442
443 if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS)
444 {
445 enumerator_t *enumerator, *block_enum;
446 traffic_selector_t *ts, *block_ts;
447
448 DBG1(DBG_IKE, "checking certificate-based traffic selector "
449 "constraints [RFC 3779]");
450 enumerator = other_ts->create_enumerator(other_ts);
451 while (enumerator->enumerate(enumerator, &ts))
452 {
453 bool contained = FALSE;
454
455 block_enum = x509->create_ipAddrBlock_enumerator(x509);
456 while (block_enum->enumerate(block_enum, &block_ts))
457 {
458 if (ts->is_contained_in(ts, block_ts))
459 {
460 DBG1(DBG_IKE, " TS %R is contained in address block"
461 " constraint %R", ts, block_ts);
462 contained = TRUE;
463 break;
464 }
465 }
466 block_enum->destroy(block_enum);
467
468 if (!contained)
469 {
470 DBG1(DBG_IKE, " TS %R is not contained in any"
471 " address block constraint", ts);
472 enumerator->destroy(enumerator);
473 return FAILED;
474 }
475 }
476 enumerator->destroy(enumerator);
477 }
478 }
479 }
480
481 this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
482 this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
483 this->child_sa->set_mode(this->child_sa, this->mode);
484 this->child_sa->set_protocol(this->child_sa,
485 this->proposal->get_protocol(this->proposal));
486
487 if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
488 {
489 this->my_cpi = this->other_cpi = 0;
490 this->ipcomp = IPCOMP_NONE;
491 }
492 status_i = status_o = FAILED;
493 if (this->keymat->derive_child_keys(this->keymat, this->proposal,
494 this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
495 {
496 if (this->initiator)
497 {
498 status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
499 this->my_spi, this->my_cpi, TRUE, my_ts, other_ts);
500 status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
501 this->other_spi, this->other_cpi, FALSE, my_ts, other_ts);
502 }
503 else
504 {
505 status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
506 this->my_spi, this->my_cpi, TRUE, my_ts, other_ts);
507 status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
508 this->other_spi, this->other_cpi, FALSE, my_ts, other_ts);
509 }
510 }
511 chunk_clear(&integ_i);
512 chunk_clear(&integ_r);
513 chunk_clear(&encr_i);
514 chunk_clear(&encr_r);
515
516 if (status_i != SUCCESS || status_o != SUCCESS)
517 {
518 DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
519 (status_i != SUCCESS) ? "inbound " : "",
520 (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
521 (status_o != SUCCESS) ? "outbound " : "");
522 return FAILED;
523 }
524
525 status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts);
526 if (status != SUCCESS)
527 {
528 DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
529 return NOT_FOUND;
530 }
531
532 charon->bus->child_keys(charon->bus, this->child_sa, this->dh,
533 nonce_i, nonce_r);
534
535 /* add to IKE_SA, and remove from task */
536 this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
537 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
538 this->established = TRUE;
539
540 if (!this->rekey)
541 { /* a rekeyed SA uses the same reqid, no need for a new job */
542 schedule_inactivity_timeout(this);
543 }
544 return SUCCESS;
545 }
546
547 /**
548 * build the payloads for the message
549 */
550 static void build_payloads(private_child_create_t *this, message_t *message)
551 {
552 sa_payload_t *sa_payload;
553 nonce_payload_t *nonce_payload;
554 ke_payload_t *ke_payload;
555 ts_payload_t *ts_payload;
556
557 /* add SA payload */
558 if (this->initiator)
559 {
560 sa_payload = sa_payload_create_from_proposal_list(this->proposals);
561 }
562 else
563 {
564 sa_payload = sa_payload_create_from_proposal(this->proposal);
565 }
566 message->add_payload(message, (payload_t*)sa_payload);
567
568 /* add nonce payload if not in IKE_AUTH */
569 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
570 {
571 nonce_payload = nonce_payload_create();
572 nonce_payload->set_nonce(nonce_payload, this->my_nonce);
573 message->add_payload(message, (payload_t*)nonce_payload);
574 }
575
576 /* diffie hellman exchange, if PFS enabled */
577 if (this->dh)
578 {
579 ke_payload = ke_payload_create_from_diffie_hellman(this->dh);
580 message->add_payload(message, (payload_t*)ke_payload);
581 }
582
583 /* add TSi/TSr payloads */
584 ts_payload = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
585 message->add_payload(message, (payload_t*)ts_payload);
586 ts_payload = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
587 message->add_payload(message, (payload_t*)ts_payload);
588
589 /* add a notify if we are not in tunnel mode */
590 switch (this->mode)
591 {
592 case MODE_TRANSPORT:
593 message->add_notify(message, FALSE, USE_TRANSPORT_MODE, chunk_empty);
594 break;
595 case MODE_BEET:
596 message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
597 break;
598 default:
599 break;
600 }
601 }
602
603 /**
604 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
605 */
606 static void add_ipcomp_notify(private_child_create_t *this,
607 message_t *message, u_int8_t ipcomp)
608 {
609 if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
610 {
611 DBG1(DBG_IKE, "IPComp is not supported if either peer is natted, "
612 "IPComp disabled");
613 return;
614 }
615
616 this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
617 if (this->my_cpi)
618 {
619 this->ipcomp = ipcomp;
620 message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
621 chunk_cata("cc", chunk_from_thing(this->my_cpi),
622 chunk_from_thing(ipcomp)));
623 }
624 else
625 {
626 DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
627 }
628 }
629
630 /**
631 * handle a received notify payload
632 */
633 static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
634 {
635 switch (notify->get_notify_type(notify))
636 {
637 case USE_TRANSPORT_MODE:
638 this->mode = MODE_TRANSPORT;
639 break;
640 case USE_BEET_MODE:
641 if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN))
642 { /* handle private use notify only if we know its meaning */
643 this->mode = MODE_BEET;
644 }
645 else
646 {
647 DBG1(DBG_IKE, "received a notify strongSwan uses for BEET "
648 "mode, but peer implementation unknown, skipped");
649 }
650 break;
651 case IPCOMP_SUPPORTED:
652 {
653 ipcomp_transform_t ipcomp;
654 u_int16_t cpi;
655 chunk_t data;
656
657 data = notify->get_notification_data(notify);
658 cpi = *(u_int16_t*)data.ptr;
659 ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
660 switch (ipcomp)
661 {
662 case IPCOMP_DEFLATE:
663 this->other_cpi = cpi;
664 this->ipcomp_received = ipcomp;
665 break;
666 case IPCOMP_LZS:
667 case IPCOMP_LZJH:
668 default:
669 DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
670 "transform ID we don't support %N",
671 ipcomp_transform_names, ipcomp);
672 break;
673 }
674 }
675 default:
676 break;
677 }
678 }
679
680 /**
681 * Read payloads from message
682 */
683 static void process_payloads(private_child_create_t *this, message_t *message)
684 {
685 enumerator_t *enumerator;
686 payload_t *payload;
687 sa_payload_t *sa_payload;
688 ke_payload_t *ke_payload;
689 ts_payload_t *ts_payload;
690
691 /* defaults to TUNNEL mode */
692 this->mode = MODE_TUNNEL;
693
694 enumerator = message->create_payload_enumerator(message);
695 while (enumerator->enumerate(enumerator, &payload))
696 {
697 switch (payload->get_type(payload))
698 {
699 case SECURITY_ASSOCIATION:
700 sa_payload = (sa_payload_t*)payload;
701 this->proposals = sa_payload->get_proposals(sa_payload);
702 break;
703 case KEY_EXCHANGE:
704 ke_payload = (ke_payload_t*)payload;
705 if (!this->initiator)
706 {
707 this->dh_group = ke_payload->get_dh_group_number(ke_payload);
708 this->dh = this->keymat->create_dh(this->keymat, this->dh_group);
709 }
710 if (this->dh)
711 {
712 this->dh->set_other_public_value(this->dh,
713 ke_payload->get_key_exchange_data(ke_payload));
714 }
715 break;
716 case TRAFFIC_SELECTOR_INITIATOR:
717 ts_payload = (ts_payload_t*)payload;
718 this->tsi = ts_payload->get_traffic_selectors(ts_payload);
719 break;
720 case TRAFFIC_SELECTOR_RESPONDER:
721 ts_payload = (ts_payload_t*)payload;
722 this->tsr = ts_payload->get_traffic_selectors(ts_payload);
723 break;
724 case NOTIFY:
725 handle_notify(this, (notify_payload_t*)payload);
726 break;
727 default:
728 break;
729 }
730 }
731 enumerator->destroy(enumerator);
732 }
733
734 /**
735 * Implementation of task_t.build for initiator
736 */
737 static status_t build_i(private_child_create_t *this, message_t *message)
738 {
739 host_t *me, *other, *vip;
740 peer_cfg_t *peer_cfg;
741
742 switch (message->get_exchange_type(message))
743 {
744 case IKE_SA_INIT:
745 return get_nonce(message, &this->my_nonce);
746 case CREATE_CHILD_SA:
747 if (generate_nonce(&this->my_nonce) != SUCCESS)
748 {
749 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
750 return SUCCESS;
751 }
752 if (this->dh_group == MODP_NONE)
753 {
754 this->dh_group = this->config->get_dh_group(this->config);
755 }
756 break;
757 case IKE_AUTH:
758 if (message->get_message_id(message) != 1)
759 {
760 /* send only in the first request, not in subsequent rounds */
761 return NEED_MORE;
762 }
763 break;
764 default:
765 break;
766 }
767
768 if (this->reqid)
769 {
770 DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
771 this->config->get_name(this->config), this->reqid);
772 }
773 else
774 {
775 DBG0(DBG_IKE, "establishing CHILD_SA %s",
776 this->config->get_name(this->config));
777 }
778
779 /* reuse virtual IP if we already have one */
780 me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
781 if (me == NULL)
782 {
783 me = this->ike_sa->get_my_host(this->ike_sa);
784 }
785 other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
786 if (other == NULL)
787 {
788 other = this->ike_sa->get_other_host(this->ike_sa);
789 }
790
791 /* check if we want a virtual IP, but don't have one */
792 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
793 vip = peer_cfg->get_virtual_ip(peer_cfg);
794 if (!this->reqid && vip)
795 {
796 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
797 vip = host_create_any(vip->get_family(vip));
798 this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
799 NULL, vip);
800 vip->destroy(vip);
801 }
802 else
803 { /* but narrow it for host2host / if we already have a vip */
804 this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
805 NULL, me);
806 }
807 this->tsr = this->config->get_traffic_selectors(this->config, FALSE,
808 NULL, other);
809
810 if (this->packet_tsi)
811 {
812 this->tsi->insert_first(this->tsi,
813 this->packet_tsi->clone(this->packet_tsi));
814 }
815 if (this->packet_tsr)
816 {
817 this->tsr->insert_first(this->tsr,
818 this->packet_tsr->clone(this->packet_tsr));
819 }
820 this->proposals = this->config->get_proposals(this->config,
821 this->dh_group == MODP_NONE);
822 this->mode = this->config->get_mode(this->config);
823 if (this->mode == MODE_TRANSPORT &&
824 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
825 {
826 this->mode = MODE_TUNNEL;
827 DBG1(DBG_IKE, "not using transport mode, connection NATed");
828 }
829
830 this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
831 this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
832 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
833
834 if (!allocate_spi(this))
835 {
836 DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
837 return FAILED;
838 }
839
840 if (this->dh_group != MODP_NONE)
841 {
842 this->dh = this->keymat->create_dh(this->keymat, this->dh_group);
843 }
844
845 if (this->config->use_ipcomp(this->config))
846 {
847 /* IPCOMP_DEFLATE is the only transform we support at the moment */
848 add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
849 }
850
851 build_payloads(this, message);
852
853 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
854 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
855 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
856 this->tsi = NULL;
857 this->tsr = NULL;
858 this->proposals = NULL;
859
860 return NEED_MORE;
861 }
862
863 /**
864 * Implementation of task_t.process for responder
865 */
866 static status_t process_r(private_child_create_t *this, message_t *message)
867 {
868 switch (message->get_exchange_type(message))
869 {
870 case IKE_SA_INIT:
871 return get_nonce(message, &this->other_nonce);
872 case CREATE_CHILD_SA:
873 get_nonce(message, &this->other_nonce);
874 break;
875 case IKE_AUTH:
876 if (message->get_message_id(message) != 1)
877 {
878 /* only handle first AUTH payload, not additional rounds */
879 return NEED_MORE;
880 }
881 default:
882 break;
883 }
884
885 process_payloads(this, message);
886
887 return NEED_MORE;
888 }
889
890 /**
891 * handle CHILD_SA setup failure
892 */
893 static void handle_child_sa_failure(private_child_create_t *this,
894 message_t *message)
895 {
896 if (message->get_exchange_type(message) == IKE_AUTH &&
897 lib->settings->get_bool(lib->settings,
898 "charon.close_ike_on_child_failure", FALSE))
899 {
900 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
901 * first */
902 DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
903 charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)
904 delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
905 100);
906 }
907 }
908
909 /**
910 * Implementation of task_t.build for responder
911 */
912 static status_t build_r(private_child_create_t *this, message_t *message)
913 {
914 peer_cfg_t *peer_cfg;
915 payload_t *payload;
916 enumerator_t *enumerator;
917 bool no_dh = TRUE;
918
919 switch (message->get_exchange_type(message))
920 {
921 case IKE_SA_INIT:
922 return get_nonce(message, &this->my_nonce);
923 case CREATE_CHILD_SA:
924 if (generate_nonce(&this->my_nonce) != SUCCESS)
925 {
926 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
927 chunk_empty);
928 return SUCCESS;
929 }
930 no_dh = FALSE;
931 break;
932 case IKE_AUTH:
933 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
934 { /* wait until all authentication round completed */
935 return NEED_MORE;
936 }
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 (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 negotation "
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))
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 /**
1061 * Implementation of task_t.process for initiator
1062 */
1063 static status_t process_i(private_child_create_t *this, message_t *message)
1064 {
1065 enumerator_t *enumerator;
1066 payload_t *payload;
1067 bool no_dh = TRUE;
1068
1069 switch (message->get_exchange_type(message))
1070 {
1071 case IKE_SA_INIT:
1072 return get_nonce(message, &this->other_nonce);
1073 case CREATE_CHILD_SA:
1074 get_nonce(message, &this->other_nonce);
1075 no_dh = FALSE;
1076 break;
1077 case IKE_AUTH:
1078 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1079 { /* wait until all authentication round completed */
1080 return NEED_MORE;
1081 }
1082 default:
1083 break;
1084 }
1085
1086 /* check for erronous notifies */
1087 enumerator = message->create_payload_enumerator(message);
1088 while (enumerator->enumerate(enumerator, &payload))
1089 {
1090 if (payload->get_type(payload) == NOTIFY)
1091 {
1092 notify_payload_t *notify = (notify_payload_t*)payload;
1093 notify_type_t type = notify->get_notify_type(notify);
1094
1095 switch (type)
1096 {
1097 /* handle notify errors related to CHILD_SA only */
1098 case NO_PROPOSAL_CHOSEN:
1099 case SINGLE_PAIR_REQUIRED:
1100 case NO_ADDITIONAL_SAS:
1101 case INTERNAL_ADDRESS_FAILURE:
1102 case FAILED_CP_REQUIRED:
1103 case TS_UNACCEPTABLE:
1104 case INVALID_SELECTORS:
1105 {
1106 DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
1107 notify_type_names, type);
1108 enumerator->destroy(enumerator);
1109 handle_child_sa_failure(this, message);
1110 /* an error in CHILD_SA creation is not critical */
1111 return SUCCESS;
1112 }
1113 case INVALID_KE_PAYLOAD:
1114 {
1115 chunk_t data;
1116 u_int16_t group = MODP_NONE;
1117
1118 data = notify->get_notification_data(notify);
1119 if (data.len == sizeof(group))
1120 {
1121 memcpy(&group, data.ptr, data.len);
1122 group = ntohs(group);
1123 }
1124 DBG1(DBG_IKE, "peer didn't accept DH group %N, "
1125 "it requested %N", diffie_hellman_group_names,
1126 this->dh_group, diffie_hellman_group_names, group);
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 break;
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) == 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 /**
1186 * Implementation of task_t.get_type
1187 */
1188 static task_type_t get_type(private_child_create_t *this)
1189 {
1190 return CHILD_CREATE;
1191 }
1192
1193 /**
1194 * Implementation of child_create_t.use_reqid
1195 */
1196 static void use_reqid(private_child_create_t *this, u_int32_t reqid)
1197 {
1198 this->reqid = reqid;
1199 }
1200
1201 /**
1202 * Implementation of child_create_t.get_child
1203 */
1204 static child_sa_t* get_child(private_child_create_t *this)
1205 {
1206 return this->child_sa;
1207 }
1208
1209 /**
1210 * Implementation of child_create_t.get_lower_nonce
1211 */
1212 static chunk_t get_lower_nonce(private_child_create_t *this)
1213 {
1214 if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
1215 min(this->my_nonce.len, this->other_nonce.len)) < 0)
1216 {
1217 return this->my_nonce;
1218 }
1219 else
1220 {
1221 return this->other_nonce;
1222 }
1223 }
1224
1225 /**
1226 * Implementation of task_t.migrate
1227 */
1228 static void migrate(private_child_create_t *this, ike_sa_t *ike_sa)
1229 {
1230 chunk_free(&this->my_nonce);
1231 chunk_free(&this->other_nonce);
1232 if (this->tsi)
1233 {
1234 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1235 }
1236 if (this->tsr)
1237 {
1238 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1239 }
1240 DESTROY_IF(this->child_sa);
1241 DESTROY_IF(this->proposal);
1242 DESTROY_IF(this->dh);
1243 if (this->proposals)
1244 {
1245 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1246 }
1247
1248 this->ike_sa = ike_sa;
1249 this->keymat = ike_sa->get_keymat(ike_sa);
1250 this->proposal = NULL;
1251 this->proposals = NULL;
1252 this->tsi = NULL;
1253 this->tsr = NULL;
1254 this->dh = NULL;
1255 this->child_sa = NULL;
1256 this->mode = MODE_TUNNEL;
1257 this->ipcomp = IPCOMP_NONE;
1258 this->ipcomp_received = IPCOMP_NONE;
1259 this->other_cpi = 0;
1260 this->reqid = 0;
1261 this->established = FALSE;
1262 }
1263
1264 /**
1265 * Implementation of task_t.destroy
1266 */
1267 static void destroy(private_child_create_t *this)
1268 {
1269 chunk_free(&this->my_nonce);
1270 chunk_free(&this->other_nonce);
1271 if (this->tsr)
1272 {
1273 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1274 }
1275 if (this->tsi)
1276 {
1277 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1278 }
1279 if (!this->established)
1280 {
1281 DESTROY_IF(this->child_sa);
1282 }
1283 DESTROY_IF(this->packet_tsi);
1284 DESTROY_IF(this->packet_tsr);
1285 DESTROY_IF(this->proposal);
1286 DESTROY_IF(this->dh);
1287 if (this->proposals)
1288 {
1289 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1290 }
1291
1292 DESTROY_IF(this->config);
1293 free(this);
1294 }
1295
1296 /*
1297 * Described in header.
1298 */
1299 child_create_t *child_create_create(ike_sa_t *ike_sa,
1300 child_cfg_t *config, bool rekey,
1301 traffic_selector_t *tsi, traffic_selector_t *tsr)
1302 {
1303 private_child_create_t *this = malloc_thing(private_child_create_t);
1304
1305 this->public.get_child = (child_sa_t*(*)(child_create_t*))get_child;
1306 this->public.get_lower_nonce = (chunk_t(*)(child_create_t*))get_lower_nonce;
1307 this->public.use_reqid = (void(*)(child_create_t*,u_int32_t))use_reqid;
1308 this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
1309 this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
1310 this->public.task.destroy = (void(*)(task_t*))destroy;
1311 if (config)
1312 {
1313 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
1314 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
1315 this->initiator = TRUE;
1316 config->get_ref(config);
1317 }
1318 else
1319 {
1320 this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
1321 this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
1322 this->initiator = FALSE;
1323 }
1324
1325 this->ike_sa = ike_sa;
1326 this->config = config;
1327 this->my_nonce = chunk_empty;
1328 this->other_nonce = chunk_empty;
1329 this->proposals = NULL;
1330 this->proposal = NULL;
1331 this->tsi = NULL;
1332 this->tsr = NULL;
1333 this->packet_tsi = tsi ? tsi->clone(tsi) : NULL;
1334 this->packet_tsr = tsr ? tsr->clone(tsr) : NULL;
1335 this->dh = NULL;
1336 this->dh_group = MODP_NONE;
1337 this->keymat = ike_sa->get_keymat(ike_sa);
1338 this->child_sa = NULL;
1339 this->mode = MODE_TUNNEL;
1340 this->ipcomp = IPCOMP_NONE;
1341 this->ipcomp_received = IPCOMP_NONE;
1342 this->my_spi = 0;
1343 this->other_spi = 0;
1344 this->my_cpi = 0;
1345 this->other_cpi = 0;
1346 this->reqid = 0;
1347 this->established = FALSE;
1348 this->rekey = rekey;
1349
1350 return &this->public;
1351 }