Use bits instead of bytes for a private/public key
[strongswan.git] / src / pluto / ike_alg.c
1 /* IKE modular algorithm handling interface
2 * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
3 * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <sys/queue.h>
21
22 #include <freeswan.h>
23
24 #include <library.h>
25 #include <debug.h>
26 #include <credentials/keys/public_key.h>
27 #include <credentials/keys/private_key.h>
28 #include <crypto/hashers/hasher.h>
29 #include <crypto/crypters/crypter.h>
30 #include <crypto/prfs/prf.h>
31
32 #include "constants.h"
33 #include "defs.h"
34 #include "crypto.h"
35 #include "state.h"
36 #include "packet.h"
37 #include "keys.h"
38 #include "log.h"
39 #include "whack.h"
40 #include "spdb.h"
41 #include "alg_info.h"
42 #include "ike_alg.h"
43 #include "db_ops.h"
44 #include "connections.h"
45 #include "kernel.h"
46
47 #define return_on(var, val) do { var=val;goto return_out; } while(0);
48
49 /**
50 * IKE algorithm list handling - registration and lookup
51 */
52
53 /* Modular IKE algorithm storage structure */
54
55 static struct ike_alg *ike_alg_base[IKE_ALG_MAX+1] = {NULL, NULL};
56
57 /**
58 * Return ike_algo object by {type, id}
59 */
60 static struct ike_alg *ike_alg_find(u_int algo_type, u_int algo_id,
61 u_int keysize __attribute__((unused)))
62 {
63 struct ike_alg *e = ike_alg_base[algo_type];
64
65 while (e != NULL && algo_id > e->algo_id)
66 {
67 e = e->algo_next;
68 }
69 return (e != NULL && e->algo_id == algo_id) ? e : NULL;
70 }
71
72 /**
73 * "raw" ike_alg list adding function
74 */
75 int ike_alg_add(struct ike_alg* a)
76 {
77 if (a->algo_type > IKE_ALG_MAX)
78 {
79 plog("ike_alg: Not added, invalid algorithm type");
80 return -EINVAL;
81 }
82
83 if (ike_alg_find(a->algo_type, a->algo_id, 0) != NULL)
84 {
85 plog("ike_alg: Not added, algorithm already exists");
86 return -EEXIST;
87 }
88
89 {
90 struct ike_alg **ep = &ike_alg_base[a->algo_type];
91 struct ike_alg *e = *ep;
92
93 while (e != NULL && a->algo_id > e->algo_id)
94 {
95 ep = &e->algo_next;
96 e = *ep;
97 }
98 *ep = a;
99 a->algo_next = e;
100 return 0;
101 }
102 }
103
104 /**
105 * Get IKE hash algorithm
106 */
107 struct hash_desc *ike_alg_get_hasher(u_int alg)
108 {
109 return (struct hash_desc *) ike_alg_find(IKE_ALG_HASH, alg, 0);
110 }
111
112 /**
113 * Get IKE encryption algorithm
114 */
115 struct encrypt_desc *ike_alg_get_crypter(u_int alg)
116 {
117 return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0);
118 }
119
120 /**
121 * Get IKE dh group
122 */
123 struct dh_desc *ike_alg_get_dh_group(u_int alg)
124 {
125 return (struct dh_desc *) ike_alg_find(IKE_ALG_DH_GROUP, alg, 0);
126 }
127
128 /**
129 * Get pfsgroup for this connection
130 */
131 const struct dh_desc *ike_alg_pfsgroup(connection_t *c, lset_t policy)
132 {
133 const struct dh_desc *ret = NULL;
134
135 if ((policy & POLICY_PFS) &&
136 c->alg_info_esp && c->alg_info_esp->esp_pfsgroup)
137 {
138 ret = ike_alg_get_dh_group(c->alg_info_esp->esp_pfsgroup);
139 }
140 return ret;
141 }
142
143 /**
144 * Create an OAKLEY proposal based on alg_info and policy
145 */
146 struct db_context *ike_alg_db_new(connection_t *c, lset_t policy)
147 {
148 struct alg_info_ike *ai = c->alg_info_ike;
149 struct db_context *db_ctx = NULL;
150 struct ike_info *ike_info;
151 struct encrypt_desc *enc_desc;
152 u_int ealg, halg, modp, eklen = 0;
153 int i;
154
155 bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
156
157 if (!ai)
158 {
159 whack_log(RC_LOG_SERIOUS, "no IKE algorithms "
160 "for this connection "
161 "(check ike algorithm string)");
162 goto fail;
163 }
164 policy &= POLICY_ID_AUTH_MASK;
165 db_ctx = db_prop_new(PROTO_ISAKMP, 8, 8 * 5);
166
167 /* for each group */
168 ALG_INFO_IKE_FOREACH(ai, ike_info, i)
169 {
170 ealg = ike_info->ike_ealg;
171 halg = ike_info->ike_halg;
172 modp = ike_info->ike_modp;
173 eklen= ike_info->ike_eklen;
174
175 if (!ike_alg_get_crypter(ealg))
176 {
177 plog("ike alg: crypter %s not present",
178 enum_show(&oakley_enc_names, ealg));
179 continue;
180 }
181 if (!ike_alg_get_hasher(halg))
182 {
183 plog("ike alg: hasher %s not present",
184 enum_show(&oakley_hash_names, halg));
185 continue;
186 }
187 if (!ike_alg_get_dh_group(modp))
188 {
189 plog("ike alg: dh group %s not present",
190 enum_show(&oakley_group_names, modp));
191 continue;
192 }
193 enc_desc = ike_alg_get_crypter(ealg);
194
195 if (policy & POLICY_PUBKEY)
196 {
197 int auth_method = 0, key_size = 0;
198 key_type_t key_type = KEY_ANY;
199
200 if (c->spd.this.cert)
201 {
202 certificate_t *certificate = c->spd.this.cert->cert;
203 public_key_t *key = certificate->get_public_key(certificate);
204
205 if (key == NULL)
206 {
207 plog("ike alg: unable to retrieve my public key");
208 continue;
209 }
210 key_type = key->get_type(key);
211 key_size = key->get_keysize(key);
212 key->destroy(key);
213 }
214 else
215 {
216 private_key_t *key = get_private_key(c);
217
218 if (key == NULL)
219 {
220 plog("ike alg: unable to retrieve my private key");
221 continue;
222 }
223 key_type = key->get_type(key);
224 key_size = key->get_keysize(key);
225 }
226 switch (key_type)
227 {
228 case KEY_RSA:
229 auth_method = OAKLEY_RSA_SIG;
230 break;
231 case KEY_ECDSA:
232 switch (key_size)
233 {
234 case 256:
235 auth_method = OAKLEY_ECDSA_256;
236 break;
237 case 384:
238 auth_method = OAKLEY_ECDSA_384;
239 break;
240 case 521:
241 auth_method = OAKLEY_ECDSA_521;
242 break;
243 default:
244 continue;
245 }
246 break;
247 default:
248 continue;
249 }
250 db_trans_add(db_ctx, KEY_IKE);
251 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
252 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
253 if (eklen)
254 {
255 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
256 }
257 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, auth_method);
258 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
259 }
260
261 if (policy & POLICY_PSK)
262 {
263 db_trans_add(db_ctx, KEY_IKE);
264 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
265 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
266 if (eklen)
267 {
268 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
269 }
270 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
271 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
272 }
273
274 if (policy & POLICY_XAUTH_RSASIG)
275 {
276 db_trans_add(db_ctx, KEY_IKE);
277 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
278 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
279 if (eklen)
280 {
281 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
282 }
283 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
284 , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
285 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
286 }
287
288 if (policy & POLICY_XAUTH_PSK)
289 {
290 db_trans_add(db_ctx, KEY_IKE);
291 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
292 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
293 if (eklen)
294 {
295 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
296 }
297 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
298 , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
299 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
300 }
301 }
302 fail:
303 return db_ctx;
304 }
305
306 /**
307 * Show registered IKE algorithms
308 */
309 void ike_alg_list(void)
310 {
311 char buf[BUF_LEN];
312 char *pos;
313 int n, len;
314 struct ike_alg *a;
315
316 whack_log(RC_COMMENT, " ");
317 whack_log(RC_COMMENT, "List of registered IKEv1 Algorithms:");
318 whack_log(RC_COMMENT, " ");
319
320 pos = buf;
321 *pos = '\0';
322 len = BUF_LEN;
323 for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
324 {
325 n = snprintf(pos, len, " %s", enum_name(&oakley_enc_names, a->algo_id));
326 pos += n;
327 len -= n;
328 if (len <= 0)
329 {
330 break;
331 }
332 }
333 whack_log(RC_COMMENT, " encryption:%s", buf);
334
335 pos = buf;
336 *pos = '\0';
337 len = BUF_LEN;
338 for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
339 {
340 n = snprintf(pos, len, " %s", enum_name(&oakley_hash_names, a->algo_id));
341 pos += n;
342 len -= n;
343 if (len <= 0)
344 {
345 break;
346 }
347 }
348 whack_log(RC_COMMENT, " integrity: %s", buf);
349
350 pos = buf;
351 *pos = '\0';
352 len = BUF_LEN;
353 for (a = ike_alg_base[IKE_ALG_DH_GROUP]; a != NULL; a = a->algo_next)
354 {
355 n = snprintf(pos, len, " %s", enum_name(&oakley_group_names, a->algo_id));
356 pos += n;
357 len -= n;
358 if (len <= 0)
359 {
360 break;
361 }
362 }
363 whack_log(RC_COMMENT, " dh-group: %s", buf);
364 }
365
366 /**
367 * Show IKE algorithms for this connection (result from ike= string)
368 * and newest SA
369 */
370 void ike_alg_show_connection(connection_t *c, const char *instance)
371 {
372 struct state *st = state_with_serialno(c->newest_isakmp_sa);
373
374 if (st)
375 {
376 if (st->st_oakley.encrypt == OAKLEY_3DES_CBC)
377 {
378 whack_log(RC_COMMENT,
379 "\"%s\"%s: IKE proposal: %s/%s/%s",
380 c->name, instance,
381 enum_show(&oakley_enc_names, st->st_oakley.encrypt),
382 enum_show(&oakley_hash_names, st->st_oakley.hash),
383 enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
384 );
385 }
386 else
387 {
388 whack_log(RC_COMMENT,
389 "\"%s\"%s: IKE proposal: %s_%u/%s/%s",
390 c->name, instance,
391 enum_show(&oakley_enc_names, st->st_oakley.encrypt),
392 st->st_oakley.enckeylen,
393 enum_show(&oakley_hash_names, st->st_oakley.hash),
394 enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
395 );
396 }
397 }
398 }
399
400 /**
401 * ML: make F_STRICT logic consider enc,hash/auth,modp algorithms
402 */
403 bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group,
404 struct alg_info_ike *alg_info_ike)
405 {
406 /*
407 * simple test to discard low key_len, will accept it only
408 * if specified in "esp" string
409 */
410 bool ealg_insecure = (key_len < 128);
411
412 if (ealg_insecure
413 || (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
414 {
415 int i;
416 struct ike_info *ike_info;
417
418 if (alg_info_ike)
419 {
420 ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
421 {
422 if (ike_info->ike_ealg == ealg
423 && (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
424 && ike_info->ike_halg == aalg
425 && ike_info->ike_modp == group)
426 {
427 if (ealg_insecure)
428 loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
429 , enum_name(&oakley_enc_names, ealg));
430 return TRUE;
431 }
432 }
433 }
434 plog("Oakley Transform [%s (%d), %s, %s] refused due to %s"
435 , enum_name(&oakley_enc_names, ealg), key_len
436 , enum_name(&oakley_hash_names, aalg)
437 , enum_name(&oakley_group_names, group)
438 , ealg_insecure ?
439 "insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
440 );
441 return FALSE;
442 }
443 return TRUE;
444 }
445