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