reintegrated bus-refactoring branch
[strongswan.git] / src / charon / sa / tasks / child_create.c
1 /*
2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2005-2007 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 * $Id$
18 */
19
20 #include "child_create.h"
21
22 #include <daemon.h>
23 #include <crypto/diffie_hellman.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
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 * optional diffie hellman exchange
91 */
92 diffie_hellman_t *dh;
93
94 /**
95 * group used for DH exchange
96 */
97 diffie_hellman_group_t dh_group;
98
99 /**
100 * mode the new CHILD_SA uses (transport/tunnel/beet)
101 */
102 ipsec_mode_t mode;
103
104 /**
105 * IPComp transform to use
106 */
107 ipcomp_transform_t ipcomp;
108
109 /**
110 * IPComp transform proposed or accepted by the other peer
111 */
112 ipcomp_transform_t ipcomp_received;
113
114 /**
115 * Other Compression Parameter Index (CPI)
116 */
117 u_int16_t other_cpi;
118
119 /**
120 * reqid to use if we are rekeying
121 */
122 u_int32_t reqid;
123
124 /**
125 * CHILD_SA which gets established
126 */
127 child_sa_t *child_sa;
128
129 /**
130 * successfully established the CHILD?
131 */
132 bool established;
133 };
134
135 /**
136 * get the nonce from a message
137 */
138 static status_t get_nonce(message_t *message, chunk_t *nonce)
139 {
140 nonce_payload_t *payload;
141
142 payload = (nonce_payload_t*)message->get_payload(message, NONCE);
143 if (payload == NULL)
144 {
145 return FAILED;
146 }
147 *nonce = payload->get_nonce(payload);
148 return NEED_MORE;
149 }
150
151 /**
152 * generate a new nonce to include in a CREATE_CHILD_SA message
153 */
154 static status_t generate_nonce(chunk_t *nonce)
155 {
156 rng_t *rng;
157
158 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
159 if (!rng)
160 {
161 DBG1(DBG_IKE, "error generating nonce value, no RNG found");
162 return FAILED;
163 }
164 rng->allocate_bytes(rng, NONCE_SIZE, nonce);
165 rng->destroy(rng);
166 return SUCCESS;
167 }
168
169 /**
170 * Check a list of traffic selectors if any selector belongs to host
171 */
172 static bool ts_list_is_host(linked_list_t *list, host_t *host)
173 {
174 traffic_selector_t *ts;
175 bool is_host = TRUE;
176 iterator_t *iterator = list->create_iterator(list, TRUE);
177
178 while (is_host && iterator->iterate(iterator, (void**)&ts))
179 {
180 is_host = is_host && ts->is_host(ts, host);
181 }
182 iterator->destroy(iterator);
183 return is_host;
184 }
185
186 /**
187 * Install a CHILD_SA for usage, return value:
188 * - FAILED: no acceptable proposal
189 * - INVALID_ARG: diffie hellman group inacceptable
190 * - NOT_FOUND: TS inacceptable
191 */
192 static status_t select_and_install(private_child_create_t *this, bool no_dh)
193 {
194 prf_plus_t *prf_plus;
195 status_t status;
196 chunk_t nonce_i, nonce_r, secret, seed;
197 linked_list_t *my_ts, *other_ts;
198 host_t *me, *other, *other_vip, *my_vip;
199
200 if (this->proposals == NULL)
201 {
202 DBG1(DBG_IKE, "SA payload missing in message");
203 return FAILED;
204 }
205 if (this->tsi == NULL || this->tsr == NULL)
206 {
207 DBG1(DBG_IKE, "TS payloads missing in message");
208 return NOT_FOUND;
209 }
210
211 if (this->initiator)
212 {
213 nonce_i = this->my_nonce;
214 nonce_r = this->other_nonce;
215 my_ts = this->tsi;
216 other_ts = this->tsr;
217 }
218 else
219 {
220 nonce_r = this->my_nonce;
221 nonce_i = this->other_nonce;
222 my_ts = this->tsr;
223 other_ts = this->tsi;
224 }
225
226 me = this->ike_sa->get_my_host(this->ike_sa);
227 other = this->ike_sa->get_other_host(this->ike_sa);
228 my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
229 other_vip = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
230
231 this->proposal = this->config->select_proposal(this->config, this->proposals,
232 no_dh);
233 if (this->proposal == NULL)
234 {
235 DBG1(DBG_IKE, "no acceptable proposal found");
236 return FAILED;
237 }
238
239 if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
240 {
241 u_int16_t group;
242
243 if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
244 &group, NULL))
245 {
246 DBG1(DBG_IKE, "DH group %N inacceptable, requesting %N",
247 diffie_hellman_group_names, this->dh_group,
248 diffie_hellman_group_names, group);
249 this->dh_group = group;
250 return INVALID_ARG;
251 }
252 else
253 {
254 DBG1(DBG_IKE, "no acceptable proposal found");
255 return FAILED;
256 }
257 }
258
259 if (my_vip == NULL)
260 {
261 my_vip = me;
262 }
263 else if (this->initiator)
264 {
265 /* to setup firewall rules correctly, CHILD_SA needs the virtual IP */
266 this->child_sa->set_virtual_ip(this->child_sa, my_vip);
267 }
268 if (other_vip == NULL)
269 {
270 other_vip = other;
271 }
272
273 my_ts = this->config->get_traffic_selectors(this->config, TRUE, my_ts,
274 my_vip);
275 other_ts = this->config->get_traffic_selectors(this->config, FALSE, other_ts,
276 other_vip);
277
278 if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
279 {
280 my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
281 other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
282 DBG1(DBG_IKE, "no acceptable traffic selectors found");
283 return NOT_FOUND;
284 }
285
286 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
287 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
288 if (this->initiator)
289 {
290 this->tsi = my_ts;
291 this->tsr = other_ts;
292 }
293 else
294 {
295 this->tsr = my_ts;
296 this->tsi = other_ts;
297 }
298
299 if (!this->initiator)
300 {
301 /* check if requested mode is acceptable, downgrade if required */
302 switch (this->mode)
303 {
304 case MODE_TRANSPORT:
305 if (!ts_list_is_host(this->tsi, other) ||
306 !ts_list_is_host(this->tsr, me))
307 {
308 this->mode = MODE_TUNNEL;
309 DBG1(DBG_IKE, "not using tranport mode, not host-to-host");
310 }
311 else if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
312 {
313 this->mode = MODE_TUNNEL;
314 DBG1(DBG_IKE, "not using tranport mode, connection NATed");
315 }
316 break;
317 case MODE_BEET:
318 if (!ts_list_is_host(this->tsi, NULL) ||
319 !ts_list_is_host(this->tsr, NULL))
320 {
321 this->mode = MODE_TUNNEL;
322 DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
323 }
324 break;
325 default:
326 break;
327 }
328 }
329
330 if (this->dh)
331 {
332 if (this->dh->get_shared_secret(this->dh, &secret) != SUCCESS)
333 {
334 DBG1(DBG_IKE, "DH exchange incomplete");
335 return FAILED;
336 }
337 DBG3(DBG_IKE, "DH secret %B", &secret);
338 seed = chunk_cata("mcc", secret, nonce_i, nonce_r);
339 }
340 else
341 {
342 seed = chunk_cata("cc", nonce_i, nonce_r);
343 }
344
345 if (this->ipcomp != IPCOMP_NONE)
346 {
347 this->child_sa->activate_ipcomp(this->child_sa, this->ipcomp,
348 this->other_cpi);
349 }
350
351 status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts,
352 this->mode, this->proposal->get_protocol(this->proposal));
353 if (status != SUCCESS)
354 {
355 DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
356 return NOT_FOUND;
357 }
358
359 prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
360 if (this->initiator)
361 {
362 status = this->child_sa->update(this->child_sa, this->proposal,
363 this->mode, prf_plus);
364 }
365 else
366 {
367 status = this->child_sa->add(this->child_sa, this->proposal,
368 this->mode, prf_plus);
369 }
370 prf_plus->destroy(prf_plus);
371
372 if (status != SUCCESS)
373 {
374 DBG1(DBG_IKE, "unable to install IPsec SA (SAD) in kernel");
375 return FAILED;
376 }
377 /* add to IKE_SA, and remove from task */
378 this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
379 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
380 this->established = TRUE;
381 return SUCCESS;
382 }
383
384 /**
385 * build the payloads for the message
386 */
387 static void build_payloads(private_child_create_t *this, message_t *message)
388 {
389 sa_payload_t *sa_payload;
390 nonce_payload_t *nonce_payload;
391 ke_payload_t *ke_payload;
392 ts_payload_t *ts_payload;
393
394 /* add SA payload */
395 if (this->initiator)
396 {
397 sa_payload = sa_payload_create_from_proposal_list(this->proposals);
398 }
399 else
400 {
401 sa_payload = sa_payload_create_from_proposal(this->proposal);
402 }
403 message->add_payload(message, (payload_t*)sa_payload);
404
405 /* add nonce payload if not in IKE_AUTH */
406 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
407 {
408 nonce_payload = nonce_payload_create();
409 nonce_payload->set_nonce(nonce_payload, this->my_nonce);
410 message->add_payload(message, (payload_t*)nonce_payload);
411 }
412
413 /* diffie hellman exchange, if PFS enabled */
414 if (this->dh)
415 {
416 ke_payload = ke_payload_create_from_diffie_hellman(this->dh);
417 message->add_payload(message, (payload_t*)ke_payload);
418 }
419
420 /* add TSi/TSr payloads */
421 ts_payload = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
422 message->add_payload(message, (payload_t*)ts_payload);
423 ts_payload = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
424 message->add_payload(message, (payload_t*)ts_payload);
425
426 /* add a notify if we are not in tunnel mode */
427 switch (this->mode)
428 {
429 case MODE_TRANSPORT:
430 message->add_notify(message, FALSE, USE_TRANSPORT_MODE, chunk_empty);
431 break;
432 case MODE_BEET:
433 message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
434 break;
435 default:
436 break;
437 }
438 }
439
440 /**
441 * Adds an IPCOMP_SUPPORTED notify to the message, if possible
442 */
443 static void build_ipcomp_supported_notify(private_child_create_t *this,
444 message_t *message)
445 {
446 u_int16_t cpi;
447 u_int8_t tid;
448
449 if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
450 {
451 DBG1(DBG_IKE, "IPComp is not supported if either peer is natted, "
452 "IPComp disabled");
453 this->ipcomp = IPCOMP_NONE;
454 return;
455 }
456
457 cpi = this->child_sa->allocate_cpi(this->child_sa);
458 tid = this->ipcomp;
459 if (cpi)
460 {
461 message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
462 chunk_cata("cc", chunk_from_thing(cpi), chunk_from_thing(tid)));
463 }
464 else
465 {
466 DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
467 this->ipcomp = IPCOMP_NONE;
468 }
469 }
470
471 /**
472 * Read payloads from message
473 */
474 static void process_payloads(private_child_create_t *this, message_t *message)
475 {
476 iterator_t *iterator;
477 payload_t *payload;
478 sa_payload_t *sa_payload;
479 ke_payload_t *ke_payload;
480 ts_payload_t *ts_payload;
481 notify_payload_t *notify_payload;
482
483 /* defaults to TUNNEL mode */
484 this->mode = MODE_TUNNEL;
485
486 iterator = message->get_payload_iterator(message);
487 while (iterator->iterate(iterator, (void**)&payload))
488 {
489 switch (payload->get_type(payload))
490 {
491 case SECURITY_ASSOCIATION:
492 sa_payload = (sa_payload_t*)payload;
493 this->proposals = sa_payload->get_proposals(sa_payload);
494 break;
495 case KEY_EXCHANGE:
496 ke_payload = (ke_payload_t*)payload;
497 if (!this->initiator)
498 {
499 this->dh_group = ke_payload->get_dh_group_number(ke_payload);
500 this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
501 }
502 if (this->dh)
503 {
504 this->dh->set_other_public_value(this->dh,
505 ke_payload->get_key_exchange_data(ke_payload));
506 }
507 break;
508 case TRAFFIC_SELECTOR_INITIATOR:
509 ts_payload = (ts_payload_t*)payload;
510 this->tsi = ts_payload->get_traffic_selectors(ts_payload);
511 break;
512 case TRAFFIC_SELECTOR_RESPONDER:
513 ts_payload = (ts_payload_t*)payload;
514 this->tsr = ts_payload->get_traffic_selectors(ts_payload);
515 break;
516 case NOTIFY:
517 notify_payload = (notify_payload_t*)payload;
518 switch (notify_payload ->get_notify_type(notify_payload ))
519 {
520 case USE_TRANSPORT_MODE:
521 this->mode = MODE_TRANSPORT;
522 break;
523 case USE_BEET_MODE:
524 this->mode = MODE_BEET;
525 break;
526 case IPCOMP_SUPPORTED:
527 {
528 chunk_t data = notify_payload->get_notification_data(notify_payload);
529 u_int16_t cpi = *(u_int16_t*)data.ptr;
530 ipcomp_transform_t ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
531 switch(ipcomp)
532 {
533 case IPCOMP_DEFLATE:
534 this->other_cpi = cpi;
535 this->ipcomp_received = ipcomp;
536 break;
537 case IPCOMP_LZS:
538 case IPCOMP_LZJH:
539 default:
540 DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a transform"
541 " ID we don't support %N", ipcomp_transform_names, ipcomp);
542 break;
543 }
544 }
545 default:
546 break;
547 }
548 break;
549 default:
550 break;
551 }
552 }
553 iterator->destroy(iterator);
554 }
555
556 /**
557 * Implementation of task_t.build for initiator
558 */
559 static status_t build_i(private_child_create_t *this, message_t *message)
560 {
561 host_t *me, *other, *vip;
562 bool propose_all = FALSE;
563 peer_cfg_t *peer_cfg;
564
565 switch (message->get_exchange_type(message))
566 {
567 case IKE_SA_INIT:
568 return get_nonce(message, &this->my_nonce);
569 case CREATE_CHILD_SA:
570 if (generate_nonce(&this->my_nonce) != SUCCESS)
571 {
572 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
573 return SUCCESS;
574 }
575 if (this->dh_group == MODP_NONE)
576 {
577 this->dh_group = this->config->get_dh_group(this->config);
578 }
579 break;
580 case IKE_AUTH:
581 if (!message->get_payload(message, ID_INITIATOR))
582 {
583 /* send only in the first request, not in subsequent EAP */
584 return NEED_MORE;
585 }
586 break;
587 default:
588 break;
589 }
590
591 if (this->reqid)
592 {
593 DBG1(DBG_IKE, "establishing CHILD_SA %s{%d}",
594 this->config->get_name(this->config), this->reqid);
595 }
596 else
597 {
598 DBG1(DBG_IKE, "establishing CHILD_SA %s",
599 this->config->get_name(this->config));
600 }
601
602 /* reuse virtual IP if we already have one */
603 me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
604 if (me == NULL)
605 {
606 me = this->ike_sa->get_my_host(this->ike_sa);
607 }
608 other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
609 if (other == NULL)
610 {
611 other = this->ike_sa->get_other_host(this->ike_sa);
612 }
613
614 /* check if we want a virtual IP, but don't have one */
615 if (!this->reqid)
616 {
617 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
618 vip = peer_cfg->get_virtual_ip(peer_cfg);
619 if (vip)
620 {
621 propose_all = TRUE;
622 }
623 }
624
625 if (propose_all)
626 { /* propose a 0.0.0.0/0 subnet when we use virtual ip */
627 this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
628 NULL, NULL);
629 }
630 else
631 { /* but shorten a 0.0.0.0/0 subnet for host2host/we already have a vip */
632 this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
633 NULL, me);
634 }
635 this->tsr = this->config->get_traffic_selectors(this->config, FALSE,
636 NULL, other);
637
638 this->proposals = this->config->get_proposals(this->config,
639 this->dh_group == MODP_NONE);
640 this->mode = this->config->get_mode(this->config);
641
642 this->child_sa = child_sa_create(
643 this->ike_sa->get_my_host(this->ike_sa),
644 this->ike_sa->get_other_host(this->ike_sa),
645 this->ike_sa->get_my_id(this->ike_sa),
646 this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
647 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
648
649 if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS)
650 {
651 DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
652 return FAILED;
653 }
654
655 if (this->dh_group != MODP_NONE)
656 {
657 this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
658 }
659
660 if (this->config->use_ipcomp(this->config)) {
661 /* IPCOMP_DEFLATE is the only transform we support at the moment */
662 this->ipcomp = IPCOMP_DEFLATE;
663 build_ipcomp_supported_notify(this, message);
664 }
665
666 build_payloads(this, message);
667
668 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
669 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
670 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
671 this->tsi = NULL;
672 this->tsr = NULL;
673 this->proposals = NULL;
674
675 return NEED_MORE;
676 }
677
678 /**
679 * Implementation of task_t.process for initiator
680 */
681 static status_t process_r(private_child_create_t *this, message_t *message)
682 {
683 peer_cfg_t *peer_cfg;
684
685 switch (message->get_exchange_type(message))
686 {
687 case IKE_SA_INIT:
688 return get_nonce(message, &this->other_nonce);
689 case CREATE_CHILD_SA:
690 get_nonce(message, &this->other_nonce);
691 break;
692 case IKE_AUTH:
693 if (message->get_payload(message, ID_INITIATOR) == NULL)
694 {
695 /* wait until extensible authentication completed, if used */
696 return NEED_MORE;
697 }
698 default:
699 break;
700 }
701
702 process_payloads(this, message);
703
704 if (this->tsi == NULL || this->tsr == NULL)
705 {
706 DBG1(DBG_IKE, "TS payload missing in message");
707 return NEED_MORE;
708 }
709
710 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
711 if (peer_cfg)
712 {
713 host_t *me, *other;
714
715 me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
716 if (me == NULL)
717 {
718 me = this->ike_sa->get_my_host(this->ike_sa);
719 }
720 other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
721 if (other == NULL)
722 {
723 other = this->ike_sa->get_other_host(this->ike_sa);
724 }
725
726 this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr,
727 this->tsi, me, other);
728 }
729 return NEED_MORE;
730 }
731
732 /**
733 * handle CHILD_SA setup failure
734 */
735 static void handle_child_sa_failure(private_child_create_t *this,
736 message_t *message)
737 {
738 if (message->get_exchange_type(message) == IKE_AUTH &&
739 lib->settings->get_bool(lib->settings,
740 "charon.close_ike_on_child_failure", FALSE))
741 {
742 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
743 * first */
744 DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
745 charon->scheduler->schedule_job(charon->scheduler, (job_t*)
746 delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
747 100);
748 }
749 }
750
751 /**
752 * Implementation of task_t.build for responder
753 */
754 static status_t build_r(private_child_create_t *this, message_t *message)
755 {
756 payload_t *payload;
757 iterator_t *iterator;
758 bool no_dh = TRUE;
759
760 switch (message->get_exchange_type(message))
761 {
762 case IKE_SA_INIT:
763 return get_nonce(message, &this->my_nonce);
764 case CREATE_CHILD_SA:
765 if (generate_nonce(&this->my_nonce) != SUCCESS)
766 {
767 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
768 chunk_empty);
769 return SUCCESS;
770 }
771 no_dh = FALSE;
772 break;
773 case IKE_AUTH:
774 if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
775 {
776 /* wait until extensible authentication completed, if used */
777 return NEED_MORE;
778 }
779 default:
780 break;
781 }
782
783 if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
784 {
785 DBG1(DBG_IKE, "unable to create CHILD_SA while rekeying IKE_SA");
786 message->add_notify(message, TRUE, NO_ADDITIONAL_SAS, chunk_empty);
787 return SUCCESS;
788 }
789
790 if (this->config == NULL)
791 {
792 DBG1(DBG_IKE, "traffic selectors %#R=== %#R inacceptable",
793 this->tsr, this->tsi);
794 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
795 handle_child_sa_failure(this, message);
796 return SUCCESS;
797 }
798
799 /* check if ike_config_t included non-critical error notifies */
800 iterator = message->get_payload_iterator(message);
801 while (iterator->iterate(iterator, (void**)&payload))
802 {
803 if (payload->get_type(payload) == NOTIFY)
804 {
805 notify_payload_t *notify = (notify_payload_t*)payload;
806
807 switch (notify->get_notify_type(notify))
808 {
809 case INTERNAL_ADDRESS_FAILURE:
810 case FAILED_CP_REQUIRED:
811 {
812 DBG1(DBG_IKE,"configuration payload negotation "
813 "failed, no CHILD_SA built");
814 iterator->destroy(iterator);
815 handle_child_sa_failure(this, message);
816 return SUCCESS;
817 }
818 default:
819 break;
820 }
821 }
822 }
823 iterator->destroy(iterator);
824
825 this->child_sa = child_sa_create(
826 this->ike_sa->get_my_host(this->ike_sa),
827 this->ike_sa->get_other_host(this->ike_sa),
828 this->ike_sa->get_my_id(this->ike_sa),
829 this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid,
830 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
831
832 if (this->config->use_ipcomp(this->config) &&
833 this->ipcomp_received != IPCOMP_NONE)
834 {
835 this->ipcomp = this->ipcomp_received;
836 build_ipcomp_supported_notify(this, message);
837 }
838 else if (this->ipcomp_received != IPCOMP_NONE)
839 {
840 DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
841 notify_type_names, IPCOMP_SUPPORTED);
842 }
843
844 switch (select_and_install(this, no_dh))
845 {
846 case SUCCESS:
847 break;
848 case NOT_FOUND:
849 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
850 handle_child_sa_failure(this, message);
851 return SUCCESS;
852 case INVALID_ARG:
853 {
854 u_int16_t group = htons(this->dh_group);
855 message->add_notify(message, FALSE, INVALID_KE_PAYLOAD,
856 chunk_from_thing(group));
857 handle_child_sa_failure(this, message);
858 return SUCCESS;
859 }
860 case FAILED:
861 default:
862 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
863 handle_child_sa_failure(this, message);
864 return SUCCESS;
865 }
866
867 build_payloads(this, message);
868
869 DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
870 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
871 this->child_sa->get_name(this->child_sa),
872 this->child_sa->get_reqid(this->child_sa),
873 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
874 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
875 this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
876 this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
877
878 return SUCCESS;
879 }
880
881 /**
882 * Implementation of task_t.process for initiator
883 */
884 static status_t process_i(private_child_create_t *this, message_t *message)
885 {
886 iterator_t *iterator;
887 payload_t *payload;
888 bool no_dh = TRUE;
889
890 switch (message->get_exchange_type(message))
891 {
892 case IKE_SA_INIT:
893 return get_nonce(message, &this->other_nonce);
894 case CREATE_CHILD_SA:
895 get_nonce(message, &this->other_nonce);
896 no_dh = FALSE;
897 break;
898 case IKE_AUTH:
899 if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
900 {
901 /* wait until extensible authentication completed, if used */
902 return NEED_MORE;
903 }
904 default:
905 break;
906 }
907
908 /* check for erronous notifies */
909 iterator = message->get_payload_iterator(message);
910 while (iterator->iterate(iterator, (void**)&payload))
911 {
912 if (payload->get_type(payload) == NOTIFY)
913 {
914 notify_payload_t *notify = (notify_payload_t*)payload;
915 notify_type_t type = notify->get_notify_type(notify);
916
917 switch (type)
918 {
919 /* handle notify errors related to CHILD_SA only */
920 case NO_PROPOSAL_CHOSEN:
921 case SINGLE_PAIR_REQUIRED:
922 case NO_ADDITIONAL_SAS:
923 case INTERNAL_ADDRESS_FAILURE:
924 case FAILED_CP_REQUIRED:
925 case TS_UNACCEPTABLE:
926 case INVALID_SELECTORS:
927 {
928 DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
929 notify_type_names, type);
930 iterator->destroy(iterator);
931 handle_child_sa_failure(this, message);
932 /* an error in CHILD_SA creation is not critical */
933 return SUCCESS;
934 }
935 case INVALID_KE_PAYLOAD:
936 {
937 chunk_t data;
938 diffie_hellman_group_t bad_group;
939
940 bad_group = this->dh_group;
941 data = notify->get_notification_data(notify);
942 this->dh_group = ntohs(*((u_int16_t*)data.ptr));
943 DBG1(DBG_IKE, "peer didn't accept DH group %N, "
944 "it requested %N", diffie_hellman_group_names,
945 bad_group, diffie_hellman_group_names, this->dh_group);
946
947 this->public.task.migrate(&this->public.task, this->ike_sa);
948 iterator->destroy(iterator);
949 return NEED_MORE;
950 }
951 default:
952 break;
953 }
954 }
955 }
956 iterator->destroy(iterator);
957
958 process_payloads(this, message);
959
960 if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
961 {
962 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify without requesting"
963 " one, no CHILD_SA built");
964 handle_child_sa_failure(this, message);
965 return SUCCESS;
966 }
967 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
968 {
969 DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
970 "IPComp is disabled");
971 this->ipcomp = IPCOMP_NONE;
972 }
973 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
974 {
975 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify we didn't propose, "
976 "no CHILD_SA built");
977 handle_child_sa_failure(this, message);
978 return SUCCESS;
979 }
980
981 if (select_and_install(this, no_dh) == SUCCESS)
982 {
983 DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
984 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
985 this->child_sa->get_name(this->child_sa),
986 this->child_sa->get_reqid(this->child_sa),
987 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
988 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
989 this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
990 this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
991 }
992 else
993 {
994 handle_child_sa_failure(this, message);
995 }
996 return SUCCESS;
997 }
998
999 /**
1000 * Implementation of task_t.get_type
1001 */
1002 static task_type_t get_type(private_child_create_t *this)
1003 {
1004 return CHILD_CREATE;
1005 }
1006
1007 /**
1008 * Implementation of child_create_t.use_reqid
1009 */
1010 static void use_reqid(private_child_create_t *this, u_int32_t reqid)
1011 {
1012 this->reqid = reqid;
1013 }
1014
1015 /**
1016 * Implementation of child_create_t.get_child
1017 */
1018 static child_sa_t* get_child(private_child_create_t *this)
1019 {
1020 return this->child_sa;
1021 }
1022
1023 /**
1024 * Implementation of child_create_t.get_lower_nonce
1025 */
1026 static chunk_t get_lower_nonce(private_child_create_t *this)
1027 {
1028 if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
1029 min(this->my_nonce.len, this->other_nonce.len)) < 0)
1030 {
1031 return this->my_nonce;
1032 }
1033 else
1034 {
1035 return this->other_nonce;
1036 }
1037 }
1038
1039 /**
1040 * Implementation of task_t.migrate
1041 */
1042 static void migrate(private_child_create_t *this, ike_sa_t *ike_sa)
1043 {
1044 chunk_free(&this->my_nonce);
1045 chunk_free(&this->other_nonce);
1046 if (this->tsi)
1047 {
1048 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1049 }
1050 if (this->tsr)
1051 {
1052 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1053 }
1054 DESTROY_IF(this->child_sa);
1055 DESTROY_IF(this->proposal);
1056 DESTROY_IF(this->dh);
1057 if (this->proposals)
1058 {
1059 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1060 }
1061
1062 this->ike_sa = ike_sa;
1063 this->proposals = NULL;
1064 this->tsi = NULL;
1065 this->tsr = NULL;
1066 this->dh = NULL;
1067 this->child_sa = NULL;
1068 this->mode = MODE_TUNNEL;
1069 this->ipcomp = IPCOMP_NONE;
1070 this->ipcomp_received = IPCOMP_NONE;
1071 this->other_cpi = 0;
1072 this->reqid = 0;
1073 this->established = FALSE;
1074 }
1075
1076 /**
1077 * Implementation of task_t.destroy
1078 */
1079 static void destroy(private_child_create_t *this)
1080 {
1081 chunk_free(&this->my_nonce);
1082 chunk_free(&this->other_nonce);
1083 if (this->tsi)
1084 {
1085 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1086 }
1087 if (this->tsr)
1088 {
1089 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1090 }
1091 if (!this->established)
1092 {
1093 DESTROY_IF(this->child_sa);
1094 }
1095 DESTROY_IF(this->proposal);
1096 DESTROY_IF(this->dh);
1097 if (this->proposals)
1098 {
1099 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1100 }
1101
1102 DESTROY_IF(this->config);
1103 free(this);
1104 }
1105
1106 /*
1107 * Described in header.
1108 */
1109 child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config)
1110 {
1111 private_child_create_t *this = malloc_thing(private_child_create_t);
1112
1113 this->public.get_child = (child_sa_t*(*)(child_create_t*))get_child;
1114 this->public.get_lower_nonce = (chunk_t(*)(child_create_t*))get_lower_nonce;
1115 this->public.use_reqid = (void(*)(child_create_t*,u_int32_t))use_reqid;
1116 this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
1117 this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
1118 this->public.task.destroy = (void(*)(task_t*))destroy;
1119 if (config)
1120 {
1121 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
1122 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
1123 this->initiator = TRUE;
1124 config->get_ref(config);
1125 }
1126 else
1127 {
1128 this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
1129 this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
1130 this->initiator = FALSE;
1131 }
1132
1133 this->ike_sa = ike_sa;
1134 this->config = config;
1135 this->my_nonce = chunk_empty;
1136 this->other_nonce = chunk_empty;
1137 this->proposals = NULL;
1138 this->proposal = NULL;
1139 this->tsi = NULL;
1140 this->tsr = NULL;
1141 this->dh = NULL;
1142 this->dh_group = MODP_NONE;
1143 this->child_sa = NULL;
1144 this->mode = MODE_TUNNEL;
1145 this->ipcomp = IPCOMP_NONE;
1146 this->ipcomp_received = IPCOMP_NONE;
1147 this->other_cpi = 0;
1148 this->reqid = 0;
1149 this->established = FALSE;
1150
1151 return &this->public;
1152 }