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