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