workaround for parsing IPv6 PSKs requires extract_last_token()
[strongswan.git] / src / charon / credentials / credential_manager.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * 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 * $Id$
16 */
17
18 #include "credential_manager.h"
19
20 #include <daemon.h>
21 #include <utils/linked_list.h>
22 #include <utils/mutex.h>
23 #include <credentials/sets/cert_cache.h>
24 #include <credentials/sets/auth_info_wrapper.h>
25 #include <credentials/sets/ocsp_response_wrapper.h>
26 #include <credentials/certificates/x509.h>
27 #include <credentials/certificates/crl.h>
28 #include <credentials/certificates/ocsp_request.h>
29 #include <credentials/certificates/ocsp_response.h>
30
31 #define MAX_CA_LEVELS 6
32
33 typedef struct private_credential_manager_t private_credential_manager_t;
34
35 /**
36 * private data of credential_manager
37 */
38 struct private_credential_manager_t {
39
40 /**
41 * public functions
42 */
43 credential_manager_t public;
44
45 /**
46 * list of credential sets
47 */
48 linked_list_t *sets;
49
50 /**
51 * trust relationship and certificate cache
52 */
53 cert_cache_t *cache;
54
55 /**
56 * mutex to gain exclusive access
57 */
58 mutex_t *mutex;
59 };
60
61 /** data to pass to create_private_enumerator */
62 typedef struct {
63 private_credential_manager_t *this;
64 key_type_t type;
65 identification_t* keyid;
66 } private_data_t;
67
68 /** data to pass to create_cert_enumerator */
69 typedef struct {
70 private_credential_manager_t *this;
71 certificate_type_t cert;
72 key_type_t key;
73 identification_t *id;
74 bool trusted;
75 } cert_data_t;
76
77 /** data to pass to create_cdp_enumerator */
78 typedef struct {
79 private_credential_manager_t *this;
80 certificate_type_t type;
81 identification_t *id;
82 } cdp_data_t;
83
84 /** data to pass to create_shared_enumerator */
85 typedef struct {
86 private_credential_manager_t *this;
87 shared_key_type_t type;
88 identification_t *me;
89 identification_t *other;
90 } shared_data_t;
91
92 /**
93 * cleanup function for cert data
94 */
95 static void destroy_cert_data(cert_data_t *data)
96 {
97 data->this->mutex->unlock(data->this->mutex);
98 free(data);
99 }
100
101 /**
102 * enumerator constructor for certificates
103 */
104 static enumerator_t *create_cert(credential_set_t *set, cert_data_t *data)
105 {
106 return set->create_cert_enumerator(set, data->cert, data->key,
107 data->id, data->trusted);
108 }
109
110 /**
111 * Implementation of credential_manager_t.create_cert_enumerator.
112 */
113 static enumerator_t *create_cert_enumerator(private_credential_manager_t *this,
114 certificate_type_t certificate, key_type_t key,
115 identification_t *id, bool trusted)
116 {
117 cert_data_t *data = malloc_thing(cert_data_t);
118 data->this = this;
119 data->cert = certificate;
120 data->key = key;
121 data->id = id;
122 data->trusted = trusted;
123
124 this->mutex->lock(this->mutex);
125 return enumerator_create_nested(this->sets->create_enumerator(this->sets),
126 (void*)create_cert, data,
127 (void*)destroy_cert_data);
128 }
129
130 /**
131 * Implementation of credential_manager_t.get_cert.
132 */
133 static certificate_t *get_cert(private_credential_manager_t *this,
134 certificate_type_t cert, key_type_t key,
135 identification_t *id, bool trusted)
136 {
137 certificate_t *current, *found = NULL;
138 enumerator_t *enumerator;
139
140 this->mutex->lock(this->mutex);
141 enumerator = create_cert_enumerator(this, cert, key, id, trusted);
142 if (enumerator->enumerate(enumerator, &current))
143 {
144 /* TODO: best match? order by keyid, subject, sualtname */
145 found = current->get_ref(current);
146 }
147 enumerator->destroy(enumerator);
148 this->mutex->unlock(this->mutex);
149 return found;
150 }
151
152
153 /**
154 * cleanup function for cdp data
155 */
156 static void destroy_cdp_data(cdp_data_t *data)
157 {
158 data->this->mutex->unlock(data->this->mutex);
159 free(data);
160 }
161
162 /**
163 * enumerator constructor for CDPs
164 */
165 static enumerator_t *create_cdp(credential_set_t *set, cdp_data_t *data)
166 {
167 return set->create_cdp_enumerator(set, data->type, data->id);
168 }
169 /**
170 * Implementation of credential_manager_t.create_cdp_enumerator.
171 */
172 static enumerator_t * create_cdp_enumerator(private_credential_manager_t *this,
173 credential_type_t type, identification_t *id)
174 {
175 cdp_data_t *data = malloc_thing(cdp_data_t);
176 data->this = this;
177 data->type = type;
178 data->id = id;
179
180 this->mutex->lock(this->mutex);
181 return enumerator_create_nested(this->sets->create_enumerator(this->sets),
182 (void*)create_cdp, data,
183 (void*)destroy_cdp_data);
184 }
185
186 /**
187 * cleanup function for private data
188 */
189 static void destroy_private_data(private_data_t *data)
190 {
191 data->this->mutex->unlock(data->this->mutex);
192 free(data);
193 }
194
195 /**
196 * enumerator constructor for private keys
197 */
198 static enumerator_t *create_private(credential_set_t *set, private_data_t *data)
199 {
200 return set->create_private_enumerator(set, data->type, data->keyid);
201 }
202
203 /**
204 * Implementation of credential_manager_t.get_private_by_keyid.
205 */
206 static enumerator_t* create_private_enumerator(
207 private_credential_manager_t *this,
208 key_type_t key, identification_t *keyid)
209 {
210 private_data_t *data;
211
212 data = malloc_thing(private_data_t);
213 data->this = this;
214 data->type = key;
215 data->keyid = keyid;
216 this->mutex->lock(this->mutex);
217 return enumerator_create_nested(this->sets->create_enumerator(this->sets),
218 (void*)create_private, data, (void*)destroy_private_data);
219 }
220
221 /**
222 * Implementation of credential_manager_t.get_private_by_keyid.
223 */
224 static private_key_t *get_private_by_keyid(private_credential_manager_t *this,
225 key_type_t key, identification_t *keyid)
226 {
227 private_key_t *found = NULL;
228 enumerator_t *enumerator;
229
230 enumerator = create_private_enumerator(this, key, keyid);
231 if (enumerator->enumerate(enumerator, &found))
232 {
233 found->get_ref(found);
234 }
235 enumerator->destroy(enumerator);
236 return found;
237 }
238
239 /**
240 * cleanup function for shared data
241 */
242 static void destroy_shared_data(shared_data_t *data)
243 {
244 data->this->mutex->unlock(data->this->mutex);
245 free(data);
246 }
247
248 /**
249 * enumerator constructor for shared keys
250 */
251 static enumerator_t *create_shared(credential_set_t *set, shared_data_t *data)
252 {
253 return set->create_shared_enumerator(set, data->type, data->me, data->other);
254 }
255
256 /**
257 * Implementation of credential_manager_t.create_shared_enumerator.
258 */
259 static enumerator_t *create_shared_enumerator(private_credential_manager_t *this,
260 shared_key_type_t type,
261 identification_t *me, identification_t *other)
262 {
263 shared_data_t *data = malloc_thing(shared_data_t);
264 data->this = this;
265 data->type = type;
266 data->me = me;
267 data->other = other;
268
269 this->mutex->lock(this->mutex);
270 return enumerator_create_nested(this->sets->create_enumerator(this->sets),
271 (void*)create_shared, data,
272 (void*)destroy_shared_data);
273 }
274
275 /**
276 * Implementation of credential_manager_t.get_shared.
277 */
278 static shared_key_t *get_shared(private_credential_manager_t *this,
279 shared_key_type_t type, identification_t *me,
280 identification_t *other)
281 {
282 shared_key_t *current, *found = NULL;
283 id_match_t *best_me = ID_MATCH_NONE, *best_other = ID_MATCH_NONE;
284 id_match_t *match_me, *match_other;
285 enumerator_t *enumerator;
286
287 enumerator = create_shared_enumerator(this, type, me, other);
288 while (enumerator->enumerate(enumerator, &current, &match_me, &match_other))
289 {
290 if (match_other > best_other ||
291 (match_other == best_other && match_me > best_me))
292 {
293 DESTROY_IF(found);
294 found = current->get_ref(current);
295 best_me = match_me;
296 best_other = match_other;
297 }
298 }
299 enumerator->destroy(enumerator);
300 return found;
301 }
302
303 /**
304 * forward declaration
305 */
306
307 static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
308 key_type_t type, identification_t *id, bool crl, bool ocsp);
309 /**
310 * Do an OCSP request
311 */
312 static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url,
313 certificate_t *subject, certificate_t *issuer)
314 {
315 certificate_t *request, *response;
316 chunk_t send, receive;
317
318 /* TODO: requestor name, signature */
319 request = lib->creds->create(lib->creds,
320 CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
321 BUILD_CA_CERT, issuer->get_ref(issuer),
322 BUILD_CERT, subject->get_ref(subject), BUILD_END);
323 if (!request)
324 {
325 DBG1(DBG_CFG, "generating ocsp request failed");
326 return NULL;
327 }
328
329 send = request->get_encoding(request);
330 request->destroy(request);
331
332 DBG1(DBG_CFG, "requesting ocsp status from '%s' ...", url);
333 /* TODO: unlock manager while fetching? */
334 if (lib->fetcher->fetch(lib->fetcher, url, &receive,
335 FETCH_REQUEST_DATA, send,
336 FETCH_REQUEST_TYPE, "application/ocsp-request",
337 FETCH_END) != SUCCESS)
338 {
339 DBG1(DBG_CFG, "ocsp request to %s failed", url);
340 chunk_free(&send);
341 return NULL;
342 }
343 chunk_free(&send);
344
345 response = lib->creds->create(lib->creds,
346 CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
347 BUILD_BLOB_ASN1_DER, receive, BUILD_END);
348 if (!response)
349 {
350 DBG1(DBG_CFG, "parsing ocsp response failed");
351 return NULL;
352 }
353 return response;
354 }
355
356 /**
357 * check the signature of an OCSP response
358 */
359 static bool verify_ocsp(private_credential_manager_t *this,
360 ocsp_response_t *response)
361 {
362 certificate_t *issuer, *subject;
363 identification_t *responder;
364 ocsp_response_wrapper_t *wrapper;
365 enumerator_t *enumerator;
366 bool verified = FALSE;
367
368 wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response);
369 this->sets->insert_last(this->sets, wrapper);
370
371 subject = &response->certificate;
372 responder = subject->get_issuer(subject);
373 enumerator = create_trusted_enumerator(this, KEY_ANY, responder, FALSE, FALSE);
374 while (enumerator->enumerate(enumerator, &issuer, NULL))
375 {
376 if (this->cache->issued_by(this->cache, subject, issuer))
377 {
378 DBG1(DBG_CFG, " ocsp response correctly signed by \"%D\"",
379 issuer->get_subject(issuer));
380 verified = TRUE;
381 break;
382 }
383 }
384 enumerator->destroy(enumerator);
385
386 this->sets->remove(this->sets, wrapper, NULL);
387 wrapper->destroy(wrapper);
388 return verified;
389 }
390
391 /**
392 * Get the better of two OCSP responses, and check for usable OCSP info
393 */
394 static certificate_t *get_better_ocsp(private_credential_manager_t *this,
395 certificate_t *cand, certificate_t *best,
396 x509_t *subject, x509_t *issuer,
397 cert_validation_t *valid)
398 {
399 ocsp_response_t *response;
400 time_t revocation, this_update, next_update, valid_until;
401 crl_reason_t reason;
402
403 response = (ocsp_response_t*)cand;
404
405 /* check ocsp signature */
406 if (!verify_ocsp(this, response))
407 {
408 DBG1(DBG_CFG, "ocsp response verification failed");
409 cand->destroy(cand);
410 return best;
411 }
412 /* check if response contains our certificate */
413 switch (response->get_status(response, subject, issuer, &revocation, &reason,
414 &this_update, &next_update))
415 {
416 case VALIDATION_REVOKED:
417 /* subject has been revoked by a valid OCSP response */
418 DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
419 &revocation, crl_reason_names, reason);
420 DESTROY_IF(best);
421 *valid = VALIDATION_REVOKED;
422 return cand;
423 case VALIDATION_GOOD:
424 /* results in either good or stale */
425 break;
426 default:
427 case VALIDATION_FAILED:
428 /* candidate unusable, does not contain our cert */
429 cand->destroy(cand);
430 return best;
431 }
432
433 /* select the better of the two responses */
434 if (best == NULL || cand->is_newer(cand, best))
435 {
436 DESTROY_IF(best);
437 best = cand;
438 if (best->get_validity(best, NULL, NULL, &valid_until))
439 {
440 DBG1(DBG_CFG, " ocsp response is valid: until %#T",
441 &valid_until, FALSE);
442 *valid = VALIDATION_GOOD;
443 }
444 else
445 {
446 DBG1(DBG_CFG, " ocsp response is stale: since %#T",
447 &valid_until, FALSE);
448 *valid = VALIDATION_STALE;
449 }
450 }
451 else
452 {
453 *valid = VALIDATION_STALE;
454 cand->destroy(cand);
455 }
456 return best;
457 }
458
459 /**
460 * validate a x509 certificate using OCSP
461 */
462 static cert_validation_t check_ocsp(private_credential_manager_t *this,
463 x509_t *subject, x509_t *issuer,
464 auth_info_t *auth)
465 {
466 enumerator_t *enumerator;
467 cert_validation_t valid = VALIDATION_SKIPPED;
468 certificate_t *best = NULL, *current;
469 identification_t *keyid = NULL;
470 public_key_t *public;
471 char *uri = NULL;
472
473 /** lookup cache for valid OCSP responses */
474 enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE,
475 KEY_ANY, NULL, FALSE);
476 while (enumerator->enumerate(enumerator, &current))
477 {
478 current->get_ref(current);
479 best = get_better_ocsp(this, current, best, subject, issuer, &valid);
480 if (best && valid != VALIDATION_STALE)
481 {
482 DBG1(DBG_CFG, "found cached ocsp response");
483 break;
484 }
485 }
486 enumerator->destroy(enumerator);
487
488 /* derive the authorityKeyIdentifier from the issuer's public key */
489 current = &issuer->interface;
490 public = current->get_public_key(current);
491 if (public)
492 {
493 keyid = public->get_id(public, ID_PUBKEY_SHA1);
494 }
495 /** fetch from configured OCSP responder URLs */
496 if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
497 {
498 enumerator = create_cdp_enumerator(this, CERT_X509_OCSP_RESPONSE, keyid);
499 while (enumerator->enumerate(enumerator, &uri))
500 {
501 current = fetch_ocsp(this, uri, &subject->interface,
502 &issuer->interface);
503 if (current)
504 {
505 best = get_better_ocsp(this, current, best, subject, issuer, &valid);
506 if (best && valid != VALIDATION_STALE)
507 {
508 break;
509 }
510 }
511 }
512 enumerator->destroy(enumerator);
513 }
514 DESTROY_IF(public);
515
516 /* fallback to URL fetching from subject certificate's URIs */
517 if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
518 {
519 enumerator = subject->create_ocsp_uri_enumerator(subject);
520 while (enumerator->enumerate(enumerator, &uri))
521 {
522 current = fetch_ocsp(this, uri, &subject->interface,
523 &issuer->interface);
524 if (current)
525 {
526 best = get_better_ocsp(this, current, best, subject, issuer, &valid);
527 if (best && valid != VALIDATION_STALE)
528 {
529 break;
530 }
531 }
532 }
533 enumerator->destroy(enumerator);
534 }
535 /* an uri was found, but no result. switch validation state to failed */
536 if (valid == VALIDATION_SKIPPED && uri)
537 {
538 valid = VALIDATION_FAILED;
539 }
540 if (auth)
541 {
542 auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid);
543 }
544 DESTROY_IF(best);
545 return valid;
546 }
547
548 /**
549 * fetch a CRL from an URL
550 */
551 static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
552 {
553 certificate_t *crl;
554 chunk_t chunk;
555
556 /* TODO: unlock the manager while fetching? */
557 DBG1(DBG_CFG, "fetching crl from '%s' ...", url);
558 if (lib->fetcher->fetch(lib->fetcher, url, &chunk, FETCH_END) != SUCCESS)
559 {
560 DBG1(DBG_CFG, "crl fetching failed");
561 return NULL;
562 }
563 crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
564 BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
565 if (!crl)
566 {
567 DBG1(DBG_CFG, "crl fetched successfully but parsing failed");
568 return NULL;
569 }
570 return crl;
571 }
572
573 /**
574 * check the signature of an CRL
575 */
576 static bool verify_crl(private_credential_manager_t *this, certificate_t *crl)
577 {
578 certificate_t *issuer;
579 enumerator_t *enumerator;
580 bool verified = FALSE;
581
582 enumerator = create_trusted_enumerator(this, KEY_ANY, crl->get_issuer(crl),
583 FALSE, FALSE);
584 while (enumerator->enumerate(enumerator, &issuer, NULL))
585 {
586 if (this->cache->issued_by(this->cache, crl, issuer))
587 {
588 DBG1(DBG_CFG, " crl correctly signed by \"%D\"",
589 issuer->get_subject(issuer));
590 verified = TRUE;
591 break;
592 }
593 }
594 enumerator->destroy(enumerator);
595
596 return verified;
597 }
598
599 /**
600 * Get the better of two CRLs, and check for usable CRL info
601 */
602 static certificate_t *get_better_crl(private_credential_manager_t *this,
603 certificate_t *cand, certificate_t *best,
604 x509_t *subject, x509_t *issuer,
605 cert_validation_t *valid)
606 {
607 enumerator_t *enumerator;
608 time_t revocation, valid_until;
609 crl_reason_t reason;
610 chunk_t serial;
611 crl_t *crl;
612
613 /* check CRL signature */
614 if (!verify_crl(this, cand))
615 {
616 DBG1(DBG_CFG, "crl response verification failed");
617 cand->destroy(cand);
618 return best;
619 }
620
621 crl = (crl_t*)cand;
622 enumerator = crl->create_enumerator(crl);
623 while (enumerator->enumerate(enumerator, &serial, &revocation, &reason))
624 {
625 if (chunk_equals(serial, subject->get_serial(subject)))
626 {
627 DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
628 &revocation, crl_reason_names, reason);
629 *valid = VALIDATION_REVOKED;
630 enumerator->destroy(enumerator);
631 DESTROY_IF(best);
632 return cand;
633 }
634 }
635 enumerator->destroy(enumerator);
636
637 /* select the better of the two CRLs */
638 if (best == NULL || cand->is_newer(cand, best))
639 {
640 DESTROY_IF(best);
641 best = cand;
642 if (best->get_validity(best, NULL, NULL, &valid_until))
643 {
644 DBG1(DBG_CFG, " crl is valid: until %#T", &valid_until, FALSE);
645 *valid = VALIDATION_GOOD;
646 }
647 else
648 {
649 DBG1(DBG_CFG, " crl is stale: since %#T", &valid_until, FALSE);
650 *valid = VALIDATION_STALE;
651 }
652 }
653 else
654 {
655 *valid = VALIDATION_STALE;
656 cand->destroy(cand);
657 }
658 return best;
659 }
660
661 /**
662 * validate a x509 certificate using CRL
663 */
664 static cert_validation_t check_crl(private_credential_manager_t *this,
665 x509_t *subject, x509_t *issuer,
666 auth_info_t *auth)
667 {
668 cert_validation_t valid = VALIDATION_SKIPPED;
669 identification_t *keyid = NULL;
670 certificate_t *best = NULL;
671 certificate_t *current;
672 public_key_t *public;
673 enumerator_t *enumerator;
674 char *uri;
675
676 /* derive the authorityKeyIdentifier from the issuer's public key */
677 current = &issuer->interface;
678 public = current->get_public_key(current);
679 if (public)
680 {
681 keyid = public->get_id(public, ID_PUBKEY_SHA1);
682 }
683
684 /* find a cached crl by authorityKeyIdentifier */
685 if (keyid)
686 {
687 enumerator = create_cert_enumerator(this, CERT_X509_CRL, KEY_ANY,
688 keyid, FALSE);
689 while (enumerator->enumerate(enumerator, &current))
690 {
691 current->get_ref(current);
692 best = get_better_crl(this, current, best, subject, issuer, &valid);
693 if (best && valid != VALIDATION_STALE)
694 {
695 DBG1(DBG_CFG, "found cached crl");
696 break;
697 }
698 }
699 enumerator->destroy(enumerator);
700 }
701
702 /* fallback to fetching crls from credential sets cdps */
703 if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
704 {
705 enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid);
706
707 while (enumerator->enumerate(enumerator, &uri))
708 {
709 current = fetch_crl(this, uri);
710 if (current)
711 {
712 best = get_better_crl(this, current, best, subject, issuer, &valid);
713 if (best && valid != VALIDATION_STALE)
714 {
715 break;
716 }
717 }
718 }
719 enumerator->destroy(enumerator);
720 }
721 DESTROY_IF(public);
722
723 /* fallback to fetching crls from cdps from subject's certificate */
724 if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
725 {
726 enumerator = subject->create_crl_uri_enumerator(subject);
727
728 while (enumerator->enumerate(enumerator, &uri))
729 {
730 current = fetch_crl(this, uri);
731 if (current)
732 {
733 best = get_better_crl(this, current, best, subject, issuer, &valid);
734 if (best && valid != VALIDATION_STALE)
735 {
736 break;
737 }
738 }
739 }
740 enumerator->destroy(enumerator);
741 }
742
743 /* an uri was found, but no result. switch validation state to failed */
744 if (valid == VALIDATION_SKIPPED && uri)
745 {
746 valid = VALIDATION_FAILED;
747 }
748 if (auth)
749 {
750 auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
751 }
752 DESTROY_IF(best);
753 return valid;
754 }
755
756 /**
757 * check a certificate for its lifetime
758 */
759 static bool check_certificate(private_credential_manager_t *this,
760 certificate_t *subject, certificate_t *issuer,
761 bool crl, bool ocsp, auth_info_t *auth)
762 {
763 time_t not_before, not_after;
764
765 if (!subject->get_validity(subject, NULL, &not_before, &not_after))
766 {
767 DBG1(DBG_CFG, "subject certificate invalid (valid from %T to %T)",
768 &not_before, &not_after);
769 return FALSE;
770 }
771 if (!issuer->get_validity(issuer, NULL, &not_before, &not_after))
772 {
773 DBG1(DBG_CFG, "issuer certificate invalid (valid from %T to %T)",
774 &not_before, &not_after);
775 return FALSE;
776 }
777 if (issuer->get_type(issuer) == CERT_X509 &&
778 subject->get_type(subject) == CERT_X509)
779 {
780 if (ocsp)
781 {
782 switch (check_ocsp(this, (x509_t*)subject, (x509_t*)issuer, auth))
783 {
784 case VALIDATION_GOOD:
785 DBG1(DBG_CFG, "certificate status is good");
786 return TRUE;
787 case VALIDATION_REVOKED:
788 /* has already been logged */
789 return FALSE;
790 case VALIDATION_SKIPPED:
791 DBG2(DBG_CFG, "ocsp check skipped, no ocsp found");
792 break;
793 case VALIDATION_STALE:
794 DBG1(DBG_CFG, "ocsp information stale, fallback to crl");
795 break;
796 case VALIDATION_FAILED:
797 DBG1(DBG_CFG, "ocsp check failed, fallback to crl");
798 break;
799 }
800 }
801 if (crl)
802 {
803 switch (check_crl(this, (x509_t*)subject, (x509_t*)issuer, auth))
804 {
805 case VALIDATION_GOOD:
806 DBG1(DBG_CFG, "certificate status is good");
807 return TRUE;
808 case VALIDATION_REVOKED:
809 /* has already been logged */
810 return FALSE;
811 case VALIDATION_FAILED:
812 case VALIDATION_SKIPPED:
813 DBG1(DBG_CFG, "certificate status is not available");
814 break;
815 case VALIDATION_STALE:
816 DBG1(DBG_CFG, "certificate status is unknown, crl is stale");
817 break;
818 }
819 }
820 }
821 return TRUE;
822 }
823
824 /**
825 * Get a trusted certificate from a credential set
826 */
827 static certificate_t *get_pretrusted_cert(private_credential_manager_t *this,
828 key_type_t type, identification_t *id)
829 {
830 certificate_t *subject;
831 public_key_t *public;
832
833 subject = get_cert(this, CERT_ANY, type, id, TRUE);
834 if (!subject)
835 {
836 return NULL;
837 }
838 public = subject->get_public_key(subject);
839 if (!public)
840 {
841 subject->destroy(subject);
842 return NULL;
843 }
844 public->destroy(public);
845 return subject;
846 }
847
848 /**
849 * Get the issuing certificate of a subject certificate
850 */
851 static certificate_t *get_issuer_cert(private_credential_manager_t *this,
852 certificate_t *subject, bool trusted)
853 {
854 enumerator_t *enumerator;
855 certificate_t *issuer = NULL, *candidate;
856
857 enumerator = create_cert_enumerator(this, subject->get_type(subject), KEY_ANY,
858 subject->get_issuer(subject), trusted);
859 while (enumerator->enumerate(enumerator, &candidate))
860 {
861 if (this->cache->issued_by(this->cache, subject, candidate))
862 {
863 issuer = candidate->get_ref(candidate);
864 break;
865 }
866 }
867 enumerator->destroy(enumerator);
868 return issuer;
869 }
870
871 /**
872 * try to verify the trust chain of subject, return TRUE if trusted
873 */
874 static bool verify_trust_chain(private_credential_manager_t *this,
875 certificate_t *subject, auth_info_t *result,
876 bool trusted, bool crl, bool ocsp)
877 {
878 certificate_t *current, *issuer;
879 auth_info_t *auth;
880 u_int level = 0;
881
882 auth = auth_info_create();
883 current = subject->get_ref(subject);
884 while (level++ < MAX_CA_LEVELS)
885 {
886 issuer = get_issuer_cert(this, current, TRUE);
887 if (issuer)
888 {
889 /* accept only self-signed CAs as trust anchor */
890 if (this->cache->issued_by(this->cache, issuer, issuer))
891 {
892 auth->add_item(auth, AUTHZ_CA_CERT, issuer);
893 DBG1(DBG_CFG, " using trusted ca certificate \"%D\"",
894 issuer->get_subject(issuer));
895 trusted = TRUE;
896 }
897 else
898 {
899 auth->add_item(auth, AUTHZ_IM_CERT, issuer);
900 DBG1(DBG_CFG, " using trusted intermediate ca certificate "
901 "\"%D\"", issuer->get_subject(issuer));
902 }
903 }
904 else
905 {
906 issuer = get_issuer_cert(this, current, FALSE);
907 if (issuer)
908 {
909 if (current->equals(current, issuer))
910 {
911 DBG1(DBG_CFG, " self-signed certificate \"%D\" is not trusted",
912 current->get_subject(current));
913 issuer->destroy(issuer);
914 break;
915 }
916 auth->add_item(auth, AUTHZ_IM_CERT, issuer);
917 DBG1(DBG_CFG, " using untrusted intermediate certificate "
918 "\"%D\"", issuer->get_subject(issuer));
919 }
920 else
921 {
922 DBG1(DBG_CFG, "no issuer certificate found for \"%D\"",
923 current->get_subject(current));
924 issuer->destroy(issuer);
925 break;
926 }
927 }
928 if (!check_certificate(this, current, issuer, crl, ocsp,
929 current == subject ? auth : NULL))
930 {
931 trusted = FALSE;
932 issuer->destroy(issuer);
933 break;
934 }
935 current->destroy(current);
936 current = issuer;
937 if (trusted)
938 {
939 break;
940 }
941 }
942 current->destroy(current);
943 if (level > MAX_CA_LEVELS)
944 {
945 DBG1(DBG_CFG, "maximum ca path length of %d levels reached", level);
946 }
947 if (trusted)
948 {
949 result->merge(result, auth);
950 }
951 auth->destroy(auth);
952 return trusted;
953 }
954
955 /**
956 * enumerator for trusted certificates
957 */
958 typedef struct {
959 /** implements enumerator_t interface */
960 enumerator_t public;
961 /** enumerator over candidate peer certificates */
962 enumerator_t *candidates;
963 /** reference to the credential_manager */
964 private_credential_manager_t *this;
965 /** type of the requested key */
966 key_type_t type;
967 /** identity the requested key belongs to */
968 identification_t *id;
969 /** TRUE to do CRL checking */
970 bool crl;
971 /** TRUE to do OCSP checking */
972 bool ocsp;
973 /** pretrusted certificate we have served at first invocation */
974 certificate_t *pretrusted;
975 /** currently enumerating auth info */
976 auth_info_t *auth;
977 } trusted_enumerator_t;
978
979 /**
980 * Implements trusted_enumerator_t.enumerate
981 */
982 static bool trusted_enumerate(trusted_enumerator_t *this,
983 certificate_t **cert, auth_info_t **auth)
984 {
985 certificate_t *current;
986
987 DESTROY_IF(this->auth);
988 this->auth = auth_info_create();
989
990 if (!this->candidates)
991 {
992 /* first invocation, build enumerator for next one */
993 this->candidates = create_cert_enumerator(this->this, CERT_ANY,
994 this->type, this->id, FALSE);
995 /* check if we have a trusted certificate for that peer */
996 this->pretrusted = get_pretrusted_cert(this->this, this->type, this->id);
997 if (this->pretrusted)
998 {
999 /* if we find a trusted self signed certificate, we just accept it.
1000 * However, in order to fulfill authorization rules, we try to build
1001 * the trust chain if it is not self signed */
1002 if (this->this->cache->issued_by(this->this->cache,
1003 this->pretrusted, this->pretrusted) ||
1004 verify_trust_chain(this->this, this->pretrusted, this->auth,
1005 TRUE, this->crl, this->ocsp))
1006 {
1007 DBG1(DBG_CFG, " using trusted certificate \"%D\"",
1008 this->pretrusted->get_subject(this->pretrusted));
1009 *cert = this->pretrusted;
1010 if (auth)
1011 {
1012 *auth = this->auth;
1013 }
1014 return TRUE;
1015 }
1016 }
1017 }
1018 /* try to verify the trust chain for each certificate found */
1019 while (this->candidates->enumerate(this->candidates, &current))
1020 {
1021 if (this->pretrusted &&
1022 this->pretrusted->equals(this->pretrusted, current))
1023 { /* skip pretrusted certificate we already served */
1024 continue;
1025 }
1026
1027 DBG1(DBG_CFG, " using certificate \"%D\"",
1028 current->get_subject(current));
1029 if (verify_trust_chain(this->this, current, this->auth, FALSE,
1030 this->crl, this->ocsp))
1031 {
1032 *cert = current;
1033 if (auth)
1034 {
1035 *auth = this->auth;
1036 }
1037 return TRUE;
1038 }
1039 }
1040 return FALSE;
1041 }
1042
1043 /**
1044 * Implements trusted_enumerator_t.destroy
1045 */
1046 static void trusted_destroy(trusted_enumerator_t *this)
1047 {
1048 DESTROY_IF(this->pretrusted);
1049 DESTROY_IF(this->auth);
1050 DESTROY_IF(this->candidates);
1051 free(this);
1052 }
1053
1054 /**
1055 * create an enumerator over trusted certificates and their trustchain
1056 */
1057 static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
1058 key_type_t type, identification_t *id, bool crl, bool ocsp)
1059 {
1060 trusted_enumerator_t *enumerator = malloc_thing(trusted_enumerator_t);
1061
1062 enumerator->public.enumerate = (void*)trusted_enumerate;
1063 enumerator->public.destroy = (void*)trusted_destroy;
1064
1065 enumerator->candidates = NULL;
1066 enumerator->this = this;
1067 enumerator->type = type;
1068 enumerator->id = id;
1069 enumerator->crl = crl;
1070 enumerator->ocsp = ocsp;
1071 enumerator->pretrusted = NULL;
1072 enumerator->auth = NULL;
1073
1074 return &enumerator->public;
1075 }
1076
1077 /**
1078 * enumerator for public keys
1079 */
1080 typedef struct {
1081 /** implements enumerator_t interface */
1082 enumerator_t public;
1083 /** enumerator over candidate peer certificates */
1084 enumerator_t *inner;
1085 /** reference to the credential_manager */
1086 private_credential_manager_t *this;
1087 /** currently enumerating key */
1088 public_key_t *current;
1089 /** credset wrapper around auth */
1090 auth_info_wrapper_t *wrapper;
1091 } public_enumerator_t;
1092
1093 /**
1094 * Implements public_enumerator_t.enumerate
1095 */
1096 static bool public_enumerate(public_enumerator_t *this,
1097 public_key_t **key, auth_info_t **auth)
1098 {
1099 certificate_t *cert;
1100
1101 while (this->inner->enumerate(this->inner, &cert, auth))
1102 {
1103 DESTROY_IF(this->current);
1104 this->current = cert->get_public_key(cert);
1105 if (this->current)
1106 {
1107 *key = this->current;
1108 return TRUE;
1109 }
1110 }
1111 return FALSE;
1112 }
1113
1114 /**
1115 * Implements public_enumerator_t.destroy
1116 */
1117 static void public_destroy(public_enumerator_t *this)
1118 {
1119 DESTROY_IF(this->current);
1120 this->inner->destroy(this->inner);
1121 if (this->wrapper)
1122 {
1123 this->this->sets->remove(this->this->sets, this->wrapper, NULL);
1124 this->wrapper->destroy(this->wrapper);
1125 }
1126 this->this->mutex->unlock(this->this->mutex);
1127 free(this);
1128 }
1129
1130 /**
1131 * Implementation of credential_manager_t.create_public_enumerator.
1132 */
1133 static enumerator_t* create_public_enumerator(private_credential_manager_t *this,
1134 key_type_t type, identification_t *id, auth_info_t *auth)
1135 {
1136 public_enumerator_t *enumerator = malloc_thing(public_enumerator_t);
1137
1138 enumerator->public.enumerate = (void*)public_enumerate;
1139 enumerator->public.destroy = (void*)public_destroy;
1140 enumerator->inner = create_trusted_enumerator(this, type, id, TRUE, TRUE);
1141 enumerator->this = this;
1142 enumerator->current = NULL;
1143 enumerator->wrapper = NULL;
1144 this->mutex->lock(this->mutex);
1145 if (auth)
1146 {
1147 enumerator->wrapper = auth_info_wrapper_create(auth);
1148 this->sets->insert_last(this->sets, enumerator->wrapper);
1149 }
1150 return &enumerator->public;
1151 }
1152
1153 /**
1154 * Check if a certificate's keyid is contained in the auth helper
1155 */
1156 static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
1157 {
1158 enumerator_t *enumerator;
1159 identification_t *value;
1160 auth_item_t type;
1161 bool found = FALSE;
1162
1163 enumerator = auth->create_item_enumerator(auth);
1164 while (enumerator->enumerate(enumerator, &type, &value))
1165 {
1166 if (type == AUTHN_CA_CERT && cert->equals(cert, (certificate_t*)value))
1167 {
1168 found = TRUE;
1169 break;
1170 }
1171 if (type == AUTHN_CA_CERT_KEYID)
1172 {
1173 public_key_t *public;
1174 identification_t *certid, *keyid;
1175
1176 public = cert->get_public_key(cert);
1177 if (public)
1178 {
1179 keyid = (identification_t*)value;
1180 certid = public->get_id(public, keyid->get_type(keyid));
1181 if (certid && certid->equals(certid, keyid))
1182 {
1183 public->destroy(public);
1184 found = TRUE;
1185 break;
1186 }
1187 public->destroy(public);
1188 }
1189 }
1190 }
1191 enumerator->destroy(enumerator);
1192 return found;
1193 }
1194
1195 /**
1196 * build a trustchain from subject up to a trust anchor in trusted
1197 */
1198 static auth_info_t *build_trustchain(private_credential_manager_t *this,
1199 certificate_t *subject, auth_info_t *auth)
1200 {
1201 certificate_t *issuer, *current;
1202 auth_info_t *trustchain;
1203 u_int level = 0;
1204
1205 trustchain = auth_info_create();
1206
1207 if (!auth->get_item(auth, AUTHN_CA_CERT, (void**)&current))
1208 {
1209 /* no trust anchor specified, return this cert only */
1210 trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, subject);
1211 return trustchain;
1212 }
1213 current = subject->get_ref(subject);
1214 while (TRUE)
1215 {
1216 if (auth_contains_cacert(auth, current))
1217 {
1218 trustchain->add_item(trustchain, AUTHZ_CA_CERT, current);
1219 current->destroy(current);
1220 return trustchain;
1221 }
1222 if (subject == current)
1223 {
1224 trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, current);
1225 }
1226 else
1227 {
1228 trustchain->add_item(trustchain, AUTHZ_IM_CERT, current);
1229 }
1230 issuer = get_issuer_cert(this, current, FALSE);
1231 if (!issuer || issuer->equals(issuer, current) || level > MAX_CA_LEVELS)
1232 {
1233 DESTROY_IF(issuer);
1234 current->destroy(current);
1235 break;
1236 }
1237 current->destroy(current);
1238 current = issuer;
1239 level++;
1240 }
1241 trustchain->destroy(trustchain);
1242 return NULL;
1243 }
1244
1245 /**
1246 * find a private key of a give certificate
1247 */
1248 static private_key_t *get_private_by_cert(private_credential_manager_t *this,
1249 certificate_t *cert, key_type_t type)
1250 {
1251 private_key_t *private = NULL;
1252 identification_t* keyid;
1253 public_key_t *public;
1254
1255 public = cert->get_public_key(cert);
1256 if (public)
1257 {
1258 keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
1259 if (keyid)
1260 {
1261 private = get_private_by_keyid(this, type, keyid);
1262 }
1263 public->destroy(public);
1264 }
1265 return private;
1266 }
1267
1268 /**
1269 * Implementation of credential_manager_t.get_private.
1270 */
1271 static private_key_t *get_private(private_credential_manager_t *this,
1272 key_type_t type, identification_t *id,
1273 auth_info_t *auth)
1274 {
1275 enumerator_t *enumerator;
1276 certificate_t *cert;
1277 private_key_t *private = NULL;
1278 auth_info_t *trustchain;
1279
1280 /* check if this is a lookup by key ID, and do it if so */
1281 if (id)
1282 {
1283 switch (id->get_type(id))
1284 {
1285 case ID_PUBKEY_SHA1:
1286 case ID_PUBKEY_INFO_SHA1:
1287 return get_private_by_keyid(this, type, id);
1288 default:
1289 break;
1290 }
1291 }
1292
1293 this->mutex->lock(this->mutex);
1294 /* try to build a trustchain for each certificate found */
1295 enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
1296 while (enumerator->enumerate(enumerator, &cert))
1297 {
1298 private = get_private_by_cert(this, cert, type);
1299 if (private)
1300 {
1301 trustchain = build_trustchain(this, cert, auth);
1302 if (trustchain)
1303 {
1304 auth->merge(auth, trustchain);
1305 trustchain->destroy(trustchain);
1306 break;
1307 }
1308 private->destroy(private);
1309 private = NULL;
1310 }
1311 }
1312 enumerator->destroy(enumerator);
1313 /* if no valid trustchain was found, fall back to the first usable cert */
1314 if (!private)
1315 {
1316 enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
1317 while (enumerator->enumerate(enumerator, &cert))
1318 {
1319 private = get_private_by_cert(this, cert, type);
1320 if (private)
1321 {
1322 auth->add_item(auth, AUTHZ_SUBJECT_CERT, cert);
1323 break;
1324 }
1325 }
1326 enumerator->destroy(enumerator);
1327 }
1328 this->mutex->unlock(this->mutex);
1329 return private;
1330 }
1331
1332 /**
1333 * Implementation of credential_manager_t.flush_cache.
1334 */
1335 static void flush_cache(private_credential_manager_t *this,
1336 certificate_type_t type)
1337 {
1338 this->mutex->lock(this->mutex);
1339 this->cache->flush(this->cache, type);
1340 this->mutex->unlock(this->mutex);
1341 }
1342
1343 /**
1344 * Implementation of credential_manager_t.add_set.
1345 */
1346 static void add_set(private_credential_manager_t *this,
1347 credential_set_t *set)
1348 {
1349 this->mutex->lock(this->mutex);
1350 this->sets->insert_last(this->sets, set);
1351 this->mutex->unlock(this->mutex);
1352 }
1353 /**
1354 * Implementation of credential_manager_t.remove_set.
1355 */
1356 static void remove_set(private_credential_manager_t *this, credential_set_t *set)
1357 {
1358 this->mutex->lock(this->mutex);
1359 this->sets->remove(this->sets, set, NULL);
1360 this->mutex->unlock(this->mutex);
1361 }
1362
1363 /**
1364 * Implementation of credential_manager_t.destroy
1365 */
1366 static void destroy(private_credential_manager_t *this)
1367 {
1368 this->sets->remove(this->sets, this->cache, NULL);
1369 this->sets->destroy(this->sets);
1370 this->cache->destroy(this->cache);
1371 this->mutex->destroy(this->mutex);
1372 free(this);
1373 }
1374
1375 /*
1376 * see header file
1377 */
1378 credential_manager_t *credential_manager_create()
1379 {
1380 private_credential_manager_t *this = malloc_thing(private_credential_manager_t);
1381
1382 this->public.create_cert_enumerator = (enumerator_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *id,bool))create_cert_enumerator;
1383 this->public.create_shared_enumerator = (enumerator_t *(*)(credential_manager_t *this, shared_key_type_t type,identification_t *me, identification_t *other))create_shared_enumerator;
1384 this->public.create_cdp_enumerator = (enumerator_t *(*)(credential_manager_t*, credential_type_t type, identification_t *id))create_cdp_enumerator;
1385 this->public.get_cert = (certificate_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *, bool))get_cert;
1386 this->public.get_shared = (shared_key_t *(*)(credential_manager_t *this,shared_key_type_t type,identification_t *me, identification_t *other))get_shared;
1387 this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_info_t*))get_private;
1388 this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_info_t *aut))create_public_enumerator;
1389 this->public.flush_cache = (void(*)(credential_manager_t*, certificate_type_t type))flush_cache;
1390 this->public.add_set = (void(*)(credential_manager_t*, credential_set_t *set))add_set;
1391 this->public.remove_set = (void(*)(credential_manager_t*, credential_set_t *set))remove_set;
1392 this->public.destroy = (void(*)(credential_manager_t*))destroy;
1393
1394 this->sets = linked_list_create();
1395 this->cache = cert_cache_create();
1396 this->sets->insert_first(this->sets, this->cache);
1397 this->mutex = mutex_create(MUTEX_RECURSIVE);
1398
1399 return &this->public;
1400 }
1401