7521dd33bd9bfc39d9b794ec3eee31eeeaa3c10f
[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;
198 size_t key_size = 0;
199 key_type_t key_type = KEY_ANY;
200
201
202 if (c->spd.this.cert)
203 {
204 certificate_t *certificate = c->spd.this.cert->cert;
205 public_key_t *key = certificate->get_public_key(certificate);
206
207 if (key == NULL)
208 {
209 plog("ike alg: unable to retrieve my public key");
210 continue;
211 }
212 key_type = key->get_type(key);
213 key_size = key->get_keysize(key);
214 key->destroy(key);
215 }
216 else
217 {
218 private_key_t *key = get_private_key(c);
219
220 if (key == NULL)
221 {
222 plog("ike alg: unable to retrieve my private key");
223 continue;
224 }
225 key_type = key->get_type(key);
226 key_size = key->get_keysize(key);
227 }
228 switch (key_type)
229 {
230 case KEY_RSA:
231 auth_method = OAKLEY_RSA_SIG;
232 break;
233 case KEY_ECDSA:
234 switch (key_size)
235 {
236 case 32:
237 auth_method = OAKLEY_ECDSA_256;
238 break;
239 case 48:
240 auth_method = OAKLEY_ECDSA_384;
241 break;
242 case 66:
243 auth_method = OAKLEY_ECDSA_521;
244 break;
245 default:
246 continue;
247 }
248 break;
249 default:
250 continue;
251 }
252 db_trans_add(db_ctx, KEY_IKE);
253 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
254 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
255 if (eklen)
256 {
257 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
258 }
259 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, auth_method);
260 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
261 }
262
263 if (policy & POLICY_PSK)
264 {
265 db_trans_add(db_ctx, KEY_IKE);
266 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
267 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
268 if (eklen)
269 {
270 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
271 }
272 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
273 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
274 }
275
276 if (policy & POLICY_XAUTH_RSASIG)
277 {
278 db_trans_add(db_ctx, KEY_IKE);
279 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
280 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
281 if (eklen)
282 {
283 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
284 }
285 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
286 , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
287 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
288 }
289
290 if (policy & POLICY_XAUTH_PSK)
291 {
292 db_trans_add(db_ctx, KEY_IKE);
293 db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
294 db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
295 if (eklen)
296 {
297 db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
298 }
299 db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
300 , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
301 db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
302 }
303 }
304 fail:
305 return db_ctx;
306 }
307
308 /**
309 * Show registered IKE algorithms
310 */
311 void ike_alg_list(void)
312 {
313 char buf[BUF_LEN];
314 char *pos;
315 int n, len;
316 struct ike_alg *a;
317
318 whack_log(RC_COMMENT, " ");
319 whack_log(RC_COMMENT, "List of registered IKEv1 Algorithms:");
320 whack_log(RC_COMMENT, " ");
321
322 pos = buf;
323 *pos = '\0';
324 len = BUF_LEN;
325 for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
326 {
327 n = snprintf(pos, len, " %s", enum_name(&oakley_enc_names, a->algo_id));
328 pos += n;
329 len -= n;
330 if (len <= 0)
331 {
332 break;
333 }
334 }
335 whack_log(RC_COMMENT, " encryption:%s", buf);
336
337 pos = buf;
338 *pos = '\0';
339 len = BUF_LEN;
340 for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
341 {
342 n = snprintf(pos, len, " %s", enum_name(&oakley_hash_names, a->algo_id));
343 pos += n;
344 len -= n;
345 if (len <= 0)
346 {
347 break;
348 }
349 }
350 whack_log(RC_COMMENT, " integrity: %s", buf);
351
352 pos = buf;
353 *pos = '\0';
354 len = BUF_LEN;
355 for (a = ike_alg_base[IKE_ALG_DH_GROUP]; a != NULL; a = a->algo_next)
356 {
357 n = snprintf(pos, len, " %s", enum_name(&oakley_group_names, a->algo_id));
358 pos += n;
359 len -= n;
360 if (len <= 0)
361 {
362 break;
363 }
364 }
365 whack_log(RC_COMMENT, " dh-group: %s", buf);
366 }
367
368 /**
369 * Show IKE algorithms for this connection (result from ike= string)
370 * and newest SA
371 */
372 void ike_alg_show_connection(connection_t *c, const char *instance)
373 {
374 struct state *st = state_with_serialno(c->newest_isakmp_sa);
375
376 if (st)
377 {
378 if (st->st_oakley.encrypt == OAKLEY_3DES_CBC)
379 {
380 whack_log(RC_COMMENT,
381 "\"%s\"%s: IKE proposal: %s/%s/%s",
382 c->name, instance,
383 enum_show(&oakley_enc_names, st->st_oakley.encrypt),
384 enum_show(&oakley_hash_names, st->st_oakley.hash),
385 enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
386 );
387 }
388 else
389 {
390 whack_log(RC_COMMENT,
391 "\"%s\"%s: IKE proposal: %s_%u/%s/%s",
392 c->name, instance,
393 enum_show(&oakley_enc_names, st->st_oakley.encrypt),
394 st->st_oakley.enckeylen,
395 enum_show(&oakley_hash_names, st->st_oakley.hash),
396 enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
397 );
398 }
399 }
400 }
401
402 /**
403 * ML: make F_STRICT logic consider enc,hash/auth,modp algorithms
404 */
405 bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group,
406 struct alg_info_ike *alg_info_ike)
407 {
408 /*
409 * simple test to discard low key_len, will accept it only
410 * if specified in "esp" string
411 */
412 bool ealg_insecure = (key_len < 128);
413
414 if (ealg_insecure
415 || (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
416 {
417 int i;
418 struct ike_info *ike_info;
419
420 if (alg_info_ike)
421 {
422 ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
423 {
424 if (ike_info->ike_ealg == ealg
425 && (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
426 && ike_info->ike_halg == aalg
427 && ike_info->ike_modp == group)
428 {
429 if (ealg_insecure)
430 loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
431 , enum_name(&oakley_enc_names, ealg));
432 return TRUE;
433 }
434 }
435 }
436 plog("Oakley Transform [%s (%d), %s, %s] refused due to %s"
437 , enum_name(&oakley_enc_names, ealg), key_len
438 , enum_name(&oakley_hash_names, aalg)
439 , enum_name(&oakley_group_names, group)
440 , ealg_insecure ?
441 "insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
442 );
443 return FALSE;
444 }
445 return TRUE;
446 }
447