Send delete if Main Mode authentication fails as initiator
[strongswan.git] / src / libcharon / sa / tasks / main_mode.c
1 /*
2 * Copyright (C) 2011 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * Copyright (C) 2011 Martin Willi
6 * Copyright (C) 2011 revosec AG
7 *
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>.
12 *
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
16 * for more details.
17 */
18
19 #include "main_mode.h"
20
21 #include <string.h>
22
23 #include <daemon.h>
24 #include <sa/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/tasks/xauth.h>
32 #include <sa/tasks/mode_config.h>
33 #include <sa/tasks/informational.h>
34 #include <sa/tasks/isakmp_delete.h>
35
36 typedef struct private_main_mode_t private_main_mode_t;
37
38 /**
39 * Private members of a main_mode_t task.
40 */
41 struct private_main_mode_t {
42
43 /**
44 * Public methods and task_t interface.
45 */
46 main_mode_t public;
47
48 /**
49 * Assigned IKE_SA.
50 */
51 ike_sa_t *ike_sa;
52
53 /**
54 * Are we the initiator?
55 */
56 bool initiator;
57
58 /**
59 * IKE config to establish
60 */
61 ike_cfg_t *ike_cfg;
62
63 /**
64 * Peer config to use
65 */
66 peer_cfg_t *peer_cfg;
67
68 /**
69 * Local authentication configuration
70 */
71 auth_cfg_t *my_auth;
72
73 /**
74 * Remote authentication configuration
75 */
76 auth_cfg_t *other_auth;
77
78 /**
79 * selected IKE proposal
80 */
81 proposal_t *proposal;
82
83 /**
84 * DH exchange
85 */
86 diffie_hellman_t *dh;
87
88 /**
89 * Keymat derivation (from SA)
90 */
91 keymat_v1_t *keymat;
92
93 /**
94 * Received public DH value from peer
95 */
96 chunk_t dh_value;
97
98 /**
99 * Initiators nonce
100 */
101 chunk_t nonce_i;
102
103 /**
104 * Responder nonce
105 */
106 chunk_t nonce_r;
107
108 /**
109 * Encoded SA initiator payload used for authentication
110 */
111 chunk_t sa_payload;
112
113 /**
114 * Negotiated SA lifetime
115 */
116 u_int32_t lifetime;
117
118 /**
119 * Negotiated authentication method
120 */
121 auth_method_t auth_method;
122
123 /** states of main mode */
124 enum {
125 MM_INIT,
126 MM_SA,
127 MM_KE,
128 MM_AUTH,
129 } state;
130 };
131
132 /**
133 * Get the first authentcation config from peer config
134 */
135 static auth_cfg_t *get_auth_cfg(peer_cfg_t *peer_cfg, bool local)
136 {
137 enumerator_t *enumerator;
138 auth_cfg_t *cfg = NULL;
139
140 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
141 enumerator->enumerate(enumerator, &cfg);
142 enumerator->destroy(enumerator);
143 return cfg;
144 }
145
146 /**
147 * Create an authenticator, if supported
148 */
149 static authenticator_t *create_authenticator(private_main_mode_t *this,
150 id_payload_t *id)
151 {
152 authenticator_t *authenticator;
153 authenticator = authenticator_create_v1(this->ike_sa, this->initiator,
154 this->auth_method, this->dh,
155 this->dh_value, this->sa_payload,
156 id->get_encoded(id));
157 if (!authenticator)
158 {
159 DBG1(DBG_IKE, "negotiated authentication method %N not supported",
160 auth_method_names, this->auth_method);
161 }
162 return authenticator;
163 }
164
165 /**
166 * Save the encoded SA payload of a message
167 */
168 static bool save_sa_payload(private_main_mode_t *this, message_t *message)
169 {
170 enumerator_t *enumerator;
171 payload_t *payload, *sa = NULL;
172 chunk_t data;
173 size_t offset = IKE_HEADER_LENGTH;
174
175 enumerator = message->create_payload_enumerator(message);
176 while (enumerator->enumerate(enumerator, &payload))
177 {
178 if (payload->get_type(payload) == SECURITY_ASSOCIATION_V1)
179 {
180 sa = payload;
181 break;
182 }
183 else
184 {
185 offset += payload->get_length(payload);
186 }
187 }
188 enumerator->destroy(enumerator);
189
190 data = message->get_packet_data(message);
191 if (sa && data.len >= offset + sa->get_length(sa))
192 {
193 /* Get SA payload without 4 byte fixed header */
194 data = chunk_skip(data, offset);
195 data.len = sa->get_length(sa);
196 data = chunk_skip(data, 4);
197 this->sa_payload = chunk_clone(data);
198 return TRUE;
199 }
200 return FALSE;
201 }
202
203 /**
204 * Generate and add NONCE, KE payload
205 */
206 static bool add_nonce_ke(private_main_mode_t *this, chunk_t *nonce,
207 message_t *message)
208 {
209 nonce_payload_t *nonce_payload;
210 ke_payload_t *ke_payload;
211 rng_t *rng;
212
213 ke_payload = ke_payload_create_from_diffie_hellman(KEY_EXCHANGE_V1,
214 this->dh);
215 message->add_payload(message, &ke_payload->payload_interface);
216
217 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
218 if (!rng)
219 {
220 DBG1(DBG_IKE, "no RNG found to create nonce");
221 return FALSE;
222 }
223 rng->allocate_bytes(rng, NONCE_SIZE, nonce);
224 rng->destroy(rng);
225
226 nonce_payload = nonce_payload_create(NONCE_V1);
227 nonce_payload->set_nonce(nonce_payload, *nonce);
228 message->add_payload(message, &nonce_payload->payload_interface);
229
230 return TRUE;
231 }
232
233 /**
234 * Extract nonce from NONCE payload, process KE payload
235 */
236 static bool get_nonce_ke(private_main_mode_t *this, chunk_t *nonce,
237 message_t *message)
238 {
239 nonce_payload_t *nonce_payload;
240 ke_payload_t *ke_payload;
241
242 ke_payload = (ke_payload_t*)message->get_payload(message, KEY_EXCHANGE_V1);
243 if (!ke_payload)
244 {
245 DBG1(DBG_IKE, "KE payload missing in message");
246 return FALSE;
247 }
248 this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload));
249 this->dh->set_other_public_value(this->dh, this->dh_value);
250
251 nonce_payload = (nonce_payload_t*)message->get_payload(message, NONCE_V1);
252 if (!nonce_payload)
253 {
254 DBG1(DBG_IKE, "NONCE payload missing in message");
255 return FALSE;
256 }
257 *nonce = nonce_payload->get_nonce(nonce_payload);
258
259 return TRUE;
260 }
261
262 /**
263 * Get the two auth classes from local or remote config
264 */
265 static void get_auth_class(peer_cfg_t *peer_cfg, bool local,
266 auth_class_t *c1, auth_class_t *c2)
267 {
268 enumerator_t *enumerator;
269 auth_cfg_t *auth;
270
271 *c1 = *c2 = AUTH_CLASS_ANY;
272
273 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
274 while (enumerator->enumerate(enumerator, &auth))
275 {
276 if (*c1 == AUTH_CLASS_ANY)
277 {
278 *c1 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
279 }
280 else
281 {
282 *c2 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
283 break;
284 }
285 }
286 enumerator->destroy(enumerator);
287 }
288
289 /**
290 * Get auth method to use from a peer config
291 */
292 static auth_method_t get_auth_method(private_main_mode_t *this,
293 peer_cfg_t *peer_cfg)
294 {
295 auth_class_t i1, i2, r1, r2;
296
297 get_auth_class(peer_cfg, this->initiator, &i1, &i2);
298 get_auth_class(peer_cfg, !this->initiator, &r1, &r2);
299
300 if (i1 == AUTH_CLASS_PUBKEY && r1 == AUTH_CLASS_PUBKEY)
301 {
302 if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
303 {
304 /* TODO-IKEv1: ECDSA? */
305 return AUTH_RSA;
306 }
307 if (i2 == AUTH_CLASS_XAUTH)
308 {
309 return AUTH_XAUTH_INIT_RSA;
310 }
311 if (r2 == AUTH_CLASS_XAUTH)
312 {
313 return AUTH_XAUTH_RESP_RSA;
314 }
315 }
316 if (i1 == AUTH_CLASS_PSK && r1 == AUTH_CLASS_PSK)
317 {
318 if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
319 {
320 return AUTH_PSK;
321 }
322 if (i2 == AUTH_CLASS_XAUTH)
323 {
324 return AUTH_XAUTH_INIT_PSK;
325 }
326 if (r2 == AUTH_CLASS_XAUTH)
327 {
328 return AUTH_XAUTH_RESP_PSK;
329 }
330 }
331 if (i1 == AUTH_CLASS_XAUTH && r1 == AUTH_CLASS_PUBKEY &&
332 i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
333 {
334 return AUTH_HYBRID_INIT_RSA;
335 }
336 return AUTH_NONE;
337 }
338
339 /**
340 * Check if a peer skipped authentication by using Hybrid authentication
341 */
342 static bool skipped_auth(private_main_mode_t *this, bool local)
343 {
344 bool initiator;
345
346 initiator = local == this->initiator;
347 if (initiator && this->auth_method == AUTH_HYBRID_INIT_RSA)
348 {
349 return TRUE;
350 }
351 if (!initiator && this->auth_method == AUTH_HYBRID_RESP_RSA)
352 {
353 return TRUE;
354 }
355 return FALSE;
356 }
357
358 /**
359 * Check if remote authentication constraints fulfilled
360 */
361 static bool check_constraints(private_main_mode_t *this)
362 {
363 identification_t *id;
364 auth_cfg_t *auth;
365
366 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
367 /* auth identity to comply */
368 id = this->ike_sa->get_other_id(this->ike_sa);
369 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
370 if (skipped_auth(this, FALSE))
371 {
372 return TRUE;
373 }
374 return auth->complies(auth, this->other_auth, TRUE);
375 }
376
377 /**
378 * Save authentication information after authentication succeeded
379 */
380 static void save_auth_cfg(private_main_mode_t *this, bool local)
381 {
382 auth_cfg_t *auth;
383
384 if (skipped_auth(this, local))
385 {
386 return;
387 }
388 auth = auth_cfg_create();
389 /* for local config, we _copy_ entires from the config, as it contains
390 * certificates we must send later. */
391 auth->merge(auth, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
392 this->ike_sa->add_auth_cfg(this->ike_sa, local, auth);
393 }
394
395 /**
396 * Select the best configuration as responder
397 */
398 static peer_cfg_t *select_config(private_main_mode_t *this, identification_t *id)
399 {
400 enumerator_t *enumerator;
401 peer_cfg_t *current, *found = NULL;
402 host_t *me, *other;
403
404 me = this->ike_sa->get_my_host(this->ike_sa);
405 other = this->ike_sa->get_other_host(this->ike_sa);
406 DBG1(DBG_CFG, "looking for %N peer configs matching %H...%H[%Y]",
407 auth_method_names, this->auth_method, me, other, id);
408 enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
409 me, other, NULL, id);
410 while (enumerator->enumerate(enumerator, &current))
411 {
412 if (get_auth_method(this, current) == this->auth_method)
413 {
414 found = current->get_ref(current);
415 break;
416 }
417 }
418 enumerator->destroy(enumerator);
419
420 if (found)
421 {
422 DBG2(DBG_CFG, "selected peer config \"%s\"", found->get_name(found));
423 }
424 return found;
425 }
426
427 /**
428 * Check for notify errors, return TRUE if error found
429 */
430 static bool has_notify_errors(private_main_mode_t *this, message_t *message)
431 {
432 enumerator_t *enumerator;
433 payload_t *payload;
434 bool err = FALSE;
435
436 enumerator = message->create_payload_enumerator(message);
437 while (enumerator->enumerate(enumerator, &payload))
438 {
439 if (payload->get_type(payload) == NOTIFY_V1)
440 {
441 notify_payload_t *notify;
442 notify_type_t type;
443
444 notify = (notify_payload_t*)payload;
445 type = notify->get_notify_type(notify);
446 if (type < 16384)
447 {
448 DBG1(DBG_IKE, "received %N error notify",
449 notify_type_names, type);
450 err = TRUE;
451 }
452 else if (type == INITIAL_CONTACT_IKEV1)
453 {
454 if (!this->initiator && this->state == MM_AUTH)
455 {
456 /* If authenticated and received INITIAL_CONTACT,
457 * delete any existing IKE_SAs with that peer.
458 * The delete takes place when the SA is checked in due
459 * to other id not known until the 3rd message.*/
460 this->ike_sa->set_condition(this->ike_sa,
461 COND_INIT_CONTACT_SEEN, TRUE);
462 }
463 }
464 else
465 {
466 DBG1(DBG_IKE, "received %N notify", notify_type_names, type);
467 }
468 }
469 }
470 enumerator->destroy(enumerator);
471
472 return err;
473 }
474
475 /**
476 * Queue a task sending a notify in an INFORMATIONAL exchange
477 */
478 static status_t send_notify(private_main_mode_t *this, notify_type_t type)
479 {
480 notify_payload_t *notify;
481 ike_sa_id_t *ike_sa_id;
482 u_int64_t spi_i, spi_r;
483 chunk_t spi;
484
485 notify = notify_payload_create_from_protocol_and_type(NOTIFY_V1,
486 PROTO_IKE, type);
487 ike_sa_id = this->ike_sa->get_id(this->ike_sa);
488 spi_i = ike_sa_id->get_initiator_spi(ike_sa_id);
489 spi_r = ike_sa_id->get_responder_spi(ike_sa_id);
490 spi = chunk_cata("cc", chunk_from_thing(spi_i), chunk_from_thing(spi_r));
491 notify->set_spi_data(notify, spi);
492
493 this->ike_sa->queue_task(this->ike_sa,
494 (task_t*)informational_create(this->ike_sa, notify));
495 /* cancel all active/passive tasks in favour of informational */
496 return ALREADY_DONE;
497 }
498
499 /**
500 * Queue a delete task if authentication failed as initiator
501 */
502 static status_t send_delete(private_main_mode_t *this)
503 {
504 this->ike_sa->queue_task(this->ike_sa,
505 (task_t*)isakmp_delete_create(this->ike_sa, TRUE));
506 /* cancel all active tasks in favour of informational */
507 return ALREADY_DONE;
508 }
509
510 METHOD(task_t, build_i, status_t,
511 private_main_mode_t *this, message_t *message)
512 {
513 switch (this->state)
514 {
515 case MM_INIT:
516 {
517 sa_payload_t *sa_payload;
518 linked_list_t *proposals;
519 packet_t *packet;
520
521 this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
522 DBG0(DBG_IKE, "initiating IKE_SA %s[%d] to %H",
523 this->ike_sa->get_name(this->ike_sa),
524 this->ike_sa->get_unique_id(this->ike_sa),
525 this->ike_sa->get_other_host(this->ike_sa));
526 this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
527
528 this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
529 this->peer_cfg->get_ref(this->peer_cfg);
530
531 this->my_auth = get_auth_cfg(this->peer_cfg, TRUE);
532 this->other_auth = get_auth_cfg(this->peer_cfg, FALSE);
533 if (!this->my_auth || !this->other_auth)
534 {
535 DBG1(DBG_CFG, "no auth config found");
536 return FAILED;
537 }
538 this->auth_method = get_auth_method(this, this->peer_cfg);
539 if (this->auth_method == AUTH_NONE)
540 {
541 DBG1(DBG_CFG, "configuration uses unsupported authentication");
542 return FAILED;
543 }
544 this->lifetime = this->peer_cfg->get_reauth_time(this->peer_cfg,
545 FALSE);
546 if (!this->lifetime)
547 { /* fall back to rekey time of no rekey time configured */
548 this->lifetime = this->peer_cfg->get_rekey_time(this->peer_cfg,
549 FALSE);
550 }
551 proposals = this->ike_cfg->get_proposals(this->ike_cfg);
552 sa_payload = sa_payload_create_from_proposals_v1(proposals,
553 this->lifetime, 0, this->auth_method, MODE_NONE, FALSE);
554 proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
555
556 message->add_payload(message, &sa_payload->payload_interface);
557
558 /* pregenerate message to store SA payload */
559 if (this->ike_sa->generate_message(this->ike_sa, message,
560 &packet) != SUCCESS)
561 {
562 DBG1(DBG_IKE, "pregenerating SA payload failed");
563 return FAILED;
564 }
565 packet->destroy(packet);
566 if (!save_sa_payload(this, message))
567 {
568 DBG1(DBG_IKE, "SA payload invalid");
569 return FAILED;
570 }
571
572 this->state = MM_SA;
573 return NEED_MORE;
574 }
575 case MM_SA:
576 {
577 u_int16_t group;
578
579 if (!this->keymat->create_hasher(this->keymat, this->proposal))
580 {
581 return send_notify(this, NO_PROPOSAL_CHOSEN);
582 }
583 if (!this->proposal->get_algorithm(this->proposal,
584 DIFFIE_HELLMAN_GROUP, &group, NULL))
585 {
586 DBG1(DBG_IKE, "DH group selection failed");
587 return send_notify(this, NO_PROPOSAL_CHOSEN);
588 }
589 this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
590 group);
591 if (!this->dh)
592 {
593 DBG1(DBG_IKE, "negotiated DH group not supported");
594 return send_notify(this, INVALID_KEY_INFORMATION);
595 }
596 if (!add_nonce_ke(this, &this->nonce_i, message))
597 {
598 return send_notify(this, INVALID_KEY_INFORMATION);
599 }
600 this->state = MM_KE;
601 return NEED_MORE;
602 }
603 case MM_KE:
604 {
605 authenticator_t *authenticator;
606 id_payload_t *id_payload;
607 identification_t *id;
608
609 id = this->my_auth->get(this->my_auth, AUTH_RULE_IDENTITY);
610 if (!id)
611 {
612 DBG1(DBG_CFG, "own identity not known");
613 return send_notify(this, INVALID_ID_INFORMATION);
614 }
615
616 this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
617
618 id_payload = id_payload_create_from_identification(ID_V1, id);
619 message->add_payload(message, &id_payload->payload_interface);
620
621 authenticator = create_authenticator(this, id_payload);
622 if (!authenticator || authenticator->build(authenticator,
623 message) != SUCCESS)
624 {
625 DESTROY_IF(authenticator);
626 return send_notify(this, AUTHENTICATION_FAILED);
627 }
628 authenticator->destroy(authenticator);
629 save_auth_cfg(this, TRUE);
630
631 this->state = MM_AUTH;
632 return NEED_MORE;
633 }
634 default:
635 return FAILED;
636 }
637 }
638
639 METHOD(task_t, process_r, status_t,
640 private_main_mode_t *this, message_t *message)
641 {
642 switch (this->state)
643 {
644 case MM_INIT:
645 {
646 linked_list_t *list;
647 sa_payload_t *sa_payload;
648
649 this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
650 DBG0(DBG_IKE, "%H is initiating a Main Mode",
651 message->get_source(message));
652 this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
653
654 this->ike_sa->update_hosts(this->ike_sa,
655 message->get_destination(message),
656 message->get_source(message), TRUE);
657
658 sa_payload = (sa_payload_t*)message->get_payload(message,
659 SECURITY_ASSOCIATION_V1);
660 if (!sa_payload || !save_sa_payload(this, message))
661 {
662 DBG1(DBG_IKE, "SA payload missing or invalid");
663 return send_notify(this, INVALID_PAYLOAD_TYPE);
664 }
665
666 list = sa_payload->get_proposals(sa_payload);
667 this->proposal = this->ike_cfg->select_proposal(this->ike_cfg,
668 list, FALSE);
669 list->destroy_offset(list, offsetof(proposal_t, destroy));
670 if (!this->proposal)
671 {
672 DBG1(DBG_IKE, "no proposal found");
673 return send_notify(this, NO_PROPOSAL_CHOSEN);
674 }
675
676 this->auth_method = sa_payload->get_auth_method(sa_payload);
677 this->lifetime = sa_payload->get_lifetime(sa_payload);
678
679 this->state = MM_SA;
680 return NEED_MORE;
681 }
682 case MM_SA:
683 {
684 u_int16_t group;
685
686 if (!this->keymat->create_hasher(this->keymat, this->proposal))
687 {
688 return send_notify(this, INVALID_KEY_INFORMATION);
689 }
690 if (!this->proposal->get_algorithm(this->proposal,
691 DIFFIE_HELLMAN_GROUP, &group, NULL))
692 {
693 DBG1(DBG_IKE, "DH group selection failed");
694 return send_notify(this, INVALID_KEY_INFORMATION);
695 }
696 this->dh = lib->crypto->create_dh(lib->crypto, group);
697 if (!this->dh)
698 {
699 DBG1(DBG_IKE, "negotiated DH group not supported");
700 return send_notify(this, INVALID_KEY_INFORMATION);
701 }
702 if (!get_nonce_ke(this, &this->nonce_i, message))
703 {
704 return send_notify(this, INVALID_PAYLOAD_TYPE);
705 }
706 this->state = MM_KE;
707 return NEED_MORE;
708 }
709 case MM_KE:
710 {
711 authenticator_t *authenticator;
712 id_payload_t *id_payload;
713 identification_t *id;
714
715 id_payload = (id_payload_t*)message->get_payload(message, ID_V1);
716 if (!id_payload)
717 {
718 DBG1(DBG_IKE, "IDii payload missing");
719 return send_notify(this, INVALID_PAYLOAD_TYPE);
720 }
721
722 id = id_payload->get_identification(id_payload);
723 this->ike_sa->set_other_id(this->ike_sa, id);
724 this->peer_cfg = select_config(this, id);
725 if (!this->peer_cfg)
726 {
727 DBG1(DBG_IKE, "no peer config found");
728 return send_notify(this, AUTHENTICATION_FAILED);
729 }
730 this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
731
732 this->my_auth = get_auth_cfg(this->peer_cfg, TRUE);
733 this->other_auth = get_auth_cfg(this->peer_cfg, FALSE);
734 if (!this->my_auth || !this->other_auth)
735 {
736 DBG1(DBG_IKE, "auth config missing");
737 return send_notify(this, AUTHENTICATION_FAILED);
738 }
739
740 authenticator = create_authenticator(this, id_payload);
741 if (!authenticator || authenticator->process(authenticator,
742 message) != SUCCESS)
743 {
744 DESTROY_IF(authenticator);
745 return send_notify(this, AUTHENTICATION_FAILED);
746 }
747 authenticator->destroy(authenticator);
748 if (!check_constraints(this))
749 {
750 return send_notify(this, AUTHENTICATION_FAILED);
751 }
752 save_auth_cfg(this, FALSE);
753
754 this->state = MM_AUTH;
755 if (has_notify_errors(this, message))
756 {
757 return FAILED;
758 }
759 return NEED_MORE;
760 }
761 default:
762 return FAILED;
763 }
764 }
765
766 /**
767 * Lookup a shared secret for this IKE_SA
768 */
769 static shared_key_t *lookup_shared_key(private_main_mode_t *this)
770 {
771 host_t *me, *other;
772 identification_t *my_id, *other_id;
773 shared_key_t *shared_key = NULL;
774
775 /* try to get a PSK for IP addresses */
776 me = this->ike_sa->get_my_host(this->ike_sa);
777 other = this->ike_sa->get_other_host(this->ike_sa);
778 my_id = identification_create_from_sockaddr(me->get_sockaddr(me));
779 other_id = identification_create_from_sockaddr(other->get_sockaddr(other));
780 if (my_id && other_id)
781 {
782 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE,
783 my_id, other_id);
784 }
785 DESTROY_IF(my_id);
786 DESTROY_IF(other_id);
787 if (shared_key)
788 {
789 return shared_key;
790 }
791
792 if (this->my_auth && this->other_auth)
793 { /* as initiator, use identities from configuraiton */
794 my_id = this->my_auth->get(this->my_auth, AUTH_RULE_IDENTITY);
795 other_id = this->other_auth->get(this->other_auth, AUTH_RULE_IDENTITY);
796 if (my_id && other_id)
797 {
798 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE,
799 my_id, other_id);
800 }
801 else
802 {
803 DBG1(DBG_IKE, "no shared key found for '%Y'[%H] - '%Y'[%H]",
804 my_id, me, other_id, other);
805 }
806 }
807 else
808 { /* as responder, we try to find a config by IP */
809 enumerator_t *enumerator;
810 auth_cfg_t *my_auth, *other_auth;
811 peer_cfg_t *peer_cfg = NULL;
812
813 enumerator = charon->backends->create_peer_cfg_enumerator(
814 charon->backends, me, other, NULL, NULL);
815 while (enumerator->enumerate(enumerator, &peer_cfg))
816 {
817 my_auth = get_auth_cfg(peer_cfg, TRUE);
818 other_auth = get_auth_cfg(peer_cfg, FALSE);
819 if (my_auth && other_auth)
820 {
821 my_id = my_auth->get(my_auth, AUTH_RULE_IDENTITY);
822 other_id = other_auth->get(other_auth, AUTH_RULE_IDENTITY);
823 if (my_id && other_id)
824 {
825 shared_key = lib->credmgr->get_shared(lib->credmgr,
826 SHARED_IKE, my_id, other_id);
827 if (shared_key)
828 {
829 break;
830 }
831 else
832 {
833 DBG1(DBG_IKE, "no shared key found for "
834 "'%Y'[%H] - '%Y'[%H]", my_id, me, other_id, other);
835 }
836 }
837 }
838 }
839 enumerator->destroy(enumerator);
840 if (!peer_cfg)
841 {
842 DBG1(DBG_IKE, "no shared key found for %H - %H", me, other);
843 }
844 }
845 return shared_key;
846 }
847
848 /**
849 * Derive key material for this IKE_SA
850 */
851 static bool derive_keys(private_main_mode_t *this, chunk_t nonce_i,
852 chunk_t nonce_r)
853 {
854 ike_sa_id_t *id = this->ike_sa->get_id(this->ike_sa);
855 shared_key_t *shared_key = NULL;
856
857 switch (this->auth_method)
858 {
859 case AUTH_PSK:
860 case AUTH_XAUTH_INIT_PSK:
861 case AUTH_XAUTH_RESP_PSK:
862 shared_key = lookup_shared_key(this);
863 break;
864 default:
865 break;
866 }
867 if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
868 this->dh_value, nonce_i, nonce_r, id, this->auth_method, shared_key))
869 {
870 DESTROY_IF(shared_key);
871 DBG1(DBG_IKE, "key derivation for %N failed",
872 auth_method_names, this->auth_method);
873 return FALSE;
874 }
875 DESTROY_IF(shared_key);
876 charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, nonce_i, nonce_r,
877 NULL);
878
879 return TRUE;
880 }
881
882 /**
883 * Set IKE_SA to established state
884 */
885 static void establish(private_main_mode_t *this)
886 {
887 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
888 this->ike_sa->get_name(this->ike_sa),
889 this->ike_sa->get_unique_id(this->ike_sa),
890 this->ike_sa->get_my_host(this->ike_sa),
891 this->ike_sa->get_my_id(this->ike_sa),
892 this->ike_sa->get_other_host(this->ike_sa),
893 this->ike_sa->get_other_id(this->ike_sa));
894
895 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
896 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
897 }
898
899 METHOD(task_t, build_r, status_t,
900 private_main_mode_t *this, message_t *message)
901 {
902 switch (this->state)
903 {
904 case MM_SA:
905 {
906 sa_payload_t *sa_payload;
907
908 sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
909 this->lifetime, 0, this->auth_method, MODE_NONE, FALSE);
910 message->add_payload(message, &sa_payload->payload_interface);
911
912 return NEED_MORE;
913 }
914 case MM_KE:
915 {
916 if (!add_nonce_ke(this, &this->nonce_r, message))
917 {
918 return send_notify(this, INVALID_KEY_INFORMATION);
919 }
920 if (!derive_keys(this, this->nonce_i, this->nonce_r))
921 {
922 return send_notify(this, INVALID_KEY_INFORMATION);
923 }
924 return NEED_MORE;
925 }
926 case MM_AUTH:
927 {
928 authenticator_t *authenticator;
929 id_payload_t *id_payload;
930 identification_t *id;
931
932 id = this->my_auth->get(this->my_auth, AUTH_RULE_IDENTITY);
933 if (!id)
934 {
935 DBG1(DBG_CFG, "own identity not known");
936 return send_notify(this, INVALID_ID_INFORMATION);
937 }
938 this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
939
940 id_payload = id_payload_create_from_identification(ID_V1, id);
941 message->add_payload(message, &id_payload->payload_interface);
942
943 authenticator = create_authenticator(this, id_payload);
944 if (!authenticator || authenticator->build(authenticator,
945 message) != SUCCESS)
946 {
947 DESTROY_IF(authenticator);
948 return send_notify(this, AUTHENTICATION_FAILED);
949 }
950 authenticator->destroy(authenticator);
951 save_auth_cfg(this, TRUE);
952
953 if (this->peer_cfg->get_virtual_ip(this->peer_cfg))
954 {
955 this->ike_sa->queue_task(this->ike_sa,
956 (task_t*)mode_config_create(this->ike_sa, TRUE));
957 }
958
959 switch (this->auth_method)
960 {
961 case AUTH_XAUTH_INIT_PSK:
962 case AUTH_XAUTH_INIT_RSA:
963 case AUTH_HYBRID_INIT_RSA:
964 this->ike_sa->queue_task(this->ike_sa,
965 (task_t*)xauth_create(this->ike_sa, TRUE));
966 return SUCCESS;
967 case AUTH_XAUTH_RESP_PSK:
968 case AUTH_XAUTH_RESP_RSA:
969 case AUTH_HYBRID_RESP_RSA:
970 /* TODO-IKEv1: not yet supported */
971 return FAILED;
972 default:
973 establish(this);
974 return SUCCESS;
975 }
976 }
977 default:
978 return FAILED;
979 }
980 }
981
982 METHOD(task_t, process_i, status_t,
983 private_main_mode_t *this, message_t *message)
984 {
985 switch (this->state)
986 {
987 case MM_SA:
988 {
989 linked_list_t *list;
990 sa_payload_t *sa_payload;
991 auth_method_t auth_method;
992 u_int32_t lifetime;
993
994 sa_payload = (sa_payload_t*)message->get_payload(message,
995 SECURITY_ASSOCIATION_V1);
996 if (!sa_payload)
997 {
998 DBG1(DBG_IKE, "SA payload missing");
999 return send_notify(this, INVALID_PAYLOAD_TYPE);
1000 }
1001 list = sa_payload->get_proposals(sa_payload);
1002 this->proposal = this->ike_cfg->select_proposal(this->ike_cfg,
1003 list, FALSE);
1004 list->destroy_offset(list, offsetof(proposal_t, destroy));
1005 if (!this->proposal)
1006 {
1007 DBG1(DBG_IKE, "no proposal found");
1008 return send_notify(this, NO_PROPOSAL_CHOSEN);
1009 }
1010
1011 lifetime = sa_payload->get_lifetime(sa_payload);
1012 if (lifetime != this->lifetime)
1013 {
1014 DBG1(DBG_IKE, "received lifetime %us does not match configured "
1015 "%us, using lower value", lifetime, this->lifetime);
1016 }
1017 this->lifetime = min(this->lifetime, lifetime);
1018 auth_method = sa_payload->get_auth_method(sa_payload);
1019 if (auth_method != this->auth_method)
1020 {
1021 DBG1(DBG_IKE, "received %N authentication, but configured %N, "
1022 "continue with configured", auth_method_names, auth_method,
1023 auth_method_names, this->auth_method);
1024 }
1025 return NEED_MORE;
1026 }
1027 case MM_KE:
1028 {
1029 if (!get_nonce_ke(this, &this->nonce_r, message))
1030 {
1031 return send_notify(this, INVALID_PAYLOAD_TYPE);
1032 }
1033 if (!derive_keys(this, this->nonce_i, this->nonce_r))
1034 {
1035 return send_notify(this, INVALID_KEY_INFORMATION);
1036 }
1037 return NEED_MORE;
1038 }
1039 case MM_AUTH:
1040 {
1041 authenticator_t *authenticator;
1042 id_payload_t *id_payload;
1043 identification_t *id;
1044
1045 id_payload = (id_payload_t*)message->get_payload(message, ID_V1);
1046 if (!id_payload)
1047 {
1048 DBG1(DBG_IKE, "IDir payload missing");
1049 return send_delete(this);
1050 }
1051 id = id_payload->get_identification(id_payload);
1052 if (!id->matches(id, this->other_auth->get(this->other_auth,
1053 AUTH_RULE_IDENTITY)))
1054 {
1055 DBG1(DBG_IKE, "IDir does not match");
1056 id->destroy(id);
1057 return send_delete(this);
1058 }
1059 this->ike_sa->set_other_id(this->ike_sa, id);
1060
1061 authenticator = create_authenticator(this, id_payload);
1062 if (!authenticator || authenticator->process(authenticator,
1063 message) != SUCCESS)
1064 {
1065 DESTROY_IF(authenticator);
1066 return send_delete(this);
1067 }
1068 authenticator->destroy(authenticator);
1069 if (!check_constraints(this))
1070 {
1071 return send_delete(this);
1072 }
1073 save_auth_cfg(this, FALSE);
1074
1075 switch (this->auth_method)
1076 {
1077 case AUTH_XAUTH_INIT_PSK:
1078 case AUTH_XAUTH_INIT_RSA:
1079 case AUTH_HYBRID_INIT_RSA:
1080 /* wait for XAUTH request */
1081 return SUCCESS;
1082 case AUTH_XAUTH_RESP_PSK:
1083 case AUTH_XAUTH_RESP_RSA:
1084 case AUTH_HYBRID_RESP_RSA:
1085 /* TODO-IKEv1: not yet */
1086 return FAILED;
1087 default:
1088 establish(this);
1089 return SUCCESS;
1090 }
1091 }
1092 default:
1093 return FAILED;
1094 }
1095 }
1096
1097 METHOD(task_t, get_type, task_type_t,
1098 private_main_mode_t *this)
1099 {
1100 return TASK_MAIN_MODE;
1101 }
1102
1103 METHOD(task_t, migrate, void,
1104 private_main_mode_t *this, ike_sa_t *ike_sa)
1105 {
1106 this->ike_sa = ike_sa;
1107 }
1108
1109 METHOD(task_t, destroy, void,
1110 private_main_mode_t *this)
1111 {
1112 DESTROY_IF(this->peer_cfg);
1113 DESTROY_IF(this->proposal);
1114 DESTROY_IF(this->dh);
1115 free(this->dh_value.ptr);
1116 free(this->nonce_i.ptr);
1117 free(this->nonce_r.ptr);
1118 free(this->sa_payload.ptr);
1119 free(this);
1120 }
1121
1122 /*
1123 * Described in header.
1124 */
1125 main_mode_t *main_mode_create(ike_sa_t *ike_sa, bool initiator)
1126 {
1127 private_main_mode_t *this;
1128
1129 INIT(this,
1130 .public = {
1131 .task = {
1132 .get_type = _get_type,
1133 .migrate = _migrate,
1134 .destroy = _destroy,
1135 },
1136 },
1137 .ike_sa = ike_sa,
1138 .keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa),
1139 .initiator = initiator,
1140 .state = MM_INIT,
1141 );
1142
1143 if (initiator)
1144 {
1145 this->public.task.build = _build_i;
1146 this->public.task.process = _process_i;
1147 }
1148 else
1149 {
1150 this->public.task.build = _build_r;
1151 this->public.task.process = _process_r;
1152 }
1153
1154 return &this->public;
1155 }