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