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