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