2 * Copyright (C) 2012-2019 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2011 Martin Willi
6 * Copyright (C) 2011 revosec AG
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * Copyright (C) 2012 Volker RĂ¼melin
22 * Permission is hereby granted, free of charge, to any person obtaining a copy
23 * of this software and associated documentation files (the "Software"), to deal
24 * in the Software without restriction, including without limitation the rights
25 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 * copies of the Software, and to permit persons to whom the Software is
27 * furnished to do so, subject to the following conditions:
29 * The above copyright notice and this permission notice shall be included in
30 * all copies or substantial portions of the Software.
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 #include "quick_mode.h"
46 #include <sa/ikev1/keymat_v1.h>
47 #include <encoding/payloads/sa_payload.h>
48 #include <encoding/payloads/nonce_payload.h>
49 #include <encoding/payloads/ke_payload.h>
50 #include <encoding/payloads/id_payload.h>
51 #include <encoding/payloads/payload.h>
52 #include <sa/ikev1/tasks/informational.h>
53 #include <sa/ikev1/tasks/quick_delete.h>
54 #include <processing/jobs/inactivity_job.h>
56 typedef struct private_quick_mode_t private_quick_mode_t
;
59 * Private members of a quick_mode_t task.
61 struct private_quick_mode_t
{
64 * Public methods and task_t interface.
74 * TRUE if we are initiating quick mode
79 * Traffic selector of initiator
81 traffic_selector_t
*tsi
;
84 * Traffic selector of responder
86 traffic_selector_t
*tsr
;
109 * Initiators IPComp CPI
114 * Responders IPComp CPI
119 * selected CHILD_SA proposal
121 proposal_t
*proposal
;
124 * Config of CHILD_SA to establish
129 * CHILD_SA we are about to establish
131 child_sa_t
*child_sa
;
139 * DH exchange, when PFS is in use
141 diffie_hellman_t
*dh
;
144 * Negotiated lifetime of new SA
149 * Negotiated lifebytes of new SA
154 * Data collected to create the CHILD_SA
156 child_sa_create_t child
;
164 * Delete old child after successful rekey
169 * Negotiated mode, tunnel or transport
174 * SA protocol (ESP|AH) negotiated
179 * Message ID of handled quick mode exchange
183 /** states of quick mode */
191 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
193 static void schedule_inactivity_timeout(private_quick_mode_t
*this)
198 timeout
= this->config
->get_inactivity(this->config
);
201 close_ike
= lib
->settings
->get_bool(lib
->settings
,
202 "%s.inactivity_close_ike", FALSE
, lib
->ns
);
203 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)
204 inactivity_job_create(this->child_sa
->get_unique_id(this->child_sa
),
205 timeout
, close_ike
), timeout
);
210 * Check if we have a an address pool configured
212 static bool have_pool(ike_sa_t
*ike_sa
)
214 enumerator_t
*enumerator
;
215 peer_cfg_t
*peer_cfg
;
219 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
222 enumerator
= peer_cfg
->create_pool_enumerator(peer_cfg
);
223 if (enumerator
->enumerate(enumerator
, &pool
))
227 enumerator
->destroy(enumerator
);
233 * Get hosts to use for dynamic traffic selectors
235 static linked_list_t
*get_dynamic_hosts(ike_sa_t
*ike_sa
, bool local
)
237 enumerator_t
*enumerator
;
241 list
= linked_list_create();
242 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, local
);
243 while (enumerator
->enumerate(enumerator
, &host
))
245 list
->insert_last(list
, host
);
247 enumerator
->destroy(enumerator
);
249 if (list
->get_count(list
) == 0)
250 { /* no virtual IPs assigned */
253 host
= ike_sa
->get_my_host(ike_sa
);
254 list
->insert_last(list
, host
);
256 else if (!have_pool(ike_sa
))
257 { /* use host only if we don't have a pool configured */
258 host
= ike_sa
->get_other_host(ike_sa
);
259 list
->insert_last(list
, host
);
266 * Install negotiated CHILD_SA
268 static bool install(private_quick_mode_t
*this)
270 status_t status
, status_i
, status_o
;
271 chunk_t encr_i
, encr_r
, integ_i
, integ_r
;
272 linked_list_t
*tsi
, *tsr
, *my_ts
, *other_ts
;
273 child_sa_t
*old
= NULL
;
275 this->child_sa
->set_proposal(this->child_sa
, this->proposal
);
276 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLING
);
277 this->child_sa
->set_mode(this->child_sa
, this->mode
);
279 if (this->cpi_i
&& this->cpi_r
)
280 { /* DEFLATE is the only transform we currently support */
281 this->child_sa
->set_ipcomp(this->child_sa
, IPCOMP_DEFLATE
);
285 this->cpi_i
= this->cpi_r
= 0;
288 this->child_sa
->set_protocol(this->child_sa
,
289 this->proposal
->get_protocol(this->proposal
));
291 status_i
= status_o
= FAILED
;
292 encr_i
= encr_r
= integ_i
= integ_r
= chunk_empty
;
293 tsi
= linked_list_create_with_items(this->tsi
->clone(this->tsi
), NULL
);
294 tsr
= linked_list_create_with_items(this->tsr
->clone(this->tsr
), NULL
);
297 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
298 NARROW_INITIATOR_POST_AUTH
, tsi
, tsr
);
302 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
303 NARROW_RESPONDER_POST
, tsr
, tsi
);
305 if (tsi
->get_count(tsi
) == 0 || tsr
->get_count(tsr
) == 0)
307 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
308 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
309 DBG1(DBG_IKE
, "no acceptable traffic selectors found");
315 this->child_sa
->set_policies(this->child_sa
, tsi
, tsr
);
319 this->child_sa
->set_policies(this->child_sa
, tsr
, tsi
);
321 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
322 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
324 if (this->keymat
->derive_child_keys(this->keymat
, this->proposal
, this->dh
,
325 this->spi_i
, this->spi_r
, this->nonce_i
, this->nonce_r
,
326 &encr_i
, &integ_i
, &encr_r
, &integ_r
))
330 status_i
= this->child_sa
->install(this->child_sa
,
331 encr_r
, integ_r
, this->spi_i
, this->cpi_i
,
332 this->initiator
, TRUE
, FALSE
);
333 status_o
= this->child_sa
->install(this->child_sa
,
334 encr_i
, integ_i
, this->spi_r
, this->cpi_r
,
335 this->initiator
, FALSE
, FALSE
);
339 status_i
= this->child_sa
->install(this->child_sa
,
340 encr_i
, integ_i
, this->spi_r
, this->cpi_r
,
341 this->initiator
, TRUE
, FALSE
);
342 status_o
= this->child_sa
->install(this->child_sa
,
343 encr_r
, integ_r
, this->spi_i
, this->cpi_i
,
344 this->initiator
, FALSE
, FALSE
);
348 if (status_i
!= SUCCESS
|| status_o
!= SUCCESS
)
350 DBG1(DBG_IKE
, "unable to install %s%s%sIPsec SA (SAD) in kernel",
351 (status_i
!= SUCCESS
) ? "inbound " : "",
352 (status_i
!= SUCCESS
&& status_o
!= SUCCESS
) ? "and ": "",
353 (status_o
!= SUCCESS
) ? "outbound " : "");
358 status
= this->child_sa
->install_policies(this->child_sa
);
360 if (status
!= SUCCESS
)
362 DBG1(DBG_IKE
, "unable to install IPsec policies (SPD) in kernel");
366 charon
->bus
->child_derived_keys(charon
->bus
, this->child_sa
,
367 this->initiator
, encr_i
, encr_r
,
371 chunk_clear(&integ_i
);
372 chunk_clear(&integ_r
);
373 chunk_clear(&encr_i
);
374 chunk_clear(&encr_r
);
376 if (status
!= SUCCESS
)
381 charon
->bus
->child_keys(charon
->bus
, this->child_sa
, this->initiator
,
382 this->dh
, this->nonce_i
, this->nonce_r
);
384 my_ts
= linked_list_create_from_enumerator(
385 this->child_sa
->create_ts_enumerator(this->child_sa
, TRUE
));
386 other_ts
= linked_list_create_from_enumerator(
387 this->child_sa
->create_ts_enumerator(this->child_sa
, FALSE
));
389 DBG0(DBG_IKE
, "CHILD_SA %s{%d} established "
390 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
391 this->child_sa
->get_name(this->child_sa
),
392 this->child_sa
->get_unique_id(this->child_sa
),
393 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
394 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)), my_ts
, other_ts
);
396 my_ts
->destroy(my_ts
);
397 other_ts
->destroy(other_ts
);
399 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
400 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
404 old
= this->ike_sa
->get_child_sa(this->ike_sa
,
405 this->proposal
->get_protocol(this->proposal
),
410 charon
->bus
->child_rekey(charon
->bus
, old
, this->child_sa
);
411 /* rekeyed CHILD_SAs stay installed until they expire or are deleted
412 * by the other peer */
413 old
->set_state(old
, CHILD_REKEYED
);
414 /* as initiator we delete the CHILD_SA if configured to do so */
415 if (this->initiator
&& this->delete)
417 this->ike_sa
->queue_task(this->ike_sa
,
418 (task_t
*)quick_delete_create(this->ike_sa
,
419 this->proposal
->get_protocol(this->proposal
),
420 this->rekey
, TRUE
, FALSE
));
425 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
427 schedule_inactivity_timeout(this);
428 this->child_sa
= NULL
;
433 * Generate and add NONCE
435 static bool add_nonce(private_quick_mode_t
*this, chunk_t
*nonce
,
438 nonce_payload_t
*nonce_payload
;
441 nonceg
= this->keymat
->keymat
.create_nonce_gen(&this->keymat
->keymat
);
444 DBG1(DBG_IKE
, "no nonce generator found to create nonce");
447 if (!nonceg
->allocate_nonce(nonceg
, NONCE_SIZE
, nonce
))
449 DBG1(DBG_IKE
, "nonce allocation failed");
450 nonceg
->destroy(nonceg
);
453 nonceg
->destroy(nonceg
);
455 nonce_payload
= nonce_payload_create(PLV1_NONCE
);
456 nonce_payload
->set_nonce(nonce_payload
, *nonce
);
457 message
->add_payload(message
, &nonce_payload
->payload_interface
);
463 * Extract nonce from NONCE payload
465 static bool get_nonce(private_quick_mode_t
*this, chunk_t
*nonce
,
468 nonce_payload_t
*nonce_payload
;
470 nonce_payload
= (nonce_payload_t
*)message
->get_payload(message
, PLV1_NONCE
);
473 DBG1(DBG_IKE
, "NONCE payload missing in message");
476 *nonce
= nonce_payload
->get_nonce(nonce_payload
);
482 * Add KE payload to message
484 static bool add_ke(private_quick_mode_t
*this, message_t
*message
)
486 ke_payload_t
*ke_payload
;
488 ke_payload
= ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE
,
492 DBG1(DBG_IKE
, "creating KE payload failed");
495 message
->add_payload(message
, &ke_payload
->payload_interface
);
500 * Get DH value from a KE payload
502 static bool get_ke(private_quick_mode_t
*this, message_t
*message
)
504 ke_payload_t
*ke_payload
;
506 ke_payload
= (ke_payload_t
*)message
->get_payload(message
, PLV1_KEY_EXCHANGE
);
509 DBG1(DBG_IKE
, "KE payload missing");
512 if (!this->dh
->set_other_public_value(this->dh
,
513 ke_payload
->get_key_exchange_data(ke_payload
)))
515 DBG1(DBG_IKE
, "unable to apply received KE value");
522 * Select a traffic selector from configuration
524 static traffic_selector_t
* select_ts(private_quick_mode_t
*this, bool local
,
525 linked_list_t
*supplied
)
527 traffic_selector_t
*ts
;
528 linked_list_t
*list
, *hosts
;
530 hosts
= get_dynamic_hosts(this->ike_sa
, local
);
531 list
= this->config
->get_traffic_selectors(this->config
,
532 local
, supplied
, hosts
, TRUE
);
533 hosts
->destroy(hosts
);
534 if (list
->get_first(list
, (void**)&ts
) == SUCCESS
)
540 DBG1(DBG_IKE
, "%s traffic selector missing in configuration",
541 local
? "local" : "remote");
544 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
549 * Add selected traffic selectors to message
551 static void add_ts(private_quick_mode_t
*this, message_t
*message
)
553 id_payload_t
*id_payload
;
555 id_payload
= id_payload_create_from_ts(this->tsi
);
556 message
->add_payload(message
, &id_payload
->payload_interface
);
557 id_payload
= id_payload_create_from_ts(this->tsr
);
558 message
->add_payload(message
, &id_payload
->payload_interface
);
562 * Get traffic selectors from received message
564 static bool get_ts(private_quick_mode_t
*this, message_t
*message
)
566 traffic_selector_t
*tsi
= NULL
, *tsr
= NULL
;
567 enumerator_t
*enumerator
;
568 id_payload_t
*id_payload
;
573 enumerator
= message
->create_payload_enumerator(message
);
574 while (enumerator
->enumerate(enumerator
, &payload
))
576 if (payload
->get_type(payload
) == PLV1_ID
)
578 id_payload
= (id_payload_t
*)payload
;
582 tsi
= id_payload
->get_ts(id_payload
);
587 tsr
= id_payload
->get_ts(id_payload
);
592 enumerator
->destroy(enumerator
);
594 /* create host2host selectors if ID payloads missing */
597 hsi
= this->ike_sa
->get_my_host(this->ike_sa
);
598 hsr
= this->ike_sa
->get_other_host(this->ike_sa
);
602 hsr
= this->ike_sa
->get_my_host(this->ike_sa
);
603 hsi
= this->ike_sa
->get_other_host(this->ike_sa
);
607 tsi
= traffic_selector_create_from_subnet(hsi
->clone(hsi
),
608 hsi
->get_family(hsi
) == AF_INET
? 32 : 128, 0, 0, 65535);
612 tsr
= traffic_selector_create_from_subnet(hsr
->clone(hsr
),
613 hsr
->get_family(hsr
) == AF_INET
? 32 : 128, 0, 0, 65535);
615 if (this->mode
== MODE_TRANSPORT
&& this->child
.encap
&&
616 (!tsi
->is_host(tsi
, hsi
) || !tsr
->is_host(tsr
, hsr
)))
617 { /* change TS in case of a NAT in transport mode */
618 DBG2(DBG_IKE
, "changing received traffic selectors %R=== %R due to NAT",
620 tsi
->set_address(tsi
, hsi
);
621 tsr
->set_address(tsr
, hsr
);
626 traffic_selector_t
*tsisub
, *tsrsub
;
628 /* check if peer selection is valid */
629 tsisub
= this->tsi
->get_subset(this->tsi
, tsi
);
630 tsrsub
= this->tsr
->get_subset(this->tsr
, tsr
);
631 if (!tsisub
|| !tsrsub
)
633 DBG1(DBG_IKE
, "peer selected invalid traffic selectors: "
634 "%R for %R, %R for %R", tsi
, this->tsi
, tsr
, this->tsr
);
643 this->tsi
->destroy(this->tsi
);
644 this->tsr
->destroy(this->tsr
);
659 static encap_t
get_encap(ike_sa_t
* ike_sa
, bool udp
)
665 if (ike_sa
->supports_extension(ike_sa
, EXT_NATT_DRAFT_02_03
))
667 return ENCAP_UDP_DRAFT_00_03
;
673 * Get NAT-OA payload type (RFC 3947 or RFC 3947 drafts).
675 static payload_type_t
get_nat_oa_payload_type(ike_sa_t
*ike_sa
)
677 if (ike_sa
->supports_extension(ike_sa
, EXT_NATT_DRAFT_02_03
))
679 return PLV1_NAT_OA_DRAFT_00_03
;
685 * Add NAT-OA payloads
687 static void add_nat_oa_payloads(private_quick_mode_t
*this, message_t
*message
)
689 identification_t
*id
;
690 id_payload_t
*nat_oa
;
692 payload_type_t nat_oa_payload_type
;
696 init
= message
->get_source(message
);
697 resp
= message
->get_destination(message
);
701 init
= message
->get_destination(message
);
702 resp
= message
->get_source(message
);
705 nat_oa_payload_type
= get_nat_oa_payload_type(this->ike_sa
);
707 /* first NAT-OA is the initiator's address */
708 id
= identification_create_from_sockaddr(init
->get_sockaddr(init
));
709 nat_oa
= id_payload_create_from_identification(nat_oa_payload_type
, id
);
710 message
->add_payload(message
, (payload_t
*)nat_oa
);
713 /* second NAT-OA is that of the responder */
714 id
= identification_create_from_sockaddr(resp
->get_sockaddr(resp
));
715 nat_oa
= id_payload_create_from_identification(nat_oa_payload_type
, id
);
716 message
->add_payload(message
, (payload_t
*)nat_oa
);
723 static void get_lifetimes(private_quick_mode_t
*this)
727 lft
= this->config
->get_lifetime(this->config
, TRUE
);
730 this->lifetime
= lft
->time
.life
;
734 this->lifebytes
= lft
->bytes
.life
;
740 * Check and apply lifetimes
742 static void apply_lifetimes(private_quick_mode_t
*this, sa_payload_t
*sa_payload
)
747 lifetime
= sa_payload
->get_lifetime(sa_payload
, this->proposal
);
748 lifebytes
= sa_payload
->get_lifebytes(sa_payload
, this->proposal
);
749 if (this->lifetime
!= lifetime
)
751 DBG1(DBG_IKE
, "received %us lifetime, configured %us",
752 lifetime
, this->lifetime
);
753 this->lifetime
= lifetime
;
755 if (this->lifebytes
!= lifebytes
)
757 DBG1(DBG_IKE
, "received %llu lifebytes, configured %llu",
758 lifebytes
, this->lifebytes
);
759 this->lifebytes
= lifebytes
;
764 * Set the task ready to build notify error message
766 static status_t
send_notify(private_quick_mode_t
*this, notify_type_t type
)
768 notify_payload_t
*notify
;
770 notify
= notify_payload_create_from_protocol_and_type(PLV1_NOTIFY
,
772 notify
->set_spi(notify
, this->spi_i
);
774 this->ike_sa
->queue_task(this->ike_sa
,
775 (task_t
*)informational_create(this->ike_sa
, notify
));
776 /* cancel all active/passive tasks in favour of informational */
777 this->ike_sa
->flush_queue(this->ike_sa
,
778 this->initiator
? TASK_QUEUE_ACTIVE
: TASK_QUEUE_PASSIVE
);
783 * Prepare a list of proposals from child_config containing only the specified
784 * DH group, unless it is set to MODP_NONE.
786 static linked_list_t
*get_proposals(private_quick_mode_t
*this,
787 diffie_hellman_group_t group
)
790 proposal_t
*proposal
;
791 enumerator_t
*enumerator
;
793 list
= this->config
->get_proposals(this->config
, FALSE
);
794 enumerator
= list
->create_enumerator(list
);
795 while (enumerator
->enumerate(enumerator
, &proposal
))
797 if (group
!= MODP_NONE
)
799 if (!proposal
->has_dh_group(proposal
, group
))
801 list
->remove_at(list
, enumerator
);
802 proposal
->destroy(proposal
);
805 proposal
->promote_dh_group(proposal
, group
);
807 proposal
->set_spi(proposal
, this->spi_i
);
809 enumerator
->destroy(enumerator
);
814 METHOD(task_t
, build_i
, status_t
,
815 private_quick_mode_t
*this, message_t
*message
)
821 sa_payload_t
*sa_payload
;
822 linked_list_t
*list
, *tsi
, *tsr
;
823 proposal_t
*proposal
;
824 diffie_hellman_group_t group
;
827 this->mode
= this->config
->get_mode(this->config
);
828 this->child
.if_id_in_def
= this->ike_sa
->get_if_id(this->ike_sa
,
830 this->child
.if_id_out_def
= this->ike_sa
->get_if_id(this->ike_sa
,
832 this->child
.encap
= this->ike_sa
->has_condition(this->ike_sa
,
834 this->child_sa
= child_sa_create(
835 this->ike_sa
->get_my_host(this->ike_sa
),
836 this->ike_sa
->get_other_host(this->ike_sa
),
837 this->config
, &this->child
);
839 if (this->child
.encap
&& this->mode
== MODE_TRANSPORT
)
841 /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
842 add_nat_oa_payloads(this, message
);
845 if (this->config
->has_option(this->config
, OPT_IPCOMP
))
847 this->cpi_i
= this->child_sa
->alloc_cpi(this->child_sa
);
850 DBG1(DBG_IKE
, "unable to allocate a CPI from kernel, "
855 list
= this->config
->get_proposals(this->config
, FALSE
);
856 if (list
->get_first(list
, (void**)&proposal
) == SUCCESS
)
858 this->proto
= proposal
->get_protocol(proposal
);
860 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
861 this->spi_i
= this->child_sa
->alloc_spi(this->child_sa
, this->proto
);
864 DBG1(DBG_IKE
, "allocating SPI from kernel failed");
868 group
= this->config
->get_dh_group(this->config
);
869 if (group
!= MODP_NONE
)
871 proposal_t
*proposal
;
872 uint16_t preferred_group
;
874 proposal
= this->ike_sa
->get_proposal(this->ike_sa
);
875 proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
,
876 &preferred_group
, NULL
);
877 /* try the negotiated DH group from IKE_SA */
878 list
= get_proposals(this, preferred_group
);
879 if (list
->get_count(list
))
881 group
= preferred_group
;
885 /* fall back to the first configured DH group */
887 list
= get_proposals(this, group
);
890 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
894 DBG1(DBG_IKE
, "configured DH group %N not supported",
895 diffie_hellman_group_names
, group
);
896 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
902 list
= get_proposals(this, MODP_NONE
);
906 encap
= get_encap(this->ike_sa
, this->child
.encap
);
907 sa_payload
= sa_payload_create_from_proposals_v1(list
,
908 this->lifetime
, this->lifebytes
, AUTH_NONE
,
909 this->mode
, encap
, this->cpi_i
);
910 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
911 message
->add_payload(message
, &sa_payload
->payload_interface
);
913 if (!add_nonce(this, &this->nonce_i
, message
))
917 if (group
!= MODP_NONE
)
919 if (!add_ke(this, message
))
926 this->tsi
= select_ts(this, TRUE
, NULL
);
930 this->tsr
= select_ts(this, FALSE
, NULL
);
932 tsi
= linked_list_create_with_items(this->tsi
, NULL
);
933 tsr
= linked_list_create_with_items(this->tsr
, NULL
);
934 this->tsi
= this->tsr
= NULL
;
935 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
936 NARROW_INITIATOR_PRE_AUTH
, tsi
, tsr
);
937 tsi
->remove_first(tsi
, (void**)&this->tsi
);
938 tsr
->remove_first(tsr
, (void**)&this->tsr
);
939 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
940 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
941 if (!this->tsi
|| !this->tsr
)
945 add_ts(this, message
);
958 * Check for notify errors, return TRUE if error found
960 static bool has_notify_errors(private_quick_mode_t
*this, message_t
*message
)
962 enumerator_t
*enumerator
;
966 enumerator
= message
->create_payload_enumerator(message
);
967 while (enumerator
->enumerate(enumerator
, &payload
))
969 if (payload
->get_type(payload
) == PLV1_NOTIFY
)
971 notify_payload_t
*notify
;
974 notify
= (notify_payload_t
*)payload
;
975 type
= notify
->get_notify_type(notify
);
979 DBG1(DBG_IKE
, "received %N error notify",
980 notify_type_names
, type
);
985 DBG1(DBG_IKE
, "received %N notify", notify_type_names
, type
);
989 enumerator
->destroy(enumerator
);
995 * Check if this is a rekey for an existing CHILD_SA, reuse reqid if so
997 static void check_for_rekeyed_child(private_quick_mode_t
*this, bool responder
)
999 enumerator_t
*enumerator
, *policies
;
1000 traffic_selector_t
*local
, *remote
, *my_ts
, *other_ts
;
1001 child_sa_t
*child_sa
;
1002 proposal_t
*proposal
;
1008 other_ts
= this->tsi
;
1013 other_ts
= this->tsr
;
1016 name
= this->config
->get_name(this->config
);
1017 enumerator
= this->ike_sa
->create_child_sa_enumerator(this->ike_sa
);
1018 while (!this->child
.reqid
&& enumerator
->enumerate(enumerator
, &child_sa
))
1020 if (streq(child_sa
->get_name(child_sa
), name
))
1022 proposal
= child_sa
->get_proposal(child_sa
);
1023 switch (child_sa
->get_state(child_sa
))
1025 case CHILD_INSTALLED
:
1026 case CHILD_REKEYING
:
1027 policies
= child_sa
->create_policy_enumerator(child_sa
);
1028 if (policies
->enumerate(policies
, &local
, &remote
) &&
1029 local
->equals(local
, my_ts
) &&
1030 remote
->equals(remote
, other_ts
) &&
1031 this->proposal
->equals(this->proposal
, proposal
))
1033 this->rekey
= child_sa
->get_spi(child_sa
, TRUE
);
1034 this->child
.reqid
= child_sa
->get_reqid(child_sa
);
1035 this->child
.mark_in
= child_sa
->get_mark(child_sa
,
1037 this->child
.mark_out
= child_sa
->get_mark(child_sa
,
1039 this->child
.if_id_in
= child_sa
->get_if_id(child_sa
,
1041 this->child
.if_id_out
= child_sa
->get_if_id(child_sa
,
1043 child_sa
->set_state(child_sa
, CHILD_REKEYING
);
1044 DBG1(DBG_IKE
, "detected rekeying of CHILD_SA %s{%u}",
1045 child_sa
->get_name(child_sa
),
1046 child_sa
->get_unique_id(child_sa
));
1048 policies
->destroy(policies
);
1056 enumerator
->destroy(enumerator
);
1059 METHOD(task_t
, process_r
, status_t
,
1060 private_quick_mode_t
*this, message_t
*message
)
1062 if (this->mid
&& this->mid
!= message
->get_message_id(message
))
1063 { /* not responsible for this quick mode exchange */
1067 switch (this->state
)
1071 sa_payload_t
*sa_payload
;
1072 linked_list_t
*tsi
, *tsr
, *hostsi
, *hostsr
, *list
= NULL
;
1073 peer_cfg_t
*peer_cfg
;
1075 proposal_selection_flag_t flags
= 0;
1077 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
1078 PLV1_SECURITY_ASSOCIATION
);
1081 DBG1(DBG_IKE
, "sa payload missing");
1082 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1085 this->mode
= sa_payload
->get_encap_mode(sa_payload
,
1086 &this->child
.encap
);
1088 if (!get_ts(this, message
))
1092 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
1093 tsi
= linked_list_create_with_items(this->tsi
, NULL
);
1094 tsr
= linked_list_create_with_items(this->tsr
, NULL
);
1095 this->tsi
= this->tsr
= NULL
;
1096 hostsi
= get_dynamic_hosts(this->ike_sa
, FALSE
);
1097 hostsr
= get_dynamic_hosts(this->ike_sa
, TRUE
);
1098 this->config
= peer_cfg
->select_child_cfg(peer_cfg
, tsr
, tsi
,
1100 hostsi
->destroy(hostsi
);
1101 hostsr
->destroy(hostsr
);
1104 this->tsi
= select_ts(this, FALSE
, tsi
);
1105 this->tsr
= select_ts(this, TRUE
, tsr
);
1107 if (!this->config
|| !this->tsi
|| !this->tsr
||
1108 this->mode
!= this->config
->get_mode(this->config
))
1110 DBG1(DBG_IKE
, "no matching CHILD_SA config found for "
1111 "%#R === %#R", tsi
, tsr
);
1112 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
1113 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
1114 return send_notify(this, INVALID_ID_INFORMATION
);
1116 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
1117 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
1119 if (this->config
->has_option(this->config
, OPT_IPCOMP
))
1121 list
= sa_payload
->get_ipcomp_proposals(sa_payload
,
1123 if (!list
->get_count(list
))
1125 DBG1(DBG_IKE
, "expected IPComp proposal but peer did "
1126 "not send one, IPComp disabled");
1130 if (!list
|| !list
->get_count(list
))
1133 list
= sa_payload
->get_proposals(sa_payload
);
1135 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
)
1136 && !lib
->settings
->get_bool(lib
->settings
,
1137 "%s.accept_private_algs", FALSE
, lib
->ns
))
1139 flags
|= PROPOSAL_SKIP_PRIVATE
;
1141 if (!lib
->settings
->get_bool(lib
->settings
,
1142 "%s.prefer_configured_proposals", TRUE
, lib
->ns
))
1144 flags
|= PROPOSAL_PREFER_SUPPLIED
;
1146 this->proposal
= this->config
->select_proposal(this->config
, list
,
1148 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1150 get_lifetimes(this);
1151 apply_lifetimes(this, sa_payload
);
1153 if (!this->proposal
)
1155 DBG1(DBG_IKE
, "no matching proposal found, sending %N",
1156 notify_type_names
, NO_PROPOSAL_CHOSEN
);
1157 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1159 this->spi_i
= this->proposal
->get_spi(this->proposal
);
1161 if (!get_nonce(this, &this->nonce_i
, message
))
1163 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1166 if (this->proposal
->get_algorithm(this->proposal
,
1167 DIFFIE_HELLMAN_GROUP
, &group
, NULL
))
1169 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
1173 DBG1(DBG_IKE
, "negotiated DH group %N not supported",
1174 diffie_hellman_group_names
, group
);
1175 return send_notify(this, INVALID_KEY_INFORMATION
);
1177 if (!get_ke(this, message
))
1179 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1183 check_for_rekeyed_child(this, TRUE
);
1184 this->child
.if_id_in_def
= this->ike_sa
->get_if_id(this->ike_sa
,
1186 this->child
.if_id_out_def
= this->ike_sa
->get_if_id(this->ike_sa
,
1188 this->child_sa
= child_sa_create(
1189 this->ike_sa
->get_my_host(this->ike_sa
),
1190 this->ike_sa
->get_other_host(this->ike_sa
),
1191 this->config
, &this->child
);
1193 tsi
= linked_list_create_with_items(this->tsi
, NULL
);
1194 tsr
= linked_list_create_with_items(this->tsr
, NULL
);
1195 this->tsi
= this->tsr
= NULL
;
1196 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1197 NARROW_RESPONDER
, tsr
, tsi
);
1198 if (tsi
->remove_first(tsi
, (void**)&this->tsi
) != SUCCESS
||
1199 tsr
->remove_first(tsr
, (void**)&this->tsr
) != SUCCESS
)
1201 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
1202 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
1203 return send_notify(this, INVALID_ID_INFORMATION
);
1205 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
1206 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
1212 if (has_notify_errors(this, message
))
1216 if (message
->get_exchange_type(message
) == INFORMATIONAL_V1
)
1218 if (message
->get_payload(message
, PLV1_DELETE
))
1220 /* If the DELETE for a Quick Mode follows immediately
1221 * after rekeying, we might receive it before the
1222 * third completing Quick Mode message. Ignore it, as
1223 * it gets handled by a separately queued delete task. */
1230 /* do another check in case SAs were created since we handled
1231 * the QM request, this is consistent with the rekey check
1232 * before installation on the initiator */
1233 check_for_rekeyed_child(this, TRUE
);
1236 this->child_sa
->destroy(this->child_sa
);
1237 this->child_sa
= child_sa_create(
1238 this->ike_sa
->get_my_host(this->ike_sa
),
1239 this->ike_sa
->get_other_host(this->ike_sa
),
1240 this->config
, &this->child
);
1245 ike_sa_t
*ike_sa
= this->ike_sa
;
1248 task
= (task_t
*)quick_delete_create(this->ike_sa
,
1249 this->proposal
->get_protocol(this->proposal
),
1250 this->spi_i
, TRUE
, TRUE
);
1251 /* flush_queue() destroys the current task */
1252 ike_sa
->flush_queue(ike_sa
, TASK_QUEUE_PASSIVE
);
1253 ike_sa
->queue_task(ike_sa
, task
);
1254 return ALREADY_DONE
;
1263 METHOD(task_t
, build_r
, status_t
,
1264 private_quick_mode_t
*this, message_t
*message
)
1266 if (this->mid
&& this->mid
!= message
->get_message_id(message
))
1267 { /* not responsible for this quick mode exchange */
1271 switch (this->state
)
1275 sa_payload_t
*sa_payload
;
1278 this->proto
= this->proposal
->get_protocol(this->proposal
);
1279 this->spi_r
= this->child_sa
->alloc_spi(this->child_sa
, this->proto
);
1282 DBG1(DBG_IKE
, "allocating SPI from kernel failed");
1283 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1285 this->proposal
->set_spi(this->proposal
, this->spi_r
);
1289 this->cpi_r
= this->child_sa
->alloc_cpi(this->child_sa
);
1292 DBG1(DBG_IKE
, "unable to allocate a CPI from "
1293 "kernel, IPComp disabled");
1294 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1298 if (this->child
.encap
&& this->mode
== MODE_TRANSPORT
)
1300 /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
1301 add_nat_oa_payloads(this, message
);
1304 encap
= get_encap(this->ike_sa
, this->child
.encap
);
1305 sa_payload
= sa_payload_create_from_proposal_v1(this->proposal
,
1306 this->lifetime
, this->lifebytes
, AUTH_NONE
,
1307 this->mode
, encap
, this->cpi_r
);
1308 message
->add_payload(message
, &sa_payload
->payload_interface
);
1310 if (!add_nonce(this, &this->nonce_r
, message
))
1316 if (!add_ke(this, message
))
1322 add_ts(this, message
);
1324 this->state
= QM_NEGOTIATED
;
1325 this->mid
= message
->get_message_id(message
);
1329 if (message
->get_exchange_type(message
) == INFORMATIONAL_V1
)
1331 /* skip INFORMATIONAL response if we received a INFORMATIONAL
1332 * delete, see process_r() */
1333 return ALREADY_DONE
;
1341 METHOD(task_t
, process_i
, status_t
,
1342 private_quick_mode_t
*this, message_t
*message
)
1344 switch (this->state
)
1348 sa_payload_t
*sa_payload
;
1349 linked_list_t
*list
= NULL
;
1350 proposal_selection_flag_t flags
= 0;
1352 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
1353 PLV1_SECURITY_ASSOCIATION
);
1356 DBG1(DBG_IKE
, "sa payload missing");
1357 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1361 list
= sa_payload
->get_ipcomp_proposals(sa_payload
,
1363 if (!list
->get_count(list
))
1365 DBG1(DBG_IKE
, "peer did not accept our IPComp proposal, "
1370 if (!list
|| !list
->get_count(list
))
1373 list
= sa_payload
->get_proposals(sa_payload
);
1375 if (!this->ike_sa
->supports_extension(this->ike_sa
, EXT_STRONGSWAN
)
1376 && !lib
->settings
->get_bool(lib
->settings
,
1377 "%s.accept_private_algs", FALSE
, lib
->ns
))
1379 flags
|= PROPOSAL_SKIP_PRIVATE
;
1381 this->proposal
= this->config
->select_proposal(this->config
, list
,
1383 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1384 if (!this->proposal
)
1386 DBG1(DBG_IKE
, "no matching proposal found");
1387 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1389 this->spi_r
= this->proposal
->get_spi(this->proposal
);
1391 apply_lifetimes(this, sa_payload
);
1393 if (!get_nonce(this, &this->nonce_r
, message
))
1395 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1397 if (this->dh
&& !get_ke(this, message
))
1399 return send_notify(this, INVALID_KEY_INFORMATION
);
1401 if (!get_ts(this, message
))
1403 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1405 check_for_rekeyed_child(this, FALSE
);
1408 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1410 this->state
= QM_NEGOTIATED
;
1418 METHOD(task_t
, get_type
, task_type_t
,
1419 private_quick_mode_t
*this)
1421 return TASK_QUICK_MODE
;
1424 METHOD(quick_mode_t
, get_mid
, uint32_t,
1425 private_quick_mode_t
*this)
1430 METHOD(quick_mode_t
, use_reqid
, void,
1431 private_quick_mode_t
*this, uint32_t reqid
)
1433 this->child
.reqid
= reqid
;
1436 METHOD(quick_mode_t
, use_marks
, void,
1437 private_quick_mode_t
*this, uint32_t in
, uint32_t out
)
1439 this->child
.mark_in
= in
;
1440 this->child
.mark_out
= out
;
1443 METHOD(quick_mode_t
, use_if_ids
, void,
1444 private_quick_mode_t
*this, uint32_t in
, uint32_t out
)
1446 this->child
.if_id_in
= in
;
1447 this->child
.if_id_out
= out
;
1450 METHOD(quick_mode_t
, rekey
, void,
1451 private_quick_mode_t
*this, uint32_t spi
)
1456 METHOD(task_t
, migrate
, void,
1457 private_quick_mode_t
*this, ike_sa_t
*ike_sa
)
1459 chunk_free(&this->nonce_i
);
1460 chunk_free(&this->nonce_r
);
1461 DESTROY_IF(this->tsi
);
1462 DESTROY_IF(this->tsr
);
1463 DESTROY_IF(this->proposal
);
1464 DESTROY_IF(this->child_sa
);
1465 DESTROY_IF(this->dh
);
1467 this->ike_sa
= ike_sa
;
1468 this->keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
);
1469 this->state
= QM_INIT
;
1473 this->proposal
= NULL
;
1474 this->child_sa
= NULL
;
1478 this->child
= (child_sa_create_t
){};
1480 if (!this->initiator
)
1482 DESTROY_IF(this->config
);
1483 this->config
= NULL
;
1487 METHOD(task_t
, destroy
, void,
1488 private_quick_mode_t
*this)
1490 chunk_free(&this->nonce_i
);
1491 chunk_free(&this->nonce_r
);
1492 DESTROY_IF(this->tsi
);
1493 DESTROY_IF(this->tsr
);
1494 DESTROY_IF(this->proposal
);
1495 DESTROY_IF(this->child_sa
);
1496 DESTROY_IF(this->config
);
1497 DESTROY_IF(this->dh
);
1502 * Described in header.
1504 quick_mode_t
*quick_mode_create(ike_sa_t
*ike_sa
, child_cfg_t
*config
,
1505 traffic_selector_t
*tsi
, traffic_selector_t
*tsr
)
1507 private_quick_mode_t
*this;
1512 .get_type
= _get_type
,
1513 .migrate
= _migrate
,
1514 .destroy
= _destroy
,
1516 .get_mid
= _get_mid
,
1517 .use_reqid
= _use_reqid
,
1518 .use_marks
= _use_marks
,
1519 .use_if_ids
= _use_if_ids
,
1523 .initiator
= config
!= NULL
,
1525 .keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
),
1527 .tsi
= tsi
? tsi
->clone(tsi
) : NULL
,
1528 .tsr
= tsr
? tsr
->clone(tsr
) : NULL
,
1530 .delete = lib
->settings
->get_bool(lib
->settings
,
1531 "%s.delete_rekeyed", FALSE
, lib
->ns
),
1536 this->public.task
.build
= _build_i
;
1537 this->public.task
.process
= _process_i
;
1541 this->public.task
.build
= _build_r
;
1542 this->public.task
.process
= _process_r
;
1545 return &this->public;