Implemented EdDSA for IKEv2 using a pro forma Identity hash function
[strongswan.git] / src / libstrongswan / credentials / auth_cfg.c
1 /*
2 * Copyright (C) 2008-2016 Tobias Brunner
3 * Copyright (C) 2007-2009 Martin Willi
4 * Copyright (C) 2016 Andreas Steffen
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 "auth_cfg.h"
19
20 #include <library.h>
21 #include <utils/debug.h>
22 #include <collections/array.h>
23 #include <utils/identification.h>
24 #include <eap/eap.h>
25 #include <credentials/certificates/certificate.h>
26
27 ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_XAUTH,
28 "any",
29 "public key",
30 "pre-shared key",
31 "EAP",
32 "XAuth",
33 );
34
35 ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
36 "RULE_IDENTITY",
37 "RULE_IDENTITY_LOOSE",
38 "RULE_AUTH_CLASS",
39 "RULE_AAA_IDENTITY",
40 "RULE_EAP_IDENTITY",
41 "RULE_EAP_TYPE",
42 "RULE_EAP_VENDOR",
43 "RULE_XAUTH_BACKEND",
44 "RULE_XAUTH_IDENTITY",
45 "RULE_CA_CERT",
46 "RULE_IM_CERT",
47 "RULE_SUBJECT_CERT",
48 "RULE_CRL_VALIDATION",
49 "RULE_OCSP_VALIDATION",
50 "RULE_CERT_VALIDATION_SUSPENDED",
51 "RULE_GROUP",
52 "RULE_RSA_STRENGTH",
53 "RULE_ECDSA_STRENGTH",
54 "RULE_BLISS_STRENGTH",
55 "RULE_SIGNATURE_SCHEME",
56 "RULE_IKE_SIGNATURE_SCHEME",
57 "RULE_CERT_POLICY",
58 "HELPER_IM_CERT",
59 "HELPER_SUBJECT_CERT",
60 "HELPER_IM_HASH_URL",
61 "HELPER_SUBJECT_HASH_URL",
62 "HELPER_REVOCATION_CERT",
63 "HELPER_AC_CERT",
64 );
65
66 /**
67 * Check if the given rule is a rule for which there may be multiple values.
68 */
69 static inline bool is_multi_value_rule(auth_rule_t type)
70 {
71 switch (type)
72 {
73 case AUTH_RULE_AUTH_CLASS:
74 case AUTH_RULE_EAP_TYPE:
75 case AUTH_RULE_EAP_VENDOR:
76 case AUTH_RULE_RSA_STRENGTH:
77 case AUTH_RULE_ECDSA_STRENGTH:
78 case AUTH_RULE_BLISS_STRENGTH:
79 case AUTH_RULE_IDENTITY:
80 case AUTH_RULE_IDENTITY_LOOSE:
81 case AUTH_RULE_EAP_IDENTITY:
82 case AUTH_RULE_AAA_IDENTITY:
83 case AUTH_RULE_XAUTH_IDENTITY:
84 case AUTH_RULE_XAUTH_BACKEND:
85 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
86 case AUTH_HELPER_SUBJECT_CERT:
87 case AUTH_HELPER_SUBJECT_HASH_URL:
88 case AUTH_RULE_MAX:
89 return FALSE;
90 case AUTH_RULE_OCSP_VALIDATION:
91 case AUTH_RULE_CRL_VALIDATION:
92 case AUTH_RULE_GROUP:
93 case AUTH_RULE_SUBJECT_CERT:
94 case AUTH_RULE_CA_CERT:
95 case AUTH_RULE_IM_CERT:
96 case AUTH_RULE_CERT_POLICY:
97 case AUTH_RULE_SIGNATURE_SCHEME:
98 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
99 case AUTH_HELPER_IM_CERT:
100 case AUTH_HELPER_IM_HASH_URL:
101 case AUTH_HELPER_REVOCATION_CERT:
102 case AUTH_HELPER_AC_CERT:
103 return TRUE;
104 }
105 return FALSE;
106 }
107
108 typedef struct private_auth_cfg_t private_auth_cfg_t;
109
110 /**
111 * private data of item_set
112 */
113 struct private_auth_cfg_t {
114
115 /**
116 * public functions
117 */
118 auth_cfg_t public;
119
120 /**
121 * Array of entry_t
122 */
123 array_t *entries;
124 };
125
126 typedef struct entry_t entry_t;
127
128 struct entry_t {
129 /** rule type */
130 auth_rule_t type;
131 /** associated value */
132 void *value;
133 };
134
135 /**
136 * enumerator for auth_cfg_t.create_enumerator()
137 */
138 typedef struct {
139 /** implements enumerator_t */
140 enumerator_t public;
141 /** inner enumerator from linked_list_t */
142 enumerator_t *inner;
143 /** current entry */
144 entry_t *current;
145 /** types we have already enumerated */
146 bool enumerated[AUTH_RULE_MAX];
147 } entry_enumerator_t;
148
149 /**
150 * enumerate function for item_enumerator_t
151 */
152 static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
153 {
154 entry_t *entry;
155
156 while (this->inner->enumerate(this->inner, &entry))
157 {
158 if (!is_multi_value_rule(entry->type) && this->enumerated[entry->type])
159 {
160 continue;
161 }
162 this->enumerated[entry->type] = TRUE;
163 this->current = entry;
164 if (type)
165 {
166 *type = entry->type;
167 }
168 if (value)
169 {
170 *value = entry->value;
171 }
172 return TRUE;
173 }
174 return FALSE;
175 }
176
177 /**
178 * destroy function for item_enumerator_t
179 */
180 static void entry_enumerator_destroy(entry_enumerator_t *this)
181 {
182 this->inner->destroy(this->inner);
183 free(this);
184 }
185
186 METHOD(auth_cfg_t, create_enumerator, enumerator_t*,
187 private_auth_cfg_t *this)
188 {
189 entry_enumerator_t *enumerator;
190
191 INIT(enumerator,
192 .public = {
193 .enumerate = (void*)enumerate,
194 .destroy = (void*)entry_enumerator_destroy,
195 },
196 .inner = array_create_enumerator(this->entries),
197 );
198 return &enumerator->public;
199 }
200
201 /**
202 * Initialize an entry.
203 */
204 static void init_entry(entry_t *this, auth_rule_t type, va_list args)
205 {
206 this->type = type;
207 switch (type)
208 {
209 case AUTH_RULE_IDENTITY_LOOSE:
210 case AUTH_RULE_AUTH_CLASS:
211 case AUTH_RULE_EAP_TYPE:
212 case AUTH_RULE_EAP_VENDOR:
213 case AUTH_RULE_CRL_VALIDATION:
214 case AUTH_RULE_OCSP_VALIDATION:
215 case AUTH_RULE_RSA_STRENGTH:
216 case AUTH_RULE_ECDSA_STRENGTH:
217 case AUTH_RULE_BLISS_STRENGTH:
218 case AUTH_RULE_SIGNATURE_SCHEME:
219 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
220 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
221 /* integer type */
222 this->value = (void*)(uintptr_t)va_arg(args, u_int);
223 break;
224 case AUTH_RULE_IDENTITY:
225 case AUTH_RULE_EAP_IDENTITY:
226 case AUTH_RULE_AAA_IDENTITY:
227 case AUTH_RULE_XAUTH_BACKEND:
228 case AUTH_RULE_XAUTH_IDENTITY:
229 case AUTH_RULE_GROUP:
230 case AUTH_RULE_CA_CERT:
231 case AUTH_RULE_IM_CERT:
232 case AUTH_RULE_SUBJECT_CERT:
233 case AUTH_RULE_CERT_POLICY:
234 case AUTH_HELPER_IM_CERT:
235 case AUTH_HELPER_SUBJECT_CERT:
236 case AUTH_HELPER_IM_HASH_URL:
237 case AUTH_HELPER_SUBJECT_HASH_URL:
238 case AUTH_HELPER_REVOCATION_CERT:
239 case AUTH_HELPER_AC_CERT:
240 /* pointer type */
241 this->value = va_arg(args, void*);
242 break;
243 case AUTH_RULE_MAX:
244 this->value = NULL;
245 break;
246 }
247 }
248
249 /**
250 * Compare two entries for equality.
251 */
252 static bool entry_equals(entry_t *e1, entry_t *e2)
253 {
254 if (e1->type != e2->type)
255 {
256 return FALSE;
257 }
258 switch (e1->type)
259 {
260 case AUTH_RULE_IDENTITY_LOOSE:
261 case AUTH_RULE_AUTH_CLASS:
262 case AUTH_RULE_EAP_TYPE:
263 case AUTH_RULE_EAP_VENDOR:
264 case AUTH_RULE_CRL_VALIDATION:
265 case AUTH_RULE_OCSP_VALIDATION:
266 case AUTH_RULE_RSA_STRENGTH:
267 case AUTH_RULE_ECDSA_STRENGTH:
268 case AUTH_RULE_BLISS_STRENGTH:
269 case AUTH_RULE_SIGNATURE_SCHEME:
270 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
271 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
272 {
273 return e1->value == e2->value;
274 }
275 case AUTH_RULE_CA_CERT:
276 case AUTH_RULE_IM_CERT:
277 case AUTH_RULE_SUBJECT_CERT:
278 case AUTH_HELPER_IM_CERT:
279 case AUTH_HELPER_SUBJECT_CERT:
280 case AUTH_HELPER_REVOCATION_CERT:
281 case AUTH_HELPER_AC_CERT:
282 {
283 certificate_t *c1, *c2;
284
285 c1 = (certificate_t*)e1->value;
286 c2 = (certificate_t*)e2->value;
287
288 return c1->equals(c1, c2);
289 }
290 case AUTH_RULE_IDENTITY:
291 case AUTH_RULE_EAP_IDENTITY:
292 case AUTH_RULE_AAA_IDENTITY:
293 case AUTH_RULE_XAUTH_IDENTITY:
294 case AUTH_RULE_GROUP:
295 {
296 identification_t *id1, *id2;
297
298 id1 = (identification_t*)e1->value;
299 id2 = (identification_t*)e2->value;
300
301 return id1->equals(id1, id2);
302 }
303 case AUTH_RULE_CERT_POLICY:
304 case AUTH_RULE_XAUTH_BACKEND:
305 case AUTH_HELPER_IM_HASH_URL:
306 case AUTH_HELPER_SUBJECT_HASH_URL:
307 {
308 return streq(e1->value, e2->value);
309 }
310 case AUTH_RULE_MAX:
311 break;
312 }
313 return FALSE;
314 }
315
316 /**
317 * Destroy the value associated with an entry
318 */
319 static void destroy_entry_value(entry_t *entry)
320 {
321 switch (entry->type)
322 {
323 case AUTH_RULE_IDENTITY:
324 case AUTH_RULE_EAP_IDENTITY:
325 case AUTH_RULE_AAA_IDENTITY:
326 case AUTH_RULE_GROUP:
327 case AUTH_RULE_XAUTH_IDENTITY:
328 {
329 identification_t *id = (identification_t*)entry->value;
330 id->destroy(id);
331 break;
332 }
333 case AUTH_RULE_CA_CERT:
334 case AUTH_RULE_IM_CERT:
335 case AUTH_RULE_SUBJECT_CERT:
336 case AUTH_HELPER_IM_CERT:
337 case AUTH_HELPER_SUBJECT_CERT:
338 case AUTH_HELPER_REVOCATION_CERT:
339 case AUTH_HELPER_AC_CERT:
340 {
341 certificate_t *cert = (certificate_t*)entry->value;
342 cert->destroy(cert);
343 break;
344 }
345 case AUTH_RULE_CERT_POLICY:
346 case AUTH_RULE_XAUTH_BACKEND:
347 case AUTH_HELPER_IM_HASH_URL:
348 case AUTH_HELPER_SUBJECT_HASH_URL:
349 {
350 free(entry->value);
351 break;
352 }
353 case AUTH_RULE_IDENTITY_LOOSE:
354 case AUTH_RULE_AUTH_CLASS:
355 case AUTH_RULE_EAP_TYPE:
356 case AUTH_RULE_EAP_VENDOR:
357 case AUTH_RULE_CRL_VALIDATION:
358 case AUTH_RULE_OCSP_VALIDATION:
359 case AUTH_RULE_RSA_STRENGTH:
360 case AUTH_RULE_ECDSA_STRENGTH:
361 case AUTH_RULE_BLISS_STRENGTH:
362 case AUTH_RULE_SIGNATURE_SCHEME:
363 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
364 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
365 case AUTH_RULE_MAX:
366 break;
367 }
368 }
369
370 /**
371 * Implementation of auth_cfg_t.replace.
372 */
373 static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
374 auth_rule_t type, ...)
375 {
376 if (enumerator->current)
377 {
378 entry_t *entry;
379 va_list args;
380
381 va_start(args, type);
382 entry = enumerator->current;
383 destroy_entry_value(entry);
384 entry->type = type;
385 switch (type)
386 {
387 case AUTH_RULE_IDENTITY_LOOSE:
388 case AUTH_RULE_AUTH_CLASS:
389 case AUTH_RULE_EAP_TYPE:
390 case AUTH_RULE_EAP_VENDOR:
391 case AUTH_RULE_CRL_VALIDATION:
392 case AUTH_RULE_OCSP_VALIDATION:
393 case AUTH_RULE_RSA_STRENGTH:
394 case AUTH_RULE_ECDSA_STRENGTH:
395 case AUTH_RULE_BLISS_STRENGTH:
396 case AUTH_RULE_SIGNATURE_SCHEME:
397 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
398 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
399 /* integer type */
400 entry->value = (void*)(uintptr_t)va_arg(args, u_int);
401 break;
402 case AUTH_RULE_IDENTITY:
403 case AUTH_RULE_EAP_IDENTITY:
404 case AUTH_RULE_AAA_IDENTITY:
405 case AUTH_RULE_XAUTH_BACKEND:
406 case AUTH_RULE_XAUTH_IDENTITY:
407 case AUTH_RULE_GROUP:
408 case AUTH_RULE_CA_CERT:
409 case AUTH_RULE_IM_CERT:
410 case AUTH_RULE_SUBJECT_CERT:
411 case AUTH_RULE_CERT_POLICY:
412 case AUTH_HELPER_IM_CERT:
413 case AUTH_HELPER_SUBJECT_CERT:
414 case AUTH_HELPER_IM_HASH_URL:
415 case AUTH_HELPER_SUBJECT_HASH_URL:
416 case AUTH_HELPER_REVOCATION_CERT:
417 case AUTH_HELPER_AC_CERT:
418 /* pointer type */
419 entry->value = va_arg(args, void*);
420 break;
421 case AUTH_RULE_MAX:
422 entry->value = NULL;
423 break;
424 }
425 va_end(args);
426 }
427 }
428
429 METHOD(auth_cfg_t, get, void*,
430 private_auth_cfg_t *this, auth_rule_t type)
431 {
432 enumerator_t *enumerator;
433 void *current_value, *best_value = NULL;
434 auth_rule_t current_type;
435 bool found = FALSE;
436
437 enumerator = create_enumerator(this);
438 while (enumerator->enumerate(enumerator, &current_type, &current_value))
439 {
440 if (type == current_type)
441 {
442 if (type == AUTH_RULE_CRL_VALIDATION ||
443 type == AUTH_RULE_OCSP_VALIDATION)
444 { /* for CRL/OCSP validation, always get() the highest value */
445 if (!found || current_value > best_value)
446 {
447 best_value = current_value;
448 }
449 found = TRUE;
450 continue;
451 }
452 best_value = current_value;
453 found = TRUE;
454 break;
455 }
456 }
457 enumerator->destroy(enumerator);
458 if (found)
459 {
460 return best_value;
461 }
462 switch (type)
463 {
464 /* use some sane defaults if we don't find an entry */
465 case AUTH_RULE_AUTH_CLASS:
466 return (void*)AUTH_CLASS_ANY;
467 case AUTH_RULE_EAP_TYPE:
468 return (void*)EAP_NAK;
469 case AUTH_RULE_EAP_VENDOR:
470 case AUTH_RULE_RSA_STRENGTH:
471 case AUTH_RULE_ECDSA_STRENGTH:
472 case AUTH_RULE_BLISS_STRENGTH:
473 return (void*)0;
474 case AUTH_RULE_SIGNATURE_SCHEME:
475 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
476 return (void*)HASH_UNKNOWN;
477 case AUTH_RULE_CRL_VALIDATION:
478 case AUTH_RULE_OCSP_VALIDATION:
479 return (void*)VALIDATION_FAILED;
480 case AUTH_RULE_IDENTITY_LOOSE:
481 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
482 return (void*)FALSE;
483 case AUTH_RULE_IDENTITY:
484 case AUTH_RULE_EAP_IDENTITY:
485 case AUTH_RULE_AAA_IDENTITY:
486 case AUTH_RULE_XAUTH_BACKEND:
487 case AUTH_RULE_XAUTH_IDENTITY:
488 case AUTH_RULE_GROUP:
489 case AUTH_RULE_CA_CERT:
490 case AUTH_RULE_IM_CERT:
491 case AUTH_RULE_SUBJECT_CERT:
492 case AUTH_RULE_CERT_POLICY:
493 case AUTH_HELPER_IM_CERT:
494 case AUTH_HELPER_SUBJECT_CERT:
495 case AUTH_HELPER_IM_HASH_URL:
496 case AUTH_HELPER_SUBJECT_HASH_URL:
497 case AUTH_HELPER_REVOCATION_CERT:
498 case AUTH_HELPER_AC_CERT:
499 case AUTH_RULE_MAX:
500 break;
501 }
502 return NULL;
503 }
504
505 /**
506 * Implementation of auth_cfg_t.add.
507 */
508 static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
509 {
510 entry_t entry;
511 va_list args;
512
513 va_start(args, type);
514 init_entry(&entry, type, args);
515 va_end(args);
516
517 if (is_multi_value_rule(type))
518 { /* insert rules that may occur multiple times at the end */
519 array_insert(this->entries, ARRAY_TAIL, &entry);
520 }
521 else
522 { /* insert rules we expect only once at the front (get() will return
523 * the latest value) */
524 array_insert(this->entries, ARRAY_HEAD, &entry);
525 }
526 }
527
528 METHOD(auth_cfg_t, add_pubkey_constraints, void,
529 private_auth_cfg_t *this, char* constraints, bool ike)
530 {
531 enumerator_t *enumerator;
532 bool is_ike = FALSE, ike_added = FALSE;
533 key_type_t expected_type = -1;
534 auth_rule_t expected_strength = AUTH_RULE_MAX;
535 int strength;
536 char *token;
537 auth_rule_t type;
538 void *value;
539
540 enumerator = enumerator_create_token(constraints, "-", "");
541 while (enumerator->enumerate(enumerator, &token))
542 {
543 bool found = FALSE;
544 int i;
545 struct {
546 char *name;
547 signature_scheme_t scheme;
548 key_type_t key;
549 } schemes[] = {
550 { "md5", SIGN_RSA_EMSA_PKCS1_MD5, KEY_RSA, },
551 { "sha1", SIGN_RSA_EMSA_PKCS1_SHA1, KEY_RSA, },
552 { "sha224", SIGN_RSA_EMSA_PKCS1_SHA2_224, KEY_RSA, },
553 { "sha256", SIGN_RSA_EMSA_PKCS1_SHA2_256, KEY_RSA, },
554 { "sha384", SIGN_RSA_EMSA_PKCS1_SHA2_384, KEY_RSA, },
555 { "sha512", SIGN_RSA_EMSA_PKCS1_SHA2_512, KEY_RSA, },
556 { "sha1", SIGN_ECDSA_WITH_SHA1_DER, KEY_ECDSA, },
557 { "sha256", SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, },
558 { "sha384", SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, },
559 { "sha512", SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, },
560 { "sha256", SIGN_ECDSA_256, KEY_ECDSA, },
561 { "sha384", SIGN_ECDSA_384, KEY_ECDSA, },
562 { "sha512", SIGN_ECDSA_521, KEY_ECDSA, },
563 { "sha256", SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, },
564 { "sha384", SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, },
565 { "sha512", SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, },
566 { "identity", SIGN_ED25519, KEY_ED25519, },
567 { "identity", SIGN_ED448, KEY_ED448, },
568 };
569
570 if (expected_strength != AUTH_RULE_MAX)
571 { /* expecting a key strength token */
572 strength = atoi(token);
573 if (strength)
574 {
575 add(this, expected_strength, (uintptr_t)strength);
576 }
577 expected_strength = AUTH_RULE_MAX;
578 if (strength)
579 {
580 continue;
581 }
582 }
583 if (streq(token, "rsa") || streq(token, "ike:rsa"))
584 {
585 expected_type = KEY_RSA;
586 expected_strength = AUTH_RULE_RSA_STRENGTH;
587 is_ike = strpfx(token, "ike:");
588 continue;
589 }
590 if (streq(token, "ecdsa") || streq(token, "ike:ecdsa"))
591 {
592 expected_type = KEY_ECDSA;
593 expected_strength = AUTH_RULE_ECDSA_STRENGTH;
594 is_ike = strpfx(token, "ike:");
595 continue;
596 }
597 if (streq(token, "ed25519") || streq(token, "ike:ed25519"))
598 {
599 expected_type = KEY_ED25519;
600 is_ike = strpfx(token, "ike:");
601 continue;
602 }
603 if (streq(token, "ed448") || streq(token, "ike:ed448"))
604 {
605 expected_type = KEY_ED448;
606 is_ike = strpfx(token, "ike:");
607 continue;
608 }
609 if (streq(token, "bliss") || streq(token, "ike:bliss"))
610 {
611 expected_type = KEY_BLISS;
612 expected_strength = AUTH_RULE_BLISS_STRENGTH;
613 is_ike = strpfx(token, "ike:");
614 continue;
615 }
616 if (streq(token, "pubkey") || streq(token, "ike:pubkey"))
617 {
618 expected_type = KEY_ANY;
619 is_ike = strpfx(token, "ike:");
620 continue;
621 }
622 if (is_ike && !ike)
623 {
624 continue;
625 }
626
627 for (i = 0; i < countof(schemes); i++)
628 {
629 if (streq(schemes[i].name, token))
630 {
631 if (expected_type == KEY_ANY || expected_type == schemes[i].key)
632 {
633 if (is_ike)
634 {
635 add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME,
636 (uintptr_t)schemes[i].scheme);
637 ike_added = TRUE;
638 }
639 else
640 {
641 add(this, AUTH_RULE_SIGNATURE_SCHEME,
642 (uintptr_t)schemes[i].scheme);
643 }
644 }
645 found = TRUE;
646 }
647 }
648 if (!found)
649 {
650 DBG1(DBG_CFG, "ignoring invalid auth token: '%s'", token);
651 }
652 }
653 enumerator->destroy(enumerator);
654
655 /* if no explicit IKE signature contraints were added we add them for all
656 * configured signature contraints */
657 if (ike && !ike_added &&
658 lib->settings->get_bool(lib->settings,
659 "%s.signature_authentication_constraints", TRUE,
660 lib->ns))
661 {
662 enumerator = create_enumerator(this);
663 while (enumerator->enumerate(enumerator, &type, &value))
664 {
665 if (type == AUTH_RULE_SIGNATURE_SCHEME)
666 {
667 add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME,
668 (uintptr_t)value);
669 }
670 }
671 enumerator->destroy(enumerator);
672 }
673 }
674
675 /**
676 * Check if signature schemes of a specific type are compliant
677 */
678 static bool complies_scheme(private_auth_cfg_t *this, auth_cfg_t *constraints,
679 auth_rule_t type, bool log_error)
680 {
681 enumerator_t *e1, *e2;
682 auth_rule_t t1, t2;
683 signature_scheme_t scheme;
684 void *value;
685 bool success = TRUE;
686
687 e2 = create_enumerator(this);
688 while (e2->enumerate(e2, &t2, &scheme))
689 {
690 if (t2 == type)
691 {
692 success = FALSE;
693 e1 = constraints->create_enumerator(constraints);
694 while (e1->enumerate(e1, &t1, &value))
695 {
696 if (t1 == type && (uintptr_t)value == scheme)
697 {
698 success = TRUE;
699 break;
700 }
701 }
702 e1->destroy(e1);
703 if (!success)
704 {
705 if (log_error)
706 {
707 DBG1(DBG_CFG, "%s signature scheme %N not acceptable",
708 AUTH_RULE_SIGNATURE_SCHEME == type ? "X.509" : "IKE",
709 signature_scheme_names, (int)scheme);
710 }
711 break;
712 }
713 }
714 }
715 e2->destroy(e2);
716 return success;
717 }
718
719 METHOD(auth_cfg_t, complies, bool,
720 private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error)
721 {
722 enumerator_t *e1, *e2;
723 bool success = TRUE, group_match = FALSE;
724 bool ca_match = FALSE, cert_match = FALSE;
725 identification_t *require_group = NULL;
726 certificate_t *require_ca = NULL, *require_cert = NULL;
727 signature_scheme_t ike_scheme = SIGN_UNKNOWN, scheme = SIGN_UNKNOWN;
728 u_int strength = 0;
729 auth_rule_t t1, t2;
730 char *key_type;
731 void *value;
732
733 e1 = constraints->create_enumerator(constraints);
734 while (e1->enumerate(e1, &t1, &value))
735 {
736 switch (t1)
737 {
738 case AUTH_RULE_CA_CERT:
739 case AUTH_RULE_IM_CERT:
740 {
741 certificate_t *cert;
742
743 /* for CA certs, a match of a single cert is sufficient */
744 require_ca = (certificate_t*)value;
745
746 e2 = create_enumerator(this);
747 while (e2->enumerate(e2, &t2, &cert))
748 {
749 if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
750 cert->equals(cert, require_ca))
751 {
752 ca_match = TRUE;
753 }
754 }
755 e2->destroy(e2);
756 break;
757 }
758 case AUTH_RULE_SUBJECT_CERT:
759 {
760 certificate_t *cert;
761
762 /* for certs, a match of a single cert is sufficient */
763 require_cert = (certificate_t*)value;
764
765 e2 = create_enumerator(this);
766 while (e2->enumerate(e2, &t2, &cert))
767 {
768 if (t2 == AUTH_RULE_SUBJECT_CERT &&
769 cert->equals(cert, require_cert))
770 {
771 cert_match = TRUE;
772 }
773 }
774 e2->destroy(e2);
775 break;
776 }
777 case AUTH_RULE_CRL_VALIDATION:
778 case AUTH_RULE_OCSP_VALIDATION:
779 {
780 uintptr_t validated;
781
782 if (get(this, AUTH_RULE_CERT_VALIDATION_SUSPENDED))
783 { /* skip validation, may happen later */
784 break;
785 }
786
787 e2 = create_enumerator(this);
788 while (e2->enumerate(e2, &t2, &validated))
789 {
790 if (t2 == t1)
791 {
792 switch ((uintptr_t)value)
793 {
794 case VALIDATION_FAILED:
795 /* no constraint */
796 break;
797 case VALIDATION_SKIPPED:
798 if (validated == VALIDATION_SKIPPED)
799 {
800 break;
801 }
802 /* FALL */
803 case VALIDATION_GOOD:
804 if (validated == VALIDATION_GOOD)
805 {
806 break;
807 }
808 /* FALL */
809 default:
810 success = FALSE;
811 if (log_error)
812 {
813 DBG1(DBG_CFG, "constraint check failed: "
814 "%N is %N, but requires at least %N",
815 auth_rule_names, t1,
816 cert_validation_names, validated,
817 cert_validation_names, (uintptr_t)value);
818 }
819 break;
820 }
821 }
822 }
823 e2->destroy(e2);
824 break;
825 }
826 case AUTH_RULE_IDENTITY:
827 case AUTH_RULE_EAP_IDENTITY:
828 case AUTH_RULE_AAA_IDENTITY:
829 case AUTH_RULE_XAUTH_IDENTITY:
830 {
831 identification_t *id1, *id2;
832
833 id1 = (identification_t*)value;
834 id2 = get(this, t1);
835 if (!id2 || !id2->matches(id2, id1))
836 {
837 if (t1 == AUTH_RULE_IDENTITY &&
838 constraints->get(constraints, AUTH_RULE_IDENTITY_LOOSE))
839 { /* also verify identity against subjectAltNames */
840 certificate_t *cert;
841
842 cert = get(this, AUTH_HELPER_SUBJECT_CERT);
843 if (cert && cert->has_subject(cert, id1))
844 {
845 break;
846 }
847 }
848 success = FALSE;
849 if (log_error)
850 {
851 DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
852 " required ", t1 == AUTH_RULE_IDENTITY ? "" :
853 "EAP ", id1);
854 }
855 }
856 break;
857 }
858 case AUTH_RULE_AUTH_CLASS:
859 {
860 if ((uintptr_t)value != AUTH_CLASS_ANY &&
861 (uintptr_t)value != (uintptr_t)get(this, t1))
862 {
863 success = FALSE;
864 if (log_error)
865 {
866 DBG1(DBG_CFG, "constraint requires %N authentication, "
867 "but %N was used", auth_class_names, (uintptr_t)value,
868 auth_class_names, (uintptr_t)get(this, t1));
869 }
870 }
871 break;
872 }
873 case AUTH_RULE_EAP_TYPE:
874 {
875 if ((uintptr_t)value != (uintptr_t)get(this, t1) &&
876 (uintptr_t)value != EAP_DYNAMIC &&
877 (uintptr_t)value != EAP_RADIUS)
878 {
879 success = FALSE;
880 if (log_error)
881 {
882 DBG1(DBG_CFG, "constraint requires %N, "
883 "but %N was used", eap_type_names, (uintptr_t)value,
884 eap_type_names, (uintptr_t)get(this, t1));
885 }
886 }
887 break;
888 }
889 case AUTH_RULE_EAP_VENDOR:
890 {
891 if ((uintptr_t)value != (uintptr_t)get(this, t1))
892 {
893 success = FALSE;
894 if (log_error)
895 {
896 DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
897 "but %d was used", (uintptr_t)value,
898 (uintptr_t)get(this, t1));
899 }
900 }
901 break;
902 }
903 case AUTH_RULE_GROUP:
904 {
905 identification_t *group;
906
907 /* for groups, a match of a single group is sufficient */
908 require_group = (identification_t*)value;
909 e2 = create_enumerator(this);
910 while (e2->enumerate(e2, &t2, &group))
911 {
912 if (t2 == AUTH_RULE_GROUP &&
913 group->matches(group, require_group))
914 {
915 group_match = TRUE;
916 }
917 }
918 e2->destroy(e2);
919 break;
920 }
921 case AUTH_RULE_RSA_STRENGTH:
922 case AUTH_RULE_ECDSA_STRENGTH:
923 case AUTH_RULE_BLISS_STRENGTH:
924 {
925 strength = (uintptr_t)value;
926 break;
927 }
928 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
929 {
930 ike_scheme = (uintptr_t)value;
931 break;
932 }
933 case AUTH_RULE_SIGNATURE_SCHEME:
934 {
935 scheme = (uintptr_t)value;
936 break;
937 }
938 case AUTH_RULE_CERT_POLICY:
939 {
940 char *oid1, *oid2;
941
942 oid1 = (char*)value;
943 success = FALSE;
944 e2 = create_enumerator(this);
945 while (e2->enumerate(e2, &t2, &oid2))
946 {
947 if (t2 == t1 && streq(oid1, oid2))
948 {
949 success = TRUE;
950 break;
951 }
952 }
953 e2->destroy(e2);
954 if (!success && log_error)
955 {
956 DBG1(DBG_CFG, "constraint requires cert policy %s", oid1);
957 }
958 break;
959 }
960 case AUTH_RULE_IDENTITY_LOOSE:
961 /* just an indication when verifying AUTH_RULE_IDENTITY */
962 case AUTH_RULE_XAUTH_BACKEND:
963 /* not enforced, just a hint for local authentication */
964 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
965 /* not a constraint */
966 case AUTH_HELPER_IM_CERT:
967 case AUTH_HELPER_SUBJECT_CERT:
968 case AUTH_HELPER_IM_HASH_URL:
969 case AUTH_HELPER_SUBJECT_HASH_URL:
970 case AUTH_HELPER_REVOCATION_CERT:
971 case AUTH_HELPER_AC_CERT:
972 case AUTH_RULE_MAX:
973 /* skip helpers */
974 continue;
975 }
976 if (!success)
977 {
978 break;
979 }
980 }
981 e1->destroy(e1);
982
983 /* Check if we have a matching constraint (or none at all) for used
984 * signature schemes. */
985 if (success && scheme != SIGN_UNKNOWN)
986 {
987 success = complies_scheme(this, constraints,
988 AUTH_RULE_SIGNATURE_SCHEME, log_error);
989 }
990 if (success && ike_scheme != SIGN_UNKNOWN)
991 {
992 success = complies_scheme(this, constraints,
993 AUTH_RULE_IKE_SIGNATURE_SCHEME, log_error);
994 }
995
996 /* Check if we have a matching constraint (or none at all) for used
997 * public key strength */
998 if (success && strength)
999 {
1000 e2 = create_enumerator(this);
1001 while (e2->enumerate(e2, &t2, &strength))
1002 {
1003 switch (t2)
1004 {
1005 default:
1006 continue;
1007 case AUTH_RULE_RSA_STRENGTH:
1008 key_type = "RSA";
1009 break;
1010 case AUTH_RULE_ECDSA_STRENGTH:
1011 key_type = "ECDSA";
1012 break;
1013 case AUTH_RULE_BLISS_STRENGTH:
1014 key_type = "BLISS";
1015 break;
1016 }
1017 success = FALSE;
1018 e1 = constraints->create_enumerator(constraints);
1019 while (e1->enumerate(e1, &t1, &value))
1020 {
1021 if (t1 == t2 && (uintptr_t)value <= strength)
1022 {
1023 success = TRUE;
1024 break;
1025 }
1026 }
1027 e1->destroy(e1);
1028 if (!success)
1029 {
1030 if (log_error)
1031 {
1032 DBG1(DBG_CFG, "%s-%d signatures not acceptable",
1033 key_type, strength);
1034 }
1035 break;
1036 }
1037 }
1038 e2->destroy(e2);
1039 }
1040
1041 if (require_group && !group_match)
1042 {
1043 if (log_error)
1044 {
1045 DBG1(DBG_CFG, "constraint check failed: group membership to "
1046 "'%Y' required", require_group);
1047 }
1048 return FALSE;
1049 }
1050 if (require_ca && !ca_match)
1051 {
1052 if (log_error)
1053 {
1054 DBG1(DBG_CFG, "constraint check failed: peer not "
1055 "authenticated by CA '%Y'",
1056 require_ca->get_subject(require_ca));
1057 }
1058 return FALSE;
1059 }
1060 if (require_cert && !cert_match)
1061 {
1062 if (log_error)
1063 {
1064 DBG1(DBG_CFG, "constraint check failed: peer not "
1065 "authenticated with peer cert '%Y'",
1066 require_cert->get_subject(require_cert));
1067 }
1068 return FALSE;
1069 }
1070 return success;
1071 }
1072
1073 /**
1074 * Implementation of auth_cfg_t.merge.
1075 */
1076 static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
1077 {
1078 if (!other)
1079 { /* nothing to merge */
1080 return;
1081 }
1082 if (copy)
1083 {
1084 enumerator_t *enumerator;
1085 auth_rule_t type;
1086 void *value;
1087
1088 /* this enumerator skips duplicates for rules we expect only once */
1089 enumerator = create_enumerator(other);
1090 while (enumerator->enumerate(enumerator, &type, &value))
1091 {
1092 switch (type)
1093 {
1094 case AUTH_RULE_CA_CERT:
1095 case AUTH_RULE_IM_CERT:
1096 case AUTH_RULE_SUBJECT_CERT:
1097 case AUTH_HELPER_IM_CERT:
1098 case AUTH_HELPER_SUBJECT_CERT:
1099 case AUTH_HELPER_REVOCATION_CERT:
1100 case AUTH_HELPER_AC_CERT:
1101 {
1102 certificate_t *cert = (certificate_t*)value;
1103
1104 add(this, type, cert->get_ref(cert));
1105 break;
1106 }
1107 case AUTH_RULE_IDENTITY_LOOSE:
1108 case AUTH_RULE_CRL_VALIDATION:
1109 case AUTH_RULE_OCSP_VALIDATION:
1110 case AUTH_RULE_AUTH_CLASS:
1111 case AUTH_RULE_EAP_TYPE:
1112 case AUTH_RULE_EAP_VENDOR:
1113 case AUTH_RULE_RSA_STRENGTH:
1114 case AUTH_RULE_ECDSA_STRENGTH:
1115 case AUTH_RULE_BLISS_STRENGTH:
1116 case AUTH_RULE_SIGNATURE_SCHEME:
1117 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
1118 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
1119 {
1120 add(this, type, (uintptr_t)value);
1121 break;
1122 }
1123 case AUTH_RULE_IDENTITY:
1124 case AUTH_RULE_EAP_IDENTITY:
1125 case AUTH_RULE_AAA_IDENTITY:
1126 case AUTH_RULE_GROUP:
1127 case AUTH_RULE_XAUTH_IDENTITY:
1128 {
1129 identification_t *id = (identification_t*)value;
1130
1131 add(this, type, id->clone(id));
1132 break;
1133 }
1134 case AUTH_RULE_XAUTH_BACKEND:
1135 case AUTH_RULE_CERT_POLICY:
1136 case AUTH_HELPER_IM_HASH_URL:
1137 case AUTH_HELPER_SUBJECT_HASH_URL:
1138 {
1139 add(this, type, strdup((char*)value));
1140 break;
1141 }
1142 case AUTH_RULE_MAX:
1143 break;
1144 }
1145 }
1146 enumerator->destroy(enumerator);
1147 }
1148 else
1149 {
1150 entry_t entry;
1151
1152 while (array_remove(other->entries, ARRAY_TAIL, &entry))
1153 { /* keep order but prefer new values (esp. for single valued ones) */
1154 array_insert(this->entries, ARRAY_HEAD, &entry);
1155 }
1156 array_compress(other->entries);
1157 }
1158 }
1159
1160 /**
1161 * Compare two auth_cfg_t objects for equality.
1162 */
1163 static bool auth_cfg_equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
1164 {
1165 enumerator_t *e1, *e2;
1166 entry_t *i1, *i2;
1167 bool equal = TRUE, found;
1168
1169 /* the rule count does not have to be equal for the two, as we only compare
1170 * the first value found for some rules */
1171 e1 = array_create_enumerator(this->entries);
1172 while (e1->enumerate(e1, &i1))
1173 {
1174 found = FALSE;
1175
1176 e2 = array_create_enumerator(other->entries);
1177 while (e2->enumerate(e2, &i2))
1178 {
1179 if (entry_equals(i1, i2))
1180 {
1181 found = TRUE;
1182 break;
1183 }
1184 else if (i1->type == i2->type && !is_multi_value_rule(i1->type))
1185 { /* we continue our search, only for multi valued rules */
1186 break;
1187 }
1188 }
1189 e2->destroy(e2);
1190 if (!found)
1191 {
1192 equal = FALSE;
1193 break;
1194 }
1195 }
1196 e1->destroy(e1);
1197 return equal;
1198 }
1199
1200 /**
1201 * Implementation of auth_cfg_t.equals.
1202 */
1203 static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
1204 {
1205 if (auth_cfg_equals(this, other))
1206 {
1207 /* as 'other' might contain entries that 'this' doesn't we also check
1208 * the other way around */
1209 return auth_cfg_equals(other, this);
1210 }
1211 return FALSE;
1212 }
1213
1214 METHOD(auth_cfg_t, purge, void,
1215 private_auth_cfg_t *this, bool keep_ca)
1216 {
1217 enumerator_t *enumerator;
1218 entry_t *entry;
1219
1220 enumerator = array_create_enumerator(this->entries);
1221 while (enumerator->enumerate(enumerator, &entry))
1222 {
1223 if (!keep_ca || entry->type != AUTH_RULE_CA_CERT)
1224 {
1225 destroy_entry_value(entry);
1226 array_remove_at(this->entries, enumerator);
1227 }
1228 }
1229 enumerator->destroy(enumerator);
1230
1231 array_compress(this->entries);
1232 }
1233
1234 METHOD(auth_cfg_t, clone_, auth_cfg_t*,
1235 private_auth_cfg_t *this)
1236 {
1237 enumerator_t *enumerator;
1238 auth_cfg_t *clone;
1239 auth_rule_t type;
1240 void *value;
1241
1242 clone = auth_cfg_create();
1243 /* this enumerator skips duplicates for rules we expect only once */
1244 enumerator = create_enumerator(this);
1245 while (enumerator->enumerate(enumerator, &type, &value))
1246 {
1247 switch (type)
1248 {
1249 case AUTH_RULE_IDENTITY:
1250 case AUTH_RULE_EAP_IDENTITY:
1251 case AUTH_RULE_AAA_IDENTITY:
1252 case AUTH_RULE_GROUP:
1253 case AUTH_RULE_XAUTH_IDENTITY:
1254 {
1255 identification_t *id = (identification_t*)value;
1256 clone->add(clone, type, id->clone(id));
1257 break;
1258 }
1259 case AUTH_RULE_CA_CERT:
1260 case AUTH_RULE_IM_CERT:
1261 case AUTH_RULE_SUBJECT_CERT:
1262 case AUTH_HELPER_IM_CERT:
1263 case AUTH_HELPER_SUBJECT_CERT:
1264 case AUTH_HELPER_REVOCATION_CERT:
1265 case AUTH_HELPER_AC_CERT:
1266 {
1267 certificate_t *cert = (certificate_t*)value;
1268 clone->add(clone, type, cert->get_ref(cert));
1269 break;
1270 }
1271 case AUTH_RULE_XAUTH_BACKEND:
1272 case AUTH_RULE_CERT_POLICY:
1273 case AUTH_HELPER_IM_HASH_URL:
1274 case AUTH_HELPER_SUBJECT_HASH_URL:
1275 {
1276 clone->add(clone, type, strdup(value));
1277 break;
1278 }
1279 case AUTH_RULE_IDENTITY_LOOSE:
1280 case AUTH_RULE_AUTH_CLASS:
1281 case AUTH_RULE_EAP_TYPE:
1282 case AUTH_RULE_EAP_VENDOR:
1283 case AUTH_RULE_CRL_VALIDATION:
1284 case AUTH_RULE_OCSP_VALIDATION:
1285 case AUTH_RULE_RSA_STRENGTH:
1286 case AUTH_RULE_ECDSA_STRENGTH:
1287 case AUTH_RULE_BLISS_STRENGTH:
1288 case AUTH_RULE_SIGNATURE_SCHEME:
1289 case AUTH_RULE_IKE_SIGNATURE_SCHEME:
1290 case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
1291 clone->add(clone, type, (uintptr_t)value);
1292 break;
1293 case AUTH_RULE_MAX:
1294 break;
1295 }
1296 }
1297 enumerator->destroy(enumerator);
1298 return clone;
1299 }
1300
1301 METHOD(auth_cfg_t, destroy, void,
1302 private_auth_cfg_t *this)
1303 {
1304 purge(this, FALSE);
1305 array_destroy(this->entries);
1306 free(this);
1307 }
1308
1309 /*
1310 * see header file
1311 */
1312 auth_cfg_t *auth_cfg_create()
1313 {
1314 private_auth_cfg_t *this;
1315
1316 INIT(this,
1317 .public = {
1318 .add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add,
1319 .add_pubkey_constraints = _add_pubkey_constraints,
1320 .get = _get,
1321 .create_enumerator = _create_enumerator,
1322 .replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace,
1323 .complies = _complies,
1324 .merge = (void(*)(auth_cfg_t*,auth_cfg_t*,bool))merge,
1325 .purge = _purge,
1326 .equals = (bool(*)(auth_cfg_t*,auth_cfg_t*))equals,
1327 .clone = _clone_,
1328 .destroy = _destroy,
1329 },
1330 .entries = array_create(sizeof(entry_t), 0),
1331 );
1332
1333 return &this->public;
1334 }