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