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