2 * Copyright (C) 2011 Tobias Brunner
3 * 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
19 #include "main_mode.h"
24 #include <sa/ikev1/keymat_v1.h>
25 #include <crypto/diffie_hellman.h>
26 #include <encoding/payloads/sa_payload.h>
27 #include <encoding/payloads/ke_payload.h>
28 #include <encoding/payloads/nonce_payload.h>
29 #include <encoding/payloads/id_payload.h>
30 #include <encoding/payloads/hash_payload.h>
31 #include <sa/ikev1/tasks/xauth.h>
32 #include <sa/ikev1/tasks/mode_config.h>
33 #include <sa/ikev1/tasks/informational.h>
34 #include <sa/ikev1/tasks/isakmp_delete.h>
35 #include <processing/jobs/adopt_children_job.h>
37 typedef struct private_main_mode_t private_main_mode_t
;
40 * Private members of a main_mode_t task.
42 struct private_main_mode_t
{
45 * Public methods and task_t interface.
55 * Are we the initiator?
60 * IKE config to establish
70 * Local authentication configuration
75 * Remote authentication configuration
77 auth_cfg_t
*other_auth
;
80 * selected IKE proposal
90 * Keymat derivation (from SA)
95 * Received public DH value from peer
110 * Encoded SA initiator payload used for authentication
115 * Negotiated SA lifetime
120 * Negotiated authentication method
122 auth_method_t auth_method
;
124 /** states of main mode */
134 * Get the first authentcation config from peer config
136 static auth_cfg_t
*get_auth_cfg(peer_cfg_t
*peer_cfg
, bool local
)
138 enumerator_t
*enumerator
;
139 auth_cfg_t
*cfg
= NULL
;
141 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, local
);
142 enumerator
->enumerate(enumerator
, &cfg
);
143 enumerator
->destroy(enumerator
);
148 * Create an authenticator, if supported
150 static authenticator_t
*create_authenticator(private_main_mode_t
*this,
153 authenticator_t
*authenticator
;
154 authenticator
= authenticator_create_v1(this->ike_sa
, this->initiator
,
155 this->auth_method
, this->dh
,
156 this->dh_value
, this->sa_payload
,
157 id
->get_encoded(id
));
160 DBG1(DBG_IKE
, "negotiated authentication method %N not supported",
161 auth_method_names
, this->auth_method
);
163 return authenticator
;
167 * Save the encoded SA payload of a message
169 static bool save_sa_payload(private_main_mode_t
*this, message_t
*message
)
171 enumerator_t
*enumerator
;
172 payload_t
*payload
, *sa
= NULL
;
174 size_t offset
= IKE_HEADER_LENGTH
;
176 enumerator
= message
->create_payload_enumerator(message
);
177 while (enumerator
->enumerate(enumerator
, &payload
))
179 if (payload
->get_type(payload
) == SECURITY_ASSOCIATION_V1
)
186 offset
+= payload
->get_length(payload
);
189 enumerator
->destroy(enumerator
);
191 data
= message
->get_packet_data(message
);
192 if (sa
&& data
.len
>= offset
+ sa
->get_length(sa
))
194 /* Get SA payload without 4 byte fixed header */
195 data
= chunk_skip(data
, offset
);
196 data
.len
= sa
->get_length(sa
);
197 data
= chunk_skip(data
, 4);
198 this->sa_payload
= chunk_clone(data
);
205 * Generate and add NONCE, KE payload
207 static bool add_nonce_ke(private_main_mode_t
*this, chunk_t
*nonce
,
210 nonce_payload_t
*nonce_payload
;
211 ke_payload_t
*ke_payload
;
214 ke_payload
= ke_payload_create_from_diffie_hellman(KEY_EXCHANGE_V1
,
216 message
->add_payload(message
, &ke_payload
->payload_interface
);
218 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
221 DBG1(DBG_IKE
, "no RNG found to create nonce");
224 rng
->allocate_bytes(rng
, NONCE_SIZE
, nonce
);
227 nonce_payload
= nonce_payload_create(NONCE_V1
);
228 nonce_payload
->set_nonce(nonce_payload
, *nonce
);
229 message
->add_payload(message
, &nonce_payload
->payload_interface
);
235 * Extract nonce from NONCE payload, process KE payload
237 static bool get_nonce_ke(private_main_mode_t
*this, chunk_t
*nonce
,
240 nonce_payload_t
*nonce_payload
;
241 ke_payload_t
*ke_payload
;
243 ke_payload
= (ke_payload_t
*)message
->get_payload(message
, KEY_EXCHANGE_V1
);
246 DBG1(DBG_IKE
, "KE payload missing in message");
249 this->dh_value
= chunk_clone(ke_payload
->get_key_exchange_data(ke_payload
));
250 this->dh
->set_other_public_value(this->dh
, this->dh_value
);
252 nonce_payload
= (nonce_payload_t
*)message
->get_payload(message
, NONCE_V1
);
255 DBG1(DBG_IKE
, "NONCE payload missing in message");
258 *nonce
= nonce_payload
->get_nonce(nonce_payload
);
264 * Get the two auth classes from local or remote config
266 static void get_auth_class(peer_cfg_t
*peer_cfg
, bool local
,
267 auth_class_t
*c1
, auth_class_t
*c2
)
269 enumerator_t
*enumerator
;
272 *c1
= *c2
= AUTH_CLASS_ANY
;
274 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, local
);
275 while (enumerator
->enumerate(enumerator
, &auth
))
277 if (*c1
== AUTH_CLASS_ANY
)
279 *c1
= (uintptr_t)auth
->get(auth
, AUTH_RULE_AUTH_CLASS
);
283 *c2
= (uintptr_t)auth
->get(auth
, AUTH_RULE_AUTH_CLASS
);
287 enumerator
->destroy(enumerator
);
291 * Get auth method to use from a peer config
293 static auth_method_t
get_auth_method(private_main_mode_t
*this,
294 peer_cfg_t
*peer_cfg
)
296 auth_class_t i1
, i2
, r1
, r2
;
298 get_auth_class(peer_cfg
, this->initiator
, &i1
, &i2
);
299 get_auth_class(peer_cfg
, !this->initiator
, &r1
, &r2
);
301 if (i1
== AUTH_CLASS_PUBKEY
&& r1
== AUTH_CLASS_PUBKEY
)
303 if (i2
== AUTH_CLASS_ANY
&& r2
== AUTH_CLASS_ANY
)
305 /* TODO-IKEv1: ECDSA? */
308 if (i2
== AUTH_CLASS_XAUTH
)
310 return AUTH_XAUTH_INIT_RSA
;
312 if (r2
== AUTH_CLASS_XAUTH
)
314 return AUTH_XAUTH_RESP_RSA
;
317 if (i1
== AUTH_CLASS_PSK
&& r1
== AUTH_CLASS_PSK
)
319 if (i2
== AUTH_CLASS_ANY
&& r2
== AUTH_CLASS_ANY
)
323 if (i2
== AUTH_CLASS_XAUTH
)
325 return AUTH_XAUTH_INIT_PSK
;
327 if (r2
== AUTH_CLASS_XAUTH
)
329 return AUTH_XAUTH_RESP_PSK
;
332 if (i1
== AUTH_CLASS_XAUTH
&& r1
== AUTH_CLASS_PUBKEY
&&
333 i2
== AUTH_CLASS_ANY
&& r2
== AUTH_CLASS_ANY
)
335 return AUTH_HYBRID_INIT_RSA
;
341 * Check if a peer skipped authentication by using Hybrid authentication
343 static bool skipped_auth(private_main_mode_t
*this, bool local
)
347 initiator
= local
== this->initiator
;
348 if (initiator
&& this->auth_method
== AUTH_HYBRID_INIT_RSA
)
352 if (!initiator
&& this->auth_method
== AUTH_HYBRID_RESP_RSA
)
360 * Check if remote authentication constraints fulfilled
362 static bool check_constraints(private_main_mode_t
*this)
364 identification_t
*id
;
367 auth
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
368 /* auth identity to comply */
369 id
= this->ike_sa
->get_other_id(this->ike_sa
);
370 auth
->add(auth
, AUTH_RULE_IDENTITY
, id
->clone(id
));
371 if (skipped_auth(this, FALSE
))
375 return auth
->complies(auth
, this->other_auth
, TRUE
);
379 * Save authentication information after authentication succeeded
381 static void save_auth_cfg(private_main_mode_t
*this, bool local
)
385 if (skipped_auth(this, local
))
389 auth
= auth_cfg_create();
390 /* for local config, we _copy_ entires from the config, as it contains
391 * certificates we must send later. */
392 auth
->merge(auth
, this->ike_sa
->get_auth_cfg(this->ike_sa
, local
), local
);
393 this->ike_sa
->add_auth_cfg(this->ike_sa
, local
, auth
);
397 * Select the best configuration as responder
399 static peer_cfg_t
*select_config(private_main_mode_t
*this, identification_t
*id
)
401 enumerator_t
*enumerator
;
402 peer_cfg_t
*current
, *found
= NULL
;
405 me
= this->ike_sa
->get_my_host(this->ike_sa
);
406 other
= this->ike_sa
->get_other_host(this->ike_sa
);
407 DBG1(DBG_CFG
, "looking for %N peer configs matching %H...%H[%Y]",
408 auth_method_names
, this->auth_method
, me
, other
, id
);
409 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
410 me
, other
, NULL
, id
, IKEV1
);
411 while (enumerator
->enumerate(enumerator
, ¤t
))
413 if (get_auth_method(this, current
) == this->auth_method
)
415 found
= current
->get_ref(current
);
419 enumerator
->destroy(enumerator
);
423 DBG2(DBG_CFG
, "selected peer config \"%s\"", found
->get_name(found
));
429 * Check for notify errors, return TRUE if error found
431 static bool has_notify_errors(private_main_mode_t
*this, message_t
*message
)
433 enumerator_t
*enumerator
;
437 enumerator
= message
->create_payload_enumerator(message
);
438 while (enumerator
->enumerate(enumerator
, &payload
))
440 if (payload
->get_type(payload
) == NOTIFY_V1
)
442 notify_payload_t
*notify
;
445 notify
= (notify_payload_t
*)payload
;
446 type
= notify
->get_notify_type(notify
);
449 DBG1(DBG_IKE
, "received %N error notify",
450 notify_type_names
, type
);
453 else if (type
== INITIAL_CONTACT_IKEV1
)
455 if (!this->initiator
&& this->state
== MM_AUTH
)
457 /* If authenticated and received INITIAL_CONTACT,
458 * delete any existing IKE_SAs with that peer.
459 * The delete takes place when the SA is checked in due
460 * to other id not known until the 3rd message.*/
461 this->ike_sa
->set_condition(this->ike_sa
,
462 COND_INIT_CONTACT_SEEN
, TRUE
);
467 DBG1(DBG_IKE
, "received %N notify", notify_type_names
, type
);
471 enumerator
->destroy(enumerator
);
477 * Queue a task sending a notify in an INFORMATIONAL exchange
479 static status_t
send_notify(private_main_mode_t
*this, notify_type_t type
)
481 notify_payload_t
*notify
;
482 ike_sa_id_t
*ike_sa_id
;
483 u_int64_t spi_i
, spi_r
;
486 notify
= notify_payload_create_from_protocol_and_type(NOTIFY_V1
,
488 ike_sa_id
= this->ike_sa
->get_id(this->ike_sa
);
489 spi_i
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
490 spi_r
= ike_sa_id
->get_responder_spi(ike_sa_id
);
491 spi
= chunk_cata("cc", chunk_from_thing(spi_i
), chunk_from_thing(spi_r
));
492 notify
->set_spi_data(notify
, spi
);
494 this->ike_sa
->queue_task(this->ike_sa
,
495 (task_t
*)informational_create(this->ike_sa
, notify
));
496 /* cancel all active/passive tasks in favour of informational */
501 * Queue a delete task if authentication failed as initiator
503 static status_t
send_delete(private_main_mode_t
*this)
505 this->ike_sa
->queue_task(this->ike_sa
,
506 (task_t
*)isakmp_delete_create(this->ike_sa
, TRUE
));
507 /* cancel all active tasks in favour of informational */
511 METHOD(task_t
, build_i
, status_t
,
512 private_main_mode_t
*this, message_t
*message
)
518 sa_payload_t
*sa_payload
;
519 linked_list_t
*proposals
;
522 this->ike_cfg
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
523 DBG0(DBG_IKE
, "initiating IKE_SA %s[%d] to %H",
524 this->ike_sa
->get_name(this->ike_sa
),
525 this->ike_sa
->get_unique_id(this->ike_sa
),
526 this->ike_sa
->get_other_host(this->ike_sa
));
527 this->ike_sa
->set_state(this->ike_sa
, IKE_CONNECTING
);
529 this->peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
530 this->peer_cfg
->get_ref(this->peer_cfg
);
532 this->my_auth
= get_auth_cfg(this->peer_cfg
, TRUE
);
533 this->other_auth
= get_auth_cfg(this->peer_cfg
, FALSE
);
534 if (!this->my_auth
|| !this->other_auth
)
536 DBG1(DBG_CFG
, "no auth config found");
539 this->auth_method
= get_auth_method(this, this->peer_cfg
);
540 if (this->auth_method
== AUTH_NONE
)
542 DBG1(DBG_CFG
, "configuration uses unsupported authentication");
545 this->lifetime
= this->peer_cfg
->get_reauth_time(this->peer_cfg
,
548 { /* fall back to rekey time of no rekey time configured */
549 this->lifetime
= this->peer_cfg
->get_rekey_time(this->peer_cfg
,
552 this->lifetime
+= this->peer_cfg
->get_over_time(this->peer_cfg
);
553 proposals
= this->ike_cfg
->get_proposals(this->ike_cfg
);
554 sa_payload
= sa_payload_create_from_proposals_v1(proposals
,
555 this->lifetime
, 0, this->auth_method
, MODE_NONE
, FALSE
);
556 proposals
->destroy_offset(proposals
, offsetof(proposal_t
, destroy
));
558 message
->add_payload(message
, &sa_payload
->payload_interface
);
560 /* pregenerate message to store SA payload */
561 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
564 DBG1(DBG_IKE
, "pregenerating SA payload failed");
567 packet
->destroy(packet
);
568 if (!save_sa_payload(this, message
))
570 DBG1(DBG_IKE
, "SA payload invalid");
581 if (!this->keymat
->create_hasher(this->keymat
, this->proposal
))
583 return send_notify(this, NO_PROPOSAL_CHOSEN
);
585 if (!this->proposal
->get_algorithm(this->proposal
,
586 DIFFIE_HELLMAN_GROUP
, &group
, NULL
))
588 DBG1(DBG_IKE
, "DH group selection failed");
589 return send_notify(this, NO_PROPOSAL_CHOSEN
);
591 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
595 DBG1(DBG_IKE
, "negotiated DH group not supported");
596 return send_notify(this, INVALID_KEY_INFORMATION
);
598 if (!add_nonce_ke(this, &this->nonce_i
, message
))
600 return send_notify(this, INVALID_KEY_INFORMATION
);
607 authenticator_t
*authenticator
;
608 id_payload_t
*id_payload
;
609 identification_t
*id
;
611 id
= this->my_auth
->get(this->my_auth
, AUTH_RULE_IDENTITY
);
614 DBG1(DBG_CFG
, "own identity not known");
615 return send_notify(this, INVALID_ID_INFORMATION
);
618 this->ike_sa
->set_my_id(this->ike_sa
, id
->clone(id
));
620 id_payload
= id_payload_create_from_identification(ID_V1
, id
);
621 message
->add_payload(message
, &id_payload
->payload_interface
);
623 authenticator
= create_authenticator(this, id_payload
);
624 if (!authenticator
|| authenticator
->build(authenticator
,
627 DESTROY_IF(authenticator
);
628 return send_notify(this, AUTHENTICATION_FAILED
);
630 authenticator
->destroy(authenticator
);
631 save_auth_cfg(this, TRUE
);
633 this->state
= MM_AUTH
;
641 METHOD(task_t
, process_r
, status_t
,
642 private_main_mode_t
*this, message_t
*message
)
649 sa_payload_t
*sa_payload
;
651 this->ike_cfg
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
652 DBG0(DBG_IKE
, "%H is initiating a Main Mode",
653 message
->get_source(message
));
654 this->ike_sa
->set_state(this->ike_sa
, IKE_CONNECTING
);
656 this->ike_sa
->update_hosts(this->ike_sa
,
657 message
->get_destination(message
),
658 message
->get_source(message
), TRUE
);
660 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
661 SECURITY_ASSOCIATION_V1
);
662 if (!sa_payload
|| !save_sa_payload(this, message
))
664 DBG1(DBG_IKE
, "SA payload missing or invalid");
665 return send_notify(this, INVALID_PAYLOAD_TYPE
);
668 list
= sa_payload
->get_proposals(sa_payload
);
669 this->proposal
= this->ike_cfg
->select_proposal(this->ike_cfg
,
671 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
674 DBG1(DBG_IKE
, "no proposal found");
675 return send_notify(this, NO_PROPOSAL_CHOSEN
);
678 this->auth_method
= sa_payload
->get_auth_method(sa_payload
);
679 this->lifetime
= sa_payload
->get_lifetime(sa_payload
);
688 if (!this->keymat
->create_hasher(this->keymat
, this->proposal
))
690 return send_notify(this, INVALID_KEY_INFORMATION
);
692 if (!this->proposal
->get_algorithm(this->proposal
,
693 DIFFIE_HELLMAN_GROUP
, &group
, NULL
))
695 DBG1(DBG_IKE
, "DH group selection failed");
696 return send_notify(this, INVALID_KEY_INFORMATION
);
698 this->dh
= lib
->crypto
->create_dh(lib
->crypto
, group
);
701 DBG1(DBG_IKE
, "negotiated DH group not supported");
702 return send_notify(this, INVALID_KEY_INFORMATION
);
704 if (!get_nonce_ke(this, &this->nonce_i
, message
))
706 return send_notify(this, INVALID_PAYLOAD_TYPE
);
713 authenticator_t
*authenticator
;
714 id_payload_t
*id_payload
;
715 identification_t
*id
;
717 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_V1
);
720 DBG1(DBG_IKE
, "IDii payload missing");
721 return send_notify(this, INVALID_PAYLOAD_TYPE
);
724 id
= id_payload
->get_identification(id_payload
);
725 this->ike_sa
->set_other_id(this->ike_sa
, id
);
726 this->peer_cfg
= select_config(this, id
);
729 DBG1(DBG_IKE
, "no peer config found");
730 return send_notify(this, AUTHENTICATION_FAILED
);
732 this->ike_sa
->set_peer_cfg(this->ike_sa
, this->peer_cfg
);
734 this->my_auth
= get_auth_cfg(this->peer_cfg
, TRUE
);
735 this->other_auth
= get_auth_cfg(this->peer_cfg
, FALSE
);
736 if (!this->my_auth
|| !this->other_auth
)
738 DBG1(DBG_IKE
, "auth config missing");
739 return send_notify(this, AUTHENTICATION_FAILED
);
742 authenticator
= create_authenticator(this, id_payload
);
743 if (!authenticator
|| authenticator
->process(authenticator
,
746 DESTROY_IF(authenticator
);
747 return send_notify(this, AUTHENTICATION_FAILED
);
749 authenticator
->destroy(authenticator
);
750 if (!check_constraints(this))
752 return send_notify(this, AUTHENTICATION_FAILED
);
754 save_auth_cfg(this, FALSE
);
756 this->state
= MM_AUTH
;
757 if (has_notify_errors(this, message
))
769 * Lookup a shared secret for this IKE_SA
771 static shared_key_t
*lookup_shared_key(private_main_mode_t
*this)
774 identification_t
*my_id
, *other_id
;
775 shared_key_t
*shared_key
= NULL
;
777 /* try to get a PSK for IP addresses */
778 me
= this->ike_sa
->get_my_host(this->ike_sa
);
779 other
= this->ike_sa
->get_other_host(this->ike_sa
);
780 my_id
= identification_create_from_sockaddr(me
->get_sockaddr(me
));
781 other_id
= identification_create_from_sockaddr(other
->get_sockaddr(other
));
782 if (my_id
&& other_id
)
784 shared_key
= lib
->credmgr
->get_shared(lib
->credmgr
, SHARED_IKE
,
788 DESTROY_IF(other_id
);
794 if (this->my_auth
&& this->other_auth
)
795 { /* as initiator, use identities from configuraiton */
796 my_id
= this->my_auth
->get(this->my_auth
, AUTH_RULE_IDENTITY
);
797 other_id
= this->other_auth
->get(this->other_auth
, AUTH_RULE_IDENTITY
);
798 if (my_id
&& other_id
)
800 shared_key
= lib
->credmgr
->get_shared(lib
->credmgr
, SHARED_IKE
,
805 DBG1(DBG_IKE
, "no shared key found for '%Y'[%H] - '%Y'[%H]",
806 my_id
, me
, other_id
, other
);
810 { /* as responder, we try to find a config by IP */
811 enumerator_t
*enumerator
;
812 auth_cfg_t
*my_auth
, *other_auth
;
813 peer_cfg_t
*peer_cfg
= NULL
;
815 enumerator
= charon
->backends
->create_peer_cfg_enumerator(
816 charon
->backends
, me
, other
, NULL
, NULL
, IKEV1
);
817 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
819 my_auth
= get_auth_cfg(peer_cfg
, TRUE
);
820 other_auth
= get_auth_cfg(peer_cfg
, FALSE
);
821 if (my_auth
&& other_auth
)
823 my_id
= my_auth
->get(my_auth
, AUTH_RULE_IDENTITY
);
824 other_id
= other_auth
->get(other_auth
, AUTH_RULE_IDENTITY
);
825 if (my_id
&& other_id
)
827 shared_key
= lib
->credmgr
->get_shared(lib
->credmgr
,
828 SHARED_IKE
, my_id
, other_id
);
835 DBG1(DBG_IKE
, "no shared key found for "
836 "'%Y'[%H] - '%Y'[%H]", my_id
, me
, other_id
, other
);
841 enumerator
->destroy(enumerator
);
844 DBG1(DBG_IKE
, "no shared key found for %H - %H", me
, other
);
851 * Derive key material for this IKE_SA
853 static bool derive_keys(private_main_mode_t
*this, chunk_t nonce_i
,
856 ike_sa_id_t
*id
= this->ike_sa
->get_id(this->ike_sa
);
857 shared_key_t
*shared_key
= NULL
;
859 switch (this->auth_method
)
862 case AUTH_XAUTH_INIT_PSK
:
863 case AUTH_XAUTH_RESP_PSK
:
864 shared_key
= lookup_shared_key(this);
869 if (!this->keymat
->derive_ike_keys(this->keymat
, this->proposal
, this->dh
,
870 this->dh_value
, nonce_i
, nonce_r
, id
, this->auth_method
, shared_key
))
872 DESTROY_IF(shared_key
);
873 DBG1(DBG_IKE
, "key derivation for %N failed",
874 auth_method_names
, this->auth_method
);
877 DESTROY_IF(shared_key
);
878 charon
->bus
->ike_keys(charon
->bus
, this->ike_sa
, this->dh
, nonce_i
, nonce_r
,
885 * Set IKE_SA to established state
887 static void establish(private_main_mode_t
*this)
889 DBG0(DBG_IKE
, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
890 this->ike_sa
->get_name(this->ike_sa
),
891 this->ike_sa
->get_unique_id(this->ike_sa
),
892 this->ike_sa
->get_my_host(this->ike_sa
),
893 this->ike_sa
->get_my_id(this->ike_sa
),
894 this->ike_sa
->get_other_host(this->ike_sa
),
895 this->ike_sa
->get_other_id(this->ike_sa
));
897 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
898 charon
->bus
->ike_updown(charon
->bus
, this->ike_sa
, TRUE
);
901 METHOD(task_t
, build_r
, status_t
,
902 private_main_mode_t
*this, message_t
*message
)
908 sa_payload_t
*sa_payload
;
910 sa_payload
= sa_payload_create_from_proposal_v1(this->proposal
,
911 this->lifetime
, 0, this->auth_method
, MODE_NONE
, FALSE
);
912 message
->add_payload(message
, &sa_payload
->payload_interface
);
918 if (!add_nonce_ke(this, &this->nonce_r
, message
))
920 return send_notify(this, INVALID_KEY_INFORMATION
);
922 if (!derive_keys(this, this->nonce_i
, this->nonce_r
))
924 return send_notify(this, INVALID_KEY_INFORMATION
);
930 authenticator_t
*authenticator
;
931 id_payload_t
*id_payload
;
932 identification_t
*id
;
934 id
= this->my_auth
->get(this->my_auth
, AUTH_RULE_IDENTITY
);
937 DBG1(DBG_CFG
, "own identity not known");
938 return send_notify(this, INVALID_ID_INFORMATION
);
940 this->ike_sa
->set_my_id(this->ike_sa
, id
->clone(id
));
942 id_payload
= id_payload_create_from_identification(ID_V1
, id
);
943 message
->add_payload(message
, &id_payload
->payload_interface
);
945 authenticator
= create_authenticator(this, id_payload
);
946 if (!authenticator
|| authenticator
->build(authenticator
,
949 DESTROY_IF(authenticator
);
950 return send_notify(this, AUTHENTICATION_FAILED
);
952 authenticator
->destroy(authenticator
);
953 save_auth_cfg(this, TRUE
);
955 switch (this->auth_method
)
957 case AUTH_XAUTH_INIT_PSK
:
958 case AUTH_XAUTH_INIT_RSA
:
959 case AUTH_HYBRID_INIT_RSA
:
960 this->ike_sa
->queue_task(this->ike_sa
,
961 (task_t
*)xauth_create(this->ike_sa
, TRUE
));
963 case AUTH_XAUTH_RESP_PSK
:
964 case AUTH_XAUTH_RESP_RSA
:
965 case AUTH_HYBRID_RESP_RSA
:
966 /* TODO-IKEv1: not yet supported */
970 lib
->processor
->queue_job(lib
->processor
, (job_t
*)
971 adopt_children_job_create(
972 this->ike_sa
->get_id(this->ike_sa
)));
981 METHOD(task_t
, process_i
, status_t
,
982 private_main_mode_t
*this, message_t
*message
)
989 sa_payload_t
*sa_payload
;
990 auth_method_t auth_method
;
993 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
994 SECURITY_ASSOCIATION_V1
);
997 DBG1(DBG_IKE
, "SA payload missing");
998 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1000 list
= sa_payload
->get_proposals(sa_payload
);
1001 this->proposal
= this->ike_cfg
->select_proposal(this->ike_cfg
,
1003 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1004 if (!this->proposal
)
1006 DBG1(DBG_IKE
, "no proposal found");
1007 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1010 lifetime
= sa_payload
->get_lifetime(sa_payload
);
1011 if (lifetime
!= this->lifetime
)
1013 DBG1(DBG_IKE
, "received lifetime %us does not match configured "
1014 "lifetime %us", lifetime
, this->lifetime
);
1016 this->lifetime
= lifetime
;
1017 auth_method
= sa_payload
->get_auth_method(sa_payload
);
1018 if (auth_method
!= this->auth_method
)
1020 DBG1(DBG_IKE
, "received %N authentication, but configured %N, "
1021 "continue with configured", auth_method_names
, auth_method
,
1022 auth_method_names
, this->auth_method
);
1028 if (!get_nonce_ke(this, &this->nonce_r
, message
))
1030 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1032 if (!derive_keys(this, this->nonce_i
, this->nonce_r
))
1034 return send_notify(this, INVALID_KEY_INFORMATION
);
1040 authenticator_t
*authenticator
;
1041 id_payload_t
*id_payload
;
1042 identification_t
*id
;
1044 id_payload
= (id_payload_t
*)message
->get_payload(message
, ID_V1
);
1047 DBG1(DBG_IKE
, "IDir payload missing");
1048 return send_delete(this);
1050 id
= id_payload
->get_identification(id_payload
);
1051 if (!id
->matches(id
, this->other_auth
->get(this->other_auth
,
1052 AUTH_RULE_IDENTITY
)))
1054 DBG1(DBG_IKE
, "IDir does not match");
1056 return send_delete(this);
1058 this->ike_sa
->set_other_id(this->ike_sa
, id
);
1060 authenticator
= create_authenticator(this, id_payload
);
1061 if (!authenticator
|| authenticator
->process(authenticator
,
1062 message
) != SUCCESS
)
1064 DESTROY_IF(authenticator
);
1065 return send_delete(this);
1067 authenticator
->destroy(authenticator
);
1068 if (!check_constraints(this))
1070 return send_delete(this);
1072 save_auth_cfg(this, FALSE
);
1074 if (this->peer_cfg
->get_virtual_ip(this->peer_cfg
))
1076 this->ike_sa
->queue_task(this->ike_sa
,
1077 (task_t
*)mode_config_create(this->ike_sa
, TRUE
));
1080 switch (this->auth_method
)
1082 case AUTH_XAUTH_INIT_PSK
:
1083 case AUTH_XAUTH_INIT_RSA
:
1084 case AUTH_HYBRID_INIT_RSA
:
1085 /* wait for XAUTH request */
1087 case AUTH_XAUTH_RESP_PSK
:
1088 case AUTH_XAUTH_RESP_RSA
:
1089 case AUTH_HYBRID_RESP_RSA
:
1090 /* TODO-IKEv1: not yet */
1102 METHOD(task_t
, get_type
, task_type_t
,
1103 private_main_mode_t
*this)
1105 return TASK_MAIN_MODE
;
1108 METHOD(task_t
, migrate
, void,
1109 private_main_mode_t
*this, ike_sa_t
*ike_sa
)
1111 DESTROY_IF(this->peer_cfg
);
1112 DESTROY_IF(this->proposal
);
1113 DESTROY_IF(this->dh
);
1114 chunk_free(&this->dh_value
);
1115 chunk_free(&this->nonce_i
);
1116 chunk_free(&this->nonce_r
);
1117 chunk_free(&this->sa_payload
);
1119 this->ike_sa
= ike_sa
;
1120 this->keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
);
1121 this->state
= MM_INIT
;
1122 this->peer_cfg
= NULL
;
1123 this->proposal
= NULL
;
1127 METHOD(task_t
, destroy
, void,
1128 private_main_mode_t
*this)
1130 DESTROY_IF(this->peer_cfg
);
1131 DESTROY_IF(this->proposal
);
1132 DESTROY_IF(this->dh
);
1133 free(this->dh_value
.ptr
);
1134 free(this->nonce_i
.ptr
);
1135 free(this->nonce_r
.ptr
);
1136 free(this->sa_payload
.ptr
);
1141 * Described in header.
1143 main_mode_t
*main_mode_create(ike_sa_t
*ike_sa
, bool initiator
)
1145 private_main_mode_t
*this;
1150 .get_type
= _get_type
,
1151 .migrate
= _migrate
,
1152 .destroy
= _destroy
,
1156 .keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
),
1157 .initiator
= initiator
,
1163 this->public.task
.build
= _build_i
;
1164 this->public.task
.process
= _process_i
;
1168 this->public.task
.build
= _build_r
;
1169 this->public.task
.process
= _process_r
;
1172 return &this->public;