updated Doxyfile
[strongswan.git] / src / charon / sa / authenticators / psk_authenticator.c
1 /*
2 * Copyright (C) 2005-2008 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * $Id$
17 */
18
19 #include <string.h>
20
21 #include "psk_authenticator.h"
22
23 #include <daemon.h>
24 #include <credentials/auth_info.h>
25
26
27 typedef struct private_psk_authenticator_t private_psk_authenticator_t;
28
29 /**
30 * Private data of an psk_authenticator_t object.
31 */
32 struct private_psk_authenticator_t {
33
34 /**
35 * Public authenticator_t interface.
36 */
37 psk_authenticator_t public;
38
39 /**
40 * Assigned IKE_SA
41 */
42 ike_sa_t *ike_sa;
43 };
44
45 /**
46 * Implementation of authenticator_t.verify.
47 */
48 static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
49 chunk_t my_nonce, auth_payload_t *auth_payload)
50 {
51 chunk_t auth_data, recv_auth_data;
52 identification_t *my_id, *other_id;
53 shared_key_t *key;
54 enumerator_t *enumerator;
55 bool authenticated = FALSE;
56 int keys_found = 0;
57 keymat_t *keymat;
58
59 keymat = this->ike_sa->get_keymat(this->ike_sa);
60 recv_auth_data = auth_payload->get_data(auth_payload);
61 my_id = this->ike_sa->get_my_id(this->ike_sa);
62 other_id = this->ike_sa->get_other_id(this->ike_sa);
63 enumerator = charon->credentials->create_shared_enumerator(
64 charon->credentials, SHARED_IKE, my_id, other_id);
65 while (!authenticated && enumerator->enumerate(enumerator, &key, NULL, NULL))
66 {
67 keys_found++;
68
69 auth_data = keymat->get_psk_sig(keymat, TRUE, ike_sa_init, my_nonce,
70 key->get_key(key), other_id);
71 if (auth_data.len && chunk_equals(auth_data, recv_auth_data))
72 {
73 DBG1(DBG_IKE, "authentication of '%D' with %N successful",
74 other_id, auth_method_names, AUTH_PSK);
75 authenticated = TRUE;
76 }
77 chunk_free(&auth_data);
78 }
79 enumerator->destroy(enumerator);
80
81 if (!authenticated)
82 {
83 if (keys_found == 0)
84 {
85 DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
86 return NOT_FOUND;
87 }
88 DBG1(DBG_IKE, "tried %d shared key%s for '%D' - '%D', but MAC mismatched",
89 keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
90 return FAILED;
91 }
92 return SUCCESS;
93 }
94
95 /**
96 * Implementation of authenticator_t.build.
97 */
98 static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
99 chunk_t other_nonce, auth_payload_t **auth_payload)
100 {
101 identification_t *my_id, *other_id;
102 shared_key_t *key;
103 chunk_t auth_data;
104 keymat_t *keymat;
105
106 keymat = this->ike_sa->get_keymat(this->ike_sa);
107 my_id = this->ike_sa->get_my_id(this->ike_sa);
108 other_id = this->ike_sa->get_other_id(this->ike_sa);
109 DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
110 my_id, auth_method_names, AUTH_PSK);
111 key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
112 my_id, other_id);
113 if (key == NULL)
114 {
115 DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
116 return NOT_FOUND;
117 }
118 auth_data = keymat->get_psk_sig(keymat, FALSE, ike_sa_init, other_nonce,
119 key->get_key(key), my_id);
120 key->destroy(key);
121 DBG2(DBG_IKE, "successfully created shared key MAC");
122 *auth_payload = auth_payload_create();
123 (*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
124 (*auth_payload)->set_data(*auth_payload, auth_data);
125
126 chunk_free(&auth_data);
127 return SUCCESS;
128 }
129
130 /**
131 * Implementation of authenticator_t.destroy.
132 */
133 static void destroy(private_psk_authenticator_t *this)
134 {
135 free(this);
136 }
137
138 /*
139 * Described in header.
140 */
141 psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa)
142 {
143 private_psk_authenticator_t *this = malloc_thing(private_psk_authenticator_t);
144
145 /* public functions */
146 this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
147 this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
148 this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
149
150 /* private data */
151 this->ike_sa = ike_sa;
152
153 return &this->public;
154 }