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