965f70aa5544b7b7f43543ac4a8c9e94341d2b82
[strongswan.git] / src / libcharon / sa / ikev2 / authenticators / pubkey_authenticator.c
1 /*
2 * Copyright (C) 2008-2015 Tobias Brunner
3 * Copyright (C) 2005-2009 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * 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 "pubkey_authenticator.h"
19
20 #include <daemon.h>
21 #include <encoding/payloads/auth_payload.h>
22 #include <sa/ikev2/keymat_v2.h>
23 #include <asn1/asn1.h>
24 #include <asn1/oid.h>
25
26 typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
27
28 /**
29 * Private data of an pubkey_authenticator_t object.
30 */
31 struct private_pubkey_authenticator_t {
32
33 /**
34 * Public authenticator_t interface.
35 */
36 pubkey_authenticator_t public;
37
38 /**
39 * Assigned IKE_SA
40 */
41 ike_sa_t *ike_sa;
42
43 /**
44 * nonce to include in AUTH calculation
45 */
46 chunk_t nonce;
47
48 /**
49 * IKE_SA_INIT message data to include in AUTH calculation
50 */
51 chunk_t ike_sa_init;
52
53 /**
54 * Reserved bytes of ID payload
55 */
56 char reserved[3];
57
58 /**
59 * Whether to store signature schemes on remote auth configs.
60 */
61 bool store_signature_scheme;
62 };
63
64 /**
65 * Parse authentication data used for Signature Authentication as per RFC 7427
66 */
67 static bool parse_signature_auth_data(chunk_t *auth_data, key_type_t *key_type,
68 signature_scheme_t *scheme)
69 {
70 u_int8_t len;
71 int oid;
72
73 if (!auth_data->len)
74 {
75 return FALSE;
76 }
77 len = auth_data->ptr[0];
78 *auth_data = chunk_skip(*auth_data, 1);
79 /* we currently don't support schemes that require parameters */
80 oid = asn1_parse_algorithmIdentifier(*auth_data, 1, NULL);
81 *scheme = signature_scheme_from_oid(oid);
82 if (*scheme == SIGN_UNKNOWN)
83 {
84 return FALSE;
85 }
86 *key_type = key_type_from_signature_scheme(*scheme);
87 *auth_data = chunk_skip(*auth_data, len);
88 return TRUE;
89 }
90
91 /**
92 * Build authentication data used for Signature Authentication as per RFC 7427
93 */
94 static bool build_signature_auth_data(chunk_t *auth_data,
95 signature_scheme_t scheme)
96 {
97 chunk_t data;
98 u_int8_t len;
99 int oid;
100
101 oid = signature_scheme_to_oid(scheme);
102 if (oid == OID_UNKNOWN)
103 {
104 return FALSE;
105 }
106 data = asn1_algorithmIdentifier(oid);
107 len = data.len;
108 *auth_data = chunk_cat("cmm", chunk_from_thing(len), data, *auth_data);
109 return TRUE;
110 }
111
112 /**
113 * Select a signature scheme based on our configuration, the other peer's
114 * capabilities and the private key
115 */
116 static signature_scheme_t select_signature_scheme(keymat_v2_t *keymat,
117 auth_cfg_t *auth, private_key_t *private)
118 {
119 enumerator_t *enumerator;
120 signature_scheme_t selected = SIGN_UNKNOWN, scheme;
121 uintptr_t config;
122 auth_rule_t rule;
123 key_type_t key_type;
124 bool have_config = FALSE;
125
126 key_type = private->get_type(private);
127 enumerator = auth->create_enumerator(auth);
128 while (enumerator->enumerate(enumerator, &rule, &config))
129 {
130 if (rule != AUTH_RULE_SIGNATURE_SCHEME)
131 {
132 continue;
133 }
134 have_config = TRUE;
135 if (key_type == key_type_from_signature_scheme(config) &&
136 keymat->hash_algorithm_supported(keymat,
137 hasher_from_signature_scheme(config)))
138 {
139 selected = config;
140 break;
141 }
142 }
143 enumerator->destroy(enumerator);
144
145 if (selected == SIGN_UNKNOWN && !have_config)
146 {
147 /* if no specific configuration, find a scheme appropriate for the key
148 * and supported by the other peer */
149 enumerator = signature_schemes_for_key(key_type,
150 private->get_keysize(private));
151 while (enumerator->enumerate(enumerator, &scheme))
152 {
153 if (keymat->hash_algorithm_supported(keymat,
154 hasher_from_signature_scheme(scheme)))
155 {
156 selected = scheme;
157 break;
158 }
159 }
160 enumerator->destroy(enumerator);
161
162 /* for RSA we tried at least SHA-512, also try other schemes down to
163 * what we'd use with classic authentication */
164 if (selected == SIGN_UNKNOWN && key_type == KEY_RSA)
165 {
166 signature_scheme_t schemes[] = {
167 SIGN_RSA_EMSA_PKCS1_SHA384,
168 SIGN_RSA_EMSA_PKCS1_SHA256,
169 SIGN_RSA_EMSA_PKCS1_SHA1,
170 };
171 int i;
172
173 for (i = 0; i < countof(schemes); i++)
174 {
175 if (keymat->hash_algorithm_supported(keymat,
176 hasher_from_signature_scheme(schemes[i])))
177 {
178 selected = scheme;
179 break;
180 }
181 }
182 }
183 }
184 return selected;
185 }
186
187 METHOD(authenticator_t, build, status_t,
188 private_pubkey_authenticator_t *this, message_t *message)
189 {
190 chunk_t octets = chunk_empty, auth_data;
191 status_t status = FAILED;
192 private_key_t *private;
193 identification_t *id;
194 auth_cfg_t *auth;
195 auth_payload_t *auth_payload;
196 auth_method_t auth_method;
197 signature_scheme_t scheme = SIGN_UNKNOWN;
198 keymat_v2_t *keymat;
199
200 id = this->ike_sa->get_my_id(this->ike_sa);
201 auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
202 private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
203 if (private == NULL)
204 {
205 DBG1(DBG_IKE, "no private key found for '%Y'", id);
206 return NOT_FOUND;
207 }
208 keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
209
210 if (this->ike_sa->supports_extension(this->ike_sa, EXT_SIGNATURE_AUTH))
211 {
212 scheme = select_signature_scheme(keymat, auth, private);
213 auth_method = AUTH_DS;
214 if (scheme == SIGN_UNKNOWN)
215 {
216 DBG1(DBG_IKE, "no common hash algorithm found to create signature "
217 "with %N key", key_type_names, private->get_type(private));
218 return status;
219 }
220 }
221 else
222 {
223 switch (private->get_type(private))
224 {
225 case KEY_RSA:
226 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
227 auth_method = AUTH_RSA;
228 break;
229 case KEY_ECDSA:
230 /* deduct the signature scheme from the keysize */
231 switch (private->get_keysize(private))
232 {
233 case 256:
234 scheme = SIGN_ECDSA_256;
235 auth_method = AUTH_ECDSA_256;
236 break;
237 case 384:
238 scheme = SIGN_ECDSA_384;
239 auth_method = AUTH_ECDSA_384;
240 break;
241 case 521:
242 scheme = SIGN_ECDSA_521;
243 auth_method = AUTH_ECDSA_521;
244 break;
245 default:
246 DBG1(DBG_IKE, "%d bit ECDSA private key size not "
247 "supported", private->get_keysize(private));
248 return status;
249 }
250 break;
251 default:
252 DBG1(DBG_IKE, "private key of type %N not supported",
253 key_type_names, private->get_type(private));
254 return status;
255 }
256 }
257
258 if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
259 this->nonce, id, this->reserved, &octets) &&
260 private->sign(private, scheme, octets, &auth_data))
261 {
262 if (auth_method != AUTH_DS ||
263 build_signature_auth_data(&auth_data, scheme))
264 {
265 auth_payload = auth_payload_create();
266 auth_payload->set_auth_method(auth_payload, auth_method);
267 auth_payload->set_data(auth_payload, auth_data);
268 chunk_free(&auth_data);
269 message->add_payload(message, (payload_t*)auth_payload);
270 status = SUCCESS;
271 }
272 }
273 DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
274 auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
275 auth_method == AUTH_DS ? scheme : auth_method,
276 status == SUCCESS ? "successful" : "failed");
277 chunk_free(&octets);
278 private->destroy(private);
279
280 return status;
281 }
282
283 METHOD(authenticator_t, process, status_t,
284 private_pubkey_authenticator_t *this, message_t *message)
285 {
286 public_key_t *public;
287 auth_method_t auth_method;
288 auth_payload_t *auth_payload;
289 chunk_t auth_data, octets;
290 identification_t *id;
291 auth_cfg_t *auth, *current_auth;
292 enumerator_t *enumerator;
293 key_type_t key_type = KEY_ECDSA;
294 signature_scheme_t scheme;
295 status_t status = NOT_FOUND;
296 keymat_v2_t *keymat;
297
298 auth_payload = (auth_payload_t*)message->get_payload(message, PLV2_AUTH);
299 if (!auth_payload)
300 {
301 return FAILED;
302 }
303 auth_method = auth_payload->get_auth_method(auth_payload);
304 auth_data = auth_payload->get_data(auth_payload);
305 switch (auth_method)
306 {
307 case AUTH_RSA:
308 key_type = KEY_RSA;
309 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
310 break;
311 case AUTH_ECDSA_256:
312 scheme = SIGN_ECDSA_256;
313 break;
314 case AUTH_ECDSA_384:
315 scheme = SIGN_ECDSA_384;
316 break;
317 case AUTH_ECDSA_521:
318 scheme = SIGN_ECDSA_521;
319 break;
320 case AUTH_DS:
321 if (parse_signature_auth_data(&auth_data, &key_type, &scheme))
322 {
323 break;
324 }
325 /* fall-through */
326 default:
327 return INVALID_ARG;
328 }
329 id = this->ike_sa->get_other_id(this->ike_sa);
330 keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
331 if (!keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init,
332 this->nonce, id, this->reserved, &octets))
333 {
334 return FAILED;
335 }
336 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
337 enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
338 key_type, id, auth);
339 while (enumerator->enumerate(enumerator, &public, &current_auth))
340 {
341 if (public->verify(public, scheme, octets, auth_data))
342 {
343 DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id,
344 auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
345 auth_method == AUTH_DS ? scheme : auth_method);
346 status = SUCCESS;
347 auth->merge(auth, current_auth, FALSE);
348 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
349 if (this->store_signature_scheme)
350 {
351 auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, (uintptr_t)scheme);
352 }
353 break;
354 }
355 else
356 {
357 status = FAILED;
358 DBG1(DBG_IKE, "signature validation failed, looking for another key");
359 }
360 }
361 enumerator->destroy(enumerator);
362 chunk_free(&octets);
363 if (status == NOT_FOUND)
364 {
365 DBG1(DBG_IKE, "no trusted %N public key found for '%Y'",
366 key_type_names, key_type, id);
367 }
368 return status;
369 }
370
371 METHOD(authenticator_t, destroy, void,
372 private_pubkey_authenticator_t *this)
373 {
374 free(this);
375 }
376
377 /*
378 * Described in header.
379 */
380 pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa,
381 chunk_t received_nonce, chunk_t sent_init,
382 char reserved[3])
383 {
384 private_pubkey_authenticator_t *this;
385
386 INIT(this,
387 .public = {
388 .authenticator = {
389 .build = _build,
390 .process = (void*)return_failed,
391 .is_mutual = (void*)return_false,
392 .destroy = _destroy,
393 },
394 },
395 .ike_sa = ike_sa,
396 .ike_sa_init = sent_init,
397 .nonce = received_nonce,
398 );
399 memcpy(this->reserved, reserved, sizeof(this->reserved));
400
401 return &this->public;
402 }
403
404 /*
405 * Described in header.
406 */
407 pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa,
408 chunk_t sent_nonce, chunk_t received_init,
409 char reserved[3])
410 {
411 private_pubkey_authenticator_t *this;
412
413 INIT(this,
414 .public = {
415 .authenticator = {
416 .build = (void*)return_failed,
417 .process = _process,
418 .is_mutual = (void*)return_false,
419 .destroy = _destroy,
420 },
421 },
422 .ike_sa = ike_sa,
423 .ike_sa_init = received_init,
424 .nonce = sent_nonce,
425 .store_signature_scheme = lib->settings->get_bool(lib->settings,
426 "%s.signature_authentication_constraints", TRUE, lib->ns),
427 );
428 memcpy(this->reserved, reserved, sizeof(this->reserved));
429
430 return &this->public;
431 }