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 <encoding/payloads/delete_payload.h>
31 #include <processing/jobs/delete_ike_sa_job.h>
32 #include <processing/jobs/inactivity_job.h>
35 typedef struct private_child_create_t private_child_create_t
;
38 * Private members of a child_create_t task.
40 struct private_child_create_t
{
43 * Public methods and task_t interface.
45 child_create_t
public;
53 * Are we the initiator?
63 * nonce chosen by peer
68 * config to create the CHILD_SA from
73 * list of proposal candidates
75 linked_list_t
*proposals
;
78 * selected proposal to use for CHILD_SA
83 * traffic selectors for initiators side
88 * traffic selectors for responders side
93 * source of triggering packet
95 traffic_selector_t
*packet_tsi
;
98 * destination of triggering packet
100 traffic_selector_t
*packet_tsr
;
103 * optional diffie hellman exchange
105 diffie_hellman_t
*dh
;
108 * group used for DH exchange
110 diffie_hellman_group_t dh_group
;
118 * mode the new CHILD_SA uses (transport/tunnel/beet)
123 * peer accepts TFC padding for this SA
128 * IPComp transform to use
130 ipcomp_transform_t ipcomp
;
133 * IPComp transform proposed or accepted by the other peer
135 ipcomp_transform_t ipcomp_received
;
143 * SPI received in proposal
148 * Own allocated Compression Parameter Index (CPI)
153 * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
158 * reqid to use if we are rekeying
163 * Explicit inbound mark value
168 * Explicit outbound mark value
173 * CHILD_SA which gets established
175 child_sa_t
*child_sa
;
178 * successfully established the CHILD?
183 * whether the CHILD_SA rekeys an existing one
188 * whether we are retrying with another DH group
194 * get the nonce from a message
196 static status_t
get_nonce(message_t
*message
, chunk_t
*nonce
)
198 nonce_payload_t
*payload
;
200 payload
= (nonce_payload_t
*)message
->get_payload(message
, PLV2_NONCE
);
205 *nonce
= payload
->get_nonce(payload
);
210 * generate a new nonce to include in a CREATE_CHILD_SA message
212 static status_t
generate_nonce(private_child_create_t
*this)
216 nonceg
= this->keymat
->keymat
.create_nonce_gen(&this->keymat
->keymat
);
219 DBG1(DBG_IKE
, "no nonce generator found to create nonce");
222 if (!nonceg
->allocate_nonce(nonceg
, NONCE_SIZE
, &this->my_nonce
))
224 DBG1(DBG_IKE
, "nonce allocation failed");
225 nonceg
->destroy(nonceg
);
228 nonceg
->destroy(nonceg
);
234 * Check a list of traffic selectors if any selector belongs to host
236 static bool ts_list_is_host(linked_list_t
*list
, host_t
*host
)
238 traffic_selector_t
*ts
;
240 enumerator_t
*enumerator
= list
->create_enumerator(list
);
242 while (is_host
&& enumerator
->enumerate(enumerator
, (void**)&ts
))
244 is_host
= is_host
&& ts
->is_host(ts
, host
);
246 enumerator
->destroy(enumerator
);
251 * Allocate SPIs and update proposals
253 static bool allocate_spi(private_child_create_t
*this)
255 enumerator_t
*enumerator
;
256 proposal_t
*proposal
;
257 protocol_id_t proto
= PROTO_ESP
;
261 /* we just get a SPI for the first protocol. TODO: If we ever support
262 * proposal lists with mixed protocols, we'd need multiple SPIs */
263 if (this->proposals
->get_first(this->proposals
,
264 (void**)&proposal
) == SUCCESS
)
266 proto
= proposal
->get_protocol(proposal
);
271 proto
= this->proposal
->get_protocol(this->proposal
);
273 this->my_spi
= this->child_sa
->alloc_spi(this->child_sa
, proto
);
278 enumerator
= this->proposals
->create_enumerator(this->proposals
);
279 while (enumerator
->enumerate(enumerator
, &proposal
))
281 proposal
->set_spi(proposal
, this->my_spi
);
283 enumerator
->destroy(enumerator
);
287 this->proposal
->set_spi(this->proposal
, this->my_spi
);
295 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
297 static void schedule_inactivity_timeout(private_child_create_t
*this)
299 u_int32_t timeout
, id
;
302 timeout
= this->config
->get_inactivity(this->config
);
305 close_ike
= lib
->settings
->get_bool(lib
->settings
,
306 "%s.inactivity_close_ike", FALSE
, lib
->ns
);
307 id
= this->child_sa
->get_unique_id(this->child_sa
);
308 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)
309 inactivity_job_create(id
, timeout
, close_ike
), timeout
);
314 * Check if we have a an address pool configured
316 static bool have_pool(ike_sa_t
*ike_sa
)
318 enumerator_t
*enumerator
;
319 peer_cfg_t
*peer_cfg
;
323 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
326 enumerator
= peer_cfg
->create_pool_enumerator(peer_cfg
);
327 if (enumerator
->enumerate(enumerator
, &pool
))
331 enumerator
->destroy(enumerator
);
337 * Get hosts to use for dynamic traffic selectors
339 static linked_list_t
*get_dynamic_hosts(ike_sa_t
*ike_sa
, bool local
)
341 enumerator_t
*enumerator
;
345 list
= linked_list_create();
346 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, local
);
347 while (enumerator
->enumerate(enumerator
, &host
))
349 list
->insert_last(list
, host
);
351 enumerator
->destroy(enumerator
);
353 if (list
->get_count(list
) == 0)
354 { /* no virtual IPs assigned */
357 host
= ike_sa
->get_my_host(ike_sa
);
358 list
->insert_last(list
, host
);
360 else if (!have_pool(ike_sa
))
361 { /* use host only if we don't have a pool configured */
362 host
= ike_sa
->get_other_host(ike_sa
);
363 list
->insert_last(list
, host
);
370 * Substitude any host address with NATed address in traffic selector
372 static linked_list_t
* get_transport_nat_ts(private_child_create_t
*this,
373 bool local
, linked_list_t
*in
)
375 enumerator_t
*enumerator
;
377 traffic_selector_t
*ts
;
378 host_t
*ike
, *first
= NULL
;
383 ike
= this->ike_sa
->get_my_host(this->ike_sa
);
387 ike
= this->ike_sa
->get_other_host(this->ike_sa
);
390 out
= linked_list_create();
392 enumerator
= in
->create_enumerator(in
);
393 while (enumerator
->enumerate(enumerator
, &ts
))
395 /* require that all selectors match the first "host" selector */
396 if (ts
->is_host(ts
, first
))
400 ts
->to_subnet(ts
, &first
, &mask
);
403 ts
->set_address(ts
, ike
);
404 out
->insert_last(out
, ts
);
407 enumerator
->destroy(enumerator
);
414 * Narrow received traffic selectors with configuration
416 static linked_list_t
* narrow_ts(private_child_create_t
*this, bool local
,
419 linked_list_t
*hosts
, *nat
, *ts
;
420 ike_condition_t cond
;
422 cond
= local ? COND_NAT_HERE
: COND_NAT_THERE
;
423 hosts
= get_dynamic_hosts(this->ike_sa
, local
);
425 if (this->mode
== MODE_TRANSPORT
&&
426 this->ike_sa
->has_condition(this->ike_sa
, cond
))
428 nat
= get_transport_nat_ts(this, local
, in
);
429 ts
= this->config
->get_traffic_selectors(this->config
, local
, nat
, hosts
);
430 nat
->destroy_offset(nat
, offsetof(traffic_selector_t
, destroy
));
434 ts
= this->config
->get_traffic_selectors(this->config
, local
, in
, hosts
);
437 hosts
->destroy(hosts
);
443 * Install a CHILD_SA for usage, return value:
444 * - FAILED: no acceptable proposal
445 * - INVALID_ARG: diffie hellman group inacceptable
446 * - NOT_FOUND: TS inacceptable
448 static status_t
select_and_install(private_child_create_t
*this,
449 bool no_dh
, bool ike_auth
)
451 status_t status
, status_i
, status_o
;
452 chunk_t nonce_i
, nonce_r
;
453 chunk_t encr_i
= chunk_empty
, encr_r
= chunk_empty
;
454 chunk_t integ_i
= chunk_empty
, integ_r
= chunk_empty
;
455 linked_list_t
*my_ts
, *other_ts
;
459 if (this->proposals
== NULL
)
461 DBG1(DBG_IKE
, "SA payload missing in message");
464 if (this->tsi
== NULL
|| this->tsr
== NULL
)
466 DBG1(DBG_IKE
, "TS payloads missing in message");
470 me
= this->ike_sa
->get_my_host(this->ike_sa
);
471 other
= this->ike_sa
->get_other_host(this->ike_sa
);
473 private = this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
);
474 this->proposal
= this->config
->select_proposal(this->config
,
475 this->proposals
, no_dh
, private);
476 if (this->proposal
== NULL
)
478 DBG1(DBG_IKE
, "no acceptable proposal found");
479 charon
->bus
->alert(charon
->bus
, ALERT_PROPOSAL_MISMATCH_CHILD
,
483 this->other_spi
= this->proposal
->get_spi(this->proposal
);
485 if (!this->initiator
&& !allocate_spi(this))
486 { /* responder has no SPI allocated yet */
487 DBG1(DBG_IKE
, "allocating SPI failed");
490 this->child_sa
->set_proposal(this->child_sa
, this->proposal
);
492 if (!this->proposal
->has_dh_group(this->proposal
, this->dh_group
))
496 if (this->proposal
->get_algorithm(this->proposal
, DIFFIE_HELLMAN_GROUP
,
499 DBG1(DBG_IKE
, "DH group %N inacceptable, requesting %N",
500 diffie_hellman_group_names
, this->dh_group
,
501 diffie_hellman_group_names
, group
);
502 this->dh_group
= group
;
505 /* the selected proposal does not use a DH group */
506 DBG1(DBG_IKE
, "ignoring KE exchange, agreed on a non-PFS proposal");
507 DESTROY_IF(this->dh
);
509 this->dh_group
= MODP_NONE
;
514 nonce_i
= this->my_nonce
;
515 nonce_r
= this->other_nonce
;
516 my_ts
= narrow_ts(this, TRUE
, this->tsi
);
517 other_ts
= narrow_ts(this, FALSE
, this->tsr
);
521 nonce_r
= this->my_nonce
;
522 nonce_i
= this->other_nonce
;
523 my_ts
= narrow_ts(this, TRUE
, this->tsr
);
524 other_ts
= narrow_ts(this, FALSE
, this->tsi
);
531 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
532 NARROW_INITIATOR_POST_NOAUTH
, my_ts
, other_ts
);
536 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
537 NARROW_INITIATOR_POST_AUTH
, my_ts
, other_ts
);
542 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
543 NARROW_RESPONDER
, my_ts
, other_ts
);
546 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
548 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
549 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
550 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
551 DBG1(DBG_IKE
, "no acceptable traffic selectors found");
555 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
556 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
560 this->tsr
= other_ts
;
565 this->tsi
= other_ts
;
568 if (!this->initiator
)
570 /* check if requested mode is acceptable, downgrade if required */
574 if (!this->config
->use_proxy_mode(this->config
) &&
575 (!ts_list_is_host(this->tsi
, other
) ||
576 !ts_list_is_host(this->tsr
, me
))
579 this->mode
= MODE_TUNNEL
;
580 DBG1(DBG_IKE
, "not using transport mode, not host-to-host");
582 if (this->config
->get_mode(this->config
) != MODE_TRANSPORT
)
584 this->mode
= MODE_TUNNEL
;
588 if (!ts_list_is_host(this->tsi
, NULL
) ||
589 !ts_list_is_host(this->tsr
, NULL
))
591 this->mode
= MODE_TUNNEL
;
592 DBG1(DBG_IKE
, "not using BEET mode, not host-to-host");
594 if (this->config
->get_mode(this->config
) != MODE_BEET
)
596 this->mode
= MODE_TUNNEL
;
604 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLING
);
605 this->child_sa
->set_ipcomp(this->child_sa
, this->ipcomp
);
606 this->child_sa
->set_mode(this->child_sa
, this->mode
);
607 this->child_sa
->set_protocol(this->child_sa
,
608 this->proposal
->get_protocol(this->proposal
));
610 if (this->my_cpi
== 0 || this->other_cpi
== 0 || this->ipcomp
== IPCOMP_NONE
)
612 this->my_cpi
= this->other_cpi
= 0;
613 this->ipcomp
= IPCOMP_NONE
;
615 status_i
= status_o
= FAILED
;
616 if (this->keymat
->derive_child_keys(this->keymat
, this->proposal
,
617 this->dh
, nonce_i
, nonce_r
, &encr_i
, &integ_i
, &encr_r
, &integ_r
))
621 status_i
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
622 this->my_spi
, this->my_cpi
, this->initiator
,
623 TRUE
, this->tfcv3
, my_ts
, other_ts
);
624 status_o
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
625 this->other_spi
, this->other_cpi
, this->initiator
,
626 FALSE
, this->tfcv3
, my_ts
, other_ts
);
630 status_i
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
631 this->my_spi
, this->my_cpi
, this->initiator
,
632 TRUE
, this->tfcv3
, my_ts
, other_ts
);
633 status_o
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
634 this->other_spi
, this->other_cpi
, this->initiator
,
635 FALSE
, this->tfcv3
, my_ts
, other_ts
);
638 chunk_clear(&integ_i
);
639 chunk_clear(&integ_r
);
640 chunk_clear(&encr_i
);
641 chunk_clear(&encr_r
);
643 if (status_i
!= SUCCESS
|| status_o
!= SUCCESS
)
645 DBG1(DBG_IKE
, "unable to install %s%s%sIPsec SA (SAD) in kernel",
646 (status_i
!= SUCCESS
) ?
"inbound " : "",
647 (status_i
!= SUCCESS
&& status_o
!= SUCCESS
) ?
"and ": "",
648 (status_o
!= SUCCESS
) ?
"outbound " : "");
649 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_SA_FAILED
,
656 status
= this->child_sa
->add_policies(this->child_sa
, my_ts
, other_ts
);
660 /* use a copy of the traffic selectors, as the POST hook should not
662 my_ts
= this->tsr
->clone_offset(this->tsr
,
663 offsetof(traffic_selector_t
, clone
));
664 other_ts
= this->tsi
->clone_offset(this->tsi
,
665 offsetof(traffic_selector_t
, clone
));
666 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
667 NARROW_RESPONDER_POST
, my_ts
, other_ts
);
668 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
674 status
= this->child_sa
->add_policies(this->child_sa
,
677 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
678 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
680 if (status
!= SUCCESS
)
682 DBG1(DBG_IKE
, "unable to install IPsec policies (SPD) in kernel");
683 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_POLICY_FAILED
,
688 charon
->bus
->child_keys(charon
->bus
, this->child_sa
, this->initiator
,
689 this->dh
, nonce_i
, nonce_r
);
691 /* add to IKE_SA, and remove from task */
692 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
693 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
694 this->established
= TRUE
;
696 schedule_inactivity_timeout(this);
698 my_ts
= linked_list_create_from_enumerator(
699 this->child_sa
->create_ts_enumerator(this->child_sa
, TRUE
));
700 other_ts
= linked_list_create_from_enumerator(
701 this->child_sa
->create_ts_enumerator(this->child_sa
, FALSE
));
703 DBG0(DBG_IKE
, "CHILD_SA %s{%d} established "
704 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
705 this->child_sa
->get_name(this->child_sa
),
706 this->child_sa
->get_unique_id(this->child_sa
),
707 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
708 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)), my_ts
, other_ts
);
710 my_ts
->destroy(my_ts
);
711 other_ts
->destroy(other_ts
);
717 * build the payloads for the message
719 static void build_payloads(private_child_create_t
*this, message_t
*message
)
721 sa_payload_t
*sa_payload
;
722 nonce_payload_t
*nonce_payload
;
723 ke_payload_t
*ke_payload
;
724 ts_payload_t
*ts_payload
;
725 kernel_feature_t features
;
730 sa_payload
= sa_payload_create_from_proposals_v2(this->proposals
);
734 sa_payload
= sa_payload_create_from_proposal_v2(this->proposal
);
736 message
->add_payload(message
, (payload_t
*)sa_payload
);
738 /* add nonce payload if not in IKE_AUTH */
739 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
741 nonce_payload
= nonce_payload_create(PLV2_NONCE
);
742 nonce_payload
->set_nonce(nonce_payload
, this->my_nonce
);
743 message
->add_payload(message
, (payload_t
*)nonce_payload
);
746 /* diffie hellman exchange, if PFS enabled */
749 ke_payload
= ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE
,
751 message
->add_payload(message
, (payload_t
*)ke_payload
);
754 /* add TSi/TSr payloads */
755 ts_payload
= ts_payload_create_from_traffic_selectors(TRUE
, this->tsi
);
756 message
->add_payload(message
, (payload_t
*)ts_payload
);
757 ts_payload
= ts_payload_create_from_traffic_selectors(FALSE
, this->tsr
);
758 message
->add_payload(message
, (payload_t
*)ts_payload
);
760 /* add a notify if we are not in tunnel mode */
764 message
->add_notify(message
, FALSE
, USE_TRANSPORT_MODE
, chunk_empty
);
767 message
->add_notify(message
, FALSE
, USE_BEET_MODE
, chunk_empty
);
773 features
= hydra
->kernel_interface
->get_features(hydra
->kernel_interface
);
774 if (!(features
& KERNEL_ESP_V3_TFC
))
776 message
->add_notify(message
, FALSE
, ESP_TFC_PADDING_NOT_SUPPORTED
,
782 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
784 static void add_ipcomp_notify(private_child_create_t
*this,
785 message_t
*message
, u_int8_t ipcomp
)
787 this->my_cpi
= this->child_sa
->alloc_cpi(this->child_sa
);
790 this->ipcomp
= ipcomp
;
791 message
->add_notify(message
, FALSE
, IPCOMP_SUPPORTED
,
792 chunk_cata("cc", chunk_from_thing(this->my_cpi
),
793 chunk_from_thing(ipcomp
)));
797 DBG1(DBG_IKE
, "unable to allocate a CPI from kernel, IPComp disabled");
802 * handle a received notify payload
804 static void handle_notify(private_child_create_t
*this, notify_payload_t
*notify
)
806 switch (notify
->get_notify_type(notify
))
808 case USE_TRANSPORT_MODE
:
809 this->mode
= MODE_TRANSPORT
;
812 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
))
813 { /* handle private use notify only if we know its meaning */
814 this->mode
= MODE_BEET
;
818 DBG1(DBG_IKE
, "received a notify strongSwan uses for BEET "
819 "mode, but peer implementation unknown, skipped");
822 case IPCOMP_SUPPORTED
:
824 ipcomp_transform_t ipcomp
;
828 data
= notify
->get_notification_data(notify
);
829 cpi
= *(u_int16_t
*)data
.ptr
;
830 ipcomp
= (ipcomp_transform_t
)(*(data
.ptr
+ 2));
834 this->other_cpi
= cpi
;
835 this->ipcomp_received
= ipcomp
;
840 DBG1(DBG_IKE
, "received IPCOMP_SUPPORTED notify with a "
841 "transform ID we don't support %N",
842 ipcomp_transform_names
, ipcomp
);
847 case ESP_TFC_PADDING_NOT_SUPPORTED
:
848 DBG1(DBG_IKE
, "received %N, not using ESPv3 TFC padding",
849 notify_type_names
, notify
->get_notify_type(notify
));
858 * Read payloads from message
860 static void process_payloads(private_child_create_t
*this, message_t
*message
)
862 enumerator_t
*enumerator
;
864 sa_payload_t
*sa_payload
;
865 ke_payload_t
*ke_payload
;
866 ts_payload_t
*ts_payload
;
868 /* defaults to TUNNEL mode */
869 this->mode
= MODE_TUNNEL
;
871 enumerator
= message
->create_payload_enumerator(message
);
872 while (enumerator
->enumerate(enumerator
, &payload
))
874 switch (payload
->get_type(payload
))
876 case PLV2_SECURITY_ASSOCIATION
:
877 sa_payload
= (sa_payload_t
*)payload
;
878 this->proposals
= sa_payload
->get_proposals(sa_payload
);
880 case PLV2_KEY_EXCHANGE
:
881 ke_payload
= (ke_payload_t
*)payload
;
882 if (!this->initiator
)
884 this->dh_group
= ke_payload
->get_dh_group_number(ke_payload
);
885 this->dh
= this->keymat
->keymat
.create_dh(
886 &this->keymat
->keymat
, this->dh_group
);
890 this->dh
->set_other_public_value(this->dh
,
891 ke_payload
->get_key_exchange_data(ke_payload
));
894 case PLV2_TS_INITIATOR
:
895 ts_payload
= (ts_payload_t
*)payload
;
896 this->tsi
= ts_payload
->get_traffic_selectors(ts_payload
);
898 case PLV2_TS_RESPONDER
:
899 ts_payload
= (ts_payload_t
*)payload
;
900 this->tsr
= ts_payload
->get_traffic_selectors(ts_payload
);
903 handle_notify(this, (notify_payload_t
*)payload
);
909 enumerator
->destroy(enumerator
);
912 METHOD(task_t
, build_i
, status_t
,
913 private_child_create_t
*this, message_t
*message
)
915 enumerator_t
*enumerator
;
917 peer_cfg_t
*peer_cfg
;
920 switch (message
->get_exchange_type(message
))
923 return get_nonce(message
, &this->my_nonce
);
924 case CREATE_CHILD_SA
:
925 if (generate_nonce(this) != SUCCESS
)
927 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
932 this->dh_group
= this->config
->get_dh_group(this->config
);
936 if (message
->get_message_id(message
) != 1)
938 /* send only in the first request, not in subsequent rounds */
948 DBG0(DBG_IKE
, "establishing CHILD_SA %s{%d}",
949 this->config
->get_name(this->config
), this->reqid
);
953 DBG0(DBG_IKE
, "establishing CHILD_SA %s",
954 this->config
->get_name(this->config
));
957 /* check if we want a virtual IP, but don't have one */
958 list
= linked_list_create();
959 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
962 enumerator
= peer_cfg
->create_virtual_ip_enumerator(peer_cfg
);
963 while (enumerator
->enumerate(enumerator
, &vip
))
965 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
966 vip
= host_create_any(vip
->get_family(vip
));
967 list
->insert_last(list
, vip
);
969 enumerator
->destroy(enumerator
);
971 if (list
->get_count(list
))
973 this->tsi
= this->config
->get_traffic_selectors(this->config
,
975 list
->destroy_offset(list
, offsetof(host_t
, destroy
));
978 { /* no virtual IPs configured */
980 list
= get_dynamic_hosts(this->ike_sa
, TRUE
);
981 this->tsi
= this->config
->get_traffic_selectors(this->config
,
985 list
= get_dynamic_hosts(this->ike_sa
, FALSE
);
986 this->tsr
= this->config
->get_traffic_selectors(this->config
,
990 if (this->packet_tsi
)
992 this->tsi
->insert_first(this->tsi
,
993 this->packet_tsi
->clone(this->packet_tsi
));
995 if (this->packet_tsr
)
997 this->tsr
->insert_first(this->tsr
,
998 this->packet_tsr
->clone(this->packet_tsr
));
1000 this->proposals
= this->config
->get_proposals(this->config
,
1001 this->dh_group
== MODP_NONE
);
1002 this->mode
= this->config
->get_mode(this->config
);
1004 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
1005 this->ike_sa
->get_other_host(this->ike_sa
), this->config
, this->reqid
,
1006 this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
),
1007 this->mark_in
, this->mark_out
);
1009 if (!allocate_spi(this))
1011 DBG1(DBG_IKE
, "unable to allocate SPIs from kernel");
1015 if (this->dh_group
!= MODP_NONE
)
1017 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
1021 if (this->config
->use_ipcomp(this->config
))
1023 /* IPCOMP_DEFLATE is the only transform we support at the moment */
1024 add_ipcomp_notify(this, message
, IPCOMP_DEFLATE
);
1027 if (message
->get_exchange_type(message
) == IKE_AUTH
)
1029 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1030 NARROW_INITIATOR_PRE_NOAUTH
, this->tsi
, this->tsr
);
1034 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1035 NARROW_INITIATOR_PRE_AUTH
, this->tsi
, this->tsr
);
1038 build_payloads(this, message
);
1040 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1041 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1042 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1045 this->proposals
= NULL
;
1050 METHOD(task_t
, process_r
, status_t
,
1051 private_child_create_t
*this, message_t
*message
)
1053 switch (message
->get_exchange_type(message
))
1056 return get_nonce(message
, &this->other_nonce
);
1057 case CREATE_CHILD_SA
:
1058 get_nonce(message
, &this->other_nonce
);
1061 if (message
->get_message_id(message
) != 1)
1063 /* only handle first AUTH payload, not additional rounds */
1070 process_payloads(this, message
);
1076 * handle CHILD_SA setup failure
1078 static void handle_child_sa_failure(private_child_create_t
*this,
1081 if (message
->get_exchange_type(message
) == IKE_AUTH
&&
1082 lib
->settings
->get_bool(lib
->settings
,
1083 "%s.close_ike_on_child_failure", FALSE
, lib
->ns
))
1085 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
1087 DBG1(DBG_IKE
, "closing IKE_SA due CHILD_SA setup failure");
1088 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, (job_t
*)
1089 delete_ike_sa_job_create(this->ike_sa
->get_id(this->ike_sa
), TRUE
),
1094 DBG1(DBG_IKE
, "failed to establish CHILD_SA, keeping IKE_SA");
1095 charon
->bus
->alert(charon
->bus
, ALERT_KEEP_ON_CHILD_SA_FAILURE
);
1100 * Substitute transport mode NAT selectors, if applicable
1102 static linked_list_t
* get_ts_if_nat_transport(private_child_create_t
*this,
1103 bool local
, linked_list_t
*in
)
1105 linked_list_t
*out
= NULL
;
1106 ike_condition_t cond
;
1108 if (this->mode
== MODE_TRANSPORT
)
1110 cond
= local ? COND_NAT_HERE
: COND_NAT_THERE
;
1111 if (this->ike_sa
->has_condition(this->ike_sa
, cond
))
1113 out
= get_transport_nat_ts(this, local
, in
);
1114 if (out
->get_count(out
) == 0)
1125 * Select a matching CHILD config as responder
1127 static child_cfg_t
* select_child_cfg(private_child_create_t
*this)
1129 peer_cfg_t
*peer_cfg
;
1130 child_cfg_t
*child_cfg
= NULL
;;
1132 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
1133 if (peer_cfg
&& this->tsi
&& this->tsr
)
1135 linked_list_t
*listr
, *listi
, *tsr
, *tsi
;
1137 tsr
= get_ts_if_nat_transport(this, TRUE
, this->tsr
);
1138 tsi
= get_ts_if_nat_transport(this, FALSE
, this->tsi
);
1140 listr
= get_dynamic_hosts(this->ike_sa
, TRUE
);
1141 listi
= get_dynamic_hosts(this->ike_sa
, FALSE
);
1142 child_cfg
= peer_cfg
->select_child_cfg(peer_cfg
,
1143 tsr ?
: this->tsr
, tsi ?
: this->tsi
,
1145 if ((tsi
|| tsr
) && child_cfg
&&
1146 child_cfg
->get_mode(child_cfg
) != MODE_TRANSPORT
)
1148 /* found a CHILD config, but it doesn't use transport mode */
1149 child_cfg
->destroy(child_cfg
);
1152 if (!child_cfg
&& (tsi
|| tsr
))
1154 /* no match for the substituted NAT selectors, try it without */
1155 child_cfg
= peer_cfg
->select_child_cfg(peer_cfg
,
1156 this->tsr
, this->tsi
, listr
, listi
);
1158 listr
->destroy(listr
);
1159 listi
->destroy(listi
);
1160 DESTROY_OFFSET_IF(tsi
, offsetof(traffic_selector_t
, destroy
));
1161 DESTROY_OFFSET_IF(tsr
, offsetof(traffic_selector_t
, destroy
));
1167 METHOD(task_t
, build_r
, status_t
,
1168 private_child_create_t
*this, message_t
*message
)
1171 enumerator_t
*enumerator
;
1172 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1174 switch (message
->get_exchange_type(message
))
1177 return get_nonce(message
, &this->my_nonce
);
1178 case CREATE_CHILD_SA
:
1179 if (generate_nonce(this) != SUCCESS
)
1181 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1188 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1189 { /* wait until all authentication round completed */
1197 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_REKEYING
)
1199 DBG1(DBG_IKE
, "unable to create CHILD_SA while rekeying IKE_SA");
1200 message
->add_notify(message
, TRUE
, NO_ADDITIONAL_SAS
, chunk_empty
);
1203 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_DELETING
)
1205 DBG1(DBG_IKE
, "unable to create CHILD_SA while deleting IKE_SA");
1206 message
->add_notify(message
, TRUE
, NO_ADDITIONAL_SAS
, chunk_empty
);
1210 if (this->config
== NULL
)
1212 this->config
= select_child_cfg(this);
1214 if (this->config
== NULL
)
1216 DBG1(DBG_IKE
, "traffic selectors %#R=== %#R inacceptable",
1217 this->tsr
, this->tsi
);
1218 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
1219 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1220 handle_child_sa_failure(this, message
);
1224 /* check if ike_config_t included non-critical error notifies */
1225 enumerator
= message
->create_payload_enumerator(message
);
1226 while (enumerator
->enumerate(enumerator
, &payload
))
1228 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1230 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1232 switch (notify
->get_notify_type(notify
))
1234 case INTERNAL_ADDRESS_FAILURE
:
1235 case FAILED_CP_REQUIRED
:
1237 DBG1(DBG_IKE
,"configuration payload negotiation "
1238 "failed, no CHILD_SA built");
1239 enumerator
->destroy(enumerator
);
1240 handle_child_sa_failure(this, message
);
1248 enumerator
->destroy(enumerator
);
1250 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
1251 this->ike_sa
->get_other_host(this->ike_sa
), this->config
, this->reqid
,
1252 this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
),
1253 this->mark_in
, this->mark_out
);
1255 if (this->ipcomp_received
!= IPCOMP_NONE
)
1257 if (this->config
->use_ipcomp(this->config
))
1259 add_ipcomp_notify(this, message
, this->ipcomp_received
);
1263 DBG1(DBG_IKE
, "received %N notify but IPComp is disabled, ignoring",
1264 notify_type_names
, IPCOMP_SUPPORTED
);
1268 switch (select_and_install(this, no_dh
, ike_auth
))
1273 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1274 handle_child_sa_failure(this, message
);
1278 u_int16_t group
= htons(this->dh_group
);
1279 message
->add_notify(message
, FALSE
, INVALID_KE_PAYLOAD
,
1280 chunk_from_thing(group
));
1281 handle_child_sa_failure(this, message
);
1286 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
1287 handle_child_sa_failure(this, message
);
1291 build_payloads(this, message
);
1294 { /* invoke the child_up() hook if we are not rekeying */
1295 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1301 * Raise alerts for received notify errors
1303 static void raise_alerts(private_child_create_t
*this, notify_type_t type
)
1305 linked_list_t
*list
;
1309 case NO_PROPOSAL_CHOSEN
:
1310 list
= this->config
->get_proposals(this->config
, FALSE
);
1311 charon
->bus
->alert(charon
->bus
, ALERT_PROPOSAL_MISMATCH_CHILD
, list
);
1312 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1319 METHOD(task_t
, build_i_delete
, status_t
,
1320 private_child_create_t
*this, message_t
*message
)
1322 message
->set_exchange_type(message
, INFORMATIONAL
);
1323 if (this->child_sa
&& this->proposal
)
1325 protocol_id_t proto
;
1326 delete_payload_t
*del
;
1329 proto
= this->proposal
->get_protocol(this->proposal
);
1330 spi
= this->child_sa
->get_spi(this->child_sa
, TRUE
);
1331 del
= delete_payload_create(PLV2_DELETE
, proto
);
1332 del
->add_spi(del
, spi
);
1333 message
->add_payload(message
, (payload_t
*)del
);
1335 DBG1(DBG_IKE
, "sending DELETE for %N CHILD_SA with SPI %.8x",
1336 protocol_id_names
, proto
, ntohl(spi
));
1342 * Change task to delete the failed CHILD_SA as initiator
1344 static status_t
delete_failed_sa(private_child_create_t
*this)
1346 this->public.task
.build
= _build_i_delete
;
1347 this->public.task
.process
= (void*)return_success
;
1351 METHOD(task_t
, process_i
, status_t
,
1352 private_child_create_t
*this, message_t
*message
)
1354 enumerator_t
*enumerator
;
1356 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1358 switch (message
->get_exchange_type(message
))
1361 return get_nonce(message
, &this->other_nonce
);
1362 case CREATE_CHILD_SA
:
1363 get_nonce(message
, &this->other_nonce
);
1367 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1368 { /* wait until all authentication round completed */
1376 /* check for erroneous notifies */
1377 enumerator
= message
->create_payload_enumerator(message
);
1378 while (enumerator
->enumerate(enumerator
, &payload
))
1380 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1382 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1383 notify_type_t type
= notify
->get_notify_type(notify
);
1387 /* handle notify errors related to CHILD_SA only */
1388 case NO_PROPOSAL_CHOSEN
:
1389 case SINGLE_PAIR_REQUIRED
:
1390 case NO_ADDITIONAL_SAS
:
1391 case INTERNAL_ADDRESS_FAILURE
:
1392 case FAILED_CP_REQUIRED
:
1393 case TS_UNACCEPTABLE
:
1394 case INVALID_SELECTORS
:
1396 DBG1(DBG_IKE
, "received %N notify, no CHILD_SA built",
1397 notify_type_names
, type
);
1398 enumerator
->destroy(enumerator
);
1399 raise_alerts(this, type
);
1400 handle_child_sa_failure(this, message
);
1401 /* an error in CHILD_SA creation is not critical */
1404 case INVALID_KE_PAYLOAD
:
1407 u_int16_t group
= MODP_NONE
;
1409 data
= notify
->get_notification_data(notify
);
1410 if (data
.len
== sizeof(group
))
1412 memcpy(&group
, data
.ptr
, data
.len
);
1413 group
= ntohs(group
);
1415 DBG1(DBG_IKE
, "peer didn't accept DH group %N, "
1416 "it requested %N", diffie_hellman_group_names
,
1417 this->dh_group
, diffie_hellman_group_names
, group
);
1419 this->dh_group
= group
;
1420 this->child_sa
->set_state(this->child_sa
, CHILD_RETRYING
);
1421 this->public.task
.migrate(&this->public.task
, this->ike_sa
);
1422 enumerator
->destroy(enumerator
);
1427 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
1428 { /* handle notifies if not handled in IKE_AUTH */
1431 DBG1(DBG_IKE
, "received %N notify error",
1432 notify_type_names
, type
);
1433 enumerator
->destroy(enumerator
);
1436 DBG2(DBG_IKE
, "received %N notify",
1437 notify_type_names
, type
);
1444 enumerator
->destroy(enumerator
);
1446 process_payloads(this, message
);
1448 if (this->ipcomp
== IPCOMP_NONE
&& this->ipcomp_received
!= IPCOMP_NONE
)
1450 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify without requesting"
1451 " one, no CHILD_SA built");
1452 handle_child_sa_failure(this, message
);
1453 return delete_failed_sa(this);
1455 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp_received
== IPCOMP_NONE
)
1457 DBG1(DBG_IKE
, "peer didn't accept our proposed IPComp transforms, "
1458 "IPComp is disabled");
1459 this->ipcomp
= IPCOMP_NONE
;
1461 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp
!= this->ipcomp_received
)
1463 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1464 "no CHILD_SA built");
1465 handle_child_sa_failure(this, message
);
1466 return delete_failed_sa(this);
1469 if (select_and_install(this, no_dh
, ike_auth
) == SUCCESS
)
1472 { /* invoke the child_up() hook if we are not rekeying */
1473 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1478 handle_child_sa_failure(this, message
);
1479 return delete_failed_sa(this);
1484 METHOD(child_create_t
, use_reqid
, void,
1485 private_child_create_t
*this, u_int32_t reqid
)
1487 this->reqid
= reqid
;
1490 METHOD(child_create_t
, use_marks
, void,
1491 private_child_create_t
*this, u_int in
, u_int out
)
1494 this->mark_out
= out
;
1497 METHOD(child_create_t
, get_child
, child_sa_t
*,
1498 private_child_create_t
*this)
1500 return this->child_sa
;
1503 METHOD(child_create_t
, set_config
, void,
1504 private_child_create_t
*this, child_cfg_t
*cfg
)
1506 DESTROY_IF(this->config
);
1510 METHOD(child_create_t
, get_lower_nonce
, chunk_t
,
1511 private_child_create_t
*this)
1513 if (memcmp(this->my_nonce
.ptr
, this->other_nonce
.ptr
,
1514 min(this->my_nonce
.len
, this->other_nonce
.len
)) < 0)
1516 return this->my_nonce
;
1520 return this->other_nonce
;
1524 METHOD(task_t
, get_type
, task_type_t
,
1525 private_child_create_t
*this)
1527 return TASK_CHILD_CREATE
;
1530 METHOD(task_t
, migrate
, void,
1531 private_child_create_t
*this, ike_sa_t
*ike_sa
)
1533 chunk_free(&this->my_nonce
);
1534 chunk_free(&this->other_nonce
);
1537 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1541 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1543 DESTROY_IF(this->child_sa
);
1544 DESTROY_IF(this->proposal
);
1545 DESTROY_IF(this->dh
);
1546 if (this->proposals
)
1548 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1551 this->ike_sa
= ike_sa
;
1552 this->keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
);
1553 this->proposal
= NULL
;
1554 this->proposals
= NULL
;
1558 this->child_sa
= NULL
;
1559 this->mode
= MODE_TUNNEL
;
1560 this->ipcomp
= IPCOMP_NONE
;
1561 this->ipcomp_received
= IPCOMP_NONE
;
1562 this->other_cpi
= 0;
1566 this->established
= FALSE
;
1569 METHOD(task_t
, destroy
, void,
1570 private_child_create_t
*this)
1572 chunk_free(&this->my_nonce
);
1573 chunk_free(&this->other_nonce
);
1576 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1580 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1582 if (!this->established
)
1584 DESTROY_IF(this->child_sa
);
1586 DESTROY_IF(this->packet_tsi
);
1587 DESTROY_IF(this->packet_tsr
);
1588 DESTROY_IF(this->proposal
);
1589 DESTROY_IF(this->dh
);
1590 if (this->proposals
)
1592 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1595 DESTROY_IF(this->config
);
1600 * Described in header.
1602 child_create_t
*child_create_create(ike_sa_t
*ike_sa
,
1603 child_cfg_t
*config
, bool rekey
,
1604 traffic_selector_t
*tsi
, traffic_selector_t
*tsr
)
1606 private_child_create_t
*this;
1610 .get_child
= _get_child
,
1611 .set_config
= _set_config
,
1612 .get_lower_nonce
= _get_lower_nonce
,
1613 .use_reqid
= _use_reqid
,
1614 .use_marks
= _use_marks
,
1616 .get_type
= _get_type
,
1617 .migrate
= _migrate
,
1618 .destroy
= _destroy
,
1623 .packet_tsi
= tsi ? tsi
->clone(tsi
) : NULL
,
1624 .packet_tsr
= tsr ? tsr
->clone(tsr
) : NULL
,
1625 .dh_group
= MODP_NONE
,
1626 .keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
),
1627 .mode
= MODE_TUNNEL
,
1629 .ipcomp
= IPCOMP_NONE
,
1630 .ipcomp_received
= IPCOMP_NONE
,
1637 this->public.task
.build
= _build_i
;
1638 this->public.task
.process
= _process_i
;
1639 this->initiator
= TRUE
;
1643 this->public.task
.build
= _build_r
;
1644 this->public.task
.process
= _process_r
;
1645 this->initiator
= FALSE
;
1648 return &this->public;