2 * Copyright (C) 2012-2017 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2012 Martin Willi
6 * Copyright (C) 2012 revosec AG
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>.
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
22 #include <sa/ikev1/keymat_v1.h>
23 #include <encoding/payloads/ke_payload.h>
24 #include <encoding/payloads/nonce_payload.h>
25 #include <collections/linked_list.h>
27 typedef struct private_phase1_t private_phase1_t
;
30 * Private data of an phase1_t object.
32 struct private_phase1_t
{
35 * Public phase1_t interface.
45 * Currently selected peer config
50 * Other possible peer config candidates
52 linked_list_t
*candidates
;
60 * Extracted SA payload bytes
70 * Keymat derivation (from SA)
75 * Received public DH value from peer
91 * Get the first authentcation config from peer config
93 static auth_cfg_t
*get_auth_cfg(peer_cfg_t
*peer_cfg
, bool local
)
95 enumerator_t
*enumerator
;
96 auth_cfg_t
*cfg
= NULL
;
98 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, local
);
99 enumerator
->enumerate(enumerator
, &cfg
);
100 enumerator
->destroy(enumerator
);
105 * Find a shared key for the given identities
107 static shared_key_t
*find_shared_key(identification_t
*my_id
, host_t
*me
,
108 identification_t
*other_id
, host_t
*other
)
110 identification_t
*any_id
= NULL
;
111 shared_key_t
*shared_key
;
115 any_id
= identification_create_from_encoding(ID_ANY
, chunk_empty
);
118 shared_key
= lib
->credmgr
->get_shared(lib
->credmgr
, SHARED_IKE
,
122 DBG1(DBG_IKE
, "no shared key found for '%Y'[%H] - '%Y'[%H]",
123 my_id
, me
, other_id
, other
);
130 * Lookup a shared secret for this IKE_SA
132 static shared_key_t
*lookup_shared_key(private_phase1_t
*this,
133 peer_cfg_t
*peer_cfg
)
136 identification_t
*my_id
, *other_id
;
137 shared_key_t
*shared_key
= NULL
;
138 auth_cfg_t
*my_auth
, *other_auth
;
139 enumerator_t
*enumerator
;
141 me
= this->ike_sa
->get_my_host(this->ike_sa
);
142 other
= this->ike_sa
->get_other_host(this->ike_sa
);
145 { /* as initiator or aggressive responder, use identities */
146 my_auth
= get_auth_cfg(peer_cfg
, TRUE
);
147 other_auth
= get_auth_cfg(peer_cfg
, FALSE
);
148 if (my_auth
&& other_auth
)
150 my_id
= my_auth
->get(my_auth
, AUTH_RULE_IDENTITY
);
151 if (peer_cfg
->use_aggressive(peer_cfg
))
153 other_id
= this->ike_sa
->get_other_id(this->ike_sa
);
157 other_id
= other_auth
->get(other_auth
, AUTH_RULE_IDENTITY
);
161 shared_key
= find_shared_key(my_id
, me
, other_id
, other
);
166 { /* as responder, we try to find a config by IP addresses and use the
167 * configured identities to find the PSK */
168 enumerator
= charon
->backends
->create_peer_cfg_enumerator(
169 charon
->backends
, me
, other
, NULL
, NULL
, IKEV1
);
170 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
172 my_auth
= get_auth_cfg(peer_cfg
, TRUE
);
173 other_auth
= get_auth_cfg(peer_cfg
, FALSE
);
174 if (my_auth
&& other_auth
)
176 my_id
= my_auth
->get(my_auth
, AUTH_RULE_IDENTITY
);
177 other_id
= other_auth
->get(other_auth
, AUTH_RULE_IDENTITY
);
180 shared_key
= find_shared_key(my_id
, me
, other_id
, other
);
188 enumerator
->destroy(enumerator
);
191 { /* try to get a PSK for IP addresses */
192 my_id
= identification_create_from_sockaddr(me
->get_sockaddr(me
));
193 other_id
= identification_create_from_sockaddr(
194 other
->get_sockaddr(other
));
195 if (my_id
&& other_id
)
197 shared_key
= lib
->credmgr
->get_shared(lib
->credmgr
, SHARED_IKE
,
201 DESTROY_IF(other_id
);
204 DBG1(DBG_IKE
, "no shared key found for %H - %H", me
, other
);
210 METHOD(phase1_t
, create_hasher
, bool,
211 private_phase1_t
*this)
213 return this->keymat
->create_hasher(this->keymat
,
214 this->ike_sa
->get_proposal(this->ike_sa
));
217 METHOD(phase1_t
, create_dh
, bool,
218 private_phase1_t
*this, diffie_hellman_group_t group
)
220 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
, group
);
221 return this->dh
!= NULL
;
224 METHOD(phase1_t
, derive_keys
, bool,
225 private_phase1_t
*this, peer_cfg_t
*peer_cfg
, auth_method_t method
)
227 shared_key_t
*shared_key
= NULL
;
232 case AUTH_XAUTH_INIT_PSK
:
233 case AUTH_XAUTH_RESP_PSK
:
234 shared_key
= lookup_shared_key(this, peer_cfg
);
244 if (!this->keymat
->derive_ike_keys(this->keymat
,
245 this->ike_sa
->get_proposal(this->ike_sa
),
246 this->dh
, this->dh_value
, this->nonce_i
, this->nonce_r
,
247 this->ike_sa
->get_id(this->ike_sa
), method
, shared_key
))
249 DESTROY_IF(shared_key
);
250 DBG1(DBG_IKE
, "key derivation for %N failed", auth_method_names
, method
);
253 charon
->bus
->ike_keys(charon
->bus
, this->ike_sa
, this->dh
, this->dh_value
,
254 this->nonce_i
, this->nonce_r
, NULL
, shared_key
,
256 DESTROY_IF(shared_key
);
261 * Check if a peer skipped authentication by using Hybrid authentication
263 static bool skipped_auth(private_phase1_t
*this,
264 auth_method_t method
, bool local
)
268 initiator
= local
== this->initiator
;
269 if (initiator
&& method
== AUTH_HYBRID_INIT_RSA
)
273 if (!initiator
&& method
== AUTH_HYBRID_RESP_RSA
)
281 * Check if remote authentication constraints fulfilled
283 static bool check_constraints(private_phase1_t
*this, auth_method_t method
)
285 identification_t
*id
;
286 auth_cfg_t
*auth
, *cfg
;
287 peer_cfg_t
*peer_cfg
;
289 auth
= this->ike_sa
->get_auth_cfg(this->ike_sa
, FALSE
);
290 /* auth identity to comply */
291 id
= this->ike_sa
->get_other_id(this->ike_sa
);
292 auth
->add(auth
, AUTH_RULE_IDENTITY
, id
->clone(id
));
293 if (skipped_auth(this, method
, FALSE
))
297 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
298 cfg
= get_auth_cfg(peer_cfg
, FALSE
);
299 return cfg
&& auth
->complies(auth
, cfg
, TRUE
);
303 * Save authentication information after authentication succeeded
305 static void save_auth_cfg(private_phase1_t
*this,
306 auth_method_t method
, bool local
)
310 if (skipped_auth(this, method
, local
))
314 auth
= auth_cfg_create();
315 /* for local config, we _copy_ entries from the config, as it contains
316 * certificates we must send later. */
317 auth
->merge(auth
, this->ike_sa
->get_auth_cfg(this->ike_sa
, local
), local
);
318 this->ike_sa
->add_auth_cfg(this->ike_sa
, local
, auth
);
322 * Create an authenticator instance
324 static authenticator_t
* create_authenticator(private_phase1_t
*this,
325 auth_method_t method
, chunk_t id
)
327 authenticator_t
*authenticator
;
329 authenticator
= authenticator_create_v1(this->ike_sa
, this->initiator
,
330 method
, this->dh
, this->dh_value
, this->sa_payload
, id
);
333 DBG1(DBG_IKE
, "negotiated authentication method %N not supported",
334 auth_method_names
, method
);
336 return authenticator
;
339 METHOD(phase1_t
, verify_auth
, bool,
340 private_phase1_t
*this, auth_method_t method
, message_t
*message
,
343 authenticator_t
*authenticator
;
346 authenticator
= create_authenticator(this, method
, id_data
);
349 status
= authenticator
->process(authenticator
, message
);
350 authenticator
->destroy(authenticator
);
351 if (status
== SUCCESS
&& check_constraints(this, method
))
353 save_auth_cfg(this, method
, FALSE
);
360 METHOD(phase1_t
, build_auth
, bool,
361 private_phase1_t
*this, auth_method_t method
, message_t
*message
,
364 authenticator_t
*authenticator
;
367 authenticator
= create_authenticator(this, method
, id_data
);
370 status
= authenticator
->build(authenticator
, message
);
371 authenticator
->destroy(authenticator
);
372 if (status
== SUCCESS
)
374 save_auth_cfg(this, method
, TRUE
);
382 * Get the two auth classes from local or remote config
384 static void get_auth_class(peer_cfg_t
*peer_cfg
, bool local
,
385 auth_class_t
*c1
, auth_class_t
*c2
)
387 enumerator_t
*enumerator
;
390 *c1
= *c2
= AUTH_CLASS_ANY
;
392 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, local
);
393 while (enumerator
->enumerate(enumerator
, &auth
))
395 if (*c1
== AUTH_CLASS_ANY
)
397 *c1
= (uintptr_t)auth
->get(auth
, AUTH_RULE_AUTH_CLASS
);
401 *c2
= (uintptr_t)auth
->get(auth
, AUTH_RULE_AUTH_CLASS
);
405 enumerator
->destroy(enumerator
);
409 * Select an auth method to use by checking what key we have
411 static auth_method_t
get_pubkey_method(private_phase1_t
*this, auth_cfg_t
*auth
)
413 auth_method_t method
= AUTH_NONE
;
414 identification_t
*id
;
415 private_key_t
*private;
419 id
= (identification_t
*)auth
->get(auth
, AUTH_RULE_IDENTITY
);
422 private = lib
->credmgr
->get_private(lib
->credmgr
, KEY_ANY
, id
, NULL
);
425 switch (private->get_type(private))
431 switch (private->get_keysize(private))
434 method
= AUTH_ECDSA_256
;
437 method
= AUTH_ECDSA_384
;
440 method
= AUTH_ECDSA_521
;
443 DBG1(DBG_IKE
, "%d bit ECDSA private key size not "
444 "supported", private->get_keysize(private));
449 DBG1(DBG_IKE
, "private key of type %N not supported",
450 key_type_names
, private->get_type(private));
453 private->destroy(private);
457 DBG1(DBG_IKE
, "no private key found for '%Y'", id
);
465 * Calculate authentication method from a peer config
467 static auth_method_t
calc_auth_method(private_phase1_t
*this,
468 peer_cfg_t
*peer_cfg
)
470 auth_class_t i1
, i2
, r1
, r2
;
472 get_auth_class(peer_cfg
, this->initiator
, &i1
, &i2
);
473 get_auth_class(peer_cfg
, !this->initiator
, &r1
, &r2
);
475 if (i1
== AUTH_CLASS_PUBKEY
&& r1
== AUTH_CLASS_PUBKEY
)
477 if (i2
== AUTH_CLASS_ANY
&& r2
== AUTH_CLASS_ANY
)
479 /* for any pubkey method, return RSA */
482 if (i2
== AUTH_CLASS_XAUTH
)
484 return AUTH_XAUTH_INIT_RSA
;
486 if (r2
== AUTH_CLASS_XAUTH
)
488 return AUTH_XAUTH_RESP_RSA
;
491 if (i1
== AUTH_CLASS_PSK
&& r1
== AUTH_CLASS_PSK
)
493 if (i2
== AUTH_CLASS_ANY
&& r2
== AUTH_CLASS_ANY
)
497 if (i2
== AUTH_CLASS_XAUTH
)
499 return AUTH_XAUTH_INIT_PSK
;
501 if (r2
== AUTH_CLASS_XAUTH
)
503 return AUTH_XAUTH_RESP_PSK
;
506 if (i1
== AUTH_CLASS_XAUTH
&& r1
== AUTH_CLASS_PUBKEY
&&
507 i2
== AUTH_CLASS_ANY
&& r2
== AUTH_CLASS_ANY
)
509 return AUTH_HYBRID_INIT_RSA
;
514 METHOD(phase1_t
, get_auth_method
, auth_method_t
,
515 private_phase1_t
*this, peer_cfg_t
*peer_cfg
)
517 auth_method_t method
;
519 method
= calc_auth_method(this, peer_cfg
);
520 if (method
== AUTH_RSA
)
522 return get_pubkey_method(this, get_auth_cfg(peer_cfg
, TRUE
));
528 * Check if a peer config can be used with a given auth method
530 static bool check_auth_method(private_phase1_t
*this, peer_cfg_t
*peer_cfg
,
533 auth_method_t method
;
535 method
= calc_auth_method(this, peer_cfg
);
541 return method
== AUTH_RSA
;
543 return method
== given
;
547 METHOD(phase1_t
, select_config
, peer_cfg_t
*,
548 private_phase1_t
*this, auth_method_t method
, bool aggressive
,
549 identification_t
*id
)
551 enumerator_t
*enumerator
;
557 { /* try to find an alternative config */
558 if (this->candidates
->remove_first(this->candidates
,
559 (void**)¤t
) != SUCCESS
)
561 DBG1(DBG_CFG
, "no alternative config found");
564 DBG1(DBG_CFG
, "switching to peer config '%s'",
565 current
->get_name(current
));
569 me
= this->ike_sa
->get_my_host(this->ike_sa
);
570 other
= this->ike_sa
->get_other_host(this->ike_sa
);
571 DBG1(DBG_CFG
, "looking for %N peer configs matching %H...%H[%Y]",
572 auth_method_names
, method
, me
, other
, id
);
573 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
574 me
, other
, NULL
, id
, IKEV1
);
575 while (enumerator
->enumerate(enumerator
, ¤t
))
577 if (check_auth_method(this, current
, method
) &&
578 current
->use_aggressive(current
) == aggressive
)
580 current
->get_ref(current
);
583 this->peer_cfg
= current
;
587 this->candidates
->insert_last(this->candidates
, current
);
595 enumerator
->destroy(enumerator
);
599 DBG1(DBG_CFG
, "selected peer config \"%s\"",
600 this->peer_cfg
->get_name(this->peer_cfg
));
601 return this->peer_cfg
->get_ref(this->peer_cfg
);
605 DBG1(DBG_IKE
, "found %d matching config%s, but none allows %N "
606 "authentication using %s Mode", unusable
, unusable
> 1 ? "s" : "",
607 auth_method_names
, method
, aggressive
? "Aggressive" : "Main");
610 DBG1(DBG_IKE
, "no peer config found");
614 METHOD(phase1_t
, get_id
, identification_t
*,
615 private_phase1_t
*this, peer_cfg_t
*peer_cfg
, bool local
)
617 identification_t
*id
= NULL
;
620 auth
= get_auth_cfg(peer_cfg
, local
);
623 id
= auth
->get(auth
, AUTH_RULE_IDENTITY
);
624 if (local
&& (!id
|| id
->get_type(id
) == ID_ANY
))
625 { /* no ID configured, use local IP address */
628 me
= this->ike_sa
->get_my_host(this->ike_sa
);
629 if (!me
->is_anyaddr(me
))
631 id
= identification_create_from_sockaddr(me
->get_sockaddr(me
));
632 auth
->add(auth
, AUTH_RULE_IDENTITY
, id
);
639 METHOD(phase1_t
, has_virtual_ip
, bool,
640 private_phase1_t
*this, peer_cfg_t
*peer_cfg
)
642 enumerator_t
*enumerator
;
646 enumerator
= peer_cfg
->create_virtual_ip_enumerator(peer_cfg
);
647 found
= enumerator
->enumerate(enumerator
, &host
);
648 enumerator
->destroy(enumerator
);
653 METHOD(phase1_t
, has_pool
, bool,
654 private_phase1_t
*this, peer_cfg_t
*peer_cfg
)
656 enumerator_t
*enumerator
;
660 enumerator
= peer_cfg
->create_pool_enumerator(peer_cfg
);
661 found
= enumerator
->enumerate(enumerator
, &pool
);
662 enumerator
->destroy(enumerator
);
667 METHOD(phase1_t
, save_sa_payload
, bool,
668 private_phase1_t
*this, message_t
*message
)
670 enumerator_t
*enumerator
;
671 payload_t
*payload
, *sa
= NULL
;
673 size_t offset
= IKE_HEADER_LENGTH
;
675 enumerator
= message
->create_payload_enumerator(message
);
676 while (enumerator
->enumerate(enumerator
, &payload
))
678 if (payload
->get_type(payload
) == PLV1_SECURITY_ASSOCIATION
)
685 offset
+= payload
->get_length(payload
);
688 enumerator
->destroy(enumerator
);
690 data
= message
->get_packet_data(message
);
691 if (sa
&& data
.len
>= offset
+ sa
->get_length(sa
))
693 /* Get SA payload without 4 byte fixed header */
694 data
= chunk_skip(data
, offset
);
695 data
.len
= sa
->get_length(sa
);
696 data
= chunk_skip(data
, 4);
697 this->sa_payload
= chunk_clone(data
);
700 DBG1(DBG_IKE
, "unable to extract SA payload encoding");
704 METHOD(phase1_t
, add_nonce_ke
, bool,
705 private_phase1_t
*this, message_t
*message
)
707 nonce_payload_t
*nonce_payload
;
708 ke_payload_t
*ke_payload
;
712 ke_payload
= ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE
,
716 DBG1(DBG_IKE
, "creating KE payload failed");
719 message
->add_payload(message
, &ke_payload
->payload_interface
);
721 nonceg
= this->keymat
->keymat
.create_nonce_gen(&this->keymat
->keymat
);
724 DBG1(DBG_IKE
, "no nonce generator found to create nonce");
727 if (!nonceg
->allocate_nonce(nonceg
, NONCE_SIZE
, &nonce
))
729 DBG1(DBG_IKE
, "nonce allocation failed");
730 nonceg
->destroy(nonceg
);
733 nonceg
->destroy(nonceg
);
735 nonce_payload
= nonce_payload_create(PLV1_NONCE
);
736 nonce_payload
->set_nonce(nonce_payload
, nonce
);
737 message
->add_payload(message
, &nonce_payload
->payload_interface
);
741 this->nonce_i
= nonce
;
745 this->nonce_r
= nonce
;
750 METHOD(phase1_t
, get_nonce_ke
, bool,
751 private_phase1_t
*this, message_t
*message
)
753 nonce_payload_t
*nonce_payload
;
754 ke_payload_t
*ke_payload
;
756 ke_payload
= (ke_payload_t
*)message
->get_payload(message
, PLV1_KEY_EXCHANGE
);
759 DBG1(DBG_IKE
, "KE payload missing in message");
762 this->dh_value
= chunk_clone(ke_payload
->get_key_exchange_data(ke_payload
));
763 if (!this->dh
->set_other_public_value(this->dh
, this->dh_value
))
765 DBG1(DBG_IKE
, "unable to apply received KE value");
769 nonce_payload
= (nonce_payload_t
*)message
->get_payload(message
, PLV1_NONCE
);
772 DBG1(DBG_IKE
, "NONCE payload missing in message");
778 this->nonce_r
= nonce_payload
->get_nonce(nonce_payload
);
782 this->nonce_i
= nonce_payload
->get_nonce(nonce_payload
);
787 METHOD(phase1_t
, destroy
, void,
788 private_phase1_t
*this)
790 DESTROY_IF(this->peer_cfg
);
791 this->candidates
->destroy_offset(this->candidates
,
792 offsetof(peer_cfg_t
, destroy
));
793 chunk_free(&this->sa_payload
);
794 DESTROY_IF(this->dh
);
795 free(this->dh_value
.ptr
);
796 free(this->nonce_i
.ptr
);
797 free(this->nonce_r
.ptr
);
804 phase1_t
*phase1_create(ike_sa_t
*ike_sa
, bool initiator
)
806 private_phase1_t
*this;
810 .create_hasher
= _create_hasher
,
811 .create_dh
= _create_dh
,
812 .derive_keys
= _derive_keys
,
813 .get_auth_method
= _get_auth_method
,
815 .select_config
= _select_config
,
816 .has_virtual_ip
= _has_virtual_ip
,
817 .has_pool
= _has_pool
,
818 .verify_auth
= _verify_auth
,
819 .build_auth
= _build_auth
,
820 .save_sa_payload
= _save_sa_payload
,
821 .add_nonce_ke
= _add_nonce_ke
,
822 .get_nonce_ke
= _get_nonce_ke
,
825 .candidates
= linked_list_create(),
827 .initiator
= initiator
,
828 .keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
),
831 return &this->public;