Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/authenticators/psk_authenticator.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2018 Tobias Brunner
3: * Copyright (C) 2005-2009 Martin Willi
4: * Copyright (C) 2005 Jan Hutter
5: * HSR Hochschule fuer Technik Rapperswil
6: *
7: * This program is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2 of the License, or (at your
10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: * for more details.
16: */
17:
18: #include "psk_authenticator.h"
19:
20: #include <daemon.h>
21: #include <encoding/payloads/auth_payload.h>
22: #include <sa/ikev2/keymat_v2.h>
23:
24: typedef struct private_psk_authenticator_t private_psk_authenticator_t;
25:
26: /**
27: * Private data of an psk_authenticator_t object.
28: */
29: struct private_psk_authenticator_t {
30:
31: /**
32: * Public authenticator_t interface.
33: */
34: psk_authenticator_t public;
35:
36: /**
37: * Assigned IKE_SA
38: */
39: ike_sa_t *ike_sa;
40:
41: /**
42: * nonce to include in AUTH calculation
43: */
44: chunk_t nonce;
45:
46: /**
47: * IKE_SA_INIT message data to include in AUTH calculation
48: */
49: chunk_t ike_sa_init;
50:
51: /**
52: * Reserved bytes of ID payload
53: */
54: char reserved[3];
55:
56: /**
57: * PPK to use
58: */
59: chunk_t ppk;
60:
61: /**
62: * Add a NO_PPK_AUTH notify
63: */
64: bool no_ppk_auth;
65: };
66:
67: METHOD(authenticator_t, build, status_t,
68: private_psk_authenticator_t *this, message_t *message)
69: {
70: identification_t *my_id, *other_id;
71: auth_payload_t *auth_payload;
72: shared_key_t *key;
73: chunk_t auth_data;
74: keymat_v2_t *keymat;
75:
76: keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
77: my_id = this->ike_sa->get_my_id(this->ike_sa);
78: other_id = this->ike_sa->get_other_id(this->ike_sa);
79: DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N",
80: my_id, auth_method_names, AUTH_PSK);
81: key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE, my_id, other_id);
82: if (!key)
83: {
84: DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id);
85: return NOT_FOUND;
86: }
87: if (!keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init, this->nonce,
88: key->get_key(key), this->ppk, my_id,
89: this->reserved, &auth_data))
90: {
91: key->destroy(key);
92: return FAILED;
93: }
94:
95: DBG2(DBG_IKE, "successfully created shared key MAC");
96: auth_payload = auth_payload_create();
97: auth_payload->set_auth_method(auth_payload, AUTH_PSK);
98: auth_payload->set_data(auth_payload, auth_data);
99: chunk_free(&auth_data);
100: message->add_payload(message, (payload_t*)auth_payload);
101:
102: if (this->no_ppk_auth)
103: {
104: if (!keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init, this->nonce,
105: key->get_key(key), chunk_empty, my_id,
106: this->reserved, &auth_data))
107: {
108: DBG1(DBG_IKE, "failed adding NO_PPK_AUTH notify");
109: key->destroy(key);
110: return SUCCESS;
111: }
112: DBG2(DBG_IKE, "successfully created shared key MAC without PPK");
113: message->add_notify(message, FALSE, NO_PPK_AUTH, auth_data);
114: chunk_free(&auth_data);
115: }
116: key->destroy(key);
117: return SUCCESS;
118: }
119:
120: METHOD(authenticator_t, process, status_t,
121: private_psk_authenticator_t *this, message_t *message)
122: {
123: chunk_t auth_data, recv_auth_data;
124: identification_t *my_id, *other_id;
125: auth_payload_t *auth_payload;
126: notify_payload_t *notify;
127: auth_cfg_t *auth;
128: shared_key_t *key;
129: enumerator_t *enumerator;
130: bool authenticated = FALSE;
131: int keys_found = 0;
132: keymat_v2_t *keymat;
133:
134: auth_payload = (auth_payload_t*)message->get_payload(message, PLV2_AUTH);
135: if (!auth_payload)
136: {
137: return FAILED;
138: }
139: recv_auth_data = auth_payload->get_data(auth_payload);
140:
141: if (this->ike_sa->supports_extension(this->ike_sa, EXT_PPK) &&
142: !this->ppk.ptr)
143: { /* look for a NO_PPK_AUTH notify if we have no PPK */
144: notify = message->get_notify(message, NO_PPK_AUTH);
145: if (notify)
146: {
147: DBG1(DBG_IKE, "no PPK available, using NO_PPK_AUTH notify");
148: recv_auth_data = notify->get_notification_data(notify);
149: }
150: }
151:
152: keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
153: my_id = this->ike_sa->get_my_id(this->ike_sa);
154: other_id = this->ike_sa->get_other_id(this->ike_sa);
155: enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
156: SHARED_IKE, my_id, other_id);
157: while (!authenticated && enumerator->enumerate(enumerator, &key, NULL, NULL))
158: {
159: keys_found++;
160:
161: if (!keymat->get_psk_sig(keymat, TRUE, this->ike_sa_init, this->nonce,
162: key->get_key(key), this->ppk, other_id,
163: this->reserved, &auth_data))
164: {
165: continue;
166: }
167: if (auth_data.len && chunk_equals_const(auth_data, recv_auth_data))
168: {
169: DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
170: other_id, auth_method_names, AUTH_PSK);
171: authenticated = TRUE;
172: }
173: chunk_free(&auth_data);
174: }
175: enumerator->destroy(enumerator);
176:
177: if (!authenticated)
178: {
179: if (keys_found == 0)
180: {
181: DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id);
182: return NOT_FOUND;
183: }
184: DBG1(DBG_IKE, "tried %d shared key%s for '%Y' - '%Y', but MAC mismatched",
185: keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
186: return FAILED;
187: }
188:
189: auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
190: auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
191: return SUCCESS;
192: }
193:
194: METHOD(authenticator_t, use_ppk, void,
195: private_psk_authenticator_t *this, chunk_t ppk, bool no_ppk_auth)
196: {
197: this->ppk = ppk;
198: this->no_ppk_auth = no_ppk_auth;
199: }
200:
201: METHOD(authenticator_t, destroy, void,
202: private_psk_authenticator_t *this)
203: {
204: free(this);
205: }
206:
207: /*
208: * Described in header.
209: */
210: psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa,
211: chunk_t received_nonce, chunk_t sent_init,
212: char reserved[3])
213: {
214: private_psk_authenticator_t *this;
215:
216: INIT(this,
217: .public = {
218: .authenticator = {
219: .build = _build,
220: .process = (void*)return_failed,
221: .use_ppk = _use_ppk,
222: .is_mutual = (void*)return_false,
223: .destroy = _destroy,
224: },
225: },
226: .ike_sa = ike_sa,
227: .ike_sa_init = sent_init,
228: .nonce = received_nonce,
229: );
230: memcpy(this->reserved, reserved, sizeof(this->reserved));
231:
232: return &this->public;
233: }
234:
235: /*
236: * Described in header.
237: */
238: psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa,
239: chunk_t sent_nonce, chunk_t received_init,
240: char reserved[3])
241: {
242: private_psk_authenticator_t *this;
243:
244: INIT(this,
245: .public = {
246: .authenticator = {
247: .build = (void*)return_failed,
248: .process = _process,
249: .use_ppk = _use_ppk,
250: .is_mutual = (void*)return_false,
251: .destroy = _destroy,
252: },
253: },
254: .ike_sa = ike_sa,
255: .ike_sa_init = received_init,
256: .nonce = sent_nonce,
257: );
258: memcpy(this->reserved, reserved, sizeof(this->reserved));
259:
260: return &this->public;
261: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>