Some notification errors added to main_mode process_r
[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 <processing/jobs/initiate_xauth_job.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 auth method to use
258 */
259 static auth_method_t get_auth_method(private_main_mode_t *this)
260 {
261 switch ((uintptr_t)this->my_auth->get(this->my_auth, AUTH_RULE_AUTH_CLASS))
262 {
263 case AUTH_CLASS_PSK:
264 return AUTH_PSK;
265 case AUTH_CLASS_XAUTH_PSK:
266 return AUTH_XAUTH_INIT_PSK;
267 case AUTH_CLASS_XAUTH_PUBKEY:
268 return AUTH_XAUTH_INIT_RSA;
269 case AUTH_CLASS_PUBKEY:
270 /* TODO-IKEv1: look for a key, return RSA or ECDSA */
271 default:
272 /* TODO-IKEv1: XAUTH methods */
273 return AUTH_RSA;
274 }
275 }
276
277 /**
278 * Check for notify errors, return TRUE if error found
279 */
280 static bool has_notify_errors(private_main_mode_t *this, message_t *message)
281 {
282 enumerator_t *enumerator;
283 payload_t *payload;
284 bool err = FALSE;
285
286 enumerator = message->create_payload_enumerator(message);
287 while (enumerator->enumerate(enumerator, &payload))
288 {
289 if (payload->get_type(payload) == NOTIFY_V1)
290 {
291 notify_payload_t *notify;
292 notify_type_t type;
293
294 notify = (notify_payload_t*)payload;
295 type = notify->get_notify_type(notify);
296 if (type < 16384)
297 {
298 DBG1(DBG_IKE, "received %N error notify",
299 notify_type_names, type);
300 err = TRUE;
301 }
302 else if (type == INITIAL_CONTACT_IKEV1)
303 {
304 if (!this->initiator && this->state == MM_AUTH)
305 {
306 /* If authenticated and received INITIAL_CONTACT,
307 * delete any existing IKE_SAs with that peer.
308 * The delete takes place when the SA is checked in due
309 * to other id not known until the 3rd message.*/
310 this->ike_sa->set_condition(this->ike_sa, COND_INIT_CONTACT_SEEN, TRUE);
311 }
312 }
313 else
314 {
315 DBG1(DBG_IKE, "received %N notify", notify_type_names, type);
316 }
317 }
318 }
319 enumerator->destroy(enumerator);
320
321 return err;
322 }
323
324 METHOD(task_t, build_notify_error, status_t,
325 private_main_mode_t *this, message_t *message)
326 {
327 notify_payload_t *notify;
328 ike_sa_id_t *ike_sa_id;
329 chunk_t spi;
330 u_int64_t spi_i, spi_r;
331
332 notify = notify_payload_create_from_protocol_and_type(NOTIFY_V1,
333 PROTO_IKE, this->notify_type);
334
335 if (this->notify_data.ptr)
336 {
337 notify->set_notification_data(notify, this->notify_data);
338 }
339
340 ike_sa_id = this->ike_sa->get_id(this->ike_sa);
341
342 spi_i = ike_sa_id->get_initiator_spi(ike_sa_id);
343 spi_r = ike_sa_id->get_responder_spi(ike_sa_id);
344
345 spi = chunk_cata("cc", chunk_from_thing(spi_i), chunk_from_thing(spi_r));
346
347 notify->set_spi_data(notify, spi);
348
349 message->add_payload(message, (payload_t*)notify);
350
351 return SUCCESS;
352 }
353
354 /**
355 * Set the task ready to build notify error message
356 */
357 static status_t set_notify_error(private_main_mode_t *this,
358 notify_type_t type, chunk_t data)
359 {
360 this->notify_type = type;
361 this->notify_data = data;
362 /* The task will be destroyed after build */
363 this->public.task.build = _build_notify_error;
364 return FAILED_SEND_ERROR;
365 }
366
367 METHOD(task_t, build_i, status_t,
368 private_main_mode_t *this, message_t *message)
369 {
370 switch (this->state)
371 {
372 case MM_INIT:
373 {
374 sa_payload_t *sa_payload;
375 linked_list_t *proposals;
376 packet_t *packet;
377
378 this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
379 DBG0(DBG_IKE, "initiating IKE_SA %s[%d] to %H",
380 this->ike_sa->get_name(this->ike_sa),
381 this->ike_sa->get_unique_id(this->ike_sa),
382 this->ike_sa->get_other_host(this->ike_sa));
383 this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
384
385 this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
386 this->peer_cfg->get_ref(this->peer_cfg);
387
388 this->my_auth = get_auth_cfg(this, TRUE);
389 this->other_auth = get_auth_cfg(this, FALSE);
390 if (!this->my_auth || !this->other_auth)
391 {
392 DBG1(DBG_CFG, "no auth config found");
393 return FAILED;
394 }
395
396 proposals = this->ike_cfg->get_proposals(this->ike_cfg);
397 this->auth_method = get_auth_method(this);
398 this->lifetime = this->peer_cfg->get_reauth_time(this->peer_cfg,
399 FALSE);
400 if (!this->lifetime)
401 { /* fall back to rekey time of no rekey time configured */
402 this->lifetime = this->peer_cfg->get_rekey_time(this->peer_cfg,
403 FALSE);
404 }
405 sa_payload = sa_payload_create_from_proposals_v1(proposals,
406 this->lifetime, 0, this->auth_method, MODE_NONE, FALSE);
407 proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
408
409 message->add_payload(message, &sa_payload->payload_interface);
410
411 /* pregenerate message to store SA payload */
412 if (this->ike_sa->generate_message(this->ike_sa, message,
413 &packet) != SUCCESS)
414 {
415 DBG1(DBG_IKE, "pregenerating SA payload failed");
416 return FAILED;
417 }
418 packet->destroy(packet);
419 if (!save_sa_payload(this, message))
420 {
421 DBG1(DBG_IKE, "SA payload invalid");
422 return FAILED;
423 }
424
425 this->state = MM_SA;
426 return NEED_MORE;
427 }
428 case MM_SA:
429 {
430 u_int16_t group;
431
432 if (!this->keymat->create_hasher(this->keymat, this->proposal))
433 {
434 return FAILED;
435 }
436 if (!this->proposal->get_algorithm(this->proposal,
437 DIFFIE_HELLMAN_GROUP, &group, NULL))
438 {
439 DBG1(DBG_IKE, "DH group selection failed");
440 return FAILED;
441 }
442 this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
443 group);
444 if (!this->dh)
445 {
446 DBG1(DBG_IKE, "negotiated DH group not supported");
447 return FAILED;
448 }
449 if (!add_nonce_ke(this, &this->nonce_i, message))
450 {
451 return FAILED;
452 }
453 this->state = MM_KE;
454 return NEED_MORE;
455 }
456 case MM_KE:
457 {
458 id_payload_t *id_payload;
459 identification_t *id;
460
461 id = this->my_auth->get(this->my_auth, AUTH_RULE_IDENTITY);
462 if (!id)
463 {
464 DBG1(DBG_CFG, "own identity not known");
465 return FAILED;
466 }
467
468 this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
469
470 id_payload = id_payload_create_from_identification(ID_V1, id);
471 message->add_payload(message, &id_payload->payload_interface);
472
473 if (this->authenticator->build(this->authenticator,
474 message) != SUCCESS)
475 {
476 return FAILED;
477 }
478 this->state = MM_AUTH;
479 return NEED_MORE;
480 }
481 default:
482 return FAILED;
483 }
484 }
485
486 METHOD(task_t, process_r, status_t,
487 private_main_mode_t *this, message_t *message)
488 {
489 switch (this->state)
490 {
491 case MM_INIT:
492 {
493 linked_list_t *list;
494 sa_payload_t *sa_payload;
495
496 this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
497 DBG0(DBG_IKE, "%H is initiating a Main Mode",
498 message->get_source(message));
499 this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
500
501 this->ike_sa->update_hosts(this->ike_sa,
502 message->get_destination(message),
503 message->get_source(message), TRUE);
504
505 sa_payload = (sa_payload_t*)message->get_payload(message,
506 SECURITY_ASSOCIATION_V1);
507 if (!sa_payload || !save_sa_payload(this, message))
508 {
509 DBG1(DBG_IKE, "SA payload missing or invalid");
510 return FAILED;
511 }
512
513 list = sa_payload->get_proposals(sa_payload);
514 this->proposal = this->ike_cfg->select_proposal(this->ike_cfg,
515 list, FALSE);
516 list->destroy_offset(list, offsetof(proposal_t, destroy));
517 if (!this->proposal)
518 {
519 DBG1(DBG_IKE, "no proposal found");
520 return set_notify_error(this, NO_PROPOSAL_CHOSEN, chunk_empty);
521 }
522
523 this->auth_method = sa_payload->get_auth_method(sa_payload);
524 this->lifetime = sa_payload->get_lifetime(sa_payload);
525
526 this->state = MM_SA;
527 return NEED_MORE;
528 }
529 case MM_SA:
530 {
531 u_int16_t group;
532
533 if (!this->keymat->create_hasher(this->keymat, this->proposal))
534 {
535 return FAILED;
536 }
537 if (!this->proposal->get_algorithm(this->proposal,
538 DIFFIE_HELLMAN_GROUP, &group, NULL))
539 {
540 DBG1(DBG_IKE, "DH group selection failed");
541 return FAILED;
542 }
543 this->dh = lib->crypto->create_dh(lib->crypto, group);
544 if (!this->dh)
545 {
546 DBG1(DBG_IKE, "negotiated DH group not supported");
547 return FAILED;
548 }
549 if (!get_nonce_ke(this, &this->nonce_i, message))
550 {
551 return FAILED;
552 }
553 this->state = MM_KE;
554 return NEED_MORE;
555 }
556 case MM_KE:
557 {
558 enumerator_t *enumerator;
559 id_payload_t *id_payload;
560 identification_t *id, *any;
561
562 id_payload = (id_payload_t*)message->get_payload(message, ID_V1);
563 if (!id_payload)
564 {
565 DBG1(DBG_IKE, "IDii payload missing");
566 return FAILED;
567 }
568
569 id = id_payload->get_identification(id_payload);
570 any = identification_create_from_encoding(ID_ANY, chunk_empty);
571 enumerator = charon->backends->create_peer_cfg_enumerator(
572 charon->backends,
573 this->ike_sa->get_my_host(this->ike_sa),
574 this->ike_sa->get_other_host(this->ike_sa),
575 any, id);
576 if (!enumerator->enumerate(enumerator, &this->peer_cfg))
577 {
578 DBG1(DBG_IKE, "no peer config found");
579 id->destroy(id);
580 any->destroy(any);
581 enumerator->destroy(enumerator);
582 return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
583 }
584 this->peer_cfg->get_ref(this->peer_cfg);
585 enumerator->destroy(enumerator);
586 any->destroy(any);
587
588 this->ike_sa->set_other_id(this->ike_sa, id);
589
590 this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
591
592 this->my_auth = get_auth_cfg(this, TRUE);
593 this->other_auth = get_auth_cfg(this, FALSE);
594 if (!this->my_auth || !this->other_auth)
595 {
596 DBG1(DBG_IKE, "auth config missing");
597 return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
598 }
599
600 if (this->authenticator->process(this->authenticator,
601 message) != SUCCESS)
602 {
603 return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
604 }
605 this->state = MM_AUTH;
606
607 if (has_notify_errors(this, message))
608 {
609 return FAILED;
610 }
611 return NEED_MORE;
612 }
613 default:
614 return FAILED;
615 }
616 }
617
618 /**
619 * Lookup a shared secret for this IKE_SA
620 */
621 static shared_key_t *lookup_shared_key(private_main_mode_t *this)
622 {
623 host_t *me, *other;
624 identification_t *my_id, *other_id;
625 shared_key_t *shared_key;
626
627 me = this->ike_sa->get_my_host(this->ike_sa);
628 other = this->ike_sa->get_other_host(this->ike_sa);
629 my_id = identification_create_from_sockaddr(me->get_sockaddr(me));
630 other_id = identification_create_from_sockaddr(other->get_sockaddr(other));
631 if (!my_id || !other_id)
632 {
633 DESTROY_IF(my_id);
634 DESTROY_IF(other_id);
635 return NULL;
636 }
637 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE, my_id,
638 other_id);
639 if (!shared_key)
640 {
641 DBG1(DBG_IKE, "no shared key found for %H - %H", me, other);
642 }
643 my_id->destroy(my_id);
644 other_id->destroy(other_id);
645 return shared_key;
646 }
647
648 /**
649 * Derive key material for this IKE_SA
650 */
651 static bool derive_keys(private_main_mode_t *this, chunk_t nonce_i,
652 chunk_t nonce_r)
653 {
654 ike_sa_id_t *id = this->ike_sa->get_id(this->ike_sa);
655 shared_key_t *shared_key = NULL;
656
657 switch (this->auth_method)
658 {
659 case AUTH_PSK:
660 case AUTH_XAUTH_INIT_PSK:
661 case AUTH_XAUTH_RESP_PSK:
662 shared_key = lookup_shared_key(this);
663 break;
664 default:
665 break;
666 }
667 if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
668 this->dh_value, nonce_i, nonce_r, id, this->auth_method, shared_key))
669 {
670 DESTROY_IF(shared_key);
671 DBG1(DBG_IKE, "key derivation for %N failed",
672 auth_method_names, this->auth_method);
673 return FALSE;
674 }
675 DESTROY_IF(shared_key);
676 charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, nonce_i, nonce_r,
677 NULL);
678
679 this->authenticator = authenticator_create_v1(this->ike_sa, this->initiator,
680 this->auth_method, this->dh,
681 this->dh_value, this->sa_payload);
682 if (!this->authenticator)
683 {
684 DBG1(DBG_IKE, "negotiated authentication method %N not supported",
685 auth_method_names, this->auth_method);
686 return FALSE;
687 }
688 return TRUE;
689 }
690
691 METHOD(task_t, build_r, status_t,
692 private_main_mode_t *this, message_t *message)
693 {
694 switch (this->state)
695 {
696 case MM_SA:
697 {
698 sa_payload_t *sa_payload;
699
700 sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
701 this->lifetime, 0, this->auth_method, MODE_NONE, FALSE);
702 message->add_payload(message, &sa_payload->payload_interface);
703
704 return NEED_MORE;
705 }
706 case MM_KE:
707 {
708 if (!add_nonce_ke(this, &this->nonce_r, message))
709 {
710 return FAILED;
711 }
712 if (!derive_keys(this, this->nonce_i, this->nonce_r))
713 {
714 return FAILED;
715 }
716 return NEED_MORE;
717 }
718 case MM_AUTH:
719 {
720 id_payload_t *id_payload;
721 identification_t *id;
722
723 id = this->my_auth->get(this->my_auth, AUTH_RULE_IDENTITY);
724 if (!id)
725 {
726 DBG1(DBG_CFG, "own identity not known");
727 return FAILED;
728 }
729
730 this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
731
732 id_payload = id_payload_create_from_identification(ID_V1, id);
733 message->add_payload(message, &id_payload->payload_interface);
734
735 if (this->authenticator->build(this->authenticator,
736 message) != SUCCESS)
737 {
738 return FAILED;
739 }
740
741 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
742 this->ike_sa->get_name(this->ike_sa),
743 this->ike_sa->get_unique_id(this->ike_sa),
744 this->ike_sa->get_my_host(this->ike_sa),
745 this->ike_sa->get_my_id(this->ike_sa),
746 this->ike_sa->get_other_host(this->ike_sa),
747 this->ike_sa->get_other_id(this->ike_sa));
748
749 switch (this->auth_method)
750 {
751 case AUTH_XAUTH_INIT_PSK:
752 case AUTH_XAUTH_INIT_RSA: /* There should be more INIT cases here once added */
753 {
754 job_t *job = (job_t *) initiate_xauth_job_create(this->ike_sa->get_id(this->ike_sa));
755 lib->processor->queue_job(lib->processor, job);
756 break;
757 }
758 case AUTH_XAUTH_RESP_PSK:
759 case AUTH_XAUTH_RESP_RSA: /* There should be more RESP cases here once added */
760 {
761 break;
762 }
763 default:
764 {
765 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
766 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
767 break;
768 }
769 }
770 return SUCCESS;
771 }
772 default:
773 return FAILED;
774 }
775 }
776
777 METHOD(task_t, process_i, status_t,
778 private_main_mode_t *this, message_t *message)
779 {
780 switch (this->state)
781 {
782 case MM_SA:
783 {
784 linked_list_t *list;
785 sa_payload_t *sa_payload;
786 auth_method_t auth_method;
787 u_int32_t lifetime;
788
789 sa_payload = (sa_payload_t*)message->get_payload(message,
790 SECURITY_ASSOCIATION_V1);
791 if (!sa_payload)
792 {
793 DBG1(DBG_IKE, "SA payload missing");
794 return FAILED;
795 }
796 list = sa_payload->get_proposals(sa_payload);
797 this->proposal = this->ike_cfg->select_proposal(this->ike_cfg,
798 list, FALSE);
799 list->destroy_offset(list, offsetof(proposal_t, destroy));
800 if (!this->proposal)
801 {
802 DBG1(DBG_IKE, "no proposal found");
803 return FAILED;
804 }
805
806 lifetime = sa_payload->get_lifetime(sa_payload);
807 if (lifetime != this->lifetime)
808 {
809 DBG1(DBG_IKE, "received lifetime %us does not match configured "
810 "%us, using lower value", lifetime, this->lifetime);
811 }
812 this->lifetime = min(this->lifetime, lifetime);
813 auth_method = sa_payload->get_auth_method(sa_payload);
814 if (auth_method != this->auth_method)
815 {
816 DBG1(DBG_IKE, "received %N authentication, but configured %N, "
817 "continue with configured", auth_method_names, auth_method,
818 auth_method_names, this->auth_method);
819 }
820 return NEED_MORE;
821 }
822 case MM_KE:
823 {
824 if (!get_nonce_ke(this, &this->nonce_r, message))
825 {
826 return FAILED;
827 }
828 if (!derive_keys(this, this->nonce_i, this->nonce_r))
829 {
830 return FAILED;
831 }
832 return NEED_MORE;
833 }
834 case MM_AUTH:
835 {
836 id_payload_t *id_payload;
837 identification_t *id;
838
839 id_payload = (id_payload_t*)message->get_payload(message, ID_V1);
840 if (!id_payload)
841 {
842 DBG1(DBG_IKE, "IDir payload missing");
843 return FAILED;
844 }
845 id = id_payload->get_identification(id_payload);
846 if (!id->matches(id, this->other_auth->get(this->other_auth,
847 AUTH_RULE_IDENTITY)))
848 {
849 DBG1(DBG_IKE, "IDir does not match");
850 id->destroy(id);
851 return FAILED;
852 }
853 this->ike_sa->set_other_id(this->ike_sa, id);
854
855 if (this->authenticator->process(this->authenticator,
856 message) != SUCCESS)
857 {
858 return FAILED;
859 }
860
861 /* TODO-IKEv1: check for XAUTH rounds, queue them */
862 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
863 this->ike_sa->get_name(this->ike_sa),
864 this->ike_sa->get_unique_id(this->ike_sa),
865 this->ike_sa->get_my_host(this->ike_sa),
866 this->ike_sa->get_my_id(this->ike_sa),
867 this->ike_sa->get_other_host(this->ike_sa),
868 this->ike_sa->get_other_id(this->ike_sa));
869
870 switch (this->auth_method)
871 {
872 case AUTH_XAUTH_RESP_PSK:
873 case AUTH_XAUTH_RESP_RSA: /* There should be more RESP cases here once added */
874 {
875 this->ike_sa->initiate_xauth(this->ike_sa, FALSE);
876 break;
877 }
878 case AUTH_XAUTH_INIT_PSK:
879 case AUTH_XAUTH_INIT_RSA: /* There should be more INIT cases here once added */
880 {
881 break;
882 }
883 default:
884 {
885 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
886 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
887 break;
888 }
889 }
890
891 return SUCCESS;
892 }
893 default:
894 return FAILED;
895 }
896 }
897
898 METHOD(task_t, get_type, task_type_t,
899 private_main_mode_t *this)
900 {
901 return TASK_MAIN_MODE;
902 }
903
904 METHOD(task_t, migrate, void,
905 private_main_mode_t *this, ike_sa_t *ike_sa)
906 {
907 this->ike_sa = ike_sa;
908 }
909
910 METHOD(task_t, destroy, void,
911 private_main_mode_t *this)
912 {
913 DESTROY_IF(this->peer_cfg);
914 DESTROY_IF(this->proposal);
915 DESTROY_IF(this->dh);
916 DESTROY_IF(this->authenticator);
917 free(this->dh_value.ptr);
918 free(this->nonce_i.ptr);
919 free(this->nonce_r.ptr);
920 free(this->sa_payload.ptr);
921 free(this);
922 }
923
924 /*
925 * Described in header.
926 */
927 main_mode_t *main_mode_create(ike_sa_t *ike_sa, bool initiator)
928 {
929 private_main_mode_t *this;
930
931 INIT(this,
932 .public = {
933 .task = {
934 .get_type = _get_type,
935 .migrate = _migrate,
936 .destroy = _destroy,
937 },
938 },
939 .ike_sa = ike_sa,
940 .keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa),
941 .initiator = initiator,
942 .state = MM_INIT,
943 );
944
945 if (initiator)
946 {
947 this->public.task.build = _build_i;
948 this->public.task.process = _process_i;
949 }
950 else
951 {
952 this->public.task.build = _build_r;
953 this->public.task.process = _process_r;
954 }
955
956 return &this->public;
957 }