2 * Copyright (C) 2011 Martin Willi
3 * Copyright (C) 2011 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "quick_mode.h"
21 #include <sa/ikev1/keymat_v1.h>
22 #include <encoding/payloads/sa_payload.h>
23 #include <encoding/payloads/nonce_payload.h>
24 #include <encoding/payloads/ke_payload.h>
25 #include <encoding/payloads/id_payload.h>
26 #include <encoding/payloads/payload.h>
27 #include <sa/ikev1/tasks/informational.h>
28 #include <sa/ikev1/tasks/quick_delete.h>
29 #include <processing/jobs/inactivity_job.h>
31 typedef struct private_quick_mode_t private_quick_mode_t
;
34 * Private members of a quick_mode_t task.
36 struct private_quick_mode_t
{
39 * Public methods and task_t interface.
49 * TRUE if we are initiating quick mode
54 * Traffic selector of initiator
56 traffic_selector_t
*tsi
;
59 * Traffic selector of responder
61 traffic_selector_t
*tsr
;
84 * selected CHILD_SA proposal
89 * Config of CHILD_SA to establish
94 * CHILD_SA we are about to establish
104 * DH exchange, when PFS is in use
106 diffie_hellman_t
*dh
;
109 * Negotiated lifetime of new SA
114 * Negotaited lifebytes of new SA
119 * Reqid to use, 0 for auto-allocate
129 * Negotiated mode, tunnel or transport
134 * Use UDP encapsulation
138 /** states of quick mode */
146 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
148 static void schedule_inactivity_timeout(private_quick_mode_t
*this)
153 timeout
= this->config
->get_inactivity(this->config
);
156 close_ike
= lib
->settings
->get_bool(lib
->settings
,
157 "%s.inactivity_close_ike", FALSE
, charon
->name
);
158 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)
159 inactivity_job_create(this->child_sa
->get_reqid(this->child_sa
),
160 timeout
, close_ike
), timeout
);
165 * Install negotiated CHILD_SA
167 static bool install(private_quick_mode_t
*this)
169 status_t status
, status_i
, status_o
;
170 chunk_t encr_i
, encr_r
, integ_i
, integ_r
;
171 linked_list_t
*tsi
, *tsr
;
172 child_sa_t
*old
= NULL
;
174 this->child_sa
->set_proposal(this->child_sa
, this->proposal
);
175 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLING
);
176 this->child_sa
->set_mode(this->child_sa
, this->mode
);
177 this->child_sa
->set_protocol(this->child_sa
,
178 this->proposal
->get_protocol(this->proposal
));
180 status_i
= status_o
= FAILED
;
181 encr_i
= encr_r
= integ_i
= integ_r
= chunk_empty
;
182 tsi
= linked_list_create();
183 tsr
= linked_list_create();
184 tsi
->insert_last(tsi
, this->tsi
->clone(this->tsi
));
185 tsr
->insert_last(tsr
, this->tsr
->clone(this->tsr
));
188 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
189 NARROW_INITIATOR_POST_AUTH
, tsi
, tsr
);
193 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
194 NARROW_RESPONDER
, tsr
, tsi
);
196 if (tsi
->get_count(tsi
) == 0 || tsr
->get_count(tsr
) == 0)
198 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
199 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
200 DBG1(DBG_IKE
, "no acceptable traffic selectors found");
204 if (this->keymat
->derive_child_keys(this->keymat
, this->proposal
, this->dh
,
205 this->spi_i
, this->spi_r
, this->nonce_i
, this->nonce_r
,
206 &encr_i
, &integ_i
, &encr_r
, &integ_r
))
210 status_i
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
211 this->spi_i
, 0, TRUE
, FALSE
, tsi
, tsr
);
212 status_o
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
213 this->spi_r
, 0, FALSE
, FALSE
, tsi
, tsr
);
217 status_i
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
218 this->spi_r
, 0, TRUE
, FALSE
, tsr
, tsi
);
219 status_o
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
220 this->spi_i
, 0, FALSE
, FALSE
, tsr
, tsi
);
223 chunk_clear(&integ_i
);
224 chunk_clear(&integ_r
);
225 chunk_clear(&encr_i
);
226 chunk_clear(&encr_r
);
228 if (status_i
!= SUCCESS
|| status_o
!= SUCCESS
)
230 DBG1(DBG_IKE
, "unable to install %s%s%sIPsec SA (SAD) in kernel",
231 (status_i
!= SUCCESS
) ?
"inbound " : "",
232 (status_i
!= SUCCESS
&& status_o
!= SUCCESS
) ?
"and ": "",
233 (status_o
!= SUCCESS
) ?
"outbound " : "");
234 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
235 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
241 status
= this->child_sa
->add_policies(this->child_sa
, tsi
, tsr
);
245 status
= this->child_sa
->add_policies(this->child_sa
, tsr
, tsi
);
247 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
248 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
249 if (status
!= SUCCESS
)
251 DBG1(DBG_IKE
, "unable to install IPsec policies (SPD) in kernel");
255 charon
->bus
->child_keys(charon
->bus
, this->child_sa
, this->initiator
,
256 this->dh
, this->nonce_i
, this->nonce_r
);
258 /* add to IKE_SA, and remove from task */
259 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
260 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
262 DBG0(DBG_IKE
, "CHILD_SA %s{%d} established "
263 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
264 this->child_sa
->get_name(this->child_sa
),
265 this->child_sa
->get_reqid(this->child_sa
),
266 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
267 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)),
268 this->child_sa
->get_traffic_selectors(this->child_sa
, TRUE
),
269 this->child_sa
->get_traffic_selectors(this->child_sa
, FALSE
));
273 old
= this->ike_sa
->get_child_sa(this->ike_sa
,
274 this->proposal
->get_protocol(this->proposal
),
279 charon
->bus
->child_rekey(charon
->bus
, old
, this->child_sa
);
283 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
287 schedule_inactivity_timeout(this);
289 this->child_sa
= NULL
;
294 * Generate and add NONCE
296 static bool add_nonce(private_quick_mode_t
*this, chunk_t
*nonce
,
299 nonce_payload_t
*nonce_payload
;
302 nonceg
= this->keymat
->keymat
.create_nonce_gen(&this->keymat
->keymat
);
305 DBG1(DBG_IKE
, "no nonce generator found to create nonce");
308 nonceg
->allocate_nonce(nonceg
, NONCE_SIZE
, nonce
);
309 nonceg
->destroy(nonceg
);
311 nonce_payload
= nonce_payload_create(NONCE_V1
);
312 nonce_payload
->set_nonce(nonce_payload
, *nonce
);
313 message
->add_payload(message
, &nonce_payload
->payload_interface
);
319 * Extract nonce from NONCE payload
321 static bool get_nonce(private_quick_mode_t
*this, chunk_t
*nonce
,
324 nonce_payload_t
*nonce_payload
;
326 nonce_payload
= (nonce_payload_t
*)message
->get_payload(message
, NONCE_V1
);
329 DBG1(DBG_IKE
, "NONCE payload missing in message");
332 *nonce
= nonce_payload
->get_nonce(nonce_payload
);
338 * Add KE payload to message
340 static void add_ke(private_quick_mode_t
*this, message_t
*message
)
342 ke_payload_t
*ke_payload
;
344 ke_payload
= ke_payload_create_from_diffie_hellman(KEY_EXCHANGE_V1
, this->dh
);
345 message
->add_payload(message
, &ke_payload
->payload_interface
);
349 * Get DH value from a KE payload
351 static bool get_ke(private_quick_mode_t
*this, message_t
*message
)
353 ke_payload_t
*ke_payload
;
355 ke_payload
= (ke_payload_t
*)message
->get_payload(message
, KEY_EXCHANGE_V1
);
358 DBG1(DBG_IKE
, "KE payload missing");
361 this->dh
->set_other_public_value(this->dh
,
362 ke_payload
->get_key_exchange_data(ke_payload
));
367 * Select a traffic selector from configuration
369 static traffic_selector_t
* select_ts(private_quick_mode_t
*this, bool local
,
370 linked_list_t
*supplied
)
372 traffic_selector_t
*ts
;
376 host
= this->ike_sa
->get_virtual_ip(this->ike_sa
, local
);
381 host
= this->ike_sa
->get_my_host(this->ike_sa
);
385 host
= this->ike_sa
->get_other_host(this->ike_sa
);
388 list
= this->config
->get_traffic_selectors(this->config
, local
,
390 if (list
->get_first(list
, (void**)&ts
) == SUCCESS
)
392 if (list
->get_count(list
) > 1)
394 DBG1(DBG_IKE
, "configuration has more than one %s traffic selector,"
395 " using first only", local ?
"local" : "remote");
401 DBG1(DBG_IKE
, "%s traffic selector missing in configuration",
402 local ?
"local" : "local");
405 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
410 * Add selected traffic selectors to message
412 static void add_ts(private_quick_mode_t
*this, message_t
*message
)
414 id_payload_t
*id_payload
;
419 hsi
= this->ike_sa
->get_my_host(this->ike_sa
);
420 hsr
= this->ike_sa
->get_other_host(this->ike_sa
);
424 hsr
= this->ike_sa
->get_my_host(this->ike_sa
);
425 hsi
= this->ike_sa
->get_other_host(this->ike_sa
);
427 /* add ID payload only if negotiating non host2host tunnels */
428 if (!this->tsi
->is_host(this->tsi
, hsi
) ||
429 !this->tsr
->is_host(this->tsr
, hsr
) ||
430 this->tsi
->get_protocol(this->tsi
) ||
431 this->tsr
->get_protocol(this->tsr
) ||
432 this->tsi
->get_from_port(this->tsi
) ||
433 this->tsr
->get_from_port(this->tsr
) ||
434 this->tsi
->get_to_port(this->tsi
) != 65535 ||
435 this->tsr
->get_to_port(this->tsr
) != 65535)
437 id_payload
= id_payload_create_from_ts(this->tsi
);
438 message
->add_payload(message
, &id_payload
->payload_interface
);
439 id_payload
= id_payload_create_from_ts(this->tsr
);
440 message
->add_payload(message
, &id_payload
->payload_interface
);
445 * Get traffic selectors from received message
447 static bool get_ts(private_quick_mode_t
*this, message_t
*message
)
449 traffic_selector_t
*tsi
= NULL
, *tsr
= NULL
;
450 enumerator_t
*enumerator
;
451 id_payload_t
*id_payload
;
456 enumerator
= message
->create_payload_enumerator(message
);
457 while (enumerator
->enumerate(enumerator
, &payload
))
459 if (payload
->get_type(payload
) == ID_V1
)
461 id_payload
= (id_payload_t
*)payload
;
465 tsi
= id_payload
->get_ts(id_payload
);
470 tsr
= id_payload
->get_ts(id_payload
);
475 enumerator
->destroy(enumerator
);
477 /* create host2host selectors if ID payloads missing */
480 hsi
= this->ike_sa
->get_my_host(this->ike_sa
);
481 hsr
= this->ike_sa
->get_other_host(this->ike_sa
);
485 hsr
= this->ike_sa
->get_my_host(this->ike_sa
);
486 hsi
= this->ike_sa
->get_other_host(this->ike_sa
);
490 tsi
= traffic_selector_create_from_subnet(hsi
->clone(hsi
),
491 hsi
->get_family(hsi
) == AF_INET ?
32 : 128, 0, 0);
495 tsr
= traffic_selector_create_from_subnet(hsr
->clone(hsr
),
496 hsr
->get_family(hsr
) == AF_INET ?
32 : 128, 0, 0);
500 /* check if peer selection valid */
501 if (!tsr
->is_contained_in(tsr
, this->tsr
) ||
502 !tsi
->is_contained_in(tsi
, this->tsi
))
504 DBG1(DBG_IKE
, "peer selected invalid traffic selectors: ",
505 "%R for %R, %R for %R", tsi
, this->tsi
, tsr
, this->tsr
);
510 this->tsi
->destroy(this->tsi
);
511 this->tsr
->destroy(this->tsr
);
524 * Add NAT-OA payloads
526 static void add_nat_oa_payloads(private_quick_mode_t
*this, message_t
*message
)
528 identification_t
*id
;
529 id_payload_t
*nat_oa
;
532 src
= message
->get_source(message
);
533 dst
= message
->get_destination(message
);
535 src
= this->initiator ? src
: dst
;
536 dst
= this->initiator ? dst
: src
;
538 /* first NAT-OA is the initiator's address */
539 id
= identification_create_from_sockaddr(src
->get_sockaddr(src
));
540 nat_oa
= id_payload_create_from_identification(NAT_OA_V1
, id
);
541 message
->add_payload(message
, (payload_t
*)nat_oa
);
544 /* second NAT-OA is that of the responder */
545 id
= identification_create_from_sockaddr(dst
->get_sockaddr(dst
));
546 nat_oa
= id_payload_create_from_identification(NAT_OA_V1
, id
);
547 message
->add_payload(message
, (payload_t
*)nat_oa
);
554 static void get_lifetimes(private_quick_mode_t
*this)
558 lft
= this->config
->get_lifetime(this->config
);
561 this->lifetime
= lft
->time
.life
;
563 else if (lft
->bytes
.life
)
565 this->lifebytes
= lft
->bytes
.life
;
571 * Check and apply lifetimes
573 static void apply_lifetimes(private_quick_mode_t
*this, sa_payload_t
*sa_payload
)
578 lifetime
= sa_payload
->get_lifetime(sa_payload
);
579 lifebytes
= sa_payload
->get_lifebytes(sa_payload
);
580 if (this->lifetime
!= lifetime
)
582 DBG1(DBG_IKE
, "received %us lifetime, configured %us",
583 lifetime
, this->lifetime
);
584 this->lifetime
= lifetime
;
586 if (this->lifebytes
!= lifebytes
)
588 DBG1(DBG_IKE
, "received %llu lifebytes, configured %llu",
589 lifebytes
, this->lifebytes
);
590 this->lifebytes
= lifebytes
;
595 * Set the task ready to build notify error message
597 static status_t
send_notify(private_quick_mode_t
*this, notify_type_t type
)
599 notify_payload_t
*notify
;
601 notify
= notify_payload_create_from_protocol_and_type(NOTIFY_V1
,
603 notify
->set_spi(notify
, this->spi_i
);
605 this->ike_sa
->queue_task(this->ike_sa
,
606 (task_t
*)informational_create(this->ike_sa
, notify
));
607 /* cancel all active/passive tasks in favour of informational */
608 this->ike_sa
->flush_queue(this->ike_sa
,
609 this->initiator ? TASK_QUEUE_ACTIVE
: TASK_QUEUE_PASSIVE
);
613 METHOD(task_t
, build_i
, status_t
,
614 private_quick_mode_t
*this, message_t
*message
)
620 enumerator_t
*enumerator
;
621 sa_payload_t
*sa_payload
;
622 linked_list_t
*list
, *tsi
, *tsr
;
623 proposal_t
*proposal
;
624 diffie_hellman_group_t group
;
626 this->udp
= this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
);
627 this->child_sa
= child_sa_create(
628 this->ike_sa
->get_my_host(this->ike_sa
),
629 this->ike_sa
->get_other_host(this->ike_sa
),
630 this->config
, this->reqid
, this->udp
);
632 list
= this->config
->get_proposals(this->config
, FALSE
);
634 this->spi_i
= this->child_sa
->alloc_spi(this->child_sa
, PROTO_ESP
);
637 DBG1(DBG_IKE
, "allocating SPI from kernel failed");
640 enumerator
= list
->create_enumerator(list
);
641 while (enumerator
->enumerate(enumerator
, &proposal
))
643 proposal
->set_spi(proposal
, this->spi_i
);
645 enumerator
->destroy(enumerator
);
647 this->mode
= this->config
->get_mode(this->config
);
648 if (this->udp
&& this->mode
== MODE_TRANSPORT
)
650 /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
651 add_nat_oa_payloads(this, message
);
655 sa_payload
= sa_payload_create_from_proposals_v1(list
,
656 this->lifetime
, this->lifebytes
, AUTH_NONE
,
657 this->mode
, this->udp
);
658 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
659 message
->add_payload(message
, &sa_payload
->payload_interface
);
661 if (!add_nonce(this, &this->nonce_i
, message
))
666 group
= this->config
->get_dh_group(this->config
);
667 if (group
!= MODP_NONE
)
669 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
673 DBG1(DBG_IKE
, "configured DH group %N not supported",
674 diffie_hellman_group_names
, group
);
677 add_ke(this, message
);
679 this->tsi
= select_ts(this, TRUE
, NULL
);
680 this->tsr
= select_ts(this, FALSE
, NULL
);
681 tsi
= linked_list_create();
682 tsr
= linked_list_create();
683 tsi
->insert_last(tsi
, this->tsi
);
684 tsr
->insert_last(tsr
, this->tsr
);
685 this->tsi
= this->tsr
= NULL
;
686 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
687 NARROW_INITIATOR_PRE_AUTH
, tsi
, tsr
);
688 tsi
->remove_first(tsi
, (void**)&this->tsi
);
689 tsr
->remove_first(tsr
, (void**)&this->tsr
);
690 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
691 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
692 if (!this->tsi
|| !this->tsr
)
696 add_ts(this, message
);
709 * Check for notify errors, return TRUE if error found
711 static bool has_notify_errors(private_quick_mode_t
*this, message_t
*message
)
713 enumerator_t
*enumerator
;
717 enumerator
= message
->create_payload_enumerator(message
);
718 while (enumerator
->enumerate(enumerator
, &payload
))
720 if (payload
->get_type(payload
) == NOTIFY_V1
)
722 notify_payload_t
*notify
;
725 notify
= (notify_payload_t
*)payload
;
726 type
= notify
->get_notify_type(notify
);
730 DBG1(DBG_IKE
, "received %N error notify",
731 notify_type_names
, type
);
736 DBG1(DBG_IKE
, "received %N notify", notify_type_names
, type
);
740 enumerator
->destroy(enumerator
);
746 * Check if this is a rekey for an existing CHILD_SA, reuse reqid if so
748 static void check_for_rekeyed_child(private_quick_mode_t
*this)
750 enumerator_t
*enumerator
, *policies
;
751 traffic_selector_t
*local
, *remote
;
752 child_sa_t
*child_sa
;
754 enumerator
= this->ike_sa
->create_child_sa_enumerator(this->ike_sa
);
755 while (this->reqid
== 0 && enumerator
->enumerate(enumerator
, &child_sa
))
757 if (child_sa
->get_state(child_sa
) == CHILD_INSTALLED
&&
758 streq(child_sa
->get_name(child_sa
),
759 this->config
->get_name(this->config
)))
761 policies
= child_sa
->create_policy_enumerator(child_sa
);
762 if (policies
->enumerate(policies
, &local
, &remote
))
764 if (local
->equals(local
, this->tsr
) &&
765 remote
->equals(remote
, this->tsi
) &&
766 this->proposal
->equals(this->proposal
,
767 child_sa
->get_proposal(child_sa
)))
769 this->reqid
= child_sa
->get_reqid(child_sa
);
770 this->rekey
= child_sa
->get_spi(child_sa
, TRUE
);
771 child_sa
->set_state(child_sa
, CHILD_REKEYING
);
772 DBG1(DBG_IKE
, "detected rekeying of CHILD_SA %s{%u}",
773 child_sa
->get_name(child_sa
), this->reqid
);
776 policies
->destroy(policies
);
779 enumerator
->destroy(enumerator
);
782 METHOD(task_t
, process_r
, status_t
,
783 private_quick_mode_t
*this, message_t
*message
)
789 sa_payload_t
*sa_payload
;
790 linked_list_t
*tsi
, *tsr
, *list
;
791 peer_cfg_t
*peer_cfg
;
796 if (!get_ts(this, message
))
800 me
= this->ike_sa
->get_virtual_ip(this->ike_sa
, TRUE
);
803 me
= this->ike_sa
->get_my_host(this->ike_sa
);
805 other
= this->ike_sa
->get_virtual_ip(this->ike_sa
, FALSE
);
808 other
= this->ike_sa
->get_other_host(this->ike_sa
);
810 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
811 tsi
= linked_list_create();
812 tsr
= linked_list_create();
813 tsi
->insert_last(tsi
, this->tsi
);
814 tsr
->insert_last(tsr
, this->tsr
);
815 this->tsi
= this->tsr
= NULL
;
816 this->config
= peer_cfg
->select_child_cfg(peer_cfg
, tsr
, tsi
,
820 this->tsi
= select_ts(this, FALSE
, tsi
);
821 this->tsr
= select_ts(this, TRUE
, tsr
);
823 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
824 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
825 if (!this->config
|| !this->tsi
|| !this->tsr
)
827 DBG1(DBG_IKE
, "no matching CHILD_SA config found");
828 return send_notify(this, INVALID_ID_INFORMATION
);
831 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
832 SECURITY_ASSOCIATION_V1
);
835 DBG1(DBG_IKE
, "sa payload missing");
836 return send_notify(this, INVALID_PAYLOAD_TYPE
);
838 list
= sa_payload
->get_proposals(sa_payload
);
839 private = this->ike_sa
->supports_extension(this->ike_sa
,
841 this->proposal
= this->config
->select_proposal(this->config
,
842 list
, FALSE
, private);
843 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
845 this->mode
= sa_payload
->get_encap_mode(sa_payload
, &this->udp
);
848 apply_lifetimes(this, sa_payload
);
852 DBG1(DBG_IKE
, "no matching proposal found, sending %N",
853 notify_type_names
, NO_PROPOSAL_CHOSEN
);
854 return send_notify(this, NO_PROPOSAL_CHOSEN
);
856 this->spi_i
= this->proposal
->get_spi(this->proposal
);
858 if (!get_nonce(this, &this->nonce_i
, message
))
860 return send_notify(this, INVALID_PAYLOAD_TYPE
);
863 if (this->proposal
->get_algorithm(this->proposal
,
864 DIFFIE_HELLMAN_GROUP
, &group
, NULL
))
866 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
870 DBG1(DBG_IKE
, "negotiated DH group %N not supported",
871 diffie_hellman_group_names
, group
);
872 return send_notify(this, INVALID_KEY_INFORMATION
);
874 if (!get_ke(this, message
))
876 return send_notify(this, INVALID_PAYLOAD_TYPE
);
880 check_for_rekeyed_child(this);
882 this->child_sa
= child_sa_create(
883 this->ike_sa
->get_my_host(this->ike_sa
),
884 this->ike_sa
->get_other_host(this->ike_sa
),
885 this->config
, this->reqid
, this->udp
);
890 if (message
->get_exchange_type(message
) == INFORMATIONAL_V1
||
891 has_notify_errors(this, message
))
897 this->ike_sa
->flush_queue(this->ike_sa
, TASK_QUEUE_PASSIVE
);
898 this->ike_sa
->queue_task(this->ike_sa
,
899 (task_t
*)quick_delete_create(this->ike_sa
,
900 this->proposal
->get_protocol(this->proposal
),
901 this->spi_i
, TRUE
, TRUE
));
911 METHOD(task_t
, build_r
, status_t
,
912 private_quick_mode_t
*this, message_t
*message
)
918 sa_payload_t
*sa_payload
;
920 this->spi_r
= this->child_sa
->alloc_spi(this->child_sa
, PROTO_ESP
);
923 DBG1(DBG_IKE
, "allocating SPI from kernel failed");
924 return send_notify(this, NO_PROPOSAL_CHOSEN
);
926 this->proposal
->set_spi(this->proposal
, this->spi_r
);
928 if (this->udp
&& this->mode
== MODE_TRANSPORT
)
930 /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
931 add_nat_oa_payloads(this, message
);
934 sa_payload
= sa_payload_create_from_proposal_v1(this->proposal
,
935 this->lifetime
, this->lifebytes
, AUTH_NONE
,
936 this->mode
, this->udp
);
937 message
->add_payload(message
, &sa_payload
->payload_interface
);
939 if (!add_nonce(this, &this->nonce_r
, message
))
945 add_ke(this, message
);
948 add_ts(this, message
);
950 this->state
= QM_NEGOTIATED
;
958 METHOD(task_t
, process_i
, status_t
,
959 private_quick_mode_t
*this, message_t
*message
)
965 sa_payload_t
*sa_payload
;
969 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
970 SECURITY_ASSOCIATION_V1
);
973 DBG1(DBG_IKE
, "sa payload missing");
974 return send_notify(this, NO_PROPOSAL_CHOSEN
);
976 list
= sa_payload
->get_proposals(sa_payload
);
977 private = this->ike_sa
->supports_extension(this->ike_sa
,
979 this->proposal
= this->config
->select_proposal(this->config
,
980 list
, FALSE
, private);
981 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
984 DBG1(DBG_IKE
, "no matching proposal found");
985 return send_notify(this, NO_PROPOSAL_CHOSEN
);
987 this->spi_r
= this->proposal
->get_spi(this->proposal
);
989 apply_lifetimes(this, sa_payload
);
991 if (!get_nonce(this, &this->nonce_r
, message
))
993 return send_notify(this, INVALID_PAYLOAD_TYPE
);
995 if (this->dh
&& !get_ke(this, message
))
997 return send_notify(this, INVALID_KEY_INFORMATION
);
999 if (!get_ts(this, message
))
1001 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1005 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1007 this->state
= QM_NEGOTIATED
;
1015 METHOD(task_t
, get_type
, task_type_t
,
1016 private_quick_mode_t
*this)
1018 return TASK_QUICK_MODE
;
1021 METHOD(quick_mode_t
, use_reqid
, void,
1022 private_quick_mode_t
*this, u_int32_t reqid
)
1024 this->reqid
= reqid
;
1027 METHOD(quick_mode_t
, rekey
, void,
1028 private_quick_mode_t
*this, u_int32_t spi
)
1033 METHOD(task_t
, migrate
, void,
1034 private_quick_mode_t
*this, ike_sa_t
*ike_sa
)
1036 chunk_free(&this->nonce_i
);
1037 chunk_free(&this->nonce_r
);
1038 DESTROY_IF(this->tsi
);
1039 DESTROY_IF(this->tsr
);
1040 DESTROY_IF(this->proposal
);
1041 DESTROY_IF(this->child_sa
);
1042 DESTROY_IF(this->dh
);
1044 this->ike_sa
= ike_sa
;
1045 this->keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
);
1046 this->state
= QM_INIT
;
1049 this->proposal
= NULL
;
1050 this->child_sa
= NULL
;
1055 if (!this->initiator
)
1057 DESTROY_IF(this->config
);
1058 this->config
= NULL
;
1062 METHOD(task_t
, destroy
, void,
1063 private_quick_mode_t
*this)
1065 chunk_free(&this->nonce_i
);
1066 chunk_free(&this->nonce_r
);
1067 DESTROY_IF(this->tsi
);
1068 DESTROY_IF(this->tsr
);
1069 DESTROY_IF(this->proposal
);
1070 DESTROY_IF(this->child_sa
);
1071 DESTROY_IF(this->config
);
1072 DESTROY_IF(this->dh
);
1077 * Described in header.
1079 quick_mode_t
*quick_mode_create(ike_sa_t
*ike_sa
, child_cfg_t
*config
,
1080 traffic_selector_t
*tsi
, traffic_selector_t
*tsr
)
1082 private_quick_mode_t
*this;
1087 .get_type
= _get_type
,
1088 .migrate
= _migrate
,
1089 .destroy
= _destroy
,
1091 .use_reqid
= _use_reqid
,
1095 .initiator
= config
!= NULL
,
1097 .keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
),
1103 this->public.task
.build
= _build_i
;
1104 this->public.task
.process
= _process_i
;
1108 this->public.task
.build
= _build_r
;
1109 this->public.task
.process
= _process_r
;
1112 return &this->public;