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