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
) &&
568 !lib
->settings
->get_bool(lib
->settings
, "%s.accept_private_algs",
571 flags
|= PROPOSAL_SKIP_PRIVATE
;
573 if (!lib
->settings
->get_bool(lib
->settings
,
574 "%s.prefer_configured_proposals", TRUE
, lib
->ns
))
576 flags
|= PROPOSAL_PREFER_SUPPLIED
;
578 this->proposal
= this->config
->select_proposal(this->config
,
579 this->proposals
, flags
);
580 if (this->proposal
== NULL
)
582 DBG1(DBG_IKE
, "no acceptable proposal found");
583 charon
->bus
->alert(charon
->bus
, ALERT_PROPOSAL_MISMATCH_CHILD
,
587 this->other_spi
= this->proposal
->get_spi(this->proposal
);
589 if (!this->initiator
)
591 if (!allocate_spi(this))
593 /* responder has no SPI allocated yet */
594 DBG1(DBG_IKE
, "allocating SPI failed");
597 this->proposal
->set_spi(this->proposal
, this->my_spi
);
599 this->child_sa
->set_proposal(this->child_sa
, this->proposal
);
601 if (!this->proposal
->has_dh_group(this->proposal
, this->dh_group
))
605 if (this->proposal
->get_algorithm(this->proposal
, DIFFIE_HELLMAN_GROUP
,
608 DBG1(DBG_IKE
, "DH group %N unacceptable, requesting %N",
609 diffie_hellman_group_names
, this->dh_group
,
610 diffie_hellman_group_names
, group
);
611 this->dh_group
= group
;
614 /* the selected proposal does not use a DH group */
615 DBG1(DBG_IKE
, "ignoring KE exchange, agreed on a non-PFS proposal");
616 DESTROY_IF(this->dh
);
618 this->dh_group
= MODP_NONE
;
623 nonce_i
= this->my_nonce
;
624 nonce_r
= this->other_nonce
;
625 my_ts
= narrow_ts(this, TRUE
, this->tsi
);
626 other_ts
= narrow_ts(this, FALSE
, this->tsr
);
630 nonce_r
= this->my_nonce
;
631 nonce_i
= this->other_nonce
;
632 my_ts
= narrow_ts(this, TRUE
, this->tsr
);
633 other_ts
= narrow_ts(this, FALSE
, this->tsi
);
640 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
641 NARROW_INITIATOR_POST_NOAUTH
, my_ts
, other_ts
);
645 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
646 NARROW_INITIATOR_POST_AUTH
, my_ts
, other_ts
);
651 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
652 NARROW_RESPONDER
, my_ts
, other_ts
);
655 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
657 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
658 my_ts
->destroy_offset(my_ts
, offsetof(traffic_selector_t
, destroy
));
659 other_ts
->destroy_offset(other_ts
, offsetof(traffic_selector_t
, destroy
));
660 DBG1(DBG_IKE
, "no acceptable traffic selectors found");
664 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
665 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
669 this->tsr
= other_ts
;
671 if (!check_mode(this, me
, other
))
673 DBG1(DBG_IKE
, "%N mode requested by responder is unacceptable",
674 ipsec_mode_names
, this->mode
);
681 this->tsi
= other_ts
;
683 if (!check_mode(this, other
, me
))
685 this->mode
= MODE_TUNNEL
;
689 if (!this->initiator
)
691 /* use a copy of the traffic selectors, as the POST hook should not
693 my_ts
= this->tsr
->clone_offset(this->tsr
,
694 offsetof(traffic_selector_t
, clone
));
695 other_ts
= this->tsi
->clone_offset(this->tsi
,
696 offsetof(traffic_selector_t
, clone
));
697 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
698 NARROW_RESPONDER_POST
, my_ts
, other_ts
);
700 if (my_ts
->get_count(my_ts
) == 0 || other_ts
->get_count(other_ts
) == 0)
702 my_ts
->destroy_offset(my_ts
,
703 offsetof(traffic_selector_t
, destroy
));
704 other_ts
->destroy_offset(other_ts
,
705 offsetof(traffic_selector_t
, destroy
));
710 this->child_sa
->set_policies(this->child_sa
, my_ts
, other_ts
);
711 if (!this->initiator
)
713 my_ts
->destroy_offset(my_ts
,
714 offsetof(traffic_selector_t
, destroy
));
715 other_ts
->destroy_offset(other_ts
,
716 offsetof(traffic_selector_t
, destroy
));
719 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLING
);
720 this->child_sa
->set_ipcomp(this->child_sa
, this->ipcomp
);
721 this->child_sa
->set_mode(this->child_sa
, this->mode
);
722 this->child_sa
->set_protocol(this->child_sa
,
723 this->proposal
->get_protocol(this->proposal
));
725 if (this->my_cpi
== 0 || this->other_cpi
== 0 || this->ipcomp
== IPCOMP_NONE
)
727 this->my_cpi
= this->other_cpi
= 0;
728 this->ipcomp
= IPCOMP_NONE
;
730 status_i
= status_o
= FAILED
;
731 if (this->keymat
->derive_child_keys(this->keymat
, this->proposal
,
732 this->dh
, nonce_i
, nonce_r
, &encr_i
, &integ_i
, &encr_r
, &integ_r
))
736 status_i
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
737 this->my_spi
, this->my_cpi
, this->initiator
,
742 status_i
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
743 this->my_spi
, this->my_cpi
, this->initiator
,
747 { /* during rekeyings we install the outbound SA and/or policies
748 * separately: as responder when we receive the delete for the old
749 * SA, as initiator pretty much immediately in the ike-rekey task,
750 * unless there was a rekey collision that we lost */
753 status_o
= this->child_sa
->register_outbound(this->child_sa
,
754 encr_i
, integ_i
, this->other_spi
, this->other_cpi
,
759 status_o
= this->child_sa
->register_outbound(this->child_sa
,
760 encr_r
, integ_r
, this->other_spi
, this->other_cpi
,
764 else if (this->initiator
)
766 status_o
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
767 this->other_spi
, this->other_cpi
, this->initiator
,
772 status_o
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
773 this->other_spi
, this->other_cpi
, this->initiator
,
778 if (status_i
!= SUCCESS
|| status_o
!= SUCCESS
)
780 DBG1(DBG_IKE
, "unable to install %s%s%sIPsec SA (SAD) in kernel",
781 (status_i
!= SUCCESS
) ? "inbound " : "",
782 (status_i
!= SUCCESS
&& status_o
!= SUCCESS
) ? "and ": "",
783 (status_o
!= SUCCESS
) ? "outbound " : "");
784 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_SA_FAILED
,
790 status
= this->child_sa
->install_policies(this->child_sa
);
792 if (status
!= SUCCESS
)
794 DBG1(DBG_IKE
, "unable to install IPsec policies (SPD) in kernel");
795 charon
->bus
->alert(charon
->bus
, ALERT_INSTALL_CHILD_POLICY_FAILED
,
801 charon
->bus
->child_derived_keys(charon
->bus
, this->child_sa
,
802 this->initiator
, encr_i
, encr_r
,
806 chunk_clear(&integ_i
);
807 chunk_clear(&integ_r
);
808 chunk_clear(&encr_i
);
809 chunk_clear(&encr_r
);
811 if (status
!= SUCCESS
)
816 charon
->bus
->child_keys(charon
->bus
, this->child_sa
, this->initiator
,
817 this->dh
, nonce_i
, nonce_r
);
819 my_ts
= linked_list_create_from_enumerator(
820 this->child_sa
->create_ts_enumerator(this->child_sa
, TRUE
));
821 other_ts
= linked_list_create_from_enumerator(
822 this->child_sa
->create_ts_enumerator(this->child_sa
, FALSE
));
823 out_state
= this->child_sa
->get_outbound_state(this->child_sa
);
825 DBG0(DBG_IKE
, "%sCHILD_SA %s{%d} established "
826 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
827 (out_state
== CHILD_OUTBOUND_INSTALLED
) ? "" : "inbound ",
828 this->child_sa
->get_name(this->child_sa
),
829 this->child_sa
->get_unique_id(this->child_sa
),
830 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
831 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)),
834 my_ts
->destroy(my_ts
);
835 other_ts
->destroy(other_ts
);
837 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
838 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
839 this->established
= TRUE
;
841 schedule_inactivity_timeout(this);
846 * build the payloads for the message
848 static bool build_payloads(private_child_create_t
*this, message_t
*message
)
850 sa_payload_t
*sa_payload
;
851 nonce_payload_t
*nonce_payload
;
852 ke_payload_t
*ke_payload
;
853 ts_payload_t
*ts_payload
;
854 kernel_feature_t features
;
859 sa_payload
= sa_payload_create_from_proposals_v2(this->proposals
);
863 sa_payload
= sa_payload_create_from_proposal_v2(this->proposal
);
865 message
->add_payload(message
, (payload_t
*)sa_payload
);
867 /* add nonce payload if not in IKE_AUTH */
868 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
870 nonce_payload
= nonce_payload_create(PLV2_NONCE
);
871 nonce_payload
->set_nonce(nonce_payload
, this->my_nonce
);
872 message
->add_payload(message
, (payload_t
*)nonce_payload
);
875 /* diffie hellman exchange, if PFS enabled */
878 ke_payload
= ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE
,
882 DBG1(DBG_IKE
, "creating KE payload failed");
885 message
->add_payload(message
, (payload_t
*)ke_payload
);
888 /* add TSi/TSr payloads */
889 ts_payload
= ts_payload_create_from_traffic_selectors(TRUE
, this->tsi
);
890 message
->add_payload(message
, (payload_t
*)ts_payload
);
891 ts_payload
= ts_payload_create_from_traffic_selectors(FALSE
, this->tsr
);
892 message
->add_payload(message
, (payload_t
*)ts_payload
);
894 /* add a notify if we are not in tunnel mode */
898 message
->add_notify(message
, FALSE
, USE_TRANSPORT_MODE
, chunk_empty
);
901 message
->add_notify(message
, FALSE
, USE_BEET_MODE
, chunk_empty
);
907 features
= charon
->kernel
->get_features(charon
->kernel
);
908 if (!(features
& KERNEL_ESP_V3_TFC
))
910 message
->add_notify(message
, FALSE
, ESP_TFC_PADDING_NOT_SUPPORTED
,
917 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
919 static void add_ipcomp_notify(private_child_create_t
*this,
920 message_t
*message
, uint8_t ipcomp
)
922 this->my_cpi
= this->child_sa
->alloc_cpi(this->child_sa
);
925 this->ipcomp
= ipcomp
;
926 message
->add_notify(message
, FALSE
, IPCOMP_SUPPORTED
,
927 chunk_cata("cc", chunk_from_thing(this->my_cpi
),
928 chunk_from_thing(ipcomp
)));
932 DBG1(DBG_IKE
, "unable to allocate a CPI from kernel, IPComp disabled");
937 * handle a received notify payload
939 static void handle_notify(private_child_create_t
*this, notify_payload_t
*notify
)
941 switch (notify
->get_notify_type(notify
))
943 case USE_TRANSPORT_MODE
:
944 this->mode
= MODE_TRANSPORT
;
947 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
))
948 { /* handle private use notify only if we know its meaning */
949 this->mode
= MODE_BEET
;
953 DBG1(DBG_IKE
, "received a notify strongSwan uses for BEET "
954 "mode, but peer implementation unknown, skipped");
957 case IPCOMP_SUPPORTED
:
959 ipcomp_transform_t ipcomp
;
963 data
= notify
->get_notification_data(notify
);
964 cpi
= *(uint16_t*)data
.ptr
;
965 ipcomp
= (ipcomp_transform_t
)(*(data
.ptr
+ 2));
969 this->other_cpi
= cpi
;
970 this->ipcomp_received
= ipcomp
;
975 DBG1(DBG_IKE
, "received IPCOMP_SUPPORTED notify with a "
976 "transform ID we don't support %N",
977 ipcomp_transform_names
, ipcomp
);
982 case ESP_TFC_PADDING_NOT_SUPPORTED
:
983 DBG1(DBG_IKE
, "received %N, not using ESPv3 TFC padding",
984 notify_type_names
, notify
->get_notify_type(notify
));
993 * Read payloads from message
995 static void process_payloads(private_child_create_t
*this, message_t
*message
)
997 enumerator_t
*enumerator
;
999 sa_payload_t
*sa_payload
;
1000 ke_payload_t
*ke_payload
;
1001 ts_payload_t
*ts_payload
;
1003 /* defaults to TUNNEL mode */
1004 this->mode
= MODE_TUNNEL
;
1006 enumerator
= message
->create_payload_enumerator(message
);
1007 while (enumerator
->enumerate(enumerator
, &payload
))
1009 switch (payload
->get_type(payload
))
1011 case PLV2_SECURITY_ASSOCIATION
:
1012 sa_payload
= (sa_payload_t
*)payload
;
1013 this->proposals
= sa_payload
->get_proposals(sa_payload
);
1015 case PLV2_KEY_EXCHANGE
:
1016 ke_payload
= (ke_payload_t
*)payload
;
1017 if (!this->initiator
)
1019 this->dh_group
= ke_payload
->get_dh_group_number(ke_payload
);
1020 this->dh
= this->keymat
->keymat
.create_dh(
1021 &this->keymat
->keymat
, this->dh_group
);
1025 this->dh_failed
= this->dh
->get_dh_group(this->dh
) !=
1026 ke_payload
->get_dh_group_number(ke_payload
);
1028 if (this->dh
&& !this->dh_failed
)
1030 this->dh_failed
= !this->dh
->set_other_public_value(this->dh
,
1031 ke_payload
->get_key_exchange_data(ke_payload
));
1034 case PLV2_TS_INITIATOR
:
1035 ts_payload
= (ts_payload_t
*)payload
;
1036 this->tsi
= ts_payload
->get_traffic_selectors(ts_payload
);
1038 case PLV2_TS_RESPONDER
:
1039 ts_payload
= (ts_payload_t
*)payload
;
1040 this->tsr
= ts_payload
->get_traffic_selectors(ts_payload
);
1043 handle_notify(this, (notify_payload_t
*)payload
);
1049 enumerator
->destroy(enumerator
);
1053 * Check if we should defer the creation of this CHILD_SA until after the
1054 * IKE_SA has been established childless.
1056 static status_t
defer_child_sa(private_child_create_t
*this)
1060 ike_cfg
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
1062 if (this->ike_sa
->supports_extension(this->ike_sa
, EXT_IKE_CHILDLESS
))
1064 if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_FORCE
)
1069 else if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_FORCE
)
1071 DBG1(DBG_IKE
, "peer does not support childless IKE_SA initiation");
1074 return NOT_SUPPORTED
;
1077 METHOD(task_t
, build_i
, status_t
,
1078 private_child_create_t
*this, message_t
*message
)
1080 enumerator_t
*enumerator
;
1082 peer_cfg_t
*peer_cfg
;
1083 linked_list_t
*list
;
1085 switch (message
->get_exchange_type(message
))
1088 return get_nonce(message
, &this->my_nonce
);
1089 case CREATE_CHILD_SA
:
1090 if (!generate_nonce(this))
1092 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1096 if (!this->retry
&& this->dh_group
== MODP_NONE
)
1097 { /* during a rekeying the group might already be set */
1098 this->dh_group
= this->config
->get_dh_group(this->config
);
1102 if (message
->get_message_id(message
) != 1)
1104 /* send only in the first request, not in subsequent rounds */
1107 switch (defer_child_sa(this))
1110 /* config mismatch */
1113 /* defer until after IKE_SA has been established */
1114 chunk_free(&this->my_nonce
);
1117 /* just continue to establish the CHILD_SA */
1125 /* check if we want a virtual IP, but don't have one */
1126 list
= linked_list_create();
1127 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
1130 enumerator
= peer_cfg
->create_virtual_ip_enumerator(peer_cfg
);
1131 while (enumerator
->enumerate(enumerator
, &vip
))
1133 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
1134 vip
= host_create_any(vip
->get_family(vip
));
1135 list
->insert_last(list
, vip
);
1137 enumerator
->destroy(enumerator
);
1139 if (list
->get_count(list
))
1141 this->tsi
= this->config
->get_traffic_selectors(this->config
,
1142 TRUE
, NULL
, list
, TRUE
);
1143 list
->destroy_offset(list
, offsetof(host_t
, destroy
));
1146 { /* no virtual IPs configured */
1147 list
->destroy(list
);
1148 list
= get_dynamic_hosts(this->ike_sa
, TRUE
);
1149 this->tsi
= this->config
->get_traffic_selectors(this->config
,
1150 TRUE
, NULL
, list
, TRUE
);
1151 list
->destroy(list
);
1153 list
= get_dynamic_hosts(this->ike_sa
, FALSE
);
1154 this->tsr
= this->config
->get_traffic_selectors(this->config
,
1155 FALSE
, NULL
, list
, TRUE
);
1156 list
->destroy(list
);
1158 if (this->packet_tsi
)
1160 this->tsi
->insert_first(this->tsi
,
1161 this->packet_tsi
->clone(this->packet_tsi
));
1163 if (this->packet_tsr
)
1165 this->tsr
->insert_first(this->tsr
,
1166 this->packet_tsr
->clone(this->packet_tsr
));
1168 this->proposals
= this->config
->get_proposals(this->config
,
1169 this->dh_group
== MODP_NONE
);
1170 this->mode
= this->config
->get_mode(this->config
);
1172 this->child
.if_id_in_def
= this->ike_sa
->get_if_id(this->ike_sa
, TRUE
);
1173 this->child
.if_id_out_def
= this->ike_sa
->get_if_id(this->ike_sa
, FALSE
);
1174 this->child
.encap
= this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
);
1175 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
1176 this->ike_sa
->get_other_host(this->ike_sa
),
1177 this->config
, &this->child
);
1179 if (this->child
.reqid
)
1181 DBG0(DBG_IKE
, "establishing CHILD_SA %s{%d} reqid %d",
1182 this->child_sa
->get_name(this->child_sa
),
1183 this->child_sa
->get_unique_id(this->child_sa
), this->child
.reqid
);
1187 DBG0(DBG_IKE
, "establishing CHILD_SA %s{%d}",
1188 this->child_sa
->get_name(this->child_sa
),
1189 this->child_sa
->get_unique_id(this->child_sa
));
1192 if (!allocate_spi(this))
1194 DBG1(DBG_IKE
, "unable to allocate SPIs from kernel");
1198 if (!update_and_check_proposals(this))
1200 DBG1(DBG_IKE
, "requested DH group %N not contained in any of our "
1202 diffie_hellman_group_names
, this->dh_group
);
1206 if (this->dh_group
!= MODP_NONE
)
1208 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
1212 if (this->config
->has_option(this->config
, OPT_IPCOMP
))
1214 /* IPCOMP_DEFLATE is the only transform we support at the moment */
1215 add_ipcomp_notify(this, message
, IPCOMP_DEFLATE
);
1218 if (message
->get_exchange_type(message
) == IKE_AUTH
)
1220 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1221 NARROW_INITIATOR_PRE_NOAUTH
, this->tsi
, this->tsr
);
1225 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1226 NARROW_INITIATOR_PRE_AUTH
, this->tsi
, this->tsr
);
1229 if (!build_payloads(this, message
))
1234 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1235 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1236 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1239 this->proposals
= NULL
;
1244 METHOD(task_t
, process_r
, status_t
,
1245 private_child_create_t
*this, message_t
*message
)
1247 switch (message
->get_exchange_type(message
))
1250 return get_nonce(message
, &this->other_nonce
);
1251 case CREATE_CHILD_SA
:
1252 get_nonce(message
, &this->other_nonce
);
1255 if (message
->get_message_id(message
) != 1)
1257 /* only handle first AUTH payload, not additional rounds */
1264 process_payloads(this, message
);
1270 * handle CHILD_SA setup failure
1272 static void handle_child_sa_failure(private_child_create_t
*this,
1277 is_first
= message
->get_exchange_type(message
) == IKE_AUTH
;
1279 lib
->settings
->get_bool(lib
->settings
,
1280 "%s.close_ike_on_child_failure", FALSE
, lib
->ns
))
1282 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
1284 DBG1(DBG_IKE
, "closing IKE_SA due CHILD_SA setup failure");
1285 lib
->scheduler
->schedule_job_ms(lib
->scheduler
, (job_t
*)
1286 delete_ike_sa_job_create(this->ike_sa
->get_id(this->ike_sa
), TRUE
),
1291 DBG1(DBG_IKE
, "failed to establish CHILD_SA, keeping IKE_SA");
1292 charon
->bus
->alert(charon
->bus
, ALERT_KEEP_ON_CHILD_SA_FAILURE
,
1298 * Substitute transport mode NAT selectors, if applicable
1300 static linked_list_t
* get_ts_if_nat_transport(private_child_create_t
*this,
1301 bool local
, linked_list_t
*in
)
1303 linked_list_t
*out
= NULL
;
1304 ike_condition_t cond
;
1306 if (this->mode
== MODE_TRANSPORT
)
1308 cond
= local
? COND_NAT_HERE
: COND_NAT_THERE
;
1309 if (this->ike_sa
->has_condition(this->ike_sa
, cond
))
1311 out
= get_transport_nat_ts(this, local
, in
);
1312 if (out
->get_count(out
) == 0)
1323 * Select a matching CHILD config as responder
1325 static child_cfg_t
* select_child_cfg(private_child_create_t
*this)
1327 peer_cfg_t
*peer_cfg
;
1328 child_cfg_t
*child_cfg
= NULL
;;
1330 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
1331 if (peer_cfg
&& this->tsi
&& this->tsr
)
1333 linked_list_t
*listr
, *listi
, *tsr
, *tsi
;
1335 tsr
= get_ts_if_nat_transport(this, TRUE
, this->tsr
);
1336 tsi
= get_ts_if_nat_transport(this, FALSE
, this->tsi
);
1338 listr
= get_dynamic_hosts(this->ike_sa
, TRUE
);
1339 listi
= get_dynamic_hosts(this->ike_sa
, FALSE
);
1340 child_cfg
= peer_cfg
->select_child_cfg(peer_cfg
,
1341 tsr
?: this->tsr
, tsi
?: this->tsi
,
1343 if ((tsi
|| tsr
) && child_cfg
&&
1344 child_cfg
->get_mode(child_cfg
) != MODE_TRANSPORT
)
1346 /* found a CHILD config, but it doesn't use transport mode */
1347 child_cfg
->destroy(child_cfg
);
1350 if (!child_cfg
&& (tsi
|| tsr
))
1352 /* no match for the substituted NAT selectors, try it without */
1353 child_cfg
= peer_cfg
->select_child_cfg(peer_cfg
,
1354 this->tsr
, this->tsi
, listr
, listi
);
1356 listr
->destroy(listr
);
1357 listi
->destroy(listi
);
1358 DESTROY_OFFSET_IF(tsi
, offsetof(traffic_selector_t
, destroy
));
1359 DESTROY_OFFSET_IF(tsr
, offsetof(traffic_selector_t
, destroy
));
1366 * Check how to handle a possibly childless IKE_SA
1368 static status_t
handle_childless(private_child_create_t
*this)
1372 ike_cfg
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
1374 if (!this->proposals
&& !this->tsi
&& !this->tsr
)
1376 /* looks like a childless IKE_SA, check if we allow it */
1377 if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_NEVER
)
1379 /* we don't allow childless initiation */
1380 DBG1(DBG_IKE
, "peer tried to initiate a childless IKE_SA");
1381 return INVALID_STATE
;
1386 /* the peer apparently wants to create a regular IKE_SA */
1387 if (ike_cfg
->childless(ike_cfg
) == CHILDLESS_FORCE
)
1389 /* reject it if we only allow childless initiation */
1390 DBG1(DBG_IKE
, "peer did not initiate a childless IKE_SA");
1391 return INVALID_STATE
;
1393 return NOT_SUPPORTED
;
1396 METHOD(task_t
, build_r
, status_t
,
1397 private_child_create_t
*this, message_t
*message
)
1400 enumerator_t
*enumerator
;
1401 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1403 switch (message
->get_exchange_type(message
))
1406 return get_nonce(message
, &this->my_nonce
);
1407 case CREATE_CHILD_SA
:
1408 if (!generate_nonce(this))
1410 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1414 if (this->dh_failed
)
1416 DBG1(DBG_IKE
, "applying DH public value failed");
1417 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
,
1424 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1425 { /* wait until all authentication round completed */
1428 if (this->ike_sa
->has_condition(this->ike_sa
, COND_REDIRECTED
))
1429 { /* no CHILD_SA is created for redirected SAs */
1432 switch (handle_childless(this))
1435 /* no CHILD_SA built */
1438 message
->add_notify(message
, FALSE
, INVALID_SYNTAX
,
1442 /* continue with regular initiation */
1450 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_REKEYING
)
1452 DBG1(DBG_IKE
, "unable to create CHILD_SA while rekeying IKE_SA");
1453 message
->add_notify(message
, TRUE
, TEMPORARY_FAILURE
, chunk_empty
);
1456 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_DELETING
)
1458 DBG1(DBG_IKE
, "unable to create CHILD_SA while deleting IKE_SA");
1459 message
->add_notify(message
, TRUE
, TEMPORARY_FAILURE
, chunk_empty
);
1463 if (this->config
== NULL
)
1465 this->config
= select_child_cfg(this);
1467 if (this->config
== NULL
)
1469 DBG1(DBG_IKE
, "traffic selectors %#R === %#R unacceptable",
1470 this->tsr
, this->tsi
);
1471 charon
->bus
->alert(charon
->bus
, ALERT_TS_MISMATCH
, this->tsi
, this->tsr
);
1472 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1473 handle_child_sa_failure(this, message
);
1477 /* check if ike_config_t included non-critical error notifies */
1478 enumerator
= message
->create_payload_enumerator(message
);
1479 while (enumerator
->enumerate(enumerator
, &payload
))
1481 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1483 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1485 switch (notify
->get_notify_type(notify
))
1487 case INTERNAL_ADDRESS_FAILURE
:
1488 case FAILED_CP_REQUIRED
:
1490 DBG1(DBG_IKE
,"configuration payload negotiation "
1491 "failed, no CHILD_SA built");
1492 enumerator
->destroy(enumerator
);
1493 handle_child_sa_failure(this, message
);
1501 enumerator
->destroy(enumerator
);
1503 this->child
.if_id_in_def
= this->ike_sa
->get_if_id(this->ike_sa
, TRUE
);
1504 this->child
.if_id_out_def
= this->ike_sa
->get_if_id(this->ike_sa
, FALSE
);
1505 this->child
.encap
= this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
);
1506 this->child_sa
= child_sa_create(this->ike_sa
->get_my_host(this->ike_sa
),
1507 this->ike_sa
->get_other_host(this->ike_sa
),
1508 this->config
, &this->child
);
1510 if (this->ipcomp_received
!= IPCOMP_NONE
)
1512 if (this->config
->has_option(this->config
, OPT_IPCOMP
))
1514 add_ipcomp_notify(this, message
, this->ipcomp_received
);
1518 DBG1(DBG_IKE
, "received %N notify but IPComp is disabled, ignoring",
1519 notify_type_names
, IPCOMP_SUPPORTED
);
1523 switch (select_and_install(this, no_dh
, ike_auth
))
1528 message
->add_notify(message
, FALSE
, TS_UNACCEPTABLE
, chunk_empty
);
1529 handle_child_sa_failure(this, message
);
1533 uint16_t group
= htons(this->dh_group
);
1534 message
->add_notify(message
, FALSE
, INVALID_KE_PAYLOAD
,
1535 chunk_from_thing(group
));
1540 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
1541 handle_child_sa_failure(this, message
);
1545 if (!build_payloads(this, message
))
1547 message
->add_notify(message
, FALSE
, NO_PROPOSAL_CHOSEN
, chunk_empty
);
1548 handle_child_sa_failure(this, message
);
1553 { /* invoke the child_up() hook if we are not rekeying */
1554 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1560 * Raise alerts for received notify errors
1562 static void raise_alerts(private_child_create_t
*this, notify_type_t type
)
1564 linked_list_t
*list
;
1568 case NO_PROPOSAL_CHOSEN
:
1569 list
= this->config
->get_proposals(this->config
, FALSE
);
1570 charon
->bus
->alert(charon
->bus
, ALERT_PROPOSAL_MISMATCH_CHILD
, list
);
1571 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1578 METHOD(task_t
, build_i_delete
, status_t
,
1579 private_child_create_t
*this, message_t
*message
)
1581 message
->set_exchange_type(message
, INFORMATIONAL
);
1582 if (this->my_spi
&& this->proto
)
1584 delete_payload_t
*del
;
1586 del
= delete_payload_create(PLV2_DELETE
, this->proto
);
1587 del
->add_spi(del
, this->my_spi
);
1588 message
->add_payload(message
, (payload_t
*)del
);
1590 DBG1(DBG_IKE
, "sending DELETE for %N CHILD_SA with SPI %.8x",
1591 protocol_id_names
, this->proto
, ntohl(this->my_spi
));
1597 * Change task to delete the failed CHILD_SA as initiator
1599 static status_t
delete_failed_sa(private_child_create_t
*this)
1601 if (this->my_spi
&& this->proto
)
1603 this->public.task
.build
= _build_i_delete
;
1604 this->public.task
.process
= (void*)return_success
;
1610 METHOD(task_t
, process_i
, status_t
,
1611 private_child_create_t
*this, message_t
*message
)
1613 enumerator_t
*enumerator
;
1615 bool no_dh
= TRUE
, ike_auth
= FALSE
;
1617 switch (message
->get_exchange_type(message
))
1620 return get_nonce(message
, &this->other_nonce
);
1621 case CREATE_CHILD_SA
:
1622 get_nonce(message
, &this->other_nonce
);
1626 if (this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
1627 { /* wait until all authentication round completed */
1630 if (defer_child_sa(this) == NEED_MORE
)
1631 { /* defer until after IKE_SA has been established */
1632 chunk_free(&this->other_nonce
);
1640 /* check for erroneous notifies */
1641 enumerator
= message
->create_payload_enumerator(message
);
1642 while (enumerator
->enumerate(enumerator
, &payload
))
1644 if (payload
->get_type(payload
) == PLV2_NOTIFY
)
1646 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
1647 notify_type_t type
= notify
->get_notify_type(notify
);
1651 /* handle notify errors related to CHILD_SA only */
1652 case NO_PROPOSAL_CHOSEN
:
1653 case SINGLE_PAIR_REQUIRED
:
1654 case NO_ADDITIONAL_SAS
:
1655 case INTERNAL_ADDRESS_FAILURE
:
1656 case FAILED_CP_REQUIRED
:
1657 case TS_UNACCEPTABLE
:
1658 case INVALID_SELECTORS
:
1660 DBG1(DBG_IKE
, "received %N notify, no CHILD_SA built",
1661 notify_type_names
, type
);
1662 enumerator
->destroy(enumerator
);
1663 raise_alerts(this, type
);
1664 handle_child_sa_failure(this, message
);
1665 /* an error in CHILD_SA creation is not critical */
1668 case TEMPORARY_FAILURE
:
1670 DBG1(DBG_IKE
, "received %N notify, will retry later",
1671 notify_type_names
, type
);
1672 enumerator
->destroy(enumerator
);
1674 { /* the rekey task will retry itself if necessary */
1675 schedule_delayed_retry(this);
1679 case INVALID_KE_PAYLOAD
:
1682 uint16_t group
= MODP_NONE
;
1684 data
= notify
->get_notification_data(notify
);
1685 if (data
.len
== sizeof(group
))
1687 memcpy(&group
, data
.ptr
, data
.len
);
1688 group
= ntohs(group
);
1692 DBG1(DBG_IKE
, "already retried with DH group %N, "
1693 "ignore requested %N", diffie_hellman_group_names
,
1694 this->dh_group
, diffie_hellman_group_names
, group
);
1695 handle_child_sa_failure(this, message
);
1696 /* an error in CHILD_SA creation is not critical */
1699 DBG1(DBG_IKE
, "peer didn't accept DH group %N, "
1700 "it requested %N", diffie_hellman_group_names
,
1701 this->dh_group
, diffie_hellman_group_names
, group
);
1703 this->dh_group
= group
;
1704 this->child_sa
->set_state(this->child_sa
, CHILD_RETRYING
);
1705 this->public.task
.migrate(&this->public.task
, this->ike_sa
);
1706 enumerator
->destroy(enumerator
);
1711 if (message
->get_exchange_type(message
) == CREATE_CHILD_SA
)
1712 { /* handle notifies if not handled in IKE_AUTH */
1715 DBG1(DBG_IKE
, "received %N notify error",
1716 notify_type_names
, type
);
1717 enumerator
->destroy(enumerator
);
1720 DBG2(DBG_IKE
, "received %N notify",
1721 notify_type_names
, type
);
1728 enumerator
->destroy(enumerator
);
1730 process_payloads(this, message
);
1732 if (this->ipcomp
== IPCOMP_NONE
&& this->ipcomp_received
!= IPCOMP_NONE
)
1734 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify without requesting"
1735 " one, no CHILD_SA built");
1736 handle_child_sa_failure(this, message
);
1737 return delete_failed_sa(this);
1739 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp_received
== IPCOMP_NONE
)
1741 DBG1(DBG_IKE
, "peer didn't accept our proposed IPComp transforms, "
1742 "IPComp is disabled");
1743 this->ipcomp
= IPCOMP_NONE
;
1745 else if (this->ipcomp
!= IPCOMP_NONE
&& this->ipcomp
!= this->ipcomp_received
)
1747 DBG1(DBG_IKE
, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1748 "no CHILD_SA built");
1749 handle_child_sa_failure(this, message
);
1750 return delete_failed_sa(this);
1753 if (this->dh_failed
)
1755 DBG1(DBG_IKE
, "applying DH public value failed");
1756 handle_child_sa_failure(this, message
);
1757 return delete_failed_sa(this);
1760 if (select_and_install(this, no_dh
, ike_auth
) == SUCCESS
)
1763 { /* invoke the child_up() hook if we are not rekeying */
1764 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
1769 handle_child_sa_failure(this, message
);
1770 return delete_failed_sa(this);
1775 METHOD(child_create_t
, use_reqid
, void,
1776 private_child_create_t
*this, uint32_t reqid
)
1778 this->child
.reqid
= reqid
;
1781 METHOD(child_create_t
, use_marks
, void,
1782 private_child_create_t
*this, uint32_t in
, uint32_t out
)
1784 this->child
.mark_in
= in
;
1785 this->child
.mark_out
= out
;
1788 METHOD(child_create_t
, use_if_ids
, void,
1789 private_child_create_t
*this, uint32_t in
, uint32_t out
)
1791 this->child
.if_id_in
= in
;
1792 this->child
.if_id_out
= out
;
1795 METHOD(child_create_t
, use_dh_group
, void,
1796 private_child_create_t
*this, diffie_hellman_group_t dh_group
)
1798 this->dh_group
= dh_group
;
1801 METHOD(child_create_t
, get_child
, child_sa_t
*,
1802 private_child_create_t
*this)
1804 return this->child_sa
;
1807 METHOD(child_create_t
, set_config
, void,
1808 private_child_create_t
*this, child_cfg_t
*cfg
)
1810 DESTROY_IF(this->config
);
1814 METHOD(child_create_t
, get_lower_nonce
, chunk_t
,
1815 private_child_create_t
*this)
1817 if (memcmp(this->my_nonce
.ptr
, this->other_nonce
.ptr
,
1818 min(this->my_nonce
.len
, this->other_nonce
.len
)) < 0)
1820 return this->my_nonce
;
1824 return this->other_nonce
;
1828 METHOD(task_t
, get_type
, task_type_t
,
1829 private_child_create_t
*this)
1831 return TASK_CHILD_CREATE
;
1834 METHOD(task_t
, migrate
, void,
1835 private_child_create_t
*this, ike_sa_t
*ike_sa
)
1837 chunk_free(&this->my_nonce
);
1838 chunk_free(&this->other_nonce
);
1841 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1845 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1847 DESTROY_IF(this->child_sa
);
1848 DESTROY_IF(this->proposal
);
1849 DESTROY_IF(this->nonceg
);
1850 DESTROY_IF(this->dh
);
1851 this->dh_failed
= FALSE
;
1852 if (this->proposals
)
1854 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1857 this->ike_sa
= ike_sa
;
1858 this->keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
);
1859 this->proposal
= NULL
;
1860 this->proposals
= NULL
;
1864 this->nonceg
= NULL
;
1865 this->child_sa
= NULL
;
1866 this->mode
= MODE_TUNNEL
;
1867 this->ipcomp
= IPCOMP_NONE
;
1868 this->ipcomp_received
= IPCOMP_NONE
;
1869 this->other_cpi
= 0;
1870 this->established
= FALSE
;
1871 this->child
= (child_sa_create_t
){};
1874 METHOD(task_t
, destroy
, void,
1875 private_child_create_t
*this)
1877 chunk_free(&this->my_nonce
);
1878 chunk_free(&this->other_nonce
);
1881 this->tsr
->destroy_offset(this->tsr
, offsetof(traffic_selector_t
, destroy
));
1885 this->tsi
->destroy_offset(this->tsi
, offsetof(traffic_selector_t
, destroy
));
1887 if (!this->established
)
1889 DESTROY_IF(this->child_sa
);
1891 DESTROY_IF(this->packet_tsi
);
1892 DESTROY_IF(this->packet_tsr
);
1893 DESTROY_IF(this->proposal
);
1894 DESTROY_IF(this->dh
);
1895 if (this->proposals
)
1897 this->proposals
->destroy_offset(this->proposals
, offsetof(proposal_t
, destroy
));
1899 DESTROY_IF(this->config
);
1900 DESTROY_IF(this->nonceg
);
1905 * Described in header.
1907 child_create_t
*child_create_create(ike_sa_t
*ike_sa
,
1908 child_cfg_t
*config
, bool rekey
,
1909 traffic_selector_t
*tsi
, traffic_selector_t
*tsr
)
1911 private_child_create_t
*this;
1915 .get_child
= _get_child
,
1916 .set_config
= _set_config
,
1917 .get_lower_nonce
= _get_lower_nonce
,
1918 .use_reqid
= _use_reqid
,
1919 .use_marks
= _use_marks
,
1920 .use_if_ids
= _use_if_ids
,
1921 .use_dh_group
= _use_dh_group
,
1923 .get_type
= _get_type
,
1924 .migrate
= _migrate
,
1925 .destroy
= _destroy
,
1930 .packet_tsi
= tsi
? tsi
->clone(tsi
) : NULL
,
1931 .packet_tsr
= tsr
? tsr
->clone(tsr
) : NULL
,
1932 .dh_group
= MODP_NONE
,
1933 .keymat
= (keymat_v2_t
*)ike_sa
->get_keymat(ike_sa
),
1934 .mode
= MODE_TUNNEL
,
1936 .ipcomp
= IPCOMP_NONE
,
1937 .ipcomp_received
= IPCOMP_NONE
,
1944 this->public.task
.build
= _build_i
;
1945 this->public.task
.process
= _process_i
;
1946 this->initiator
= TRUE
;
1950 this->public.task
.build
= _build_r
;
1951 this->public.task
.process
= _process_r
;
1952 this->initiator
= FALSE
;
1954 return &this->public;