67f1e8bccf46c20b5a59d8ce8679e197d24bfff7
[strongswan.git] / src / charon / sa / tasks / ike_auth.c
1 /**
2 * @file ike_auth.c
3 *
4 * @brief Implementation of the ike_auth task.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2007 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include "ike_auth.h"
25
26 #include <string.h>
27
28 #include <daemon.h>
29 #include <crypto/diffie_hellman.h>
30 #include <encoding/payloads/id_payload.h>
31 #include <encoding/payloads/auth_payload.h>
32 #include <encoding/payloads/eap_payload.h>
33 #include <encoding/payloads/nonce_payload.h>
34 #include <sa/authenticators/eap_authenticator.h>
35
36
37
38 typedef struct private_ike_auth_t private_ike_auth_t;
39
40 /**
41 * Private members of a ike_auth_t task.
42 */
43 struct private_ike_auth_t {
44
45 /**
46 * Public methods and task_t interface.
47 */
48 ike_auth_t public;
49
50 /**
51 * Assigned IKE_SA.
52 */
53 ike_sa_t *ike_sa;
54
55 /**
56 * Are we the initiator?
57 */
58 bool initiator;
59
60 /**
61 * Nonce chosen by us in ike_init
62 */
63 chunk_t my_nonce;
64
65 /**
66 * Nonce chosen by peer in ike_init
67 */
68 chunk_t other_nonce;
69
70 /**
71 * IKE_SA_INIT message sent by us
72 */
73 packet_t *my_packet;
74
75 /**
76 * IKE_SA_INIT message sent by peer
77 */
78 packet_t *other_packet;
79
80 /**
81 * EAP authenticator when using EAP
82 */
83 eap_authenticator_t *eap_auth;
84
85 /**
86 * EAP payload received and ready to process
87 */
88 eap_payload_t *eap_payload;
89
90 /**
91 * has the peer been authenticated successfully?
92 */
93 bool peer_authenticated;
94 };
95
96 /**
97 * build the AUTH payload
98 */
99 static status_t build_auth(private_ike_auth_t *this, message_t *message)
100 {
101 authenticator_t *auth;
102 auth_payload_t *auth_payload;
103 peer_cfg_t *config;
104 auth_method_t method;
105 status_t status;
106
107 /* create own authenticator and add auth payload */
108 config = this->ike_sa->get_peer_cfg(this->ike_sa);
109 if (!config)
110 {
111 SIG(IKE_UP_FAILED, "unable to authenticate, no peer config found");
112 return FAILED;
113 }
114 method = config->get_auth_method(config);
115
116 auth = authenticator_create(this->ike_sa, method);
117 if (auth == NULL)
118 {
119 SIG(IKE_UP_FAILED, "configured authentication method %N not supported",
120 auth_method_names, method);
121 return FAILED;
122 }
123
124 status = auth->build(auth, this->my_packet->get_data(this->my_packet),
125 this->other_nonce, &auth_payload);
126 auth->destroy(auth);
127 if (status != SUCCESS)
128 {
129 SIG(IKE_UP_FAILED, "generating authentication data failed");
130 return FAILED;
131 }
132 message->add_payload(message, (payload_t*)auth_payload);
133 return SUCCESS;
134 }
135
136 /**
137 * build ID payload(s)
138 */
139 static status_t build_id(private_ike_auth_t *this, message_t *message)
140 {
141 identification_t *me, *other;
142 id_payload_t *id;
143 peer_cfg_t *config;
144
145 me = this->ike_sa->get_my_id(this->ike_sa);
146 other = this->ike_sa->get_other_id(this->ike_sa);
147 config = this->ike_sa->get_peer_cfg(this->ike_sa);
148
149 if (me->contains_wildcards(me))
150 {
151 me = config->get_my_id(config);
152 if (me->contains_wildcards(me))
153 {
154 SIG(IKE_UP_FAILED, "negotiation of own ID failed");
155 return FAILED;
156 }
157 this->ike_sa->set_my_id(this->ike_sa, me->clone(me));
158 }
159
160 id = id_payload_create_from_identification(this->initiator, me);
161 message->add_payload(message, (payload_t*)id);
162
163 /* as initiator, include other ID if it does not contain wildcards */
164 if (this->initiator && !other->contains_wildcards(other))
165 {
166 id = id_payload_create_from_identification(FALSE, other);
167 message->add_payload(message, (payload_t*)id);
168 }
169 return SUCCESS;
170 }
171
172 /**
173 * process AUTH payload
174 */
175 static status_t process_auth(private_ike_auth_t *this, message_t *message)
176 {
177 auth_payload_t *auth_payload;
178 authenticator_t *auth;
179 auth_method_t auth_method;
180 status_t status;
181
182 auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
183
184 if (auth_payload == NULL)
185 {
186 /* AUTH payload is missing, client wants to use EAP authentication */
187 return NOT_FOUND;
188 }
189
190 auth_method = auth_payload->get_auth_method(auth_payload);
191 auth = authenticator_create(this->ike_sa, auth_method);
192
193 if (auth == NULL)
194 {
195 SIG(IKE_UP_FAILED, "authentication method %N used by %D not "
196 "supported", auth_method_names, auth_method,
197 this->ike_sa->get_other_id(this->ike_sa));
198 return NOT_SUPPORTED;
199 }
200 status = auth->verify(auth, this->other_packet->get_data(this->other_packet),
201 this->my_nonce, auth_payload);
202 auth->destroy(auth);
203 if (status != SUCCESS)
204 {
205 SIG(IKE_UP_FAILED, "authentication of %D using %N failed",
206 this->ike_sa->get_other_id(this->ike_sa),
207 auth_method_names, auth_method);
208 return FAILED;
209 }
210 return SUCCESS;
211 }
212
213 /**
214 * process ID payload(s)
215 */
216 static status_t process_id(private_ike_auth_t *this, message_t *message)
217 {
218 identification_t *id;
219 id_payload_t *idr, *idi;
220
221 idi = (id_payload_t*)message->get_payload(message, ID_INITIATOR);
222 idr = (id_payload_t*)message->get_payload(message, ID_RESPONDER);
223
224 if ((this->initiator && idr == NULL) || (!this->initiator && idi == NULL))
225 {
226 SIG(IKE_UP_FAILED, "ID payload missing in message");
227 return FAILED;
228 }
229
230 if (this->initiator)
231 {
232 id = idr->get_identification(idr);
233 this->ike_sa->set_other_id(this->ike_sa, id);
234 }
235 else
236 {
237 id = idi->get_identification(idi);
238 this->ike_sa->set_other_id(this->ike_sa, id);
239 if (idr)
240 {
241 id = idr->get_identification(idr);
242 this->ike_sa->set_my_id(this->ike_sa, id);
243 }
244 }
245 return SUCCESS;
246 }
247
248 /**
249 * collect the needed information in the IKE_SA_INIT exchange from our message
250 */
251 static status_t collect_my_init_data(private_ike_auth_t *this, message_t *message)
252 {
253 nonce_payload_t *nonce;
254
255 /* get the nonce that was generated in ike_init */
256 nonce = (nonce_payload_t*)message->get_payload(message, NONCE);
257 if (nonce == NULL)
258 {
259 return FAILED;
260 }
261 this->my_nonce = nonce->get_nonce(nonce);
262
263 /* pre-generate the message, so we can store it for us */
264 if (this->ike_sa->generate_message(this->ike_sa, message,
265 &this->my_packet) != SUCCESS)
266 {
267 return FAILED;
268 }
269 return NEED_MORE;
270 }
271
272 /**
273 * collect the needed information in the IKE_SA_INIT exchange from others message
274 */
275 static status_t collect_other_init_data(private_ike_auth_t *this, message_t *message)
276 {
277 /* we collect the needed information in the IKE_SA_INIT exchange */
278 nonce_payload_t *nonce;
279
280 /* get the nonce that was generated in ike_init */
281 nonce = (nonce_payload_t*)message->get_payload(message, NONCE);
282 if (nonce == NULL)
283 {
284 return FAILED;
285 }
286 this->other_nonce = nonce->get_nonce(nonce);
287
288 /* pre-generate the message, so we can store it for us */
289 this->other_packet = message->get_packet(message);
290 return NEED_MORE;
291 }
292
293 /**
294 * Implementation of task_t.build to create AUTH payload from EAP data
295 */
296 static status_t build_auth_eap(private_ike_auth_t *this, message_t *message)
297 {
298 authenticator_t *auth;
299 auth_payload_t *auth_payload;
300
301 auth = (authenticator_t*)this->eap_auth;
302 if (auth->build(auth, this->my_packet->get_data(this->my_packet),
303 this->other_nonce, &auth_payload) != SUCCESS)
304 {
305 SIG(IKE_UP_FAILED, "generating authentication data failed");
306 if (!this->initiator)
307 {
308 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
309 }
310 return FAILED;
311 }
312 message->add_payload(message, (payload_t*)auth_payload);
313 if (!this->initiator)
314 {
315 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
316 SIG(IKE_UP_SUCCESS, "IKE_SA established between %D[%H]...[%H]%D",
317 this->ike_sa->get_my_id(this->ike_sa),
318 this->ike_sa->get_my_host(this->ike_sa),
319 this->ike_sa->get_other_host(this->ike_sa),
320 this->ike_sa->get_other_id(this->ike_sa));
321 return SUCCESS;
322 }
323 return NEED_MORE;
324 }
325
326 /**
327 * Implementation of task_t.process to verify AUTH payload after EAP
328 */
329 static status_t process_auth_eap(private_ike_auth_t *this, message_t *message)
330 {
331 auth_payload_t *auth_payload;
332 authenticator_t *auth;
333
334 auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
335 this->peer_authenticated = FALSE;
336
337 if (auth_payload)
338 {
339 auth = (authenticator_t*)this->eap_auth;
340 if (auth->verify(auth, this->other_packet->get_data(this->other_packet),
341 this->my_nonce, auth_payload) == SUCCESS)
342 {
343 this->peer_authenticated = TRUE;
344 }
345 }
346
347 if (!this->peer_authenticated)
348 {
349 SIG(IKE_UP_FAILED, "authentication of %D using %N failed",
350 this->ike_sa->get_other_id(this->ike_sa),
351 auth_method_names, AUTH_EAP);
352 if (this->initiator)
353 {
354 return FAILED;
355 }
356 return NEED_MORE;
357 }
358 if (this->initiator)
359 {
360 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
361 SIG(IKE_UP_SUCCESS, "IKE_SA established between %D[%H]...[%H]%D",
362 this->ike_sa->get_my_id(this->ike_sa),
363 this->ike_sa->get_my_host(this->ike_sa),
364 this->ike_sa->get_other_host(this->ike_sa),
365 this->ike_sa->get_other_id(this->ike_sa));
366 return SUCCESS;
367 }
368 return NEED_MORE;
369 }
370
371 /**
372 * Implementation of task_t.process for EAP exchanges
373 */
374 static status_t process_eap_i(private_ike_auth_t *this, message_t *message)
375 {
376 eap_payload_t *eap;
377
378 eap = (eap_payload_t*)message->get_payload(message, EXTENSIBLE_AUTHENTICATION);
379 if (eap == NULL)
380 {
381 SIG(IKE_UP_FAILED, "EAP payload missing");
382 return FAILED;
383 }
384 switch (this->eap_auth->process(this->eap_auth, eap, &eap))
385 {
386 case NEED_MORE:
387 this->eap_payload = eap;
388 return NEED_MORE;
389 case SUCCESS:
390 /* EAP exchange completed, now create and process AUTH */
391 this->eap_payload = NULL;
392 this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
393 this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
394 return NEED_MORE;
395 default:
396 this->eap_payload = NULL;
397 SIG(IKE_UP_FAILED, "failed to authenticate against %D using EAP",
398 this->ike_sa->get_other_id(this->ike_sa));
399 return FAILED;
400 }
401 }
402
403 /**
404 * Implementation of task_t.process for EAP exchanges
405 */
406 static status_t process_eap_r(private_ike_auth_t *this, message_t *message)
407 {
408 this->eap_payload = (eap_payload_t*)message->get_payload(message,
409 EXTENSIBLE_AUTHENTICATION);
410 return NEED_MORE;
411 }
412
413 /**
414 * Implementation of task_t.build for EAP exchanges
415 */
416 static status_t build_eap_i(private_ike_auth_t *this, message_t *message)
417 {
418 message->add_payload(message, (payload_t*)this->eap_payload);
419 return NEED_MORE;
420 }
421
422 /**
423 * Implementation of task_t.build for EAP exchanges
424 */
425 static status_t build_eap_r(private_ike_auth_t *this, message_t *message)
426 {
427 status_t status = NEED_MORE;
428 eap_payload_t *eap;
429
430 if (this->eap_payload == NULL)
431 {
432 SIG(IKE_UP_FAILED, "EAP payload missing");
433 return FAILED;
434 }
435
436 switch (this->eap_auth->process(this->eap_auth, this->eap_payload, &eap))
437 {
438 case NEED_MORE:
439
440 break;
441 case SUCCESS:
442 /* EAP exchange completed, now create and process AUTH */
443 this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
444 this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
445 break;
446 default:
447 SIG(IKE_UP_FAILED, "authentication of %D using %N failed",
448 this->ike_sa->get_other_id(this->ike_sa),
449 auth_method_names, AUTH_EAP);
450 status = FAILED;
451 break;
452 }
453 message->add_payload(message, (payload_t*)eap);
454 return status;
455 }
456
457 /**
458 * Implementation of task_t.build for initiator
459 */
460 static status_t build_i(private_ike_auth_t *this, message_t *message)
461 {
462 peer_cfg_t *config;
463
464 if (message->get_exchange_type(message) == IKE_SA_INIT)
465 {
466 return collect_my_init_data(this, message);
467 }
468
469 if (build_id(this, message) != SUCCESS)
470 {
471 return FAILED;
472 }
473
474 config = this->ike_sa->get_peer_cfg(this->ike_sa);
475 if (config->get_auth_method(config) == AUTH_EAP)
476 {
477 this->eap_auth = eap_authenticator_create(this->ike_sa);
478 }
479 else
480 {
481 if (build_auth(this, message) != SUCCESS)
482 {
483 return FAILED;
484 }
485 }
486
487 return NEED_MORE;
488 }
489
490 /**
491 * Implementation of task_t.process for responder
492 */
493 static status_t process_r(private_ike_auth_t *this, message_t *message)
494 {
495 peer_cfg_t *config;
496
497 if (message->get_exchange_type(message) == IKE_SA_INIT)
498 {
499 return collect_other_init_data(this, message);
500 }
501
502 if (process_id(this, message) != SUCCESS)
503 {
504 return NEED_MORE;
505 }
506
507 config = charon->cfg_store->get_peer_cfg(charon->cfg_store,
508 this->ike_sa->get_my_id(this->ike_sa),
509 this->ike_sa->get_other_id(this->ike_sa));
510 if (config)
511 {
512 this->ike_sa->set_peer_cfg(this->ike_sa, config);
513 config->destroy(config);
514 }
515
516 switch (process_auth(this, message))
517 {
518 case SUCCESS:
519 this->peer_authenticated = TRUE;
520 break;
521 case NOT_FOUND:
522 /* use EAP if no AUTH payload found */
523 this->eap_auth = eap_authenticator_create(this->ike_sa);
524 break;
525 default:
526 break;
527 }
528 return NEED_MORE;
529 }
530
531 /**
532 * Implementation of task_t.build for responder
533 */
534 static status_t build_r(private_ike_auth_t *this, message_t *message)
535 {
536 peer_cfg_t *config;
537 eap_type_t eap_type;
538 eap_payload_t *eap_payload;
539 status_t status;
540
541 if (message->get_exchange_type(message) == IKE_SA_INIT)
542 {
543 return collect_my_init_data(this, message);
544 }
545
546 config = this->ike_sa->get_peer_cfg(this->ike_sa);
547 if (config == NULL)
548 {
549 SIG(IKE_UP_FAILED, "no matching config found for %D...%D",
550 this->ike_sa->get_my_id(this->ike_sa),
551 this->ike_sa->get_other_id(this->ike_sa));
552 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
553 return FAILED;
554 }
555
556 if (build_id(this, message) != SUCCESS ||
557 build_auth(this, message) != SUCCESS)
558 {
559 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
560 return FAILED;
561 }
562
563 /* use "traditional" authentication if we could authenticate peer */
564 if (this->peer_authenticated)
565 {
566 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
567 SIG(IKE_UP_SUCCESS, "IKE_SA established between %D[%H]...[%H]%D",
568 this->ike_sa->get_my_id(this->ike_sa),
569 this->ike_sa->get_my_host(this->ike_sa),
570 this->ike_sa->get_other_host(this->ike_sa),
571 this->ike_sa->get_other_id(this->ike_sa));
572 return SUCCESS;
573 }
574
575 if (this->eap_auth == NULL)
576 {
577 /* peer not authenticated, nor does it want to use EAP */
578 message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
579 return FAILED;
580 }
581
582 /* initiate EAP authenitcation */
583 eap_type = config->get_eap_type(config);
584 status = this->eap_auth->initiate(this->eap_auth, eap_type, &eap_payload);
585 message->add_payload(message, (payload_t*)eap_payload);
586 if (status != NEED_MORE)
587 {
588 SIG(IKE_UP_FAILED, "unable to initiate EAP authentication");
589 return FAILED;
590 }
591
592 /* switch to EAP methods */
593 this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_r;
594 this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_r;
595 return NEED_MORE;
596 }
597
598 /**
599 * Implementation of task_t.process for initiator
600 */
601 static status_t process_i(private_ike_auth_t *this, message_t *message)
602 {
603 iterator_t *iterator;
604 payload_t *payload;
605
606 if (message->get_exchange_type(message) == IKE_SA_INIT)
607 {
608 return collect_other_init_data(this, message);
609 }
610
611 iterator = message->get_payload_iterator(message);
612 while (iterator->iterate(iterator, (void**)&payload))
613 {
614 if (payload->get_type(payload) == NOTIFY)
615 {
616 notify_payload_t *notify = (notify_payload_t*)payload;
617 notify_type_t type = notify->get_notify_type(notify);
618
619 switch (type)
620 {
621 case NO_PROPOSAL_CHOSEN:
622 case SINGLE_PAIR_REQUIRED:
623 case NO_ADDITIONAL_SAS:
624 case INTERNAL_ADDRESS_FAILURE:
625 case FAILED_CP_REQUIRED:
626 case TS_UNACCEPTABLE:
627 case INVALID_SELECTORS:
628 /* these are errors, but are not critical as only the
629 * CHILD_SA won't get build, but IKE_SA establishes anyway */
630 break;
631 default:
632 {
633 if (type < 16383)
634 {
635 SIG(IKE_UP_FAILED, "received %N notify error",
636 notify_type_names, type);
637 iterator->destroy(iterator);
638 return FAILED;
639 }
640 DBG1(DBG_IKE, "received %N notify",
641 notify_type_names, type);
642 break;
643 }
644 }
645 }
646 }
647 iterator->destroy(iterator);
648
649 if (process_id(this, message) != SUCCESS ||
650 process_auth(this, message) != SUCCESS)
651 {
652 return FAILED;
653 }
654
655 if (this->eap_auth)
656 {
657 /* switch to EAP authentication methods */
658 this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_i;
659 this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_i;
660 return process_eap_i(this, message);
661 }
662
663 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
664 SIG(IKE_UP_SUCCESS, "IKE_SA established between %D[%H]...[%H]%D",
665 this->ike_sa->get_my_id(this->ike_sa),
666 this->ike_sa->get_my_host(this->ike_sa),
667 this->ike_sa->get_other_host(this->ike_sa),
668 this->ike_sa->get_other_id(this->ike_sa));
669 return SUCCESS;
670 }
671
672 /**
673 * Implementation of task_t.get_type
674 */
675 static task_type_t get_type(private_ike_auth_t *this)
676 {
677 return IKE_AUTHENTICATE;
678 }
679
680 /**
681 * Implementation of task_t.migrate
682 */
683 static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa)
684 {
685 chunk_free(&this->my_nonce);
686 chunk_free(&this->other_nonce);
687 DESTROY_IF(this->my_packet);
688 DESTROY_IF(this->other_packet);
689 if (this->eap_auth)
690 {
691 this->eap_auth->authenticator_interface.destroy(
692 &this->eap_auth->authenticator_interface);
693 }
694
695 this->my_packet = NULL;
696 this->other_packet = NULL;
697 this->peer_authenticated = FALSE;
698 this->eap_auth = NULL;
699 this->eap_payload = NULL;
700 this->ike_sa = ike_sa;
701 if (this->initiator)
702 {
703 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
704 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
705 }
706 else
707 {
708 this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
709 this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
710 }
711 }
712
713 /**
714 * Implementation of task_t.destroy
715 */
716 static void destroy(private_ike_auth_t *this)
717 {
718 chunk_free(&this->my_nonce);
719 chunk_free(&this->other_nonce);
720 DESTROY_IF(this->my_packet);
721 DESTROY_IF(this->other_packet);
722 if (this->eap_auth)
723 {
724 this->eap_auth->authenticator_interface.destroy(
725 &this->eap_auth->authenticator_interface);
726 }
727 free(this);
728 }
729
730 /*
731 * Described in header.
732 */
733 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
734 {
735 private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
736
737 this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
738 this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
739 this->public.task.destroy = (void(*)(task_t*))destroy;
740
741 if (initiator)
742 {
743 this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
744 this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
745 }
746 else
747 {
748 this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
749 this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
750 }
751
752 this->ike_sa = ike_sa;
753 this->initiator = initiator;
754 this->my_nonce = chunk_empty;
755 this->other_nonce = chunk_empty;
756 this->my_packet = NULL;
757 this->other_packet = NULL;
758 this->peer_authenticated = FALSE;
759 this->eap_auth = NULL;
760 this->eap_payload = NULL;
761
762 return &this->public;
763 }