2 * Copyright (C) 2005-2007 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 #include <crypto/diffie_hellman.h>
25 #include <encoding/payloads/id_payload.h>
26 #include <encoding/payloads/auth_payload.h>
27 #include <encoding/payloads/eap_payload.h>
28 #include <encoding/payloads/nonce_payload.h>
29 #include <sa/authenticators/eap_authenticator.h>
32 typedef struct private_ike_auth_t private_ike_auth_t
;
35 * Private members of a ike_auth_t task.
37 struct private_ike_auth_t
{
40 * Public methods and task_t interface.
50 * Are we the initiator?
55 * Nonce chosen by us in ike_init
60 * Nonce chosen by peer in ike_init
65 * IKE_SA_INIT message sent by us
70 * IKE_SA_INIT message sent by peer
72 packet_t
*other_packet
;
75 * EAP authenticator when using EAP
77 eap_authenticator_t
*eap_auth
;
80 * EAP payload received and ready to process
82 eap_payload_t
*eap_payload
;
85 * has the peer been authenticated successfully?
87 bool peer_authenticated
;
91 * check uniqueness and delete duplicates
93 static bool check_uniqueness(private_ike_auth_t
*this)
96 unique_policy_t policy
;
97 status_t status
= SUCCESS
;
101 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
102 policy
= peer_cfg
->get_unique_policy(peer_cfg
);
103 if (policy
== UNIQUE_NO
)
107 duplicate
= charon
->ike_sa_manager
->checkout_duplicate(
108 charon
->ike_sa_manager
, this->ike_sa
);
111 peer_cfg
= duplicate
->get_peer_cfg(duplicate
);
113 peer_cfg
->equals(peer_cfg
, this->ike_sa
->get_peer_cfg(this->ike_sa
)))
115 switch (duplicate
->get_state(duplicate
))
117 case IKE_ESTABLISHED
:
122 DBG1(DBG_IKE
, "deleting duplicate IKE_SA due "
123 "uniqueness policy");
124 status
= duplicate
->delete(duplicate
);
127 DBG1(DBG_IKE
, "cancelling IKE_SA setup due "
128 "uniqueness policy");
139 if (status
== DESTROY_ME
)
141 charon
->ike_sa_manager
->checkin_and_destroy(charon
->ike_sa_manager
,
146 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, duplicate
);
153 * build the AUTH payload
155 static status_t
build_auth(private_ike_auth_t
*this, message_t
*message
)
157 authenticator_t
*auth
;
158 auth_payload_t
*auth_payload
;
160 config_auth_method_t method
;
163 /* create own authenticator and add auth payload */
164 config
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
167 SIG_IKE(UP_FAILED
, "unable to authenticate, no peer config found");
170 method
= config
->get_auth_method(config
);
172 auth
= authenticator_create(this->ike_sa
, method
);
175 SIG_IKE(UP_FAILED
, "configured authentication method %N not supported",
176 config_auth_method_names
, method
);
180 status
= auth
->build(auth
, this->my_packet
->get_data(this->my_packet
),
181 this->other_nonce
, &auth_payload
);
183 if (status
!= SUCCESS
)
185 SIG_IKE(UP_FAILED
, "generating authentication data failed");
188 message
->add_payload(message
, (payload_t
*)auth_payload
);
193 * build ID payload(s)
195 static status_t
build_id(private_ike_auth_t
*this, message_t
*message
)
197 identification_t
*me
, *other
;
201 me
= this->ike_sa
->get_my_id(this->ike_sa
);
202 other
= this->ike_sa
->get_other_id(this->ike_sa
);
203 config
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
205 if (me
->contains_wildcards(me
))
207 me
= config
->get_my_id(config
);
208 if (me
->contains_wildcards(me
))
210 SIG_IKE(UP_FAILED
, "negotiation of own ID failed");
213 this->ike_sa
->set_my_id(this->ike_sa
, me
->clone(me
));
216 id
= id_payload_create_from_identification(this->initiator ? ID_INITIATOR
: ID_RESPONDER
, me
);
217 message
->add_payload(message
, (payload_t
*)id
);
219 /* as initiator, include other ID if it does not contain wildcards */
220 if (this->initiator
&& !other
->contains_wildcards(other
))
222 id
= id_payload_create_from_identification(ID_RESPONDER
, other
);
223 message
->add_payload(message
, (payload_t
*)id
);
229 * process AUTH payload
231 static status_t
process_auth(private_ike_auth_t
*this, message_t
*message
)
233 auth_payload_t
*auth_payload
;
234 authenticator_t
*auth
;
235 auth_method_t auth_method
;
238 auth_payload
= (auth_payload_t
*)message
->get_payload(message
, AUTHENTICATION
);
240 if (auth_payload
== NULL
)
242 /* AUTH payload is missing, client wants to use EAP authentication */
246 auth_method
= auth_payload
->get_auth_method(auth_payload
);
247 auth
= authenticator_create_from_auth_payload(this->ike_sa
, auth_payload
);
251 SIG_IKE(UP_FAILED
, "authentication method %N used by '%D' not "
252 "supported", auth_method_names
, auth_method
,
253 this->ike_sa
->get_other_id(this->ike_sa
));
254 return NOT_SUPPORTED
;
256 status
= auth
->verify(auth
, this->other_packet
->get_data(this->other_packet
),
257 this->my_nonce
, auth_payload
);
259 if (status
!= SUCCESS
)
261 SIG_IKE(UP_FAILED
, "authentication of '%D' with %N failed",
262 this->ike_sa
->get_other_id(this->ike_sa
),
263 auth_method_names
, auth_method
);
270 * process ID payload(s)
272 static status_t
process_id(private_ike_auth_t
*this, message_t
*message
)
274 identification_t
*id
, *req
;
275 id_payload_t
*idr
, *idi
;
277 idi
= (id_payload_t
*)message
->get_payload(message
, ID_INITIATOR
);
278 idr
= (id_payload_t
*)message
->get_payload(message
, ID_RESPONDER
);
280 if ((this->initiator
&& idr
== NULL
) || (!this->initiator
&& idi
== NULL
))
282 SIG_IKE(UP_FAILED
, "ID payload missing in message");
288 id
= idr
->get_identification(idr
);
289 req
= this->ike_sa
->get_other_id(this->ike_sa
);
290 if (!id
->matches(id
, req
))
292 SIG_IKE(UP_FAILED
, "peer ID '%D' unacceptable, '%D' required", id
, req
);
296 this->ike_sa
->set_other_id(this->ike_sa
, id
);
300 id
= idi
->get_identification(idi
);
301 this->ike_sa
->set_other_id(this->ike_sa
, id
);
304 id
= idr
->get_identification(idr
);
305 this->ike_sa
->set_my_id(this->ike_sa
, id
);
312 * collect the needed information in the IKE_SA_INIT exchange from our message
314 static status_t
collect_my_init_data(private_ike_auth_t
*this, message_t
*message
)
316 nonce_payload_t
*nonce
;
318 /* get the nonce that was generated in ike_init */
319 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
324 this->my_nonce
= nonce
->get_nonce(nonce
);
326 /* pre-generate the message, so we can store it for us */
327 if (this->ike_sa
->generate_message(this->ike_sa
, message
,
328 &this->my_packet
) != SUCCESS
)
336 * collect the needed information in the IKE_SA_INIT exchange from others message
338 static status_t
collect_other_init_data(private_ike_auth_t
*this, message_t
*message
)
340 /* we collect the needed information in the IKE_SA_INIT exchange */
341 nonce_payload_t
*nonce
;
343 /* get the nonce that was generated in ike_init */
344 nonce
= (nonce_payload_t
*)message
->get_payload(message
, NONCE
);
349 this->other_nonce
= nonce
->get_nonce(nonce
);
351 /* pre-generate the message, so we can store it for us */
352 this->other_packet
= message
->get_packet(message
);
358 * Implementation of task_t.build to create AUTH payload from EAP data
360 static status_t
build_auth_eap(private_ike_auth_t
*this, message_t
*message
)
362 authenticator_t
*auth
;
363 auth_payload_t
*auth_payload
;
365 auth
= (authenticator_t
*)this->eap_auth
;
366 if (auth
->build(auth
, this->my_packet
->get_data(this->my_packet
),
367 this->other_nonce
, &auth_payload
) != SUCCESS
)
369 SIG_IKE(UP_FAILED
, "generating authentication data failed");
370 if (!this->initiator
)
372 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
376 message
->add_payload(message
, (payload_t
*)auth_payload
);
377 if (!this->initiator
)
379 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
380 SIG_IKE(UP_SUCCESS
, "IKE_SA '%s[%d]' established between %H[%D]...%H[%D]",
381 this->ike_sa
->get_name(this->ike_sa
),
382 this->ike_sa
->get_unique_id(this->ike_sa
),
383 this->ike_sa
->get_my_host(this->ike_sa
),
384 this->ike_sa
->get_my_id(this->ike_sa
),
385 this->ike_sa
->get_other_host(this->ike_sa
),
386 this->ike_sa
->get_other_id(this->ike_sa
));
393 * Implementation of task_t.process to verify AUTH payload after EAP
395 static status_t
process_auth_eap(private_ike_auth_t
*this, message_t
*message
)
397 auth_payload_t
*auth_payload
;
398 authenticator_t
*auth
;
400 auth_payload
= (auth_payload_t
*)message
->get_payload(message
, AUTHENTICATION
);
401 this->peer_authenticated
= FALSE
;
405 auth
= (authenticator_t
*)this->eap_auth
;
406 if (auth
->verify(auth
, this->other_packet
->get_data(this->other_packet
),
407 this->my_nonce
, auth_payload
) == SUCCESS
)
409 this->peer_authenticated
= TRUE
;
413 if (!this->peer_authenticated
)
415 SIG_IKE(UP_FAILED
, "authentication of '%D' with %N failed",
416 this->ike_sa
->get_other_id(this->ike_sa
),
417 auth_method_names
, AUTH_EAP
);
426 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
427 SIG_IKE(UP_SUCCESS
, "IKE_SA '%s[%d]' established between %H[%D]...%H[%D]",
428 this->ike_sa
->get_name(this->ike_sa
),
429 this->ike_sa
->get_unique_id(this->ike_sa
),
430 this->ike_sa
->get_my_host(this->ike_sa
),
431 this->ike_sa
->get_my_id(this->ike_sa
),
432 this->ike_sa
->get_other_host(this->ike_sa
),
433 this->ike_sa
->get_other_id(this->ike_sa
));
440 * Implementation of task_t.process for EAP exchanges
442 static status_t
process_eap_i(private_ike_auth_t
*this, message_t
*message
)
446 eap
= (eap_payload_t
*)message
->get_payload(message
, EXTENSIBLE_AUTHENTICATION
);
449 SIG_IKE(UP_FAILED
, "EAP payload missing");
452 switch (this->eap_auth
->process(this->eap_auth
, eap
, &eap
))
455 this->eap_payload
= eap
;
458 /* EAP exchange completed, now create and process AUTH */
459 this->eap_payload
= NULL
;
460 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_auth_eap
;
461 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_auth_eap
;
464 this->eap_payload
= NULL
;
465 SIG_IKE(UP_FAILED
, "failed to authenticate against '%D' using EAP",
466 this->ike_sa
->get_other_id(this->ike_sa
));
472 * Implementation of task_t.process for EAP exchanges
474 static status_t
process_eap_r(private_ike_auth_t
*this, message_t
*message
)
476 this->eap_payload
= (eap_payload_t
*)message
->get_payload(message
,
477 EXTENSIBLE_AUTHENTICATION
);
482 * Implementation of task_t.build for EAP exchanges
484 static status_t
build_eap_i(private_ike_auth_t
*this, message_t
*message
)
486 message
->add_payload(message
, (payload_t
*)this->eap_payload
);
491 * Implementation of task_t.build for EAP exchanges
493 static status_t
build_eap_r(private_ike_auth_t
*this, message_t
*message
)
495 status_t status
= NEED_MORE
;
498 if (this->eap_payload
== NULL
)
500 SIG_IKE(UP_FAILED
, "EAP payload missing");
504 switch (this->eap_auth
->process(this->eap_auth
, this->eap_payload
, &eap
))
510 /* EAP exchange completed, now create and process AUTH */
511 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_auth_eap
;
512 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_auth_eap
;
515 SIG_IKE(UP_FAILED
, "authentication of '%D' with %N failed",
516 this->ike_sa
->get_other_id(this->ike_sa
),
517 auth_method_names
, AUTH_EAP
);
521 message
->add_payload(message
, (payload_t
*)eap
);
526 * Implementation of task_t.build for initiator
528 static status_t
build_i(private_ike_auth_t
*this, message_t
*message
)
532 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
534 return collect_my_init_data(this, message
);
537 if (build_id(this, message
) != SUCCESS
)
542 config
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
543 if (config
->get_auth_method(config
) == CONF_AUTH_EAP
)
545 this->eap_auth
= eap_authenticator_create(this->ike_sa
);
549 if (build_auth(this, message
) != SUCCESS
)
559 * Implementation of task_t.process for responder
561 static status_t
process_r(private_ike_auth_t
*this, message_t
*message
)
565 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
567 return collect_other_init_data(this, message
);
570 if (process_id(this, message
) != SUCCESS
)
575 switch (process_auth(this, message
))
578 this->peer_authenticated
= TRUE
;
581 /* use EAP if no AUTH payload found */
582 this->ike_sa
->set_condition(this->ike_sa
, COND_EAP_AUTHENTICATED
, TRUE
);
583 this->eap_auth
= eap_authenticator_create(this->ike_sa
);
589 config
= charon
->backends
->get_peer_cfg(charon
->backends
,
590 this->ike_sa
->get_my_host(this->ike_sa
),
591 this->ike_sa
->get_other_host(this->ike_sa
),
592 this->ike_sa
->get_my_id(this->ike_sa
),
593 this->ike_sa
->get_other_id(this->ike_sa
),
594 this->ike_sa
->get_other_auth(this->ike_sa
));
597 this->ike_sa
->set_peer_cfg(this->ike_sa
, config
);
598 config
->destroy(config
);
605 * Implementation of task_t.build for responder
607 static status_t
build_r(private_ike_auth_t
*this, message_t
*message
)
611 u_int32_t eap_vendor
;
612 eap_payload_t
*eap_payload
;
615 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
617 return collect_my_init_data(this, message
);
620 if (!this->peer_authenticated
&& this->eap_auth
== NULL
)
622 /* peer not authenticated, nor does it want to use EAP */
623 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
627 config
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
630 SIG_IKE(UP_FAILED
, "no matching config found for '%D'...'%D'",
631 this->ike_sa
->get_my_id(this->ike_sa
),
632 this->ike_sa
->get_other_id(this->ike_sa
));
633 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
637 if (build_id(this, message
) != SUCCESS
||
638 build_auth(this, message
) != SUCCESS
)
640 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
644 if (check_uniqueness(this))
646 message
->add_notify(message
, TRUE
, AUTHENTICATION_FAILED
, chunk_empty
);
650 /* use "traditional" authentication if we could authenticate peer */
651 if (this->peer_authenticated
)
653 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
654 SIG_IKE(UP_SUCCESS
, "IKE_SA '%s[%d]' established between %H[%D]...%H[%D]",
655 this->ike_sa
->get_name(this->ike_sa
),
656 this->ike_sa
->get_unique_id(this->ike_sa
),
657 this->ike_sa
->get_my_host(this->ike_sa
),
658 this->ike_sa
->get_my_id(this->ike_sa
),
659 this->ike_sa
->get_other_host(this->ike_sa
),
660 this->ike_sa
->get_other_id(this->ike_sa
));
664 /* initiate EAP authenitcation */
665 eap_type
= config
->get_eap_type(config
, &eap_vendor
);
666 status
= this->eap_auth
->initiate(this->eap_auth
, eap_type
,
667 eap_vendor
, &eap_payload
);
668 message
->add_payload(message
, (payload_t
*)eap_payload
);
669 if (status
!= NEED_MORE
)
671 SIG_IKE(UP_FAILED
, "unable to initiate EAP authentication");
675 /* switch to EAP methods */
676 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_eap_r
;
677 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_eap_r
;
682 * Implementation of task_t.process for initiator
684 static status_t
process_i(private_ike_auth_t
*this, message_t
*message
)
686 iterator_t
*iterator
;
691 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
693 return collect_other_init_data(this, message
);
696 iterator
= message
->get_payload_iterator(message
);
697 while (iterator
->iterate(iterator
, (void**)&payload
))
699 if (payload
->get_type(payload
) == NOTIFY
)
701 notify_payload_t
*notify
= (notify_payload_t
*)payload
;
702 notify_type_t type
= notify
->get_notify_type(notify
);
706 case NO_PROPOSAL_CHOSEN
:
707 case SINGLE_PAIR_REQUIRED
:
708 case NO_ADDITIONAL_SAS
:
709 case INTERNAL_ADDRESS_FAILURE
:
710 case FAILED_CP_REQUIRED
:
711 case TS_UNACCEPTABLE
:
712 case INVALID_SELECTORS
:
713 /* these are errors, but are not critical as only the
714 * CHILD_SA won't get build, but IKE_SA establishes anyway */
716 case MOBIKE_SUPPORTED
:
717 case ADDITIONAL_IP4_ADDRESS
:
718 case ADDITIONAL_IP6_ADDRESS
:
719 /* handled in ike_mobike task */
722 /* handled in ike_auth_lifetime task */
725 /* handled in ike_me task */
731 SIG_IKE(UP_FAILED
, "received %N notify error",
732 notify_type_names
, type
);
733 iterator
->destroy(iterator
);
736 DBG2(DBG_IKE
, "received %N notify",
737 notify_type_names
, type
);
743 iterator
->destroy(iterator
);
745 if (process_id(this, message
) != SUCCESS
||
746 process_auth(this, message
) != SUCCESS
)
753 /* switch to EAP authentication methods */
754 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_eap_i
;
755 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_eap_i
;
756 return process_eap_i(this, message
);
759 config
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
760 auth
= this->ike_sa
->get_other_auth(this->ike_sa
);
761 if (!auth
->complies(auth
, config
->get_auth(config
)))
763 SIG_IKE(UP_FAILED
, "authorization of '%D' for config %s failed",
764 this->ike_sa
->get_other_id(this->ike_sa
), config
->get_name(config
));
767 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
768 SIG_IKE(UP_SUCCESS
, "IKE_SA '%s[%d]' established between %H[%D]...%H[%D]",
769 this->ike_sa
->get_name(this->ike_sa
),
770 this->ike_sa
->get_unique_id(this->ike_sa
),
771 this->ike_sa
->get_my_host(this->ike_sa
),
772 this->ike_sa
->get_my_id(this->ike_sa
),
773 this->ike_sa
->get_other_host(this->ike_sa
),
774 this->ike_sa
->get_other_id(this->ike_sa
));
779 * Implementation of task_t.get_type
781 static task_type_t
get_type(private_ike_auth_t
*this)
783 return IKE_AUTHENTICATE
;
787 * Implementation of task_t.migrate
789 static void migrate(private_ike_auth_t
*this, ike_sa_t
*ike_sa
)
791 chunk_free(&this->my_nonce
);
792 chunk_free(&this->other_nonce
);
793 DESTROY_IF(this->my_packet
);
794 DESTROY_IF(this->other_packet
);
797 this->eap_auth
->authenticator_interface
.destroy(
798 &this->eap_auth
->authenticator_interface
);
801 this->my_packet
= NULL
;
802 this->other_packet
= NULL
;
803 this->peer_authenticated
= FALSE
;
804 this->eap_auth
= NULL
;
805 this->eap_payload
= NULL
;
806 this->ike_sa
= ike_sa
;
809 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_i
;
810 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_i
;
814 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_r
;
815 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_r
;
820 * Implementation of task_t.destroy
822 static void destroy(private_ike_auth_t
*this)
824 chunk_free(&this->my_nonce
);
825 chunk_free(&this->other_nonce
);
826 DESTROY_IF(this->my_packet
);
827 DESTROY_IF(this->other_packet
);
830 this->eap_auth
->authenticator_interface
.destroy(
831 &this->eap_auth
->authenticator_interface
);
837 * Described in header.
839 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
, bool initiator
)
841 private_ike_auth_t
*this = malloc_thing(private_ike_auth_t
);
843 this->public.task
.get_type
= (task_type_t(*)(task_t
*))get_type
;
844 this->public.task
.migrate
= (void(*)(task_t
*,ike_sa_t
*))migrate
;
845 this->public.task
.destroy
= (void(*)(task_t
*))destroy
;
849 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_i
;
850 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_i
;
854 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_r
;
855 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_r
;
858 this->ike_sa
= ike_sa
;
859 this->initiator
= initiator
;
860 this->my_nonce
= chunk_empty
;
861 this->other_nonce
= chunk_empty
;
862 this->my_packet
= NULL
;
863 this->other_packet
= NULL
;
864 this->peer_authenticated
= FALSE
;
865 this->eap_auth
= NULL
;
866 this->eap_payload
= NULL
;
868 return &this->public;