2 * Copyright (C) 2008-2019 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * HSR 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"
21 #include <sa/ikev2/keymat_v2.h>
22 #include <crypto/diffie_hellman.h>
23 #include <credentials/certificates/x509.h>
24 #include <encoding/payloads/sa_payload.h>
25 #include <encoding/payloads/ke_payload.h>
26 #include <encoding/payloads/ts_payload.h>
27 #include <encoding/payloads/nonce_payload.h>
28 #include <encoding/payloads/notify_payload.h>
29 #include <encoding/payloads/delete_payload.h>
30 #include <processing/jobs/delete_ike_sa_job.h>
31 #include <processing/jobs/inactivity_job.h>
32 #include <processing/jobs/initiate_tasks_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
72 * config to create the CHILD_SA from
77 * list of proposal candidates
79 linked_list_t
*proposals
;
82 * selected proposal to use for CHILD_SA
87 * traffic selectors for initiators side
92 * traffic selectors for responders side
97 * source of triggering packet
99 traffic_selector_t
*packet_tsi
;
102 * destination of triggering packet
104 traffic_selector_t
*packet_tsr
;
107 * optional diffie hellman exchange
109 diffie_hellman_t
*dh
;
112 * Applying DH public value failed?
117 * group used for DH exchange
119 diffie_hellman_group_t dh_group
;
127 * mode the new CHILD_SA uses (transport/tunnel/beet)
132 * peer accepts TFC padding for this SA
137 * IPComp transform to use
139 ipcomp_transform_t ipcomp
;
142 * IPComp transform proposed or accepted by the other peer
144 ipcomp_transform_t ipcomp_received
;
157 * SPI received in proposal
162 * Own allocated Compression Parameter Index (CPI)
167 * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
172 * Data collected to create the CHILD_SA
174 child_sa_create_t child
;
177 * CHILD_SA which gets established
179 child_sa_t
*child_sa
;
182 * successfully established the CHILD?
187 * whether the CHILD_SA rekeys an existing one
192 * whether we are retrying with another DH group
198 * Schedule a retry if creating the CHILD_SA temporary failed
200 static void schedule_delayed_retry(private_child_create_t
*this)
202 child_create_t
*task
;
205 retry
= RETRY_INTERVAL
- (random() % RETRY_JITTER
);
207 task
= child_create_create(this->ike_sa
,
208 this->config
->get_ref(this->config
), FALSE
,
209 this->packet_tsi
, this->packet_tsr
);
210 task
->use_reqid(task
, this->child
.reqid
);
211 task
->use_marks(task
, this->child
.mark_in
, this->child
.mark_out
);
212 task
->use_if_ids(task
, this->child
.if_id_in
, this->child
.if_id_out
);
214 DBG1(DBG_IKE
, "creating CHILD_SA failed, trying again in %d seconds",
216 this->ike_sa
->queue_task_delayed(this->ike_sa
, (task_t
*)task
, retry
);
220 * get the nonce from a message
222 static status_t
get_nonce(message_t
*message
, chunk_t
*nonce
)
224 nonce_payload_t
*payload
;
226 payload
= (nonce_payload_t
*)message
->get_payload(message
, PLV2_NONCE
);
231 *nonce
= payload
->get_nonce(payload
);
236 * generate a new nonce to include in a CREATE_CHILD_SA message
238 static bool generate_nonce(private_child_create_t
*this)
240 this->nonceg
= this->keymat
->keymat
.create_nonce_gen(&this->keymat
->keymat
);
243 DBG1(DBG_IKE
, "no nonce generator found to create nonce");
246 if (!this->nonceg
->allocate_nonce(this->nonceg
, NONCE_SIZE
,
249 DBG1(DBG_IKE
, "nonce allocation failed");
256 * Check a list of traffic selectors if any selector belongs to host
258 static bool ts_list_is_host(linked_list_t
*list
, host_t
*host
)
260 traffic_selector_t
*ts
;
262 enumerator_t
*enumerator
= list
->create_enumerator(list
);
264 while (is_host
&& enumerator
->enumerate(enumerator
, (void**)&ts
))
266 is_host
= is_host
&& ts
->is_host(ts
, host
);
268 enumerator
->destroy(enumerator
);
275 static bool allocate_spi(private_child_create_t
*this)
277 proposal_t
*proposal
;
281 this->proto
= PROTO_ESP
;
282 /* we just get a SPI for the first protocol. TODO: If we ever support
283 * proposal lists with mixed protocols, we'd need multiple SPIs */
284 if (this->proposals
->get_first(this->proposals
,
285 (void**)&proposal
) == SUCCESS
)
287 this->proto
= proposal
->get_protocol(proposal
);
292 this->proto
= this->proposal
->get_protocol(this->proposal
);
294 this->my_spi
= this->child_sa
->alloc_spi(this->child_sa
, this->proto
);
295 return this->my_spi
!= 0;
299 * Update the proposals with the allocated SPIs as initiator and check the DH
300 * group and promote it if necessary
302 static bool update_and_check_proposals(private_child_create_t
*this)
304 enumerator_t
*enumerator
;
305 proposal_t
*proposal
;
306 linked_list_t
*other_dh_groups
;
309 other_dh_groups
= linked_list_create();
310 enumerator
= this->proposals
->create_enumerator(this->proposals
);
311 while (enumerator
->enumerate(enumerator
, &proposal
))
313 proposal
->set_spi(proposal
, this->my_spi
);
315 /* move the selected DH group to the front, if any */
316 if (this->dh_group
!= MODP_NONE
)
317 { /* proposals that don't contain the selected group are
318 * moved to the back */
319 if (!proposal
->promote_dh_group(proposal
, this->dh_group
))
321 this->proposals
->remove_at(this->proposals
, enumerator
);
322 other_dh_groups
->insert_last(other_dh_groups
, proposal
);
330 enumerator
->destroy(enumerator
);
331 enumerator
= other_dh_groups
->create_enumerator(other_dh_groups
);
332 while (enumerator
->enumerate(enumerator
, (void**)&proposal
))
333 { /* no need to remove from the list as we destroy it anyway*/
334 this->proposals
->insert_last(this->proposals
, proposal
);
336 enumerator
->destroy(enumerator
);
337 other_dh_groups
->destroy(other_dh_groups
);
339 return this->dh_group
== MODP_NONE
|| found
;
343 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
345 static void schedule_inactivity_timeout(private_child_create_t
*this)
347 uint32_t timeout
, id
;
350 timeout
= this->config
->get_inactivity(this->config
);
353 close_ike
= lib
->settings
->get_bool(lib
->settings
,
354 "%s.inactivity_close_ike", FALSE
, lib
->ns
);
355 id
= this->child_sa
->get_unique_id(this->child_sa
);
356 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)
357 inactivity_job_create(id
, timeout
, close_ike
), timeout
);
362 * Check if we have a an address pool configured
364 static bool have_pool(ike_sa_t
*ike_sa
)
366 enumerator_t
*enumerator
;
367 peer_cfg_t
*peer_cfg
;
371 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
374 enumerator
= peer_cfg
->create_pool_enumerator(peer_cfg
);
375 if (enumerator
->enumerate(enumerator
, &pool
))
379 enumerator
->destroy(enumerator
);
385 * Get hosts to use for dynamic traffic selectors
387 static linked_list_t
*get_dynamic_hosts(ike_sa_t
*ike_sa
, bool local
)
389 enumerator_t
*enumerator
;
393 list
= linked_list_create();
394 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, local
);
395 while (enumerator
->enumerate(enumerator
, &host
))
397 list
->insert_last(list
, host
);
399 enumerator
->destroy(enumerator
);
401 if (list
->get_count(list
) == 0)
402 { /* no virtual IPs assigned */
405 host
= ike_sa
->get_my_host(ike_sa
);
406 list
->insert_last(list
, host
);
408 else if (!have_pool(ike_sa
))
409 { /* use host only if we don't have a pool configured */
410 host
= ike_sa
->get_other_host(ike_sa
);
411 list
->insert_last(list
, host
);
418 * Substitute any host address with NATed address in traffic selector
420 static linked_list_t
* get_transport_nat_ts(private_child_create_t
*this,
421 bool local
, linked_list_t
*in
)
423 enumerator_t
*enumerator
;
425 traffic_selector_t
*ts
;
426 host_t
*ike
, *first
= NULL
;
431 ike
= this->ike_sa
->get_my_host(this->ike_sa
);
435 ike
= this->ike_sa
->get_other_host(this->ike_sa
);
438 out
= linked_list_create();
440 enumerator
= in
->create_enumerator(in
);
441 while (enumerator
->enumerate(enumerator
, &ts
))
443 /* require that all selectors match the first "host" selector */
444 if (ts
->is_host(ts
, first
))
448 ts
->to_subnet(ts
, &first
, &mask
);
451 ts
->set_address(ts
, ike
);
452 out
->insert_last(out
, ts
);
455 enumerator
->destroy(enumerator
);
462 * Narrow received traffic selectors with configuration
464 static linked_list_t
* narrow_ts(private_child_create_t
*this, bool local
,
467 linked_list_t
*hosts
, *nat
, *ts
;
468 ike_condition_t cond
;
470 cond
= local ? COND_NAT_HERE
: COND_NAT_THERE
;
471 hosts
= get_dynamic_hosts(this->ike_sa
, local
);
473 if (this->mode
== MODE_TRANSPORT
&&
474 this->ike_sa
->has_condition(this->ike_sa
, cond
))
476 nat
= get_transport_nat_ts(this, local
, in
);
477 ts
= this->config
->get_traffic_selectors(this->config
, local
, nat
,
479 nat
->destroy_offset(nat
, offsetof(traffic_selector_t
, destroy
));
483 ts
= this->config
->get_traffic_selectors(this->config
, local
, in
,
487 hosts
->destroy(hosts
);
493 * Check if requested mode is acceptable
495 static bool check_mode(private_child_create_t
*this, host_t
*i
, host_t
*r
)
500 if (!this->config
->has_option(this->config
, OPT_PROXY_MODE
) &&
501 (!ts_list_is_host(this->tsi
, i
) ||
502 !ts_list_is_host(this->tsr
, r
))
505 DBG1(DBG_IKE
, "not using transport mode, not host-to-host");
508 if (this->config
->get_mode(this->config
) != MODE_TRANSPORT
)
514 if (!ts_list_is_host(this->tsi
, NULL
) ||
515 !ts_list_is_host(this->tsr
, NULL
))
517 DBG1(DBG_IKE
, "not using BEET mode, not host-to-host");
520 if (this->config
->get_mode(this->config
) != MODE_BEET
)
532 * Install a CHILD_SA for usage, return value:
533 * - FAILED: no acceptable proposal
534 * - INVALID_ARG: diffie hellman group unacceptable
535 * - NOT_FOUND: TS unacceptable
537 static status_t
select_and_install(private_child_create_t
*this,
538 bool no_dh
, bool ike_auth
)
540 status_t status
, status_i
, status_o
;
541 child_sa_outbound_state_t out_state
;
542 chunk_t nonce_i
, nonce_r
;
543 chunk_t encr_i
= chunk_empty
, encr_r
= chunk_empty
;
544 chunk_t integ_i
= chunk_empty
, integ_r
= chunk_empty
;
545 linked_list_t
*my_ts
, *other_ts
;
547 proposal_selection_flag_t flags
= 0;
549 if (this->proposals
== NULL
)
551 DBG1(DBG_IKE
, "SA payload missing in message");
554 if (this->tsi
== NULL
|| this->tsr
== NULL
)
556 DBG1(DBG_IKE
, "TS payloads missing in message");
560 me
= this->ike_sa
->get_my_host(this->ike_sa
);
561 other
= this->ike_sa
->get_other_host(this->ike_sa
);
565 flags
|= PROPOSAL_SKIP_DH
;
567 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
))
569 flags
|= PROPOSAL_SKIP_PRIVATE
;
571 if (!lib
->settings
->get_bool(lib
->settings
,
572 "%s.prefer_configured_proposals", TRUE
, lib
->ns
))
574 flags
|= PROPOSAL_PREFER_SUPPLIED
;
576 this->proposal
= this->config
->select_proposal(this->config
,
577 this->proposals
, flags
);
578 if (this->proposal
== NULL
)
580 DBG1(DBG_IKE
, "no acceptable proposal found");
581 charon
->bus
->alert(charon
->bus
, ALERT_PROPOSAL_MISMATCH_CHILD
,
585 this->other_spi
= this->proposal
->get_spi(this->proposal
);
587 if (!this->initiator
)
589 if (!allocate_spi(this))
591 /* responder has no SPI allocated yet */
592 DBG1(DBG_IKE
, "allocating SPI failed");
595 this->proposal
->set_spi(this->proposal
, this->my_spi
);
597 this->child_sa
->set_proposal(this->child_sa
, this->proposal
);
599 if (!this->proposal
->has_dh_group(this->proposal
, this->dh_group
))
603 if (this->proposal
->get_algorithm(this->proposal
, DIFFIE_HELLMAN_GROUP
,
606 DBG1(DBG_IKE
, "DH group %N unacceptable, requesting %N",
607 diffie_hellman_group_names
, this->dh_group
,
608 diffie_hellman_group_names
, group
);
609 this->dh_group
= group
;
612 /* the selected proposal does not use a DH group */
613 DBG1(DBG_IKE
, "ignoring KE exchange, agreed on a non-PFS proposal");
614 DESTROY_IF(this->dh
);
616 this->dh_group
= MODP_NONE
;
621 nonce_i
= this->my_nonce
;
622 nonce_r
= this->other_nonce
;
623 my_ts
= narrow_ts(this, TRUE
, this->tsi
);
624 other_ts
= narrow_ts(this, FALSE
, this->tsr
);
628 nonce_r
= this->my_nonce
;
629 nonce_i
= this->other_nonce
;
630 my_ts
= narrow_ts(this, TRUE
, this->tsr
);
631 other_ts
= narrow_ts(this, FALSE
, this->tsi
);
638 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
639 NARROW_INITIATOR_POST_NOAUTH
, my_ts
, other_ts
);
643 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
644 NARROW_INITIATOR_POST_AUTH
, my_ts
, other_ts
);
649 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
650 NARROW_RESPONDER
, my_ts
, other_ts
);
653 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
655 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
656 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
657 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
658 DBG1(DBG_IKE
, "no acceptable traffic selectors found");
662 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
663 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
667 this->tsr
= other_ts
;
669 if (!check_mode(this, me
, other
))
671 DBG1(DBG_IKE
, "%N mode requested by responder is unacceptable",
672 ipsec_mode_names
, this->mode
);
679 this->tsi
= other_ts
;
681 if (!check_mode(this, other
, me
))
683 this->mode
= MODE_TUNNEL
;
687 if (!this->initiator
)
689 /* use a copy of the traffic selectors, as the POST hook should not
691 my_ts
= this->tsr
->clone_offset(this->tsr
,
692 offsetof(traffic_selector_t
, clone
));
693 other_ts
= this->tsi
->clone_offset(this->tsi
,
694 offsetof(traffic_selector_t
, clone
));
695 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
696 NARROW_RESPONDER_POST
, my_ts
, other_ts
);
698 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
700 my_ts
->destroy_offset(my_ts
,
701 offsetof(traffic_selector_t
, destroy
));
702 other_ts
->destroy_offset(other_ts
,
703 offsetof(traffic_selector_t
, destroy
));
708 this->child_sa
->set_policies(this->child_sa
, my_ts
, other_ts
);
709 if (!this->initiator
)
711 my_ts
->destroy_offset(my_ts
,
712 offsetof(traffic_selector_t
, destroy
));
713 other_ts
->destroy_offset(other_ts
,
714 offsetof(traffic_selector_t
, destroy
));
717 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLING
);
718 this->child_sa
->set_ipcomp(this->child_sa
, this->ipcomp
);
719 this->child_sa
->set_mode(this->child_sa
, this->mode
);
720 this->child_sa
->set_protocol(this->child_sa
,
721 this->proposal
->get_protocol(this->proposal
));
723 if (this->my_cpi
== 0 || this->other_cpi
== 0 || this->ipcomp
== IPCOMP_NONE
)
725 this->my_cpi
= this->other_cpi
= 0;
726 this->ipcomp
= IPCOMP_NONE
;
728 status_i
= status_o
= FAILED
;
729 if (this->keymat
->derive_child_keys(this->keymat
, this->proposal
,
730 this->dh
, nonce_i
, nonce_r
, &encr_i
, &integ_i
, &encr_r
, &integ_r
))
734 status_i
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
735 this->my_spi
, this->my_cpi
, this->initiator
,
740 status_i
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
741 this->my_spi
, this->my_cpi
, this->initiator
,
745 { /* during rekeyings we install the outbound SA and/or policies
746 * separately: as responder when we receive the delete for the old
747 * SA, as initiator pretty much immediately in the ike-rekey task,
748 * unless there was a rekey collision that we lost */
751 status_o
= this->child_sa
->register_outbound(this->child_sa
,
752 encr_i
, integ_i
, this->other_spi
, this->other_cpi
,
757 status_o
= this->child_sa
->register_outbound(this->child_sa
,
758 encr_r
, integ_r
, this->other_spi
, this->other_cpi
,
762 else if (this->initiator
)
764 status_o
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
765 this->other_spi
, this->other_cpi
, this->initiator
,
770 status_o
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
771 this->other_spi
, this->other_cpi
, this->initiator
,
776 if (status_i
!= SUCCESS
|| status_o
!= SUCCESS
)
778 DBG1(DBG_IKE
, "unable to install %s%s%sIPsec SA (SAD) in kernel",
779 (status_i
!= SUCCESS
) ?
"inbound " : "",
780 (status_i
!= SUCCESS
&& status_o
!= SUCCESS
) ?
"and ": "",
781 (status_o
!= SUCCESS
) ?
"outbound " : "");
782 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_SA_FAILED
,
788 status
= this->child_sa
->install_policies(this->child_sa
);
790 if (status
!= SUCCESS
)
792 DBG1(DBG_IKE
, "unable to install IPsec policies (SPD) in kernel");
793 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_POLICY_FAILED
,
799 charon
->bus
->child_derived_keys(charon
->bus
, this->child_sa
,
800 this->initiator
, encr_i
, encr_r
,
804 chunk_clear(&integ_i
);
805 chunk_clear(&integ_r
);
806 chunk_clear(&encr_i
);
807 chunk_clear(&encr_r
);
809 if (status
!= SUCCESS
)
814 charon
->bus
->child_keys(charon
->bus
, this->child_sa
, this->initiator
,
815 this->dh
, nonce_i
, nonce_r
);
817 my_ts
= linked_list_create_from_enumerator(
818 this->child_sa
->create_ts_enumerator(this->child_sa
, TRUE
));
819 other_ts
= linked_list_create_from_enumerator(
820 this->child_sa
->create_ts_enumerator(this->child_sa
, FALSE
));
821 out_state
= this->child_sa
->get_outbound_state(this->child_sa
);
823 DBG0(DBG_IKE
, "%sCHILD_SA %s{%d} established "
824 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
825 (out_state
== CHILD_OUTBOUND_INSTALLED
) ?
"" : "inbound ",
826 this->child_sa
->get_name(this->child_sa
),
827 this->child_sa
->get_unique_id(this->child_sa
),
828 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
829 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)),
832 my_ts
->destroy(my_ts
);
833 other_ts
->destroy(other_ts
);
835 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
836 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
837 this->established
= TRUE
;
839 schedule_inactivity_timeout(this);
844 * build the payloads for the message
846 static bool build_payloads(private_child_create_t
*this, message_t
*message
)
848 sa_payload_t
*sa_payload
;
849 nonce_payload_t
*nonce_payload
;
850 ke_payload_t
*ke_payload
;
851 ts_payload_t
*ts_payload
;
852 kernel_feature_t features
;
857 sa_payload
= sa_payload_create_from_proposals_v2(this->proposals
);
861 sa_payload
= sa_payload_create_from_proposal_v2(this->proposal
);
863 message
->add_payload(message
, (payload_t
*)sa_payload
);
865 /* add nonce payload if not in IKE_AUTH */
866 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
868 nonce_payload
= nonce_payload_create(PLV2_NONCE
);
869 nonce_payload
->set_nonce(nonce_payload
, this->my_nonce
);
870 message
->add_payload(message
, (payload_t
*)nonce_payload
);
873 /* diffie hellman exchange, if PFS enabled */
876 ke_payload
= ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE
,
880 DBG1(DBG_IKE
, "creating KE payload failed");
883 message
->add_payload(message
, (payload_t
*)ke_payload
);
886 /* add TSi/TSr payloads */
887 ts_payload
= ts_payload_create_from_traffic_selectors(TRUE
, this->tsi
);
888 message
->add_payload(message
, (payload_t
*)ts_payload
);
889 ts_payload
= ts_payload_create_from_traffic_selectors(FALSE
, this->tsr
);
890 message
->add_payload(message
, (payload_t
*)ts_payload
);
892 /* add a notify if we are not in tunnel mode */
896 message
->add_notify(message
, FALSE
, USE_TRANSPORT_MODE
, chunk_empty
);
899 message
->add_notify(message
, FALSE
, USE_BEET_MODE
, chunk_empty
);
905 features
= charon
->kernel
->get_features(charon
->kernel
);
906 if (!(features
& KERNEL_ESP_V3_TFC
))
908 message
->add_notify(message
, FALSE
, ESP_TFC_PADDING_NOT_SUPPORTED
,
915 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
917 static void add_ipcomp_notify(private_child_create_t
*this,
918 message_t
*message
, uint8_t ipcomp
)
920 this->my_cpi
= this->child_sa
->alloc_cpi(this->child_sa
);
923 this->ipcomp
= ipcomp
;
924 message
->add_notify(message
, FALSE
, IPCOMP_SUPPORTED
,
925 chunk_cata("cc", chunk_from_thing(this->my_cpi
),
926 chunk_from_thing(ipcomp
)));
930 DBG1(DBG_IKE
, "unable to allocate a CPI from kernel, IPComp disabled");
935 * handle a received notify payload
937 static void handle_notify(private_child_create_t
*this, notify_payload_t
*notify
)
939 switch (notify
->get_notify_type(notify
))
941 case USE_TRANSPORT_MODE
:
942 this->mode
= MODE_TRANSPORT
;
945 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
))
946 { /* handle private use notify only if we know its meaning */
947 this->mode
= MODE_BEET
;
951 DBG1(DBG_IKE
, "received a notify strongSwan uses for BEET "
952 "mode, but peer implementation unknown, skipped");
955 case IPCOMP_SUPPORTED
:
957 ipcomp_transform_t ipcomp
;
961 data
= notify
->get_notification_data(notify
);
962 cpi
= *(uint16_t*)data
.ptr
;
963 ipcomp
= (ipcomp_transform_t
)(*(data
.ptr
+ 2));
967 this->other_cpi
= cpi
;
968 this->ipcomp_received
= ipcomp
;
973 DBG1(DBG_IKE
, "received IPCOMP_SUPPORTED notify with a "
974 "transform ID we don't support %N",
975 ipcomp_transform_names
, ipcomp
);
980 case ESP_TFC_PADDING_NOT_SUPPORTED
:
981 DBG1(DBG_IKE
, "received %N, not using ESPv3 TFC padding",
982 notify_type_names
, notify
->get_notify_type(notify
));
991 * Read payloads from message
993 static void process_payloads(private_child_create_t
*this, message_t
*message
)
995 enumerator_t
*enumerator
;
997 sa_payload_t
*sa_payload
;
998 ke_payload_t
*ke_payload
;
999 ts_payload_t
*ts_payload
;
1001 /* defaults to TUNNEL mode */
1002 this->mode
= MODE_TUNNEL
;
1004 enumerator
= message
->create_payload_enumerator(message
);
1005 while (enumerator
->enumerate(enumerator
, &payload
))
1007 switch (payload
->get_type(payload
))
1009 case PLV2_SECURITY_ASSOCIATION
:
1010 sa_payload
= (sa_payload_t
*)payload
;
1011 this->proposals
= sa_payload
->get_proposals(sa_payload
);
1013 case PLV2_KEY_EXCHANGE
:
1014 ke_payload
= (ke_payload_t
*)payload
;
1015 if (!this->initiator
)
1017 this->dh_group
= ke_payload
->get_dh_group_number(ke_payload
);
1018 this->dh
= this->keymat
->keymat
.create_dh(
1019 &this->keymat
->keymat
, this->dh_group
);
1023 this->dh_failed
= this->dh
->get_dh_group(this->dh
) !=
1024 ke_payload
->get_dh_group_number(ke_payload
);
1026 if (this->dh
&& !this->dh_failed
)
1028 this->dh_failed
= !this->dh
->set_other_public_value(this->dh
,
1029 ke_payload
->get_key_exchange_data(ke_payload
));
1032 case PLV2_TS_INITIATOR
:
1033 ts_payload
= (ts_payload_t
*)payload
;
1034 this->tsi
= ts_payload
->get_traffic_selectors(ts_payload
);
1036 case PLV2_TS_RESPONDER
:
1037 ts_payload
= (ts_payload_t
*)payload
;
1038 this->tsr
= ts_payload
->get_traffic_selectors(ts_payload
);
1041 handle_notify(this, (notify_payload_t
*)payload
);
1047 enumerator
->destroy(enumerator
);
1051 * Check if we should defer the creation of this CHILD_SA until after the
1052 * IKE_SA has been established childless.
1054 static status_t
defer_child_sa(private_child_create_t
*this)
1058 ike_cfg
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
1060 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_IKE_CHILDLESS
))
1062 if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_FORCE
)
1067 else if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_FORCE
)
1069 DBG1(DBG_IKE
, "peer does not support childless IKE_SA initiation");
1072 return NOT_SUPPORTED
;
1075 METHOD(task_t
, build_i
, status_t
,
1076 private_child_create_t
*this, message_t
*message
)
1078 enumerator_t
*enumerator
;
1080 peer_cfg_t
*peer_cfg
;
1081 linked_list_t
*list
;
1083 switch (message
->get_exchange_type(message
))
1086 return get_nonce(message
, &this->my_nonce
);
1087 case CREATE_CHILD_SA
:
1088 if (!generate_nonce(this))
1090 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1094 if (!this->retry
&& this->dh_group
== MODP_NONE
)
1095 { /* during a rekeying the group might already be set */
1096 this->dh_group
= this->config
->get_dh_group(this->config
);
1100 if (message
->get_message_id(message
) != 1)
1102 /* send only in the first request, not in subsequent rounds */
1105 switch (defer_child_sa(this))
1108 /* config mismatch */
1111 /* defer until after IKE_SA has been established */
1112 chunk_free(&this->my_nonce
);
1115 /* just continue to establish the CHILD_SA */
1123 /* check if we want a virtual IP, but don't have one */
1124 list
= linked_list_create();
1125 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
1128 enumerator
= peer_cfg
->create_virtual_ip_enumerator(peer_cfg
);
1129 while (enumerator
->enumerate(enumerator
, &vip
))
1131 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
1132 vip
= host_create_any(vip
->get_family(vip
));
1133 list
->insert_last(list
, vip
);
1135 enumerator
->destroy(enumerator
);
1137 if (list
->get_count(list
))
1139 this->tsi
= this->config
->get_traffic_selectors(this->config
,
1140 TRUE
, NULL
, list
, TRUE
);
1141 list
->destroy_offset(list
, offsetof(host_t
, destroy
));
1144 { /* no virtual IPs configured */
1145 list
->destroy(list
);
1146 list
= get_dynamic_hosts(this->ike_sa
, TRUE
);
1147 this->tsi
= this->config
->get_traffic_selectors(this->config
,
1148 TRUE
, NULL
, list
, TRUE
);
1149 list
->destroy(list
);
1151 list
= get_dynamic_hosts(this->ike_sa
, FALSE
);
1152 this->tsr
= this->config
->get_traffic_selectors(this->config
,
1153 FALSE
, NULL
, list
, TRUE
);
1154 list
->destroy(list
);
1156 if (this->packet_tsi
)
1158 this->tsi
->insert_first(this->tsi
,
1159 this->packet_tsi
->clone(this->packet_tsi
));
1161 if (this->packet_tsr
)
1163 this->tsr
->insert_first(this->tsr
,
1164 this->packet_tsr
->clone(this->packet_tsr
));
1166 this->proposals
= this->config
->get_proposals(this->config
,
1167 this->dh_group
== MODP_NONE
);
1168 this->mode
= this->config
->get_mode(this->config
);
1170 this->child
.if_id_in_def
= this->ike_sa
->get_if_id(this->ike_sa
, TRUE
);
1171 this->child
.if_id_out_def
= this->ike_sa
->get_if_id(this->ike_sa
, FALSE
);
1172 this->child
.encap
= this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
);
1173 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
1174 this->ike_sa
->get_other_host(this->ike_sa
),
1175 this->config
, &this->child
);
1177 if (this->child
.reqid
)
1179 DBG0(DBG_IKE
, "establishing CHILD_SA %s{%d} reqid %d",
1180 this->child_sa
->get_name(this->child_sa
),
1181 this->child_sa
->get_unique_id(this->child_sa
), this->child
.reqid
);
1185 DBG0(DBG_IKE
, "establishing CHILD_SA %s{%d}",
1186 this->child_sa
->get_name(this->child_sa
),
1187 this->child_sa
->get_unique_id(this->child_sa
));
1190 if (!allocate_spi(this))
1192 DBG1(DBG_IKE
, "unable to allocate SPIs from kernel");
1196 if (!update_and_check_proposals(this))
1198 DBG1(DBG_IKE
, "requested DH group %N not contained in any of our "
1200 diffie_hellman_group_names
, this->dh_group
);
1204 if (this->dh_group
!= MODP_NONE
)
1206 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
1210 if (this->config
->has_option(this->config
, OPT_IPCOMP
))
1212 /* IPCOMP_DEFLATE is the only transform we support at the moment */
1213 add_ipcomp_notify(this, message
, IPCOMP_DEFLATE
);
1216 if (message
->get_exchange_type(message
) == IKE_AUTH
)
1218 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1219 NARROW_INITIATOR_PRE_NOAUTH
, this->tsi
, this->tsr
);
1223 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1224 NARROW_INITIATOR_PRE_AUTH
, this->tsi
, this->tsr
);
1227 if (!build_payloads(this, message
))
1232 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1233 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1234 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1237 this->proposals
= NULL
;
1242 METHOD(task_t
, process_r
, status_t
,
1243 private_child_create_t
*this, message_t
*message
)
1245 switch (message
->get_exchange_type(message
))
1248 return get_nonce(message
, &this->other_nonce
);
1249 case CREATE_CHILD_SA
:
1250 get_nonce(message
, &this->other_nonce
);
1253 if (message
->get_message_id(message
) != 1)
1255 /* only handle first AUTH payload, not additional rounds */
1262 process_payloads(this, message
);
1268 * handle CHILD_SA setup failure
1270 static void handle_child_sa_failure(private_child_create_t
*this,
1275 is_first
= message
->get_exchange_type(message
) == IKE_AUTH
;
1277 lib
->settings
->get_bool(lib
->settings
,
1278 "%s.close_ike_on_child_failure", FALSE
, lib
->ns
))
1280 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
1282 DBG1(DBG_IKE
, "closing IKE_SA due CHILD_SA setup failure");
1283 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, (job_t
*)
1284 delete_ike_sa_job_create(this->ike_sa
->get_id(this->ike_sa
), TRUE
),
1289 DBG1(DBG_IKE
, "failed to establish CHILD_SA, keeping IKE_SA");
1290 charon
->bus
->alert(charon
->bus
, ALERT_KEEP_ON_CHILD_SA_FAILURE
,
1296 * Substitute transport mode NAT selectors, if applicable
1298 static linked_list_t
* get_ts_if_nat_transport(private_child_create_t
*this,
1299 bool local
, linked_list_t
*in
)
1301 linked_list_t
*out
= NULL
;
1302 ike_condition_t cond
;
1304 if (this->mode
== MODE_TRANSPORT
)
1306 cond
= local ? COND_NAT_HERE
: COND_NAT_THERE
;
1307 if (this->ike_sa
->has_condition(this->ike_sa
, cond
))
1309 out
= get_transport_nat_ts(this, local
, in
);
1310 if (out
->get_count(out
) == 0)
1321 * Select a matching CHILD config as responder
1323 static child_cfg_t
* select_child_cfg(private_child_create_t
*this)
1325 peer_cfg_t
*peer_cfg
;
1326 child_cfg_t
*child_cfg
= NULL
;;
1328 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
1329 if (peer_cfg
&& this->tsi
&& this->tsr
)
1331 linked_list_t
*listr
, *listi
, *tsr
, *tsi
;
1333 tsr
= get_ts_if_nat_transport(this, TRUE
, this->tsr
);
1334 tsi
= get_ts_if_nat_transport(this, FALSE
, this->tsi
);
1336 listr
= get_dynamic_hosts(this->ike_sa
, TRUE
);
1337 listi
= get_dynamic_hosts(this->ike_sa
, FALSE
);
1338 child_cfg
= peer_cfg
->select_child_cfg(peer_cfg
,
1339 tsr ?
: this->tsr
, tsi ?
: this->tsi
,
1341 if ((tsi
|| tsr
) && child_cfg
&&
1342 child_cfg
->get_mode(child_cfg
) != MODE_TRANSPORT
)
1344 /* found a CHILD config, but it doesn't use transport mode */
1345 child_cfg
->destroy(child_cfg
);
1348 if (!child_cfg
&& (tsi
|| tsr
))
1350 /* no match for the substituted NAT selectors, try it without */
1351 child_cfg
= peer_cfg
->select_child_cfg(peer_cfg
,
1352 this->tsr
, this->tsi
, listr
, listi
);
1354 listr
->destroy(listr
);
1355 listi
->destroy(listi
);
1356 DESTROY_OFFSET_IF(tsi
, offsetof(traffic_selector_t
, destroy
));
1357 DESTROY_OFFSET_IF(tsr
, offsetof(traffic_selector_t
, destroy
));
1364 * Check how to handle a possibly childless IKE_SA
1366 static status_t
handle_childless(private_child_create_t
*this)
1370 ike_cfg
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
1372 if (!this->proposals
&& !this->tsi
&& !this->tsr
)
1374 /* looks like a childless IKE_SA, check if we allow it */
1375 if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_NEVER
)
1377 /* we don't allow childless initiation */
1378 DBG1(DBG_IKE
, "peer tried to initiate a childless IKE_SA");
1379 return INVALID_STATE
;
1384 /* the peer apparently wants to create a regular IKE_SA */
1385 if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_FORCE
)
1387 /* reject it if we only allow childless initiation */
1388 DBG1(DBG_IKE
, "peer did not initiate a childless IKE_SA");
1389 return INVALID_STATE
;
1391 return NOT_SUPPORTED
;
1394 METHOD(task_t
, build_r
, status_t
,
1395 private_child_create_t
*this, message_t
*message
)
1398 enumerator_t
*enumerator
;
1399 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1401 switch (message
->get_exchange_type(message
))
1404 return get_nonce(message
, &this->my_nonce
);
1405 case CREATE_CHILD_SA
:
1406 if (!generate_nonce(this))
1408 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1412 if (this->dh_failed
)
1414 DBG1(DBG_IKE
, "applying DH public value failed");
1415 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1422 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1423 { /* wait until all authentication round completed */
1426 if (this->ike_sa
->has_condition(this->ike_sa
, COND_REDIRECTED
))
1427 { /* no CHILD_SA is created for redirected SAs */
1430 switch (handle_childless(this))
1433 /* no CHILD_SA built */
1436 message
->add_notify(message
, FALSE
, INVALID_SYNTAX
,
1440 /* continue with regular initiation */
1448 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_REKEYING
)
1450 DBG1(DBG_IKE
, "unable to create CHILD_SA while rekeying IKE_SA");
1451 message
->add_notify(message
, TRUE
, TEMPORARY_FAILURE
, chunk_empty
);
1454 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_DELETING
)
1456 DBG1(DBG_IKE
, "unable to create CHILD_SA while deleting IKE_SA");
1457 message
->add_notify(message
, TRUE
, TEMPORARY_FAILURE
, chunk_empty
);
1461 if (this->config
== NULL
)
1463 this->config
= select_child_cfg(this);
1465 if (this->config
== NULL
)
1467 DBG1(DBG_IKE
, "traffic selectors %#R === %#R unacceptable",
1468 this->tsr
, this->tsi
);
1469 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
1470 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1471 handle_child_sa_failure(this, message
);
1475 /* check if ike_config_t included non-critical error notifies */
1476 enumerator
= message
->create_payload_enumerator(message
);
1477 while (enumerator
->enumerate(enumerator
, &payload
))
1479 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1481 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1483 switch (notify
->get_notify_type(notify
))
1485 case INTERNAL_ADDRESS_FAILURE
:
1486 case FAILED_CP_REQUIRED
:
1488 DBG1(DBG_IKE
,"configuration payload negotiation "
1489 "failed, no CHILD_SA built");
1490 enumerator
->destroy(enumerator
);
1491 handle_child_sa_failure(this, message
);
1499 enumerator
->destroy(enumerator
);
1501 this->child
.if_id_in_def
= this->ike_sa
->get_if_id(this->ike_sa
, TRUE
);
1502 this->child
.if_id_out_def
= this->ike_sa
->get_if_id(this->ike_sa
, FALSE
);
1503 this->child
.encap
= this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
);
1504 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
1505 this->ike_sa
->get_other_host(this->ike_sa
),
1506 this->config
, &this->child
);
1508 if (this->ipcomp_received
!= IPCOMP_NONE
)
1510 if (this->config
->has_option(this->config
, OPT_IPCOMP
))
1512 add_ipcomp_notify(this, message
, this->ipcomp_received
);
1516 DBG1(DBG_IKE
, "received %N notify but IPComp is disabled, ignoring",
1517 notify_type_names
, IPCOMP_SUPPORTED
);
1521 switch (select_and_install(this, no_dh
, ike_auth
))
1526 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1527 handle_child_sa_failure(this, message
);
1531 uint16_t group
= htons(this->dh_group
);
1532 message
->add_notify(message
, FALSE
, INVALID_KE_PAYLOAD
,
1533 chunk_from_thing(group
));
1538 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
1539 handle_child_sa_failure(this, message
);
1543 if (!build_payloads(this, message
))
1545 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
1546 handle_child_sa_failure(this, message
);
1551 { /* invoke the child_up() hook if we are not rekeying */
1552 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1558 * Raise alerts for received notify errors
1560 static void raise_alerts(private_child_create_t
*this, notify_type_t type
)
1562 linked_list_t
*list
;
1566 case NO_PROPOSAL_CHOSEN
:
1567 list
= this->config
->get_proposals(this->config
, FALSE
);
1568 charon
->bus
->alert(charon
->bus
, ALERT_PROPOSAL_MISMATCH_CHILD
, list
);
1569 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1576 METHOD(task_t
, build_i_delete
, status_t
,
1577 private_child_create_t
*this, message_t
*message
)
1579 message
->set_exchange_type(message
, INFORMATIONAL
);
1580 if (this->my_spi
&& this->proto
)
1582 delete_payload_t
*del
;
1584 del
= delete_payload_create(PLV2_DELETE
, this->proto
);
1585 del
->add_spi(del
, this->my_spi
);
1586 message
->add_payload(message
, (payload_t
*)del
);
1588 DBG1(DBG_IKE
, "sending DELETE for %N CHILD_SA with SPI %.8x",
1589 protocol_id_names
, this->proto
, ntohl(this->my_spi
));
1595 * Change task to delete the failed CHILD_SA as initiator
1597 static status_t
delete_failed_sa(private_child_create_t
*this)
1599 if (this->my_spi
&& this->proto
)
1601 this->public.task
.build
= _build_i_delete
;
1602 this->public.task
.process
= (void*)return_success
;
1608 METHOD(task_t
, process_i
, status_t
,
1609 private_child_create_t
*this, message_t
*message
)
1611 enumerator_t
*enumerator
;
1613 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1615 switch (message
->get_exchange_type(message
))
1618 return get_nonce(message
, &this->other_nonce
);
1619 case CREATE_CHILD_SA
:
1620 get_nonce(message
, &this->other_nonce
);
1624 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1625 { /* wait until all authentication round completed */
1628 if (defer_child_sa(this) == NEED_MORE
)
1629 { /* defer until after IKE_SA has been established */
1630 chunk_free(&this->other_nonce
);
1638 /* check for erroneous notifies */
1639 enumerator
= message
->create_payload_enumerator(message
);
1640 while (enumerator
->enumerate(enumerator
, &payload
))
1642 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1644 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1645 notify_type_t type
= notify
->get_notify_type(notify
);
1649 /* handle notify errors related to CHILD_SA only */
1650 case NO_PROPOSAL_CHOSEN
:
1651 case SINGLE_PAIR_REQUIRED
:
1652 case NO_ADDITIONAL_SAS
:
1653 case INTERNAL_ADDRESS_FAILURE
:
1654 case FAILED_CP_REQUIRED
:
1655 case TS_UNACCEPTABLE
:
1656 case INVALID_SELECTORS
:
1658 DBG1(DBG_IKE
, "received %N notify, no CHILD_SA built",
1659 notify_type_names
, type
);
1660 enumerator
->destroy(enumerator
);
1661 raise_alerts(this, type
);
1662 handle_child_sa_failure(this, message
);
1663 /* an error in CHILD_SA creation is not critical */
1666 case TEMPORARY_FAILURE
:
1668 DBG1(DBG_IKE
, "received %N notify, will retry later",
1669 notify_type_names
, type
);
1670 enumerator
->destroy(enumerator
);
1672 { /* the rekey task will retry itself if necessary */
1673 schedule_delayed_retry(this);
1677 case INVALID_KE_PAYLOAD
:
1680 uint16_t group
= MODP_NONE
;
1682 data
= notify
->get_notification_data(notify
);
1683 if (data
.len
== sizeof(group
))
1685 memcpy(&group
, data
.ptr
, data
.len
);
1686 group
= ntohs(group
);
1690 DBG1(DBG_IKE
, "already retried with DH group %N, "
1691 "ignore requested %N", diffie_hellman_group_names
,
1692 this->dh_group
, diffie_hellman_group_names
, group
);
1693 handle_child_sa_failure(this, message
);
1694 /* an error in CHILD_SA creation is not critical */
1697 DBG1(DBG_IKE
, "peer didn't accept DH group %N, "
1698 "it requested %N", diffie_hellman_group_names
,
1699 this->dh_group
, diffie_hellman_group_names
, group
);
1701 this->dh_group
= group
;
1702 this->child_sa
->set_state(this->child_sa
, CHILD_RETRYING
);
1703 this->public.task
.migrate(&this->public.task
, this->ike_sa
);
1704 enumerator
->destroy(enumerator
);
1709 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
1710 { /* handle notifies if not handled in IKE_AUTH */
1713 DBG1(DBG_IKE
, "received %N notify error",
1714 notify_type_names
, type
);
1715 enumerator
->destroy(enumerator
);
1718 DBG2(DBG_IKE
, "received %N notify",
1719 notify_type_names
, type
);
1726 enumerator
->destroy(enumerator
);
1728 process_payloads(this, message
);
1730 if (this->ipcomp
== IPCOMP_NONE
&& this->ipcomp_received
!= IPCOMP_NONE
)
1732 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify without requesting"
1733 " one, no CHILD_SA built");
1734 handle_child_sa_failure(this, message
);
1735 return delete_failed_sa(this);
1737 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp_received
== IPCOMP_NONE
)
1739 DBG1(DBG_IKE
, "peer didn't accept our proposed IPComp transforms, "
1740 "IPComp is disabled");
1741 this->ipcomp
= IPCOMP_NONE
;
1743 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp
!= this->ipcomp_received
)
1745 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1746 "no CHILD_SA built");
1747 handle_child_sa_failure(this, message
);
1748 return delete_failed_sa(this);
1751 if (this->dh_failed
)
1753 DBG1(DBG_IKE
, "applying DH public value failed");
1754 handle_child_sa_failure(this, message
);
1755 return delete_failed_sa(this);
1758 if (select_and_install(this, no_dh
, ike_auth
) == SUCCESS
)
1761 { /* invoke the child_up() hook if we are not rekeying */
1762 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1767 handle_child_sa_failure(this, message
);
1768 return delete_failed_sa(this);
1773 METHOD(child_create_t
, use_reqid
, void,
1774 private_child_create_t
*this, uint32_t reqid
)
1776 this->child
.reqid
= reqid
;
1779 METHOD(child_create_t
, use_marks
, void,
1780 private_child_create_t
*this, uint32_t in
, uint32_t out
)
1782 this->child
.mark_in
= in
;
1783 this->child
.mark_out
= out
;
1786 METHOD(child_create_t
, use_if_ids
, void,
1787 private_child_create_t
*this, uint32_t in
, uint32_t out
)
1789 this->child
.if_id_in
= in
;
1790 this->child
.if_id_out
= out
;
1793 METHOD(child_create_t
, use_dh_group
, void,
1794 private_child_create_t
*this, diffie_hellman_group_t dh_group
)
1796 this->dh_group
= dh_group
;
1799 METHOD(child_create_t
, get_child
, child_sa_t
*,
1800 private_child_create_t
*this)
1802 return this->child_sa
;
1805 METHOD(child_create_t
, set_config
, void,
1806 private_child_create_t
*this, child_cfg_t
*cfg
)
1808 DESTROY_IF(this->config
);
1812 METHOD(child_create_t
, get_lower_nonce
, chunk_t
,
1813 private_child_create_t
*this)
1815 if (memcmp(this->my_nonce
.ptr
, this->other_nonce
.ptr
,
1816 min(this->my_nonce
.len
, this->other_nonce
.len
)) < 0)
1818 return this->my_nonce
;
1822 return this->other_nonce
;
1826 METHOD(task_t
, get_type
, task_type_t
,
1827 private_child_create_t
*this)
1829 return TASK_CHILD_CREATE
;
1832 METHOD(task_t
, migrate
, void,
1833 private_child_create_t
*this, ike_sa_t
*ike_sa
)
1835 chunk_free(&this->my_nonce
);
1836 chunk_free(&this->other_nonce
);
1839 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1843 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1845 DESTROY_IF(this->child_sa
);
1846 DESTROY_IF(this->proposal
);
1847 DESTROY_IF(this->nonceg
);
1848 DESTROY_IF(this->dh
);
1849 this->dh_failed
= FALSE
;
1850 if (this->proposals
)
1852 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1855 this->ike_sa
= ike_sa
;
1856 this->keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
);
1857 this->proposal
= NULL
;
1858 this->proposals
= NULL
;
1862 this->nonceg
= NULL
;
1863 this->child_sa
= NULL
;
1864 this->mode
= MODE_TUNNEL
;
1865 this->ipcomp
= IPCOMP_NONE
;
1866 this->ipcomp_received
= IPCOMP_NONE
;
1867 this->other_cpi
= 0;
1868 this->established
= FALSE
;
1869 this->child
= (child_sa_create_t
){};
1872 METHOD(task_t
, destroy
, void,
1873 private_child_create_t
*this)
1875 chunk_free(&this->my_nonce
);
1876 chunk_free(&this->other_nonce
);
1879 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1883 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1885 if (!this->established
)
1887 DESTROY_IF(this->child_sa
);
1889 DESTROY_IF(this->packet_tsi
);
1890 DESTROY_IF(this->packet_tsr
);
1891 DESTROY_IF(this->proposal
);
1892 DESTROY_IF(this->dh
);
1893 if (this->proposals
)
1895 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1897 DESTROY_IF(this->config
);
1898 DESTROY_IF(this->nonceg
);
1903 * Described in header.
1905 child_create_t
*child_create_create(ike_sa_t
*ike_sa
,
1906 child_cfg_t
*config
, bool rekey
,
1907 traffic_selector_t
*tsi
, traffic_selector_t
*tsr
)
1909 private_child_create_t
*this;
1913 .get_child
= _get_child
,
1914 .set_config
= _set_config
,
1915 .get_lower_nonce
= _get_lower_nonce
,
1916 .use_reqid
= _use_reqid
,
1917 .use_marks
= _use_marks
,
1918 .use_if_ids
= _use_if_ids
,
1919 .use_dh_group
= _use_dh_group
,
1921 .get_type
= _get_type
,
1922 .migrate
= _migrate
,
1923 .destroy
= _destroy
,
1928 .packet_tsi
= tsi ? tsi
->clone(tsi
) : NULL
,
1929 .packet_tsr
= tsr ? tsr
->clone(tsr
) : NULL
,
1930 .dh_group
= MODP_NONE
,
1931 .keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
),
1932 .mode
= MODE_TUNNEL
,
1934 .ipcomp
= IPCOMP_NONE
,
1935 .ipcomp_received
= IPCOMP_NONE
,
1942 this->public.task
.build
= _build_i
;
1943 this->public.task
.process
= _process_i
;
1944 this->initiator
= TRUE
;
1948 this->public.task
.build
= _build_r
;
1949 this->public.task
.process
= _process_r
;
1950 this->initiator
= FALSE
;
1952 return &this->public;