2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
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>.
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
18 #include "child_create.h"
22 #include <sa/ikev2/keymat_v2.h>
23 #include <crypto/diffie_hellman.h>
24 #include <credentials/certificates/x509.h>
25 #include <encoding/payloads/sa_payload.h>
26 #include <encoding/payloads/ke_payload.h>
27 #include <encoding/payloads/ts_payload.h>
28 #include <encoding/payloads/nonce_payload.h>
29 #include <encoding/payloads/notify_payload.h>
30 #include <processing/jobs/delete_ike_sa_job.h>
31 #include <processing/jobs/inactivity_job.h>
34 typedef struct private_child_create_t private_child_create_t
;
37 * Private members of a child_create_t task.
39 struct private_child_create_t
{
42 * Public methods and task_t interface.
44 child_create_t
public;
52 * Are we the initiator?
62 * nonce chosen by peer
67 * config to create the CHILD_SA from
72 * list of proposal candidates
74 linked_list_t
*proposals
;
77 * selected proposal to use for CHILD_SA
82 * traffic selectors for initiators side
87 * traffic selectors for responders side
92 * source of triggering packet
94 traffic_selector_t
*packet_tsi
;
97 * destination of triggering packet
99 traffic_selector_t
*packet_tsr
;
102 * optional diffie hellman exchange
104 diffie_hellman_t
*dh
;
107 * group used for DH exchange
109 diffie_hellman_group_t dh_group
;
117 * mode the new CHILD_SA uses (transport/tunnel/beet)
122 * peer accepts TFC padding for this SA
127 * IPComp transform to use
129 ipcomp_transform_t ipcomp
;
132 * IPComp transform proposed or accepted by the other peer
134 ipcomp_transform_t ipcomp_received
;
142 * SPI received in proposal
147 * Own allocated Compression Parameter Index (CPI)
152 * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
157 * reqid to use if we are rekeying
162 * CHILD_SA which gets established
164 child_sa_t
*child_sa
;
167 * successfully established the CHILD?
172 * whether the CHILD_SA rekeys an existing one
177 * whether we are retrying with another DH group
183 * get the nonce from a message
185 static status_t
get_nonce(message_t
*message
, chunk_t
*nonce
)
187 nonce_payload_t
*payload
;
189 payload
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
194 *nonce
= payload
->get_nonce(payload
);
199 * generate a new nonce to include in a CREATE_CHILD_SA message
201 static status_t
generate_nonce(private_child_create_t
*this)
205 nonceg
= this->keymat
->keymat
.create_nonce_gen(&this->keymat
->keymat
);
208 DBG1(DBG_IKE
, "no nonce generator found to create nonce");
211 if (!nonceg
->allocate_nonce(nonceg
, NONCE_SIZE
, &this->my_nonce
))
213 DBG1(DBG_IKE
, "nonce allocation failed");
214 nonceg
->destroy(nonceg
);
217 nonceg
->destroy(nonceg
);
223 * Check a list of traffic selectors if any selector belongs to host
225 static bool ts_list_is_host(linked_list_t
*list
, host_t
*host
)
227 traffic_selector_t
*ts
;
229 enumerator_t
*enumerator
= list
->create_enumerator(list
);
231 while (is_host
&& enumerator
->enumerate(enumerator
, (void**)&ts
))
233 is_host
= is_host
&& ts
->is_host(ts
, host
);
235 enumerator
->destroy(enumerator
);
240 * Allocate SPIs and update proposals
242 static bool allocate_spi(private_child_create_t
*this)
244 enumerator_t
*enumerator
;
245 proposal_t
*proposal
;
247 /* TODO: allocate additional SPI for AH if we have such proposals */
248 this->my_spi
= this->child_sa
->alloc_spi(this->child_sa
, PROTO_ESP
);
253 enumerator
= this->proposals
->create_enumerator(this->proposals
);
254 while (enumerator
->enumerate(enumerator
, &proposal
))
256 proposal
->set_spi(proposal
, this->my_spi
);
258 enumerator
->destroy(enumerator
);
262 this->proposal
->set_spi(this->proposal
, this->my_spi
);
270 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
272 static void schedule_inactivity_timeout(private_child_create_t
*this)
277 timeout
= this->config
->get_inactivity(this->config
);
280 close_ike
= lib
->settings
->get_bool(lib
->settings
,
281 "%s.inactivity_close_ike", FALSE
, charon
->name
);
282 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)
283 inactivity_job_create(this->child_sa
->get_reqid(this->child_sa
),
284 timeout
, close_ike
), timeout
);
289 * Check if we have a an address pool configured
291 static bool have_pool(ike_sa_t
*ike_sa
)
293 enumerator_t
*enumerator
;
294 peer_cfg_t
*peer_cfg
;
298 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
301 enumerator
= peer_cfg
->create_pool_enumerator(peer_cfg
);
302 if (enumerator
->enumerate(enumerator
, &pool
))
306 enumerator
->destroy(enumerator
);
312 * Get hosts to use for dynamic traffic selectors
314 static linked_list_t
*get_dynamic_hosts(ike_sa_t
*ike_sa
, bool local
)
316 enumerator_t
*enumerator
;
320 list
= linked_list_create();
321 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, local
);
322 while (enumerator
->enumerate(enumerator
, &host
))
324 list
->insert_last(list
, host
);
326 enumerator
->destroy(enumerator
);
328 if (list
->get_count(list
) == 0)
329 { /* no virtual IPs assigned */
332 host
= ike_sa
->get_my_host(ike_sa
);
333 list
->insert_last(list
, host
);
335 else if (!have_pool(ike_sa
))
336 { /* use host only if we don't have a pool configured */
337 host
= ike_sa
->get_other_host(ike_sa
);
338 list
->insert_last(list
, host
);
345 * Install a CHILD_SA for usage, return value:
346 * - FAILED: no acceptable proposal
347 * - INVALID_ARG: diffie hellman group inacceptable
348 * - NOT_FOUND: TS inacceptable
350 static status_t
select_and_install(private_child_create_t
*this,
351 bool no_dh
, bool ike_auth
)
353 status_t status
, status_i
, status_o
;
354 chunk_t nonce_i
, nonce_r
;
355 chunk_t encr_i
= chunk_empty
, encr_r
= chunk_empty
;
356 chunk_t integ_i
= chunk_empty
, integ_r
= chunk_empty
;
357 linked_list_t
*my_ts
, *other_ts
, *list
;
361 if (this->proposals
== NULL
)
363 DBG1(DBG_IKE
, "SA payload missing in message");
366 if (this->tsi
== NULL
|| this->tsr
== NULL
)
368 DBG1(DBG_IKE
, "TS payloads missing in message");
372 me
= this->ike_sa
->get_my_host(this->ike_sa
);
373 other
= this->ike_sa
->get_other_host(this->ike_sa
);
375 private = this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
);
376 this->proposal
= this->config
->select_proposal(this->config
,
377 this->proposals
, no_dh
, private);
378 if (this->proposal
== NULL
)
380 DBG1(DBG_IKE
, "no acceptable proposal found");
381 charon
->bus
->alert(charon
->bus
, ALERT_PROPOSAL_MISMATCH_CHILD
,
385 this->other_spi
= this->proposal
->get_spi(this->proposal
);
387 if (!this->initiator
&& !allocate_spi(this))
388 { /* responder has no SPI allocated yet */
389 DBG1(DBG_IKE
, "allocating SPI failed");
392 this->child_sa
->set_proposal(this->child_sa
, this->proposal
);
394 if (!this->proposal
->has_dh_group(this->proposal
, this->dh_group
))
398 if (this->proposal
->get_algorithm(this->proposal
, DIFFIE_HELLMAN_GROUP
,
401 DBG1(DBG_IKE
, "DH group %N inacceptable, requesting %N",
402 diffie_hellman_group_names
, this->dh_group
,
403 diffie_hellman_group_names
, group
);
404 this->dh_group
= group
;
407 /* the selected proposal does not use a DH group */
408 DBG1(DBG_IKE
, "ignoring KE exchange, agreed on a non-PFS proposal");
409 DESTROY_IF(this->dh
);
411 this->dh_group
= MODP_NONE
;
416 nonce_i
= this->my_nonce
;
417 nonce_r
= this->other_nonce
;
419 other_ts
= this->tsr
;
423 nonce_r
= this->my_nonce
;
424 nonce_i
= this->other_nonce
;
426 other_ts
= this->tsi
;
428 list
= get_dynamic_hosts(this->ike_sa
, TRUE
);
429 my_ts
= this->config
->get_traffic_selectors(this->config
,
432 list
= get_dynamic_hosts(this->ike_sa
, FALSE
);
433 other_ts
= this->config
->get_traffic_selectors(this->config
,
434 FALSE
, other_ts
, list
);
441 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
442 NARROW_INITIATOR_POST_NOAUTH
, my_ts
, other_ts
);
446 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
447 NARROW_INITIATOR_POST_AUTH
, my_ts
, other_ts
);
452 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
453 NARROW_RESPONDER
, my_ts
, other_ts
);
456 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
458 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
459 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
460 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
461 DBG1(DBG_IKE
, "no acceptable traffic selectors found");
465 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
466 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
470 this->tsr
= other_ts
;
475 this->tsi
= other_ts
;
478 if (!this->initiator
)
480 /* check if requested mode is acceptable, downgrade if required */
484 if (!this->config
->use_proxy_mode(this->config
) &&
485 (!ts_list_is_host(this->tsi
, other
) ||
486 !ts_list_is_host(this->tsr
, me
))
489 this->mode
= MODE_TUNNEL
;
490 DBG1(DBG_IKE
, "not using transport mode, not host-to-host");
492 else if (this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
))
494 this->mode
= MODE_TUNNEL
;
495 DBG1(DBG_IKE
, "not using transport mode, connection NATed");
499 if (!ts_list_is_host(this->tsi
, NULL
) ||
500 !ts_list_is_host(this->tsr
, NULL
))
502 this->mode
= MODE_TUNNEL
;
503 DBG1(DBG_IKE
, "not using BEET mode, not host-to-host");
511 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLING
);
512 this->child_sa
->set_ipcomp(this->child_sa
, this->ipcomp
);
513 this->child_sa
->set_mode(this->child_sa
, this->mode
);
514 this->child_sa
->set_protocol(this->child_sa
,
515 this->proposal
->get_protocol(this->proposal
));
517 if (this->my_cpi
== 0 || this->other_cpi
== 0 || this->ipcomp
== IPCOMP_NONE
)
519 this->my_cpi
= this->other_cpi
= 0;
520 this->ipcomp
= IPCOMP_NONE
;
522 status_i
= status_o
= FAILED
;
523 if (this->keymat
->derive_child_keys(this->keymat
, this->proposal
,
524 this->dh
, nonce_i
, nonce_r
, &encr_i
, &integ_i
, &encr_r
, &integ_r
))
528 status_i
= this->child_sa
->install(this->child_sa
,
529 encr_r
, integ_r
, this->my_spi
, this->my_cpi
,
530 TRUE
, this->tfcv3
, my_ts
, other_ts
);
531 status_o
= this->child_sa
->install(this->child_sa
,
532 encr_i
, integ_i
, this->other_spi
, this->other_cpi
,
533 FALSE
, this->tfcv3
, my_ts
, other_ts
);
537 status_i
= this->child_sa
->install(this->child_sa
,
538 encr_i
, integ_i
, this->my_spi
, this->my_cpi
,
539 TRUE
, this->tfcv3
, my_ts
, other_ts
);
540 status_o
= this->child_sa
->install(this->child_sa
,
541 encr_r
, integ_r
, this->other_spi
, this->other_cpi
,
542 FALSE
, this->tfcv3
, my_ts
, other_ts
);
545 chunk_clear(&integ_i
);
546 chunk_clear(&integ_r
);
547 chunk_clear(&encr_i
);
548 chunk_clear(&encr_r
);
550 if (status_i
!= SUCCESS
|| status_o
!= SUCCESS
)
552 DBG1(DBG_IKE
, "unable to install %s%s%sIPsec SA (SAD) in kernel",
553 (status_i
!= SUCCESS
) ?
"inbound " : "",
554 (status_i
!= SUCCESS
&& status_o
!= SUCCESS
) ?
"and ": "",
555 (status_o
!= SUCCESS
) ?
"outbound " : "");
556 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_SA_FAILED
,
563 status
= this->child_sa
->add_policies(this->child_sa
, my_ts
, other_ts
);
567 /* use a copy of the traffic selectors, as the POST hook should not
569 my_ts
= this->tsr
->clone_offset(this->tsr
,
570 offsetof(traffic_selector_t
, clone
));
571 other_ts
= this->tsi
->clone_offset(this->tsi
,
572 offsetof(traffic_selector_t
, clone
));
573 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
574 NARROW_RESPONDER_POST
, my_ts
, other_ts
);
575 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
581 status
= this->child_sa
->add_policies(this->child_sa
,
584 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
585 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
587 if (status
!= SUCCESS
)
589 DBG1(DBG_IKE
, "unable to install IPsec policies (SPD) in kernel");
590 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_POLICY_FAILED
,
595 charon
->bus
->child_keys(charon
->bus
, this->child_sa
, this->initiator
,
596 this->dh
, nonce_i
, nonce_r
);
598 /* add to IKE_SA, and remove from task */
599 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
600 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
601 this->established
= TRUE
;
604 { /* a rekeyed SA uses the same reqid, no need for a new job */
605 schedule_inactivity_timeout(this);
611 * build the payloads for the message
613 static void build_payloads(private_child_create_t
*this, message_t
*message
)
615 sa_payload_t
*sa_payload
;
616 nonce_payload_t
*nonce_payload
;
617 ke_payload_t
*ke_payload
;
618 ts_payload_t
*ts_payload
;
619 kernel_feature_t features
;
624 sa_payload
= sa_payload_create_from_proposals_v2(this->proposals
);
628 sa_payload
= sa_payload_create_from_proposal_v2(this->proposal
);
630 message
->add_payload(message
, (payload_t
*)sa_payload
);
632 /* add nonce payload if not in IKE_AUTH */
633 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
635 nonce_payload
= nonce_payload_create(NONCE
);
636 nonce_payload
->set_nonce(nonce_payload
, this->my_nonce
);
637 message
->add_payload(message
, (payload_t
*)nonce_payload
);
640 /* diffie hellman exchange, if PFS enabled */
643 ke_payload
= ke_payload_create_from_diffie_hellman(KEY_EXCHANGE
,
645 message
->add_payload(message
, (payload_t
*)ke_payload
);
648 /* add TSi/TSr payloads */
649 ts_payload
= ts_payload_create_from_traffic_selectors(TRUE
, this->tsi
);
650 message
->add_payload(message
, (payload_t
*)ts_payload
);
651 ts_payload
= ts_payload_create_from_traffic_selectors(FALSE
, this->tsr
);
652 message
->add_payload(message
, (payload_t
*)ts_payload
);
654 /* add a notify if we are not in tunnel mode */
658 message
->add_notify(message
, FALSE
, USE_TRANSPORT_MODE
, chunk_empty
);
661 message
->add_notify(message
, FALSE
, USE_BEET_MODE
, chunk_empty
);
667 features
= hydra
->kernel_interface
->get_features(hydra
->kernel_interface
);
668 if (!(features
& KERNEL_ESP_V3_TFC
))
670 message
->add_notify(message
, FALSE
, ESP_TFC_PADDING_NOT_SUPPORTED
,
676 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
678 static void add_ipcomp_notify(private_child_create_t
*this,
679 message_t
*message
, u_int8_t ipcomp
)
681 if (this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
))
683 DBG1(DBG_IKE
, "IPComp is not supported if either peer is natted, "
688 this->my_cpi
= this->child_sa
->alloc_cpi(this->child_sa
);
691 this->ipcomp
= ipcomp
;
692 message
->add_notify(message
, FALSE
, IPCOMP_SUPPORTED
,
693 chunk_cata("cc", chunk_from_thing(this->my_cpi
),
694 chunk_from_thing(ipcomp
)));
698 DBG1(DBG_IKE
, "unable to allocate a CPI from kernel, IPComp disabled");
703 * handle a received notify payload
705 static void handle_notify(private_child_create_t
*this, notify_payload_t
*notify
)
707 switch (notify
->get_notify_type(notify
))
709 case USE_TRANSPORT_MODE
:
710 this->mode
= MODE_TRANSPORT
;
713 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
))
714 { /* handle private use notify only if we know its meaning */
715 this->mode
= MODE_BEET
;
719 DBG1(DBG_IKE
, "received a notify strongSwan uses for BEET "
720 "mode, but peer implementation unknown, skipped");
723 case IPCOMP_SUPPORTED
:
725 ipcomp_transform_t ipcomp
;
729 data
= notify
->get_notification_data(notify
);
730 cpi
= *(u_int16_t
*)data
.ptr
;
731 ipcomp
= (ipcomp_transform_t
)(*(data
.ptr
+ 2));
735 this->other_cpi
= cpi
;
736 this->ipcomp_received
= ipcomp
;
741 DBG1(DBG_IKE
, "received IPCOMP_SUPPORTED notify with a "
742 "transform ID we don't support %N",
743 ipcomp_transform_names
, ipcomp
);
748 case ESP_TFC_PADDING_NOT_SUPPORTED
:
749 DBG1(DBG_IKE
, "received %N, not using ESPv3 TFC padding",
750 notify_type_names
, notify
->get_notify_type(notify
));
759 * Read payloads from message
761 static void process_payloads(private_child_create_t
*this, message_t
*message
)
763 enumerator_t
*enumerator
;
765 sa_payload_t
*sa_payload
;
766 ke_payload_t
*ke_payload
;
767 ts_payload_t
*ts_payload
;
769 /* defaults to TUNNEL mode */
770 this->mode
= MODE_TUNNEL
;
772 enumerator
= message
->create_payload_enumerator(message
);
773 while (enumerator
->enumerate(enumerator
, &payload
))
775 switch (payload
->get_type(payload
))
777 case SECURITY_ASSOCIATION
:
778 sa_payload
= (sa_payload_t
*)payload
;
779 this->proposals
= sa_payload
->get_proposals(sa_payload
);
782 ke_payload
= (ke_payload_t
*)payload
;
783 if (!this->initiator
)
785 this->dh_group
= ke_payload
->get_dh_group_number(ke_payload
);
786 this->dh
= this->keymat
->keymat
.create_dh(
787 &this->keymat
->keymat
, this->dh_group
);
791 this->dh
->set_other_public_value(this->dh
,
792 ke_payload
->get_key_exchange_data(ke_payload
));
795 case TRAFFIC_SELECTOR_INITIATOR
:
796 ts_payload
= (ts_payload_t
*)payload
;
797 this->tsi
= ts_payload
->get_traffic_selectors(ts_payload
);
799 case TRAFFIC_SELECTOR_RESPONDER
:
800 ts_payload
= (ts_payload_t
*)payload
;
801 this->tsr
= ts_payload
->get_traffic_selectors(ts_payload
);
804 handle_notify(this, (notify_payload_t
*)payload
);
810 enumerator
->destroy(enumerator
);
813 METHOD(task_t
, build_i
, status_t
,
814 private_child_create_t
*this, message_t
*message
)
816 enumerator_t
*enumerator
;
818 peer_cfg_t
*peer_cfg
;
821 switch (message
->get_exchange_type(message
))
824 return get_nonce(message
, &this->my_nonce
);
825 case CREATE_CHILD_SA
:
826 if (generate_nonce(this) != SUCCESS
)
828 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
833 this->dh_group
= this->config
->get_dh_group(this->config
);
837 if (message
->get_message_id(message
) != 1)
839 /* send only in the first request, not in subsequent rounds */
849 DBG0(DBG_IKE
, "establishing CHILD_SA %s{%d}",
850 this->config
->get_name(this->config
), this->reqid
);
854 DBG0(DBG_IKE
, "establishing CHILD_SA %s",
855 this->config
->get_name(this->config
));
858 /* check if we want a virtual IP, but don't have one */
859 list
= linked_list_create();
860 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
863 enumerator
= peer_cfg
->create_virtual_ip_enumerator(peer_cfg
);
864 while (enumerator
->enumerate(enumerator
, &vip
))
866 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
867 vip
= host_create_any(vip
->get_family(vip
));
868 list
->insert_last(list
, vip
);
870 enumerator
->destroy(enumerator
);
872 if (list
->get_count(list
))
874 this->tsi
= this->config
->get_traffic_selectors(this->config
,
876 list
->destroy_offset(list
, offsetof(host_t
, destroy
));
879 { /* no virtual IPs configured */
881 list
= get_dynamic_hosts(this->ike_sa
, TRUE
);
882 this->tsi
= this->config
->get_traffic_selectors(this->config
,
886 list
= get_dynamic_hosts(this->ike_sa
, FALSE
);
887 this->tsr
= this->config
->get_traffic_selectors(this->config
,
891 if (this->packet_tsi
)
893 this->tsi
->insert_first(this->tsi
,
894 this->packet_tsi
->clone(this->packet_tsi
));
896 if (this->packet_tsr
)
898 this->tsr
->insert_first(this->tsr
,
899 this->packet_tsr
->clone(this->packet_tsr
));
901 this->proposals
= this->config
->get_proposals(this->config
,
902 this->dh_group
== MODP_NONE
);
903 this->mode
= this->config
->get_mode(this->config
);
904 if (this->mode
== MODE_TRANSPORT
&&
905 this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
))
907 this->mode
= MODE_TUNNEL
;
908 DBG1(DBG_IKE
, "not using transport mode, connection NATed");
911 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
912 this->ike_sa
->get_other_host(this->ike_sa
), this->config
, this->reqid
,
913 this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
));
915 if (!allocate_spi(this))
917 DBG1(DBG_IKE
, "unable to allocate SPIs from kernel");
921 if (this->dh_group
!= MODP_NONE
)
923 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
927 if (this->config
->use_ipcomp(this->config
))
929 /* IPCOMP_DEFLATE is the only transform we support at the moment */
930 add_ipcomp_notify(this, message
, IPCOMP_DEFLATE
);
933 if (message
->get_exchange_type(message
) == IKE_AUTH
)
935 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
936 NARROW_INITIATOR_PRE_NOAUTH
, this->tsi
, this->tsr
);
940 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
941 NARROW_INITIATOR_PRE_AUTH
, this->tsi
, this->tsr
);
944 build_payloads(this, message
);
946 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
947 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
948 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
951 this->proposals
= NULL
;
956 METHOD(task_t
, process_r
, status_t
,
957 private_child_create_t
*this, message_t
*message
)
959 switch (message
->get_exchange_type(message
))
962 return get_nonce(message
, &this->other_nonce
);
963 case CREATE_CHILD_SA
:
964 get_nonce(message
, &this->other_nonce
);
967 if (message
->get_message_id(message
) != 1)
969 /* only handle first AUTH payload, not additional rounds */
976 process_payloads(this, message
);
982 * handle CHILD_SA setup failure
984 static void handle_child_sa_failure(private_child_create_t
*this,
987 if (message
->get_exchange_type(message
) == IKE_AUTH
&&
988 lib
->settings
->get_bool(lib
->settings
,
989 "%s.close_ike_on_child_failure", FALSE
, charon
->name
))
991 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
993 DBG1(DBG_IKE
, "closing IKE_SA due CHILD_SA setup failure");
994 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, (job_t
*)
995 delete_ike_sa_job_create(this->ike_sa
->get_id(this->ike_sa
), TRUE
),
1000 DBG1(DBG_IKE
, "failed to establish CHILD_SA, keeping IKE_SA");
1001 charon
->bus
->alert(charon
->bus
, ALERT_KEEP_ON_CHILD_SA_FAILURE
);
1005 METHOD(task_t
, build_r
, status_t
,
1006 private_child_create_t
*this, message_t
*message
)
1008 peer_cfg_t
*peer_cfg
;
1010 enumerator_t
*enumerator
;
1011 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1013 switch (message
->get_exchange_type(message
))
1016 return get_nonce(message
, &this->my_nonce
);
1017 case CREATE_CHILD_SA
:
1018 if (generate_nonce(this) != SUCCESS
)
1020 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1027 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1028 { /* wait until all authentication round completed */
1036 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_REKEYING
)
1038 DBG1(DBG_IKE
, "unable to create CHILD_SA while rekeying IKE_SA");
1039 message
->add_notify(message
, TRUE
, NO_ADDITIONAL_SAS
, chunk_empty
);
1043 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
1044 if (!this->config
&& peer_cfg
&& this->tsi
&& this->tsr
)
1046 linked_list_t
*listr
, *listi
;
1048 listr
= get_dynamic_hosts(this->ike_sa
, TRUE
);
1049 listi
= get_dynamic_hosts(this->ike_sa
, FALSE
);
1050 this->config
= peer_cfg
->select_child_cfg(peer_cfg
,
1051 this->tsr
, this->tsi
, listr
, listi
);
1052 listr
->destroy(listr
);
1053 listi
->destroy(listi
);
1056 if (this->config
== NULL
)
1058 DBG1(DBG_IKE
, "traffic selectors %#R=== %#R inacceptable",
1059 this->tsr
, this->tsi
);
1060 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
1061 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1062 handle_child_sa_failure(this, message
);
1066 /* check if ike_config_t included non-critical error notifies */
1067 enumerator
= message
->create_payload_enumerator(message
);
1068 while (enumerator
->enumerate(enumerator
, &payload
))
1070 if (payload
->get_type(payload
) == NOTIFY
)
1072 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1074 switch (notify
->get_notify_type(notify
))
1076 case INTERNAL_ADDRESS_FAILURE
:
1077 case FAILED_CP_REQUIRED
:
1079 DBG1(DBG_IKE
,"configuration payload negotiation "
1080 "failed, no CHILD_SA built");
1081 enumerator
->destroy(enumerator
);
1082 handle_child_sa_failure(this, message
);
1090 enumerator
->destroy(enumerator
);
1092 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
1093 this->ike_sa
->get_other_host(this->ike_sa
), this->config
, this->reqid
,
1094 this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
));
1096 if (this->ipcomp_received
!= IPCOMP_NONE
)
1098 if (this->config
->use_ipcomp(this->config
))
1100 add_ipcomp_notify(this, message
, this->ipcomp_received
);
1104 DBG1(DBG_IKE
, "received %N notify but IPComp is disabled, ignoring",
1105 notify_type_names
, IPCOMP_SUPPORTED
);
1109 switch (select_and_install(this, no_dh
, ike_auth
))
1114 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1115 handle_child_sa_failure(this, message
);
1119 u_int16_t group
= htons(this->dh_group
);
1120 message
->add_notify(message
, FALSE
, INVALID_KE_PAYLOAD
,
1121 chunk_from_thing(group
));
1122 handle_child_sa_failure(this, message
);
1127 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
1128 handle_child_sa_failure(this, message
);
1132 build_payloads(this, message
);
1134 DBG0(DBG_IKE
, "CHILD_SA %s{%d} established "
1135 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
1136 this->child_sa
->get_name(this->child_sa
),
1137 this->child_sa
->get_reqid(this->child_sa
),
1138 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
1139 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)),
1140 this->child_sa
->get_traffic_selectors(this->child_sa
, TRUE
),
1141 this->child_sa
->get_traffic_selectors(this->child_sa
, FALSE
));
1144 { /* invoke the child_up() hook if we are not rekeying */
1145 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1150 METHOD(task_t
, process_i
, status_t
,
1151 private_child_create_t
*this, message_t
*message
)
1153 enumerator_t
*enumerator
;
1155 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1157 switch (message
->get_exchange_type(message
))
1160 return get_nonce(message
, &this->other_nonce
);
1161 case CREATE_CHILD_SA
:
1162 get_nonce(message
, &this->other_nonce
);
1166 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1167 { /* wait until all authentication round completed */
1175 /* check for erroneous notifies */
1176 enumerator
= message
->create_payload_enumerator(message
);
1177 while (enumerator
->enumerate(enumerator
, &payload
))
1179 if (payload
->get_type(payload
) == NOTIFY
)
1181 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1182 notify_type_t type
= notify
->get_notify_type(notify
);
1186 /* handle notify errors related to CHILD_SA only */
1187 case NO_PROPOSAL_CHOSEN
:
1188 case SINGLE_PAIR_REQUIRED
:
1189 case NO_ADDITIONAL_SAS
:
1190 case INTERNAL_ADDRESS_FAILURE
:
1191 case FAILED_CP_REQUIRED
:
1192 case TS_UNACCEPTABLE
:
1193 case INVALID_SELECTORS
:
1195 DBG1(DBG_IKE
, "received %N notify, no CHILD_SA built",
1196 notify_type_names
, type
);
1197 enumerator
->destroy(enumerator
);
1198 handle_child_sa_failure(this, message
);
1199 /* an error in CHILD_SA creation is not critical */
1202 case INVALID_KE_PAYLOAD
:
1205 u_int16_t group
= MODP_NONE
;
1207 data
= notify
->get_notification_data(notify
);
1208 if (data
.len
== sizeof(group
))
1210 memcpy(&group
, data
.ptr
, data
.len
);
1211 group
= ntohs(group
);
1213 DBG1(DBG_IKE
, "peer didn't accept DH group %N, "
1214 "it requested %N", diffie_hellman_group_names
,
1215 this->dh_group
, diffie_hellman_group_names
, group
);
1217 this->dh_group
= group
;
1218 this->public.task
.migrate(&this->public.task
, this->ike_sa
);
1219 enumerator
->destroy(enumerator
);
1224 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
1225 { /* handle notifies if not handled in IKE_AUTH */
1228 DBG1(DBG_IKE
, "received %N notify error",
1229 notify_type_names
, type
);
1230 enumerator
->destroy(enumerator
);
1233 DBG2(DBG_IKE
, "received %N notify",
1234 notify_type_names
, type
);
1241 enumerator
->destroy(enumerator
);
1243 process_payloads(this, message
);
1245 if (this->ipcomp
== IPCOMP_NONE
&& this->ipcomp_received
!= IPCOMP_NONE
)
1247 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify without requesting"
1248 " one, no CHILD_SA built");
1249 handle_child_sa_failure(this, message
);
1252 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp_received
== IPCOMP_NONE
)
1254 DBG1(DBG_IKE
, "peer didn't accept our proposed IPComp transforms, "
1255 "IPComp is disabled");
1256 this->ipcomp
= IPCOMP_NONE
;
1258 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp
!= this->ipcomp_received
)
1260 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1261 "no CHILD_SA built");
1262 handle_child_sa_failure(this, message
);
1266 if (select_and_install(this, no_dh
, ike_auth
) == SUCCESS
)
1268 DBG0(DBG_IKE
, "CHILD_SA %s{%d} established "
1269 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
1270 this->child_sa
->get_name(this->child_sa
),
1271 this->child_sa
->get_reqid(this->child_sa
),
1272 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
1273 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)),
1274 this->child_sa
->get_traffic_selectors(this->child_sa
, TRUE
),
1275 this->child_sa
->get_traffic_selectors(this->child_sa
, FALSE
));
1278 { /* invoke the child_up() hook if we are not rekeying */
1279 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1284 handle_child_sa_failure(this, message
);
1289 METHOD(child_create_t
, use_reqid
, void,
1290 private_child_create_t
*this, u_int32_t reqid
)
1292 this->reqid
= reqid
;
1295 METHOD(child_create_t
, get_child
, child_sa_t
*,
1296 private_child_create_t
*this)
1298 return this->child_sa
;
1301 METHOD(child_create_t
, set_config
, void,
1302 private_child_create_t
*this, child_cfg_t
*cfg
)
1304 DESTROY_IF(this->config
);
1308 METHOD(child_create_t
, get_lower_nonce
, chunk_t
,
1309 private_child_create_t
*this)
1311 if (memcmp(this->my_nonce
.ptr
, this->other_nonce
.ptr
,
1312 min(this->my_nonce
.len
, this->other_nonce
.len
)) < 0)
1314 return this->my_nonce
;
1318 return this->other_nonce
;
1322 METHOD(task_t
, get_type
, task_type_t
,
1323 private_child_create_t
*this)
1325 return TASK_CHILD_CREATE
;
1328 METHOD(task_t
, migrate
, void,
1329 private_child_create_t
*this, ike_sa_t
*ike_sa
)
1331 chunk_free(&this->my_nonce
);
1332 chunk_free(&this->other_nonce
);
1335 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1339 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1341 DESTROY_IF(this->child_sa
);
1342 DESTROY_IF(this->proposal
);
1343 DESTROY_IF(this->dh
);
1344 if (this->proposals
)
1346 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1349 this->ike_sa
= ike_sa
;
1350 this->keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
);
1351 this->proposal
= NULL
;
1352 this->proposals
= NULL
;
1356 this->child_sa
= NULL
;
1357 this->mode
= MODE_TUNNEL
;
1358 this->ipcomp
= IPCOMP_NONE
;
1359 this->ipcomp_received
= IPCOMP_NONE
;
1360 this->other_cpi
= 0;
1362 this->established
= FALSE
;
1365 METHOD(task_t
, destroy
, void,
1366 private_child_create_t
*this)
1368 chunk_free(&this->my_nonce
);
1369 chunk_free(&this->other_nonce
);
1372 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1376 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1378 if (!this->established
)
1380 DESTROY_IF(this->child_sa
);
1382 DESTROY_IF(this->packet_tsi
);
1383 DESTROY_IF(this->packet_tsr
);
1384 DESTROY_IF(this->proposal
);
1385 DESTROY_IF(this->dh
);
1386 if (this->proposals
)
1388 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1391 DESTROY_IF(this->config
);
1396 * Described in header.
1398 child_create_t
*child_create_create(ike_sa_t
*ike_sa
,
1399 child_cfg_t
*config
, bool rekey
,
1400 traffic_selector_t
*tsi
, traffic_selector_t
*tsr
)
1402 private_child_create_t
*this;
1406 .get_child
= _get_child
,
1407 .set_config
= _set_config
,
1408 .get_lower_nonce
= _get_lower_nonce
,
1409 .use_reqid
= _use_reqid
,
1411 .get_type
= _get_type
,
1412 .migrate
= _migrate
,
1413 .destroy
= _destroy
,
1418 .packet_tsi
= tsi ? tsi
->clone(tsi
) : NULL
,
1419 .packet_tsr
= tsr ? tsr
->clone(tsr
) : NULL
,
1420 .dh_group
= MODP_NONE
,
1421 .keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
),
1422 .mode
= MODE_TUNNEL
,
1424 .ipcomp
= IPCOMP_NONE
,
1425 .ipcomp_received
= IPCOMP_NONE
,
1432 this->public.task
.build
= _build_i
;
1433 this->public.task
.process
= _process_i
;
1434 this->initiator
= TRUE
;
1438 this->public.task
.build
= _build_r
;
1439 this->public.task
.process
= _process_r
;
1440 this->initiator
= FALSE
;
1443 return &this->public;