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