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