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