Support multiple virtual IPs on peer_cfg and ike_sa classes
[strongswan.git] / src / libcharon / sa / ikev1 / phase1.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * Copyright (C) 2012 Martin Willi
6 * Copyright (C) 2012 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 "phase1.h"
20
21 #include <daemon.h>
22 #include <sa/ikev1/keymat_v1.h>
23 #include <encoding/payloads/ke_payload.h>
24 #include <encoding/payloads/nonce_payload.h>
25 #include <utils/linked_list.h>
26
27 typedef struct private_phase1_t private_phase1_t;
28
29 /**
30 * Private data of an phase1_t object.
31 */
32 struct private_phase1_t {
33
34 /**
35 * Public phase1_t interface.
36 */
37 phase1_t public;
38
39 /**
40 * IKE_SA we negotiate
41 */
42 ike_sa_t *ike_sa;
43
44 /**
45 * Currently selected peer config
46 */
47 peer_cfg_t *peer_cfg;
48
49 /**
50 * Other possible peer config candidates
51 */
52 linked_list_t *candidates;
53
54 /**
55 * Acting as initiator
56 */
57 bool initiator;
58
59 /**
60 * Extracted SA payload bytes
61 */
62 chunk_t sa_payload;
63
64 /**
65 * DH exchange
66 */
67 diffie_hellman_t *dh;
68
69 /**
70 * Keymat derivation (from SA)
71 */
72 keymat_v1_t *keymat;
73
74 /**
75 * Received public DH value from peer
76 */
77 chunk_t dh_value;
78
79 /**
80 * Initiators nonce
81 */
82 chunk_t nonce_i;
83
84 /**
85 * Responder nonce
86 */
87 chunk_t nonce_r;
88 };
89
90 /**
91 * Get the first authentcation config from peer config
92 */
93 static auth_cfg_t *get_auth_cfg(peer_cfg_t *peer_cfg, bool local)
94 {
95 enumerator_t *enumerator;
96 auth_cfg_t *cfg = NULL;
97
98 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
99 enumerator->enumerate(enumerator, &cfg);
100 enumerator->destroy(enumerator);
101 return cfg;
102 }
103
104 /**
105 * Lookup a shared secret for this IKE_SA
106 */
107 static shared_key_t *lookup_shared_key(private_phase1_t *this,
108 peer_cfg_t *peer_cfg)
109 {
110 host_t *me, *other;
111 identification_t *my_id, *other_id;
112 shared_key_t *shared_key = NULL;
113 auth_cfg_t *my_auth, *other_auth;
114 enumerator_t *enumerator;
115
116 /* try to get a PSK for IP addresses */
117 me = this->ike_sa->get_my_host(this->ike_sa);
118 other = this->ike_sa->get_other_host(this->ike_sa);
119 my_id = identification_create_from_sockaddr(me->get_sockaddr(me));
120 other_id = identification_create_from_sockaddr(other->get_sockaddr(other));
121 if (my_id && other_id)
122 {
123 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE,
124 my_id, other_id);
125 }
126 DESTROY_IF(my_id);
127 DESTROY_IF(other_id);
128 if (shared_key)
129 {
130 return shared_key;
131 }
132
133 if (peer_cfg)
134 { /* as initiator or aggressive responder, use identities */
135 my_auth = get_auth_cfg(peer_cfg, TRUE);
136 other_auth = get_auth_cfg(peer_cfg, FALSE);
137 if (my_auth && other_auth)
138 {
139 my_id = my_auth->get(my_auth, AUTH_RULE_IDENTITY);
140 if (peer_cfg->use_aggressive(peer_cfg))
141 {
142 other_id = this->ike_sa->get_other_id(this->ike_sa);
143 }
144 else
145 {
146 other_id = other_auth->get(other_auth, AUTH_RULE_IDENTITY);
147 }
148 if (my_id && other_id)
149 {
150 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE,
151 my_id, other_id);
152 if (!shared_key)
153 {
154 DBG1(DBG_IKE, "no shared key found for '%Y'[%H] - '%Y'[%H]",
155 my_id, me, other_id, other);
156 }
157 }
158 }
159 return shared_key;
160 }
161 /* as responder, we try to find a config by IP */
162 enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
163 me, other, NULL, NULL, IKEV1);
164 while (enumerator->enumerate(enumerator, &peer_cfg))
165 {
166 my_auth = get_auth_cfg(peer_cfg, TRUE);
167 other_auth = get_auth_cfg(peer_cfg, FALSE);
168 if (my_auth && other_auth)
169 {
170 my_id = my_auth->get(my_auth, AUTH_RULE_IDENTITY);
171 other_id = other_auth->get(other_auth, AUTH_RULE_IDENTITY);
172 if (my_id)
173 {
174 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE,
175 my_id, other_id);
176 if (shared_key)
177 {
178 break;
179 }
180 else
181 {
182 DBG1(DBG_IKE, "no shared key found for '%Y'[%H] - '%Y'[%H]",
183 my_id, me, other_id, other);
184 }
185 }
186 }
187 }
188 enumerator->destroy(enumerator);
189 if (!peer_cfg)
190 {
191 DBG1(DBG_IKE, "no shared key found for %H - %H", me, other);
192 }
193 return shared_key;
194 }
195
196 METHOD(phase1_t, create_hasher, bool,
197 private_phase1_t *this)
198 {
199 return this->keymat->create_hasher(this->keymat,
200 this->ike_sa->get_proposal(this->ike_sa));
201 }
202
203 METHOD(phase1_t, create_dh, bool,
204 private_phase1_t *this, diffie_hellman_group_t group)
205 {
206 this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, group);
207 return this->dh != NULL;
208 }
209
210 METHOD(phase1_t, derive_keys, bool,
211 private_phase1_t *this, peer_cfg_t *peer_cfg, auth_method_t method)
212 {
213 shared_key_t *shared_key = NULL;
214
215 switch (method)
216 {
217 case AUTH_PSK:
218 case AUTH_XAUTH_INIT_PSK:
219 case AUTH_XAUTH_RESP_PSK:
220 shared_key = lookup_shared_key(this, peer_cfg);
221 if (!shared_key)
222 {
223 return FALSE;
224 }
225 break;
226 default:
227 break;
228 }
229
230 if (!this->keymat->derive_ike_keys(this->keymat,
231 this->ike_sa->get_proposal(this->ike_sa),
232 this->dh, this->dh_value, this->nonce_i, this->nonce_r,
233 this->ike_sa->get_id(this->ike_sa), method, shared_key))
234 {
235 DESTROY_IF(shared_key);
236 DBG1(DBG_IKE, "key derivation for %N failed", auth_method_names, method);
237 return FALSE;
238 }
239 charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, this->dh_value,
240 this->nonce_i, this->nonce_r, NULL, shared_key);
241 DESTROY_IF(shared_key);
242 return TRUE;
243 }
244
245 /**
246 * Check if a peer skipped authentication by using Hybrid authentication
247 */
248 static bool skipped_auth(private_phase1_t *this,
249 auth_method_t method, bool local)
250 {
251 bool initiator;
252
253 initiator = local == this->initiator;
254 if (initiator && method == AUTH_HYBRID_INIT_RSA)
255 {
256 return TRUE;
257 }
258 if (!initiator && method == AUTH_HYBRID_RESP_RSA)
259 {
260 return TRUE;
261 }
262 return FALSE;
263 }
264
265 /**
266 * Check if remote authentication constraints fulfilled
267 */
268 static bool check_constraints(private_phase1_t *this, auth_method_t method)
269 {
270 identification_t *id;
271 auth_cfg_t *auth, *cfg;
272 peer_cfg_t *peer_cfg;
273
274 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
275 /* auth identity to comply */
276 id = this->ike_sa->get_other_id(this->ike_sa);
277 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
278 if (skipped_auth(this, method, FALSE))
279 {
280 return TRUE;
281 }
282 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
283 cfg = get_auth_cfg(peer_cfg, FALSE);
284 return cfg && auth->complies(auth, cfg, TRUE);
285 }
286
287 /**
288 * Save authentication information after authentication succeeded
289 */
290 static void save_auth_cfg(private_phase1_t *this,
291 auth_method_t method, bool local)
292 {
293 auth_cfg_t *auth;
294
295 if (skipped_auth(this, method, local))
296 {
297 return;
298 }
299 auth = auth_cfg_create();
300 /* for local config, we _copy_ entires from the config, as it contains
301 * certificates we must send later. */
302 auth->merge(auth, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
303 this->ike_sa->add_auth_cfg(this->ike_sa, local, auth);
304 }
305
306 /**
307 * Create an authenticator instance
308 */
309 static authenticator_t* create_authenticator(private_phase1_t *this,
310 auth_method_t method, chunk_t id)
311 {
312 authenticator_t *authenticator;
313
314 authenticator = authenticator_create_v1(this->ike_sa, this->initiator,
315 method, this->dh, this->dh_value, this->sa_payload, id);
316 if (!authenticator)
317 {
318 DBG1(DBG_IKE, "negotiated authentication method %N not supported",
319 auth_method_names, method);
320 }
321 return authenticator;
322 }
323
324 METHOD(phase1_t, verify_auth, bool,
325 private_phase1_t *this, auth_method_t method, message_t *message,
326 chunk_t id_data)
327 {
328 authenticator_t *authenticator;
329 status_t status;
330
331 authenticator = create_authenticator(this, method, id_data);
332 if (authenticator)
333 {
334 status = authenticator->process(authenticator, message);
335 authenticator->destroy(authenticator);
336 if (status == SUCCESS && check_constraints(this, method))
337 {
338 save_auth_cfg(this, method, FALSE);
339 return TRUE;
340 }
341 }
342 return FALSE;
343 }
344
345 METHOD(phase1_t, build_auth, bool,
346 private_phase1_t *this, auth_method_t method, message_t *message,
347 chunk_t id_data)
348 {
349 authenticator_t *authenticator;
350 status_t status;
351
352 authenticator = create_authenticator(this, method, id_data);
353 if (authenticator)
354 {
355 status = authenticator->build(authenticator, message);
356 authenticator->destroy(authenticator);
357 if (status == SUCCESS)
358 {
359 save_auth_cfg(this, method, TRUE);
360 return TRUE;
361 }
362 }
363 return FALSE;
364 }
365
366 /**
367 * Get the two auth classes from local or remote config
368 */
369 static void get_auth_class(peer_cfg_t *peer_cfg, bool local,
370 auth_class_t *c1, auth_class_t *c2)
371 {
372 enumerator_t *enumerator;
373 auth_cfg_t *auth;
374
375 *c1 = *c2 = AUTH_CLASS_ANY;
376
377 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
378 while (enumerator->enumerate(enumerator, &auth))
379 {
380 if (*c1 == AUTH_CLASS_ANY)
381 {
382 *c1 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
383 }
384 else
385 {
386 *c2 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
387 break;
388 }
389 }
390 enumerator->destroy(enumerator);
391 }
392
393 /**
394 * Select an auth method to use by checking what key we have
395 */
396 static auth_method_t get_pubkey_method(private_phase1_t *this, auth_cfg_t *auth)
397 {
398 auth_method_t method = AUTH_NONE;
399 identification_t *id;
400 private_key_t *private;
401
402 if (auth)
403 {
404 id = (identification_t*)auth->get(auth, AUTH_RULE_IDENTITY);
405 if (id)
406 {
407 private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, NULL);
408 if (private)
409 {
410 switch (private->get_type(private))
411 {
412 case KEY_RSA:
413 method = AUTH_RSA;
414 break;
415 case KEY_ECDSA:
416 switch (private->get_keysize(private))
417 {
418 case 256:
419 method = AUTH_ECDSA_256;
420 break;
421 case 384:
422 method = AUTH_ECDSA_384;
423 break;
424 case 521:
425 method = AUTH_ECDSA_521;
426 break;
427 default:
428 DBG1(DBG_IKE, "%d bit ECDSA private key size not "
429 "supported", private->get_keysize(private));
430 break;
431 }
432 break;
433 default:
434 DBG1(DBG_IKE, "private key of type %N not supported",
435 key_type_names, private->get_type(private));
436 break;
437 }
438 private->destroy(private);
439 }
440 else
441 {
442 DBG1(DBG_IKE, "no private key found for '%Y'", id);
443 }
444 }
445 }
446 return method;
447 }
448
449 /**
450 * Calculate authentication method from a peer config
451 */
452 static auth_method_t calc_auth_method(private_phase1_t *this,
453 peer_cfg_t *peer_cfg)
454 {
455 auth_class_t i1, i2, r1, r2;
456
457 get_auth_class(peer_cfg, this->initiator, &i1, &i2);
458 get_auth_class(peer_cfg, !this->initiator, &r1, &r2);
459
460 if (i1 == AUTH_CLASS_PUBKEY && r1 == AUTH_CLASS_PUBKEY)
461 {
462 if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
463 {
464 /* for any pubkey method, return RSA */
465 return AUTH_RSA;
466 }
467 if (i2 == AUTH_CLASS_XAUTH)
468 {
469 return AUTH_XAUTH_INIT_RSA;
470 }
471 if (r2 == AUTH_CLASS_XAUTH)
472 {
473 return AUTH_XAUTH_RESP_RSA;
474 }
475 }
476 if (i1 == AUTH_CLASS_PSK && r1 == AUTH_CLASS_PSK)
477 {
478 if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
479 {
480 return AUTH_PSK;
481 }
482 if (i2 == AUTH_CLASS_XAUTH)
483 {
484 return AUTH_XAUTH_INIT_PSK;
485 }
486 if (r2 == AUTH_CLASS_XAUTH)
487 {
488 return AUTH_XAUTH_RESP_PSK;
489 }
490 }
491 if (i1 == AUTH_CLASS_XAUTH && r1 == AUTH_CLASS_PUBKEY &&
492 i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
493 {
494 return AUTH_HYBRID_INIT_RSA;
495 }
496 return AUTH_NONE;
497 }
498
499 METHOD(phase1_t, get_auth_method, auth_method_t,
500 private_phase1_t *this, peer_cfg_t *peer_cfg)
501 {
502 auth_method_t method;
503
504 method = calc_auth_method(this, peer_cfg);
505 if (method == AUTH_RSA)
506 {
507 return get_pubkey_method(this, get_auth_cfg(peer_cfg, TRUE));
508 }
509 return method;
510 }
511
512 /**
513 * Check if a peer config can be used with a given auth method
514 */
515 static bool check_auth_method(private_phase1_t *this, peer_cfg_t *peer_cfg,
516 auth_method_t given)
517 {
518 auth_method_t method;
519
520 method = calc_auth_method(this, peer_cfg);
521 switch (given)
522 {
523 case AUTH_ECDSA_256:
524 case AUTH_ECDSA_384:
525 case AUTH_ECDSA_521:
526 return method == AUTH_RSA;
527 default:
528 return method == given;
529 }
530 }
531
532 METHOD(phase1_t, select_config, peer_cfg_t*,
533 private_phase1_t *this, auth_method_t method, bool aggressive,
534 identification_t *id)
535 {
536 enumerator_t *enumerator;
537 peer_cfg_t *current;
538 host_t *me, *other;
539
540 if (this->peer_cfg)
541 { /* try to find an alternative config */
542 if (this->candidates->remove_first(this->candidates,
543 (void**)&current) != SUCCESS)
544 {
545 DBG1(DBG_CFG, "no alternative config found");
546 return NULL;
547 }
548 DBG1(DBG_CFG, "switching to peer config '%s'",
549 current->get_name(current));
550 return current;
551 }
552
553 me = this->ike_sa->get_my_host(this->ike_sa);
554 other = this->ike_sa->get_other_host(this->ike_sa);
555 DBG1(DBG_CFG, "looking for %N peer configs matching %H...%H[%Y]",
556 auth_method_names, method, me, other, id);
557 enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
558 me, other, NULL, id, IKEV1);
559 while (enumerator->enumerate(enumerator, &current))
560 {
561 if (check_auth_method(this, current, method) &&
562 current->use_aggressive(current) == aggressive)
563 {
564 current->get_ref(current);
565 if (!this->peer_cfg)
566 {
567 this->peer_cfg = current;
568 }
569 else
570 {
571 this->candidates->insert_last(this->candidates, current);
572 }
573 }
574 }
575 enumerator->destroy(enumerator);
576
577 if (this->peer_cfg)
578 {
579 DBG1(DBG_CFG, "selected peer config \"%s\"",
580 this->peer_cfg->get_name(this->peer_cfg));
581 return this->peer_cfg->get_ref(this->peer_cfg);
582 }
583 DBG1(DBG_IKE, "no peer config found");
584 return NULL;
585 }
586
587 METHOD(phase1_t, get_id, identification_t*,
588 private_phase1_t *this, peer_cfg_t *peer_cfg, bool local)
589 {
590 auth_cfg_t *auth;
591
592 auth = get_auth_cfg(peer_cfg, local);
593 if (auth)
594 {
595 return auth->get(auth, AUTH_RULE_IDENTITY);
596 }
597 return NULL;
598 }
599
600 METHOD(phase1_t, has_virtual_ip, bool,
601 private_phase1_t *this, peer_cfg_t *peer_cfg)
602 {
603 enumerator_t *enumerator;
604 bool found = FALSE;
605 host_t *host;
606
607 enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
608 found = enumerator->enumerate(enumerator, &host);
609 enumerator->destroy(enumerator);
610
611 return found;
612 }
613
614 METHOD(phase1_t, save_sa_payload, bool,
615 private_phase1_t *this, message_t *message)
616 {
617 enumerator_t *enumerator;
618 payload_t *payload, *sa = NULL;
619 chunk_t data;
620 size_t offset = IKE_HEADER_LENGTH;
621
622 enumerator = message->create_payload_enumerator(message);
623 while (enumerator->enumerate(enumerator, &payload))
624 {
625 if (payload->get_type(payload) == SECURITY_ASSOCIATION_V1)
626 {
627 sa = payload;
628 break;
629 }
630 else
631 {
632 offset += payload->get_length(payload);
633 }
634 }
635 enumerator->destroy(enumerator);
636
637 data = message->get_packet_data(message);
638 if (sa && data.len >= offset + sa->get_length(sa))
639 {
640 /* Get SA payload without 4 byte fixed header */
641 data = chunk_skip(data, offset);
642 data.len = sa->get_length(sa);
643 data = chunk_skip(data, 4);
644 this->sa_payload = chunk_clone(data);
645 return TRUE;
646 }
647 DBG1(DBG_IKE, "unable to extract SA payload encoding");
648 return FALSE;
649 }
650
651 METHOD(phase1_t, add_nonce_ke, bool,
652 private_phase1_t *this, message_t *message)
653 {
654 nonce_payload_t *nonce_payload;
655 ke_payload_t *ke_payload;
656 nonce_gen_t *nonceg;
657 chunk_t nonce;
658
659 ke_payload = ke_payload_create_from_diffie_hellman(KEY_EXCHANGE_V1, this->dh);
660 message->add_payload(message, &ke_payload->payload_interface);
661
662 nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
663 if (!nonceg)
664 {
665 DBG1(DBG_IKE, "no nonce generator found to create nonce");
666 return FALSE;
667 }
668 if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &nonce))
669 {
670 DBG1(DBG_IKE, "nonce allocation failed");
671 nonceg->destroy(nonceg);
672 return FALSE;
673 }
674 nonceg->destroy(nonceg);
675
676 nonce_payload = nonce_payload_create(NONCE_V1);
677 nonce_payload->set_nonce(nonce_payload, nonce);
678 message->add_payload(message, &nonce_payload->payload_interface);
679
680 if (this->initiator)
681 {
682 this->nonce_i = nonce;
683 }
684 else
685 {
686 this->nonce_r = nonce;
687 }
688 return TRUE;
689 }
690
691 METHOD(phase1_t, get_nonce_ke, bool,
692 private_phase1_t *this, message_t *message)
693 {
694 nonce_payload_t *nonce_payload;
695 ke_payload_t *ke_payload;
696
697 ke_payload = (ke_payload_t*)message->get_payload(message, KEY_EXCHANGE_V1);
698 if (!ke_payload)
699 {
700 DBG1(DBG_IKE, "KE payload missing in message");
701 return FALSE;
702 }
703 this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload));
704 this->dh->set_other_public_value(this->dh, this->dh_value);
705
706 nonce_payload = (nonce_payload_t*)message->get_payload(message, NONCE_V1);
707 if (!nonce_payload)
708 {
709 DBG1(DBG_IKE, "NONCE payload missing in message");
710 return FALSE;
711 }
712
713 if (this->initiator)
714 {
715 this->nonce_r = nonce_payload->get_nonce(nonce_payload);
716 }
717 else
718 {
719 this->nonce_i = nonce_payload->get_nonce(nonce_payload);
720 }
721 return TRUE;
722 }
723
724 METHOD(phase1_t, destroy, void,
725 private_phase1_t *this)
726 {
727 DESTROY_IF(this->peer_cfg);
728 this->candidates->destroy_offset(this->candidates,
729 offsetof(peer_cfg_t, destroy));
730 chunk_free(&this->sa_payload);
731 DESTROY_IF(this->dh);
732 free(this->dh_value.ptr);
733 free(this->nonce_i.ptr);
734 free(this->nonce_r.ptr);
735 free(this);
736 }
737
738 /**
739 * See header
740 */
741 phase1_t *phase1_create(ike_sa_t *ike_sa, bool initiator)
742 {
743 private_phase1_t *this;
744
745 INIT(this,
746 .public = {
747 .create_hasher = _create_hasher,
748 .create_dh = _create_dh,
749 .derive_keys = _derive_keys,
750 .get_auth_method = _get_auth_method,
751 .get_id = _get_id,
752 .select_config = _select_config,
753 .has_virtual_ip = _has_virtual_ip,
754 .verify_auth = _verify_auth,
755 .build_auth = _build_auth,
756 .save_sa_payload = _save_sa_payload,
757 .add_nonce_ke = _add_nonce_ke,
758 .get_nonce_ke = _get_nonce_ke,
759 .destroy = _destroy,
760 },
761 .candidates = linked_list_create(),
762 .ike_sa = ike_sa,
763 .initiator = initiator,
764 .keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa),
765 );
766
767 return &this->public;
768 }