use trusted self-signed root CA certificates as trust anchor only
[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 static certificate_t *get_trusted_cert(private_credential_manager_t *this,
307 key_type_t type, identification_t *id,
308 auth_info_t *auth, bool crl, bool ocsp);
309
310 /**
311 * Do an OCSP request
312 */
313 static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url,
314 certificate_t *subject, certificate_t *issuer)
315 {
316 certificate_t *request, *response;
317 chunk_t send, receive;
318
319 /* TODO: requestor name, signature */
320 request = lib->creds->create(lib->creds,
321 CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
322 BUILD_CA_CERT, issuer->get_ref(issuer),
323 BUILD_CERT, subject->get_ref(subject), BUILD_END);
324 if (!request)
325 {
326 DBG1(DBG_CFG, "generating ocsp request failed");
327 return NULL;
328 }
329
330 send = request->get_encoding(request);
331 request->destroy(request);
332
333 DBG1(DBG_CFG, "requesting ocsp status from '%s' ...", url);
334 /* TODO: unlock manager while fetching? */
335 if (lib->fetcher->fetch(lib->fetcher, url, &receive,
336 FETCH_REQUEST_DATA, send,
337 FETCH_REQUEST_TYPE, "application/ocsp-request",
338 FETCH_END) != SUCCESS)
339 {
340 DBG1(DBG_CFG, "ocsp request to %s failed", url);
341 chunk_free(&send);
342 return NULL;
343 }
344 chunk_free(&send);
345
346 response = lib->creds->create(lib->creds,
347 CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
348 BUILD_BLOB_ASN1_DER, receive, BUILD_END);
349 if (!response)
350 {
351 DBG1(DBG_CFG, "parsing ocsp response failed");
352 return NULL;
353 }
354 return response;
355 }
356
357 /**
358 * check the signature of an OCSP response
359 */
360 static bool check_ocsp_response(private_credential_manager_t *this,
361 ocsp_response_t *response)
362 {
363 certificate_t *issuer, *subject;
364 identification_t *responder;
365 auth_info_t *auth;
366 ocsp_response_wrapper_t *wrapper;
367
368 auth = auth_info_create();
369 wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response);
370 this->sets->remove(this->sets, this->cache, NULL);
371 this->sets->insert_first(this->sets, wrapper);
372 this->sets->insert_first(this->sets, this->cache);
373
374 subject = &response->certificate;
375 responder = subject->get_issuer(subject);
376 issuer = get_trusted_cert(this, KEY_ANY, responder, auth, FALSE, FALSE);
377
378 this->sets->remove(this->sets, wrapper, NULL);
379 wrapper->destroy(wrapper);
380 auth->destroy(auth);
381
382 if (!issuer)
383 {
384 DBG1(DBG_CFG, "OCSP response verification failed, responder cert missing");
385 return FALSE;
386 }
387 if (!this->cache->issued_by(this->cache, subject, issuer))
388 {
389 DBG1(DBG_CFG, "OCSP response verification failed");
390 issuer->destroy(issuer);
391 return FALSE;
392 }
393 issuer->destroy(issuer);
394 return TRUE;
395 }
396
397 /**
398 * Get the better of two OCSP responses, and check for usable OCSP info
399 */
400 static certificate_t *get_better_ocsp(private_credential_manager_t *this,
401 certificate_t *cand, certificate_t *best,
402 x509_t *subject, x509_t *issuer,
403 cert_validation_t *valid)
404 {
405 ocsp_response_t *response;
406 time_t revocation, this_update, next_update, valid_until;
407 crl_reason_t reason;
408
409 response = (ocsp_response_t*)cand;
410
411 /* check ocsp signature */
412 if (!check_ocsp_response(this, response))
413 {
414 cand->destroy(cand);
415 return best;
416 }
417 /* check if response contains our certificate */
418 switch (response->get_status(response, subject, issuer, &revocation, &reason,
419 &this_update, &next_update))
420 {
421 case VALIDATION_REVOKED:
422 /* subject has been revoked by a valid OCSP response */
423 DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
424 &revocation, crl_reason_names, reason);
425 DESTROY_IF(best);
426 return cand;
427 case VALIDATION_GOOD:
428 /* results in either good or stale */
429 break;
430 default:
431 case VALIDATION_FAILED:
432 /* candidate unusable, does not contain our cert */
433 cand->destroy(cand);
434 return best;
435 }
436
437 /* select the better of the two responses */
438 if (best == NULL || cand->is_newer(cand, best))
439 {
440 DESTROY_IF(best);
441 best = cand;
442 if (best->get_validity(best, NULL, NULL, &valid_until))
443 {
444 DBG1(DBG_CFG, " ocsp response is valid: until %#T", &valid_until);
445 *valid = VALIDATION_GOOD;
446 }
447 else
448 {
449 DBG1(DBG_CFG, " ocsp response is stale: since %#T", &valid_until);
450 *valid = VALIDATION_STALE;
451 }
452 }
453 else
454 {
455 *valid = VALIDATION_STALE;
456 cand->destroy(cand);
457 }
458 return best;
459 }
460
461 /**
462 * validate a x509 certificate using OCSP
463 */
464 static cert_validation_t check_ocsp(private_credential_manager_t *this,
465 x509_t *subject, x509_t *issuer,
466 auth_info_t *auth)
467 {
468 enumerator_t *enumerator;
469 cert_validation_t valid = VALIDATION_SKIPPED;
470 certificate_t *best = NULL, *current;
471 identification_t *keyid = NULL;
472 public_key_t *public;
473 char *uri = NULL;
474
475 /** lookup cache for valid OCSP responses */
476 enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE,
477 KEY_ANY, NULL, FALSE);
478 while (enumerator->enumerate(enumerator, &current))
479 {
480 current->get_ref(current);
481 best = get_better_ocsp(this, current, best, subject, issuer, &valid);
482 if (best && valid != VALIDATION_STALE)
483 {
484 DBG1(DBG_CFG, " used cached ocsp response");
485 break;
486 }
487 }
488 enumerator->destroy(enumerator);
489
490 /* derive the authorityKeyIdentifier from the issuer's public key */
491 current = &issuer->interface;
492 public = current->get_public_key(current);
493 if (public)
494 {
495 keyid = public->get_id(public, ID_PUBKEY_SHA1);
496 }
497 /** fetch from configured OCSP responder URLs */
498 if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
499 {
500 enumerator = create_cdp_enumerator(this, CERT_X509_OCSP_RESPONSE, keyid);
501 while (enumerator->enumerate(enumerator, &uri))
502 {
503 current = fetch_ocsp(this, uri, &subject->interface,
504 &issuer->interface);
505 if (current)
506 {
507 best = get_better_ocsp(this, current, best, subject, issuer, &valid);
508 if (best && valid != VALIDATION_STALE)
509 {
510 break;
511 }
512 }
513 }
514 enumerator->destroy(enumerator);
515 }
516 DESTROY_IF(public);
517
518 /* fallback to URL fetching from subject certificate's URIs */
519 if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
520 {
521 enumerator = subject->create_ocsp_uri_enumerator(subject);
522 while (enumerator->enumerate(enumerator, &uri))
523 {
524 current = fetch_ocsp(this, uri, &subject->interface,
525 &issuer->interface);
526 if (current)
527 {
528 best = get_better_ocsp(this, current, best, subject, issuer, &valid);
529 if (best && valid != VALIDATION_STALE)
530 {
531 break;
532 }
533 }
534 }
535 enumerator->destroy(enumerator);
536 }
537 /* an uri was found, but no result. switch validation state to failed */
538 if (valid == VALIDATION_SKIPPED && uri)
539 {
540 valid = VALIDATION_FAILED;
541 }
542 if (auth)
543 {
544 auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid);
545 }
546 DESTROY_IF(best);
547 return valid;
548 }
549
550 /**
551 * fetch a CRL from an URL
552 */
553 static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
554 {
555 certificate_t *crl_cert;
556 chunk_t chunk;
557
558 /* TODO: unlock the manager while fetching? */
559 DBG1(DBG_CFG, "fetching crl from '%s' ...", url);
560 if (lib->fetcher->fetch(lib->fetcher, url, &chunk, FETCH_END) != SUCCESS)
561 {
562 DBG1(DBG_CFG, "crl fetching failed");
563 return NULL;
564 }
565 crl_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
566 BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
567 if (!crl_cert)
568 {
569 DBG1(DBG_CFG, "crl fetched successfully but parsing failed");
570 return NULL;
571 }
572
573 /* verify the signature of the fetched crl */
574 {
575 identification_t *issuer = crl_cert->get_issuer(crl_cert);
576 auth_info_t *auth = auth_info_create();
577 certificate_t *issuer_cert = get_trusted_cert(this, KEY_ANY, issuer,
578 auth, FALSE, FALSE);
579 auth->destroy(auth);
580
581 if (!issuer_cert)
582 {
583 DBG1(DBG_CFG, "crl is untrusted: issuer certificate not found");
584 crl_cert->destroy(crl_cert);
585 return NULL;
586 }
587
588 if (this->cache->issued_by(this->cache, crl_cert, issuer_cert))
589 {
590 DBG1(DBG_CFG, " crl correctly signed by \"%D\"",
591 issuer_cert->get_subject(issuer_cert));
592 issuer_cert->destroy(issuer_cert);
593 }
594 else
595 {
596 DBG1(DBG_CFG, "crl not accepted from \"%D\"",
597 issuer_cert->get_subject(issuer_cert));
598 issuer_cert->destroy(issuer_cert);
599 crl_cert->destroy(crl_cert);
600 return NULL;
601 }
602 }
603 return crl_cert;
604 }
605
606 /**
607 * validate a x509 certificate using CRL
608 */
609 static cert_validation_t check_crl(private_credential_manager_t *this,
610 x509_t *subject, x509_t *issuer,
611 auth_info_t *auth)
612 {
613 identification_t *keyid = NULL;
614 certificate_t *best_cert = NULL;
615 certificate_t *cert;
616 public_key_t *public;
617 cert_validation_t valid = VALIDATION_SKIPPED;
618 bool stale = TRUE;
619
620 /* derive the authorityKeyIdentifier from the issuer's public key */
621 cert = &issuer->interface;
622 public = cert->get_public_key(cert);
623 if (public)
624 {
625 keyid = public->get_id(public, ID_PUBKEY_SHA1);
626 }
627
628 /* find a cached crl by authorityKeyIdentifier */
629 if (keyid)
630 {
631 enumerator_t *enumerator = create_cert_enumerator(this, CERT_X509_CRL,
632 KEY_ANY, keyid, TRUE);
633 certificate_t *cert;
634
635 while (enumerator->enumerate(enumerator, &cert))
636 {
637 /* select most recent crl */
638 if (best_cert == NULL || cert->is_newer(cert, best_cert))
639 {
640 DESTROY_IF(best_cert);
641 best_cert = cert->get_ref(cert);
642 }
643 }
644 enumerator->destroy(enumerator);
645 }
646
647 /* check the validity of the cached crl if one was found */
648 if (best_cert)
649 {
650 time_t nextUpdate;
651
652 stale = !best_cert->get_validity(best_cert, NULL, NULL, &nextUpdate);
653 DBG1(DBG_CFG, "cached crl is %s %#T",
654 stale? "stale: since":"valid: until",
655 &nextUpdate, FALSE );
656 }
657
658 /* fallback to fetching crls from cdps defined in ca info sections */
659 if (stale && keyid)
660 {
661 enumerator_t *enumerator = create_cdp_enumerator(this, CERT_X509_CRL,
662 keyid);
663 char *uri;
664
665 while (enumerator->enumerate(enumerator, &uri))
666 {
667 certificate_t *cert = fetch_crl(this, uri);
668
669 /* redefine default since we have at least one uri */
670 valid = VALIDATION_FAILED;
671
672 if (cert)
673 {
674 /* select most recent crl until valid one is found */
675 if (best_cert == NULL || cert->is_newer(cert, best_cert))
676 {
677 time_t nextUpdate;
678
679 DESTROY_IF(best_cert);
680 best_cert = cert;
681 stale = !best_cert->get_validity(best_cert, NULL, NULL, &nextUpdate);
682 DBG1(DBG_CFG, "fetched crl is %s %#T",
683 stale? "stale: since":"valid: until",
684 &nextUpdate, FALSE );
685 if (!stale)
686 {
687 break;
688 }
689 }
690 else
691 {
692 cert->destroy(cert);
693 }
694 }
695 }
696 enumerator->destroy(enumerator);
697 }
698
699 /* fallback to fetching crls from cdps defined in the subject's certificate */
700 if (stale)
701 {
702 enumerator_t *enumerator = subject->create_crl_uri_enumerator(subject);
703 char *uri;
704
705 while (enumerator->enumerate(enumerator, &uri))
706 {
707 certificate_t *cert = fetch_crl(this, uri);
708
709 /* redefine default since we have at least one uri */
710 valid = VALIDATION_FAILED;
711
712 if (cert)
713 {
714 /* select most recent crl until valid one is found */
715 if (best_cert == NULL || cert->is_newer(cert, best_cert))
716 {
717 time_t nextUpdate;
718
719 DESTROY_IF(best_cert);
720 best_cert = cert;
721 stale = !best_cert->get_validity(best_cert, NULL, NULL, &nextUpdate);
722 DBG1(DBG_CFG, "fetched crl is %s %#T",
723 stale? "stale: since":"valid: until",
724 &nextUpdate, FALSE );
725 if (!stale)
726 {
727 break;
728 }
729 }
730 else
731 {
732 cert->destroy(cert);
733 }
734 }
735 }
736 enumerator->destroy(enumerator);
737 }
738 DESTROY_IF(public);
739
740 /* if we have a crl, check the revocation status */
741 if (best_cert)
742 {
743 chunk_t subject_serial = subject->get_serial(subject);
744 chunk_t serial;
745 time_t revocation;
746 crl_reason_t reason;
747 crl_t *crl = (crl_t*)best_cert;
748 enumerator_t *enumerator = crl->create_enumerator(crl);
749
750 /* redefine default */
751 valid = stale ? VALIDATION_STALE : VALIDATION_GOOD;
752
753 while (enumerator->enumerate(enumerator, &serial, &revocation, &reason))
754 {
755 if (chunk_equals(serial, subject_serial))
756 {
757 DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
758 &revocation, crl_reason_names, reason);
759 valid = VALIDATION_REVOKED;
760 break;
761 }
762 }
763 enumerator->destroy(enumerator);
764 best_cert->destroy(best_cert);
765 }
766
767 if (auth)
768 {
769 auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
770 }
771 return valid;
772 }
773
774 /**
775 * check a certificate for its lifetime
776 */
777 static bool check_certificate(private_credential_manager_t *this,
778 certificate_t *subject, certificate_t *issuer,
779 bool crl, bool ocsp, auth_info_t *auth)
780 {
781 time_t not_before, not_after;
782
783 if (!subject->get_validity(subject, NULL, &not_before, &not_after))
784 {
785 DBG1(DBG_CFG, "subject certificate invalid (valid from %T to %T)",
786 &not_before, &not_after);
787 return FALSE;
788 }
789 if (!issuer->get_validity(issuer, NULL, &not_before, &not_after))
790 {
791 DBG1(DBG_CFG, "issuer certificate invalid (valid from %T to %T)",
792 &not_before, &not_after);
793 return FALSE;
794 }
795 if (issuer->get_type(issuer) == CERT_X509 &&
796 subject->get_type(subject) == CERT_X509)
797 {
798 if (ocsp)
799 {
800 switch (check_ocsp(this, (x509_t*)subject, (x509_t*)issuer, auth))
801 {
802 case VALIDATION_GOOD:
803 DBG1(DBG_CFG, "certificate status is good");
804 return TRUE;
805 case VALIDATION_REVOKED:
806 /* has already been logged */
807 return FALSE;
808 case VALIDATION_SKIPPED:
809 DBG2(DBG_CFG, "ocsp check skipped, no ocsp found");
810 break;
811 case VALIDATION_STALE:
812 DBG1(DBG_CFG, "ocsp information stale, fallback to crl");
813 break;
814 case VALIDATION_FAILED:
815 DBG1(DBG_CFG, "ocsp check failed, fallback to crl");
816 break;
817 }
818 }
819 if (crl)
820 {
821 switch (check_crl(this, (x509_t*)subject, (x509_t*)issuer, auth))
822 {
823 case VALIDATION_GOOD:
824 DBG1(DBG_CFG, "certificate status is good");
825 return TRUE;
826 case VALIDATION_REVOKED:
827 /* has already been logged */
828 return FALSE;
829 case VALIDATION_FAILED:
830 case VALIDATION_SKIPPED:
831 DBG1(DBG_CFG, "certificate status is not available");
832 break;
833 case VALIDATION_STALE:
834 DBG1(DBG_CFG, "certificate status is unknown, crl is stale");
835 break;
836 }
837 }
838 }
839 return TRUE;
840 }
841
842 /**
843 * Get a trusted certificate from a credential set
844 */
845 static certificate_t *get_pretrusted_cert(private_credential_manager_t *this,
846 key_type_t type, identification_t *id)
847 {
848 certificate_t *subject;
849 public_key_t *public;
850
851 subject = get_cert(this, CERT_ANY, type, id, TRUE);
852 if (!subject)
853 {
854 return NULL;
855 }
856 public = subject->get_public_key(subject);
857 if (!public)
858 {
859 subject->destroy(subject);
860 return NULL;
861 }
862 public->destroy(public);
863 return subject;
864 }
865
866 /**
867 * Get the issuing certificate of a subject certificate
868 */
869 static certificate_t *get_issuer_cert(private_credential_manager_t *this,
870 certificate_t *subject, bool trusted)
871 {
872 enumerator_t *enumerator;
873 certificate_t *issuer = NULL, *candidate;
874
875 enumerator = create_cert_enumerator(this, subject->get_type(subject), KEY_ANY,
876 subject->get_issuer(subject), trusted);
877 while (enumerator->enumerate(enumerator, &candidate))
878 {
879 if (this->cache->issued_by(this->cache, subject, candidate))
880 {
881 issuer = candidate->get_ref(candidate);
882 break;
883 }
884 }
885 enumerator->destroy(enumerator);
886 return issuer;
887 }
888
889 /**
890 * try to verify the trust chain of subject, return TRUE if trusted
891 */
892 static bool verify_trust_chain(private_credential_manager_t *this,
893 certificate_t *subject, auth_info_t *result,
894 bool trusted, bool crl, bool ocsp)
895 {
896 certificate_t *current, *issuer;
897 auth_info_t *auth;
898 u_int level = 0;
899
900 auth = auth_info_create();
901 current = subject->get_ref(subject);
902 while (level++ < MAX_CA_LEVELS)
903 {
904 issuer = get_issuer_cert(this, current, TRUE);
905 if (issuer)
906 {
907 /* accept only self-signed CAs as trust anchor */
908 if (this->cache->issued_by(this->cache, issuer, issuer))
909 {
910 auth->add_item(auth, AUTHZ_CA_CERT, issuer);
911 DBG1(DBG_CFG, " using trusted ca certificate \"%D\"",
912 issuer->get_subject(issuer));
913 trusted = TRUE;
914 }
915 else
916 {
917 auth->add_item(auth, AUTHZ_IM_CERT, issuer);
918 DBG1(DBG_CFG, " using trusted intermediate ca certificate "
919 "\"%D\"", issuer->get_subject(issuer));
920 }
921 }
922 else
923 {
924 issuer = get_issuer_cert(this, current, FALSE);
925 if (issuer)
926 {
927 if (current->equals(current, issuer))
928 {
929 DBG1(DBG_CFG, " self-signed certificate \"%D\" is not trusted",
930 current->get_subject(current));
931 issuer->destroy(issuer);
932 break;
933 }
934 auth->add_item(auth, AUTHZ_IM_CERT, issuer);
935 DBG1(DBG_CFG, " using untrusted intermediate certificate "
936 "\"%D\"", issuer->get_subject(issuer));
937 }
938 else
939 {
940 DBG1(DBG_CFG, "no issuer certificate found for \"%D\"",
941 issuer->get_subject(issuer));
942 current->destroy(current);
943 break;
944 }
945 }
946 if (!check_certificate(this, current, issuer, crl, ocsp,
947 current == subject ? auth : NULL))
948 {
949 trusted = FALSE;
950 issuer->destroy(issuer);
951 break;
952 }
953 current->destroy(current);
954 current = issuer;
955 if (trusted)
956 {
957 break;
958 }
959 }
960 current->destroy(current);
961 if (trusted)
962 {
963 result->merge(result, auth);
964 }
965 auth->destroy(auth);
966 return trusted;
967 }
968
969 /**
970 * Get a trusted certificate by verifying the trust chain
971 */
972 static certificate_t *get_trusted_cert(private_credential_manager_t *this,
973 key_type_t type, identification_t *id,
974 auth_info_t *auth, bool crl, bool ocsp)
975 {
976 certificate_t *subject, *current;
977 enumerator_t *enumerator;
978
979 /* check if we have a trusted certificate for that peer */
980 subject = get_pretrusted_cert(this, type, id);
981 if (subject)
982 {
983 /* if we find a trusted self signed certificate, we just accept it */
984 if (this->cache->issued_by(this->cache, subject, subject))
985 {
986 DBG1(DBG_CFG, " using trusted self-signed certificate \"%D\"",
987 subject->get_subject(subject));
988 return subject;
989 }
990
991 /* if we find a trusted certificate, we accept it. However, in order
992 * to fulfill authorization rules, we try to build the trust chain
993 * anyway.
994 */
995 if (verify_trust_chain(this, subject, auth, TRUE, crl, ocsp))
996 {
997 DBG1(DBG_CFG, " using trusted certificate \"%D\"",
998 subject->get_subject(subject));
999 return subject;
1000 }
1001 subject->destroy(subject);
1002 }
1003
1004 subject = NULL;
1005 /* try to verify the trust chain for each certificate found */
1006 enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
1007 while (enumerator->enumerate(enumerator, &current))
1008 {
1009 DBG1(DBG_CFG, " using certificate \"%D\"",
1010 current->get_subject(current));
1011 if (verify_trust_chain(this, current, auth, FALSE, crl, ocsp))
1012 {
1013 subject = current->get_ref(current);
1014 break;
1015 }
1016 }
1017 enumerator->destroy(enumerator);
1018
1019 if (!subject)
1020 {
1021 DBG1(DBG_CFG, "no trusted certificate found for '%D'", id);
1022 }
1023 return subject;
1024 }
1025
1026 /**
1027 * Implementation of credential_manager_t.get_public.
1028 */
1029 static public_key_t *get_public(private_credential_manager_t *this,
1030 key_type_t type, identification_t *id,
1031 auth_info_t *auth)
1032 {
1033 public_key_t *public = NULL;
1034 certificate_t *cert;
1035 auth_info_wrapper_t *wrapper;
1036
1037 wrapper = auth_info_wrapper_create(auth);
1038 this->mutex->lock(this->mutex);
1039 this->sets->remove(this->sets, this->cache, NULL);
1040 this->sets->insert_first(this->sets, wrapper);
1041 this->sets->insert_first(this->sets, this->cache);
1042
1043 cert = get_trusted_cert(this, type, id, auth, TRUE, TRUE);
1044 if (cert)
1045 {
1046 public = cert->get_public_key(cert);
1047 cert->destroy(cert);
1048 }
1049
1050 this->sets->remove(this->sets, wrapper, NULL);
1051 wrapper->destroy(wrapper);
1052 this->mutex->unlock(this->mutex);
1053 return public;
1054 }
1055
1056 /**
1057 * Check if a certificate's keyid is contained in the auth helper
1058 */
1059 static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
1060 {
1061 enumerator_t *enumerator;
1062 identification_t *value;
1063 auth_item_t type;
1064 bool found = FALSE;
1065
1066 enumerator = auth->create_item_enumerator(auth);
1067 while (enumerator->enumerate(enumerator, &type, &value))
1068 {
1069 if (type == AUTHN_CA_CERT && cert->equals(cert, (certificate_t*)value))
1070 {
1071 found = TRUE;
1072 break;
1073 }
1074 if (type == AUTHN_CA_CERT_KEYID)
1075 {
1076 public_key_t *public;
1077 identification_t *certid, *keyid;
1078
1079 public = cert->get_public_key(cert);
1080 if (public)
1081 {
1082 keyid = (identification_t*)value;
1083 certid = public->get_id(public, keyid->get_type(keyid));
1084 if (certid && certid->equals(certid, keyid))
1085 {
1086 public->destroy(public);
1087 found = TRUE;
1088 break;
1089 }
1090 public->destroy(public);
1091 }
1092 }
1093 }
1094 enumerator->destroy(enumerator);
1095 return found;
1096 }
1097
1098 /**
1099 * build a trustchain from subject up to a trust anchor in trusted
1100 */
1101 static auth_info_t *build_trustchain(private_credential_manager_t *this,
1102 certificate_t *subject, auth_info_t *auth)
1103 {
1104 certificate_t *issuer, *current;
1105 auth_info_t *trustchain;
1106 u_int level = 0;
1107
1108 trustchain = auth_info_create();
1109
1110 if (!auth->get_item(auth, AUTHN_CA_CERT, (void**)&current))
1111 {
1112 /* no trust anchor specified, return this cert only */
1113 trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, subject);
1114 return trustchain;
1115 }
1116 current = subject->get_ref(subject);
1117 while (TRUE)
1118 {
1119 if (auth_contains_cacert(auth, current))
1120 {
1121 trustchain->add_item(trustchain, AUTHZ_CA_CERT, current);
1122 current->destroy(current);
1123 return trustchain;
1124 }
1125 if (subject == current)
1126 {
1127 trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, current);
1128 }
1129 else
1130 {
1131 trustchain->add_item(trustchain, AUTHZ_IM_CERT, current);
1132 }
1133 issuer = get_issuer_cert(this, current, FALSE);
1134 if (!issuer || issuer->equals(issuer, current) || level > MAX_CA_LEVELS)
1135 {
1136 DESTROY_IF(issuer);
1137 current->destroy(current);
1138 break;
1139 }
1140 current->destroy(current);
1141 current = issuer;
1142 level++;
1143 }
1144 trustchain->destroy(trustchain);
1145 return NULL;
1146 }
1147
1148 /**
1149 * find a private key of a give certificate
1150 */
1151 static private_key_t *get_private_by_cert(private_credential_manager_t *this,
1152 certificate_t *cert, key_type_t type)
1153 {
1154 private_key_t *private = NULL;
1155 identification_t* keyid;
1156 public_key_t *public;
1157
1158 public = cert->get_public_key(cert);
1159 if (public)
1160 {
1161 keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
1162 if (keyid)
1163 {
1164 private = get_private_by_keyid(this, type, keyid);
1165 }
1166 public->destroy(public);
1167 }
1168 return private;
1169 }
1170
1171 /**
1172 * Implementation of credential_manager_t.get_private.
1173 */
1174 static private_key_t *get_private(private_credential_manager_t *this,
1175 key_type_t type, identification_t *id,
1176 auth_info_t *auth)
1177 {
1178 enumerator_t *enumerator;
1179 certificate_t *cert;
1180 private_key_t *private = NULL;
1181 auth_info_t *trustchain;
1182
1183 /* check if this is a lookup by key ID, and do it if so */
1184 if (id)
1185 {
1186 switch (id->get_type(id))
1187 {
1188 case ID_PUBKEY_SHA1:
1189 case ID_PUBKEY_INFO_SHA1:
1190 return get_private_by_keyid(this, type, id);
1191 default:
1192 break;
1193 }
1194 }
1195
1196 this->mutex->lock(this->mutex);
1197 /* try to build a trustchain for each certificate found */
1198 enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
1199 while (enumerator->enumerate(enumerator, &cert))
1200 {
1201 private = get_private_by_cert(this, cert, type);
1202 if (private)
1203 {
1204 trustchain = build_trustchain(this, cert, auth);
1205 if (trustchain)
1206 {
1207 auth->merge(auth, trustchain);
1208 trustchain->destroy(trustchain);
1209 break;
1210 }
1211 private->destroy(private);
1212 private = NULL;
1213 }
1214 }
1215 enumerator->destroy(enumerator);
1216 /* if no valid trustchain was found, fall back to the first usable cert */
1217 if (!private)
1218 {
1219 enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
1220 while (enumerator->enumerate(enumerator, &cert))
1221 {
1222 private = get_private_by_cert(this, cert, type);
1223 if (private)
1224 {
1225 auth->add_item(auth, AUTHZ_SUBJECT_CERT, cert);
1226 break;
1227 }
1228 }
1229 enumerator->destroy(enumerator);
1230 }
1231 this->mutex->unlock(this->mutex);
1232 return private;
1233 }
1234
1235 /**
1236 * Implementation of credential_manager_t.flush_cache.
1237 */
1238 static void flush_cache(private_credential_manager_t *this,
1239 certificate_type_t type)
1240 {
1241 this->mutex->lock(this->mutex);
1242 this->cache->flush(this->cache, type);
1243 this->mutex->unlock(this->mutex);
1244 }
1245
1246 /**
1247 * Implementation of credential_manager_t.add_set.
1248 */
1249 static void add_set(private_credential_manager_t *this,
1250 credential_set_t *set)
1251 {
1252 this->mutex->lock(this->mutex);
1253 this->sets->insert_last(this->sets, set);
1254 this->mutex->unlock(this->mutex);
1255 }
1256 /**
1257 * Implementation of credential_manager_t.remove_set.
1258 */
1259 static void remove_set(private_credential_manager_t *this, credential_set_t *set)
1260 {
1261 this->mutex->lock(this->mutex);
1262 this->sets->remove(this->sets, set, NULL);
1263 this->mutex->unlock(this->mutex);
1264 }
1265
1266 /**
1267 * Implementation of credential_manager_t.destroy
1268 */
1269 static void destroy(private_credential_manager_t *this)
1270 {
1271 this->sets->remove(this->sets, this->cache, NULL);
1272 this->sets->destroy(this->sets);
1273 this->cache->destroy(this->cache);
1274 this->mutex->destroy(this->mutex);
1275 free(this);
1276 }
1277
1278 /*
1279 * see header file
1280 */
1281 credential_manager_t *credential_manager_create()
1282 {
1283 private_credential_manager_t *this = malloc_thing(private_credential_manager_t);
1284
1285 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;
1286 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;
1287 this->public.create_cdp_enumerator = (enumerator_t *(*)(credential_manager_t*, credential_type_t type, identification_t *id))create_cdp_enumerator;
1288 this->public.get_cert = (certificate_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *, bool))get_cert;
1289 this->public.get_shared = (shared_key_t *(*)(credential_manager_t *this,shared_key_type_t type,identification_t *me, identification_t *other))get_shared;
1290 this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_info_t*))get_private;
1291 this->public.get_public = (public_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_info_t*))get_public;
1292 this->public.flush_cache = (void(*)(credential_manager_t*, certificate_type_t type))flush_cache;
1293 this->public.add_set = (void(*)(credential_manager_t*, credential_set_t *set))add_set;
1294 this->public.remove_set = (void(*)(credential_manager_t*, credential_set_t *set))remove_set;
1295 this->public.destroy = (void(*)(credential_manager_t*))destroy;
1296
1297 this->sets = linked_list_create();
1298 this->cache = cert_cache_create();
1299 this->sets->insert_first(this->sets, this->cache);
1300 this->mutex = mutex_create(MUTEX_RECURSIVE);
1301
1302 return &this->public;
1303 }
1304