search : delimiter in ipsec.secrets entries from the rear
[strongswan.git] / src / charon / config / credentials / local_credential_store.c
1 /**
2 * @file local_credential_store.c
3 *
4 * @brief Implementation of local_credential_store_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 * RCSID $Id$
23 */
24
25 #include <sys/stat.h>
26 #include <dirent.h>
27 #include <string.h>
28 #include <pthread.h>
29 #include <errno.h>
30
31 #include <library.h>
32 #include <utils/lexparser.h>
33 #include <utils/linked_list.h>
34 #include <crypto/rsa/rsa_public_key.h>
35 #include <crypto/certinfo.h>
36 #include <crypto/x509.h>
37 #include <crypto/ca.h>
38 #include <crypto/ac.h>
39 #include <crypto/crl.h>
40 #include <asn1/ttodata.h>
41
42 #include "local_credential_store.h"
43
44 #define PATH_BUF 256
45
46 typedef struct shared_key_t shared_key_t;
47
48 /**
49 * Private date of a shared_key_t object
50 */
51 struct shared_key_t {
52
53 /**
54 * shared secret
55 */
56 chunk_t secret;
57
58 /**
59 * list of peer IDs
60 */
61 linked_list_t *peers;
62 };
63
64
65 /**
66 * Implementation of shared_key_t.destroy.
67 */
68 static void shared_key_destroy(shared_key_t *this)
69 {
70 this->peers->destroy_offset(this->peers, offsetof(identification_t, destroy));
71 chunk_free_randomized(&this->secret);
72 free(this);
73 }
74
75 /**
76 * @brief Creates a shared_key_t object.
77 *
78 * @param shared_key shared key value
79 * @return shared_key_t object
80 *
81 * @ingroup config
82 */
83 static shared_key_t *shared_key_create(chunk_t secret)
84 {
85 shared_key_t *this = malloc_thing(shared_key_t);
86
87 /* private data */
88 this->secret = secret;
89 this->peers = linked_list_create();
90
91 return (this);
92 }
93
94 /* ------------------------------------------------------------------------ *
95 * the ca_info_t object as a central control element
96
97 +--------------------------------------------------------+
98 | local_credential_store_t |
99 +--------------------------------------------------------+
100 | |
101 +---------------------------+ +-------------------------+
102 | linked_list_t *auth_certs | | linked_list_t *ca_infos |
103 +---------------------------+ +-------------------------+
104 | |
105 | +------------------------- +
106 | | ca_info_t |
107 | +--------------------------+
108 +---------------+ | char *name |
109 | x509_t |<--| x509_t *cacert |
110 +---------------+ | linked_list_t *attrcerts | +----------------------+
111 | chunk_t keyid | | linked_list_t *certinfos |-->| certinfo_t |
112 +---------------+ | linked_list_t *ocspuris | +----------------------+
113 | | crl_t *crl | | chunk_t serialNumber |
114 | | linked_list_t *crluris | | cert_status_t status |
115 +---------------+ | pthread_mutex_t mutex | | time_t thisUpdate |
116 | x509_t | +--------------------------+ | time_t nextUpdate |
117 +---------------+ | | bool once |
118 | chunk_t keyid | | +----------------------+
119 +---------------+ +------------------------- + |
120 | | ca_info_t | +----------------------+
121 | +--------------------------+ | certinfo_t |
122 +---------------+ | char *name | +----------------------+
123 | x509_t |<--| x509_t *cacert | | chunk_t serialNumber |
124 +---------------+ | linked_list_t *attrcerts | | cert_status_t status |
125 | chunk_t keyid | | linked_list_t *certinfos | | time_t thisUpdate |
126 +---------------+ | linked_list_t *ocspuris | | time_t nextUpdate |
127 | | crl_t *crl | | bool once |
128 | | linked_list_t *crluris | +----------------------+
129 | | pthread_mutex_t mutex; | |
130 | +--------------------------+
131 | |
132
133 * ------------------------------------------------------------------------ */
134
135 typedef struct private_local_credential_store_t private_local_credential_store_t;
136
137 /**
138 * Private data of an local_credential_store_t object
139 */
140 struct private_local_credential_store_t {
141
142 /**
143 * Public part
144 */
145 local_credential_store_t public;
146
147 /**
148 * list of shared keys
149 */
150 linked_list_t *shared_keys;
151
152 /**
153 * list of EAP keys
154 */
155 linked_list_t *eap_keys;
156
157 /**
158 * list of key_entry_t's with private keys
159 */
160 linked_list_t *private_keys;
161
162 /**
163 * mutex controls access to the linked lists of secret keys
164 */
165 pthread_mutex_t keys_mutex;
166
167 /**
168 * list of X.509 certificates with public keys
169 */
170 linked_list_t *certs;
171
172 /**
173 * list of X.509 authority certificates with public keys
174 */
175 linked_list_t *auth_certs;
176
177 /**
178 * list of X.509 CA information records
179 */
180 linked_list_t *ca_infos;
181
182 /**
183 * list of X.509 attribute certificates
184 */
185 linked_list_t *acerts;
186
187 /**
188 * mutex controls access to the linked list of attribute certificates
189 */
190 pthread_mutex_t acerts_mutex;
191 };
192
193
194 /**
195 * Get a key from a list with shared_key_t's
196 */
197 static status_t get_key(linked_list_t *keys,
198 identification_t *my_id,
199 identification_t *other_id, chunk_t *secret)
200 {
201 typedef enum {
202 PRIO_UNDEFINED= 0x00,
203 PRIO_ANY_MATCH= 0x01,
204 PRIO_MY_MATCH= 0x02,
205 PRIO_OTHER_MATCH= 0x04,
206 } prio_t;
207
208 prio_t best_prio = PRIO_UNDEFINED;
209 chunk_t found = chunk_empty;
210 shared_key_t *shared_key;
211 iterator_t *iterator;
212
213 iterator = keys->create_iterator(keys, TRUE);
214
215 while (iterator->iterate(iterator, (void**)&shared_key))
216 {
217 iterator_t *peer_iterator;
218 identification_t *peer_id;
219 prio_t prio = PRIO_UNDEFINED;
220
221 peer_iterator = shared_key->peers->create_iterator(shared_key->peers, TRUE);
222
223 if (peer_iterator->get_count(peer_iterator) == 0)
224 {
225 /* this is a wildcard shared key */
226 prio = PRIO_ANY_MATCH;
227 }
228 else
229 {
230 while (peer_iterator->iterate(peer_iterator, (void**)&peer_id))
231 {
232 if (my_id->equals(my_id, peer_id))
233 {
234 prio |= PRIO_MY_MATCH;
235 }
236 if (other_id->equals(other_id, peer_id))
237 {
238 prio |= PRIO_OTHER_MATCH;
239 }
240 }
241 }
242 peer_iterator->destroy(peer_iterator);
243
244 if (prio > best_prio)
245 {
246 best_prio = prio;
247 found = shared_key->secret;
248 }
249 }
250 iterator->destroy(iterator);
251
252 if (best_prio == PRIO_UNDEFINED)
253 {
254 return NOT_FOUND;
255 }
256 else
257 {
258 *secret = chunk_clone(found);
259 return SUCCESS;
260 }
261 }
262
263 /**
264 * Implementation of local_credential_store_t.get_shared_key.
265 */
266 static status_t get_shared_key(private_local_credential_store_t *this,
267 identification_t *my_id,
268 identification_t *other_id, chunk_t *secret)
269 {
270 status_t status;
271
272 pthread_mutex_lock(&(this->keys_mutex));
273 status = get_key(this->shared_keys, my_id, other_id, secret);
274 pthread_mutex_unlock(&(this->keys_mutex));
275 return status;
276 }
277
278 /**
279 * Implementation of local_credential_store_t.get_eap_key.
280 */
281 static status_t get_eap_key(private_local_credential_store_t *this,
282 identification_t *my_id,
283 identification_t *other_id, chunk_t *secret)
284 {
285 status_t status;
286
287 pthread_mutex_lock(&(this->keys_mutex));
288 status = get_key(this->eap_keys, my_id, other_id, secret);
289 pthread_mutex_unlock(&(this->keys_mutex));
290 return status;
291 }
292
293 /**
294 * Implementation of credential_store_t.get_certificate.
295 */
296 static x509_t* get_certificate(private_local_credential_store_t *this,
297 identification_t *id)
298 {
299 x509_t *found = NULL;
300 x509_t *current_cert;
301
302 iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
303
304 while (iterator->iterate(iterator, (void**)&current_cert))
305 {
306 if (id->equals(id, current_cert->get_subject(current_cert)) ||
307 current_cert->equals_subjectAltName(current_cert, id))
308 {
309 found = current_cert;
310 break;
311 }
312 }
313 iterator->destroy(iterator);
314 return found;
315 }
316
317 /**
318 * Implementation of local_credential_store_t.get_rsa_public_key.
319 */
320 static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this,
321 identification_t *id)
322 {
323 x509_t *cert = get_certificate(this, id);
324
325 return (cert == NULL)? NULL:cert->get_public_key(cert);
326 }
327
328 /**
329 * Implementation of credential_store_t.get_issuer.
330 */
331 static ca_info_t* get_issuer(private_local_credential_store_t *this, x509_t *cert)
332 {
333 ca_info_t *found = cert->get_ca_info(cert);
334
335 if (found == NULL)
336 {
337 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
338 ca_info_t *ca_info;
339
340 while (iterator->iterate(iterator, (void**)&ca_info))
341 {
342 if (ca_info->is_cert_issuer(ca_info, cert))
343 {
344 found = ca_info;
345 cert->set_ca_info(cert, found);
346 break;
347 }
348 }
349 iterator->destroy(iterator);
350 }
351 return found;
352 }
353
354 /**
355 * Implementation of local_credential_store_t.has_rsa_private_key.
356 */
357 static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
358 {
359 bool found = FALSE;
360 rsa_private_key_t *current;
361 iterator_t *iterator;
362
363 pthread_mutex_lock(&(this->keys_mutex));
364 iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
365
366 while (iterator->iterate(iterator, (void**)&current))
367 {
368 if (current->belongs_to(current, pubkey))
369 {
370 found = TRUE;
371 break;
372 }
373 }
374 iterator->destroy(iterator);
375 pthread_mutex_unlock(&(this->keys_mutex));
376 return found;
377 }
378
379 /**
380 * Implementation of credential_store_t.get_auth_certificate.
381 */
382 static x509_t* get_auth_certificate(private_local_credential_store_t *this,
383 u_int auth_flags,
384 identification_t *id)
385 {
386 x509_t *found = NULL;
387 x509_t *current_cert;
388
389 iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
390
391 while (iterator->iterate(iterator, (void**)&current_cert))
392 {
393 if (current_cert->has_authority_flag(current_cert, auth_flags)
394 && id->equals(id, current_cert->get_subject(current_cert)))
395 {
396 found = current_cert;
397 break;
398 }
399 }
400 iterator->destroy(iterator);
401
402 return found;
403 }
404
405 /**
406 * Implementation of credential_store_t.get_ca_certificate_by_keyid.
407 */
408 static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *this,
409 chunk_t keyid)
410 {
411 x509_t *found = NULL;
412 x509_t *current_cert;
413
414 iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
415
416 while (iterator->iterate(iterator, (void**)&current_cert))
417 {
418 rsa_public_key_t *pubkey = current_cert->get_public_key(current_cert);
419
420 if (current_cert->has_authority_flag(current_cert, AUTH_CA)
421 && chunk_equals(keyid, pubkey->get_keyid(pubkey)))
422 {
423 found = current_cert;
424 break;
425 }
426 }
427 iterator->destroy(iterator);
428
429 return found;
430 }
431
432 /**
433 * Find an exact copy of a certificate in a linked list
434 */
435 static x509_t* find_certificate(linked_list_t *certs, x509_t *cert)
436 {
437 x509_t *found_cert = NULL, *current_cert;
438
439 iterator_t *iterator = certs->create_iterator(certs, TRUE);
440
441 while (iterator->iterate(iterator, (void**)&current_cert))
442 {
443 if (cert->equals(cert, current_cert))
444 {
445 found_cert = current_cert;
446 break;
447 }
448 }
449 iterator->destroy(iterator);
450
451 return found_cert;
452 }
453
454 /**
455 * Adds crl and ocsp uris to the corresponding issuer info record
456 */
457 static void add_uris(ca_info_t *issuer, x509_t *cert)
458 {
459 iterator_t *iterator;
460 identification_t *uri;
461
462 /* add any crl distribution points to the issuer ca info record */
463 iterator = cert->create_crluri_iterator(cert);
464
465 while (iterator->iterate(iterator, (void**)&uri))
466 {
467 if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
468 {
469 issuer->add_crluri(issuer, uri->get_encoding(uri));
470 }
471 }
472 iterator->destroy(iterator);
473
474 /* add any ocsp access points to the issuer ca info record */
475 iterator = cert->create_ocspuri_iterator(cert);
476
477 while (iterator->iterate(iterator, (void**)&uri))
478 {
479 if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
480 {
481 issuer->add_ocspuri(issuer, uri->get_encoding(uri));
482 }
483 }
484 iterator->destroy(iterator);
485 }
486
487 /**
488 * Implementation of credential_store_t.is_trusted
489 */
490 static bool is_trusted(private_local_credential_store_t *this, const char *label, x509_t *cert)
491 {
492 int pathlen;
493 time_t until = UNDEFINED_TIME;
494 x509_t *cert_to_be_trusted = cert;
495
496 DBG1(DBG_CFG, "establishing trust in %s certificate:", label);
497
498 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
499 {
500 err_t ugh = NULL;
501 ca_info_t *issuer;
502 x509_t *issuer_cert;
503 rsa_public_key_t *issuer_public_key;
504 bool valid_signature;
505
506 DBG1(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
507 DBG1(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
508
509 ugh = cert->is_valid(cert, &until);
510 if (ugh != NULL)
511 {
512 DBG1(DBG_CFG, "certificate %s", ugh);
513 return FALSE;
514 }
515 DBG2(DBG_CFG, "certificate is valid");
516
517 issuer = get_issuer(this, cert);
518 if (issuer == NULL)
519 {
520 DBG1(DBG_CFG, "issuer not found");
521 return FALSE;
522 }
523 DBG2(DBG_CFG, "issuer found");
524
525 issuer_cert = issuer->get_certificate(issuer);
526 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
527 valid_signature = cert->verify(cert, issuer_public_key);
528
529 if (!valid_signature)
530 {
531 DBG1(DBG_CFG, "certificate signature is invalid");
532 return FALSE;
533 }
534 DBG2(DBG_CFG, "certificate signature is valid");
535
536 /* check if cert is a self-signed root ca */
537 if (pathlen > 0 && cert->is_self_signed(cert))
538 {
539 DBG1(DBG_CFG, "reached self-signed root ca");
540 cert_to_be_trusted->set_until(cert_to_be_trusted, until);
541 cert_to_be_trusted->set_status(cert_to_be_trusted, CERT_GOOD);
542 return TRUE;
543 }
544 else
545 {
546 DBG1(DBG_CFG, "going up one step in the certificate trust chain (%d)",
547 pathlen + 1);
548 cert = issuer_cert;
549 }
550 }
551 DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
552 return FALSE;
553 }
554
555 /**
556 * Implementation of credential_store_t.verify.
557 */
558 static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *found)
559 {
560 int pathlen;
561 time_t until = UNDEFINED_TIME;
562
563 x509_t *end_cert = cert;
564 x509_t *cert_copy = find_certificate(this->certs, end_cert);
565
566 DBG1(DBG_CFG, "verifying end entity certificate up to trust anchor:");
567
568 *found = (cert_copy != NULL);
569 if (*found)
570 {
571 DBG2(DBG_CFG,
572 "end entitity certificate is already in credential store");
573 }
574
575 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
576 {
577 bool valid_signature;
578 err_t ugh = NULL;
579 ca_info_t *issuer;
580 x509_t *issuer_cert;
581 rsa_public_key_t *issuer_public_key;
582 chunk_t keyid = cert->get_keyid(cert);
583
584 DBG1(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
585 DBG1(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
586 DBG1(DBG_CFG, "keyid: %#B", &keyid);
587
588 ugh = cert->is_valid(cert, &until);
589 if (ugh != NULL)
590 {
591 DBG1(DBG_CFG, "certificate %s", ugh);
592 return FALSE;
593 }
594 DBG2(DBG_CFG, "certificate is valid");
595
596 issuer = get_issuer(this, cert);
597 if (issuer == NULL)
598 {
599 DBG1(DBG_CFG, "issuer not found");
600 return FALSE;
601 }
602 DBG2(DBG_CFG, "issuer found");
603
604 issuer_cert = issuer->get_certificate(issuer);
605 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
606 valid_signature = cert->verify(cert, issuer_public_key);
607
608 if (!valid_signature)
609 {
610 DBG1(DBG_CFG, "certificate signature is invalid");
611 return FALSE;
612 }
613 DBG2(DBG_CFG, "certificate signature is valid");
614
615 /* check if cert is a self-signed root ca */
616 if (pathlen > 0 && cert->is_self_signed(cert))
617 {
618 DBG1(DBG_CFG, "reached self-signed root ca");
619
620 /* set the definite status and trust interval of the end entity certificate */
621 end_cert->set_until(end_cert, until);
622 if (cert_copy)
623 {
624 cert_copy->set_status(cert_copy, end_cert->get_status(end_cert));
625 cert_copy->set_until(cert_copy, until);
626 }
627 return TRUE;
628 }
629 else
630 {
631 bool strict;
632 time_t nextUpdate;
633 cert_status_t status;
634 certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
635
636 if (pathlen == 0)
637 {
638 /* add any crl and ocsp uris contained in the certificate under test */
639 add_uris(issuer, cert);
640 }
641
642 strict = issuer->is_strict(issuer);
643 DBG1(DBG_CFG, "issuer %s a strict crl policy",
644 strict ? "enforces":"does not enforce");
645
646 /* first check certificate revocation using ocsp */
647 status = issuer->verify_by_ocsp(issuer, certinfo, &this->public.credential_store);
648
649 /* if ocsp service is not available then fall back to crl */
650 if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && strict))
651 {
652
653 certinfo->set_status(certinfo, CERT_UNKNOWN);
654 status = issuer->verify_by_crl(issuer, certinfo, CRL_DIR);
655 }
656
657 nextUpdate = certinfo->get_nextUpdate(certinfo);
658 cert->set_status(cert, status);
659
660 switch (status)
661 {
662 case CERT_GOOD:
663 /* with strict crl policy the public key must have the same
664 * lifetime as the validity of the ocsp status or crl lifetime
665 */
666 if (strict)
667 {
668 cert->set_until(cert, nextUpdate);
669 until = (nextUpdate < until)? nextUpdate : until;
670 }
671
672 /* if status information is stale */
673 if (strict && nextUpdate < time(NULL))
674 {
675 DBG2(DBG_CFG, "certificate is good but status is stale");
676 certinfo->destroy(certinfo);
677 return FALSE;
678 }
679 DBG1(DBG_CFG, "certificate is good");
680 break;
681 case CERT_REVOKED:
682 {
683 time_t revocationTime = certinfo->get_revocationTime(certinfo);
684 DBG1(DBG_CFG,
685 "certificate was revoked on %T, reason: %N",
686 &revocationTime, crl_reason_names,
687 certinfo->get_revocationReason(certinfo));
688
689 /* set revocationTime */
690 cert->set_until(cert, revocationTime);
691
692 /* update status of end certificate in the credential store */
693 if (cert_copy)
694 {
695 if (pathlen > 0)
696 {
697 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
698 }
699 else
700 {
701 cert_copy->set_status(cert_copy, CERT_REVOKED);
702 cert_copy->set_until(cert_copy,
703 certinfo->get_revocationTime(certinfo));
704 }
705 }
706 certinfo->destroy(certinfo);
707 return FALSE;
708 }
709 case CERT_UNKNOWN:
710 case CERT_UNDEFINED:
711 default:
712 DBG1(DBG_CFG, "certificate status unknown");
713 if (strict)
714 {
715 /* update status of end certificate in the credential store */
716 if (cert_copy)
717 {
718 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
719 }
720 certinfo->destroy(certinfo);
721 return FALSE;
722 }
723 break;
724 }
725 certinfo->destroy(certinfo);
726 }
727 DBG1(DBG_CFG, "going up one step in the certificate trust chain (%d)",
728 pathlen + 1);
729 cert = issuer_cert;
730 }
731 DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
732 return FALSE;
733 }
734
735 /**
736 * Implementation of local_credential_store_t.rsa_signature.
737 */
738 static status_t rsa_signature(private_local_credential_store_t *this,
739 rsa_public_key_t *pubkey,
740 hash_algorithm_t hash_algorithm,
741 chunk_t data, chunk_t *signature)
742 {
743 rsa_private_key_t *current, *key = NULL;
744 iterator_t *iterator;
745 status_t status;
746 chunk_t keyid = pubkey->get_keyid(pubkey);
747
748 DBG2(DBG_IKE, "looking for RSA private key with keyid %#B...", &keyid);
749 pthread_mutex_lock(&(this->keys_mutex));
750
751 iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
752 while (iterator->iterate(iterator, (void**)&current))
753 {
754 if (current->belongs_to(current, pubkey))
755 {
756 key = current;
757 break;
758 }
759 }
760 iterator->destroy(iterator);
761
762 if (key)
763 {
764 DBG2(DBG_IKE, " matching RSA private key found");
765 status = key->build_emsa_pkcs1_signature(key, hash_algorithm, data, signature);
766 }
767 else
768 {
769 DBG1(DBG_IKE, "no RSA private key found with keyid %#B", &keyid);
770 status = NOT_FOUND;
771 }
772 pthread_mutex_unlock(&(this->keys_mutex));
773 return status;
774 }
775
776 /**
777 * Implementation of local_credential_store_t.verify_signature.
778 */
779 static status_t verify_signature(private_local_credential_store_t *this,
780 chunk_t hash, chunk_t signature,
781 identification_t *id, ca_info_t **issuer_p)
782 {
783 iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
784 status_t sig_status;
785 x509_t *cert;
786
787 /* default return values in case of failure */
788 sig_status = NOT_FOUND;
789 *issuer_p = NULL;
790
791 while (iterator->iterate(iterator, (void**)&cert))
792 {
793 if (id->equals(id, cert->get_subject(cert))
794 || cert->equals_subjectAltName(cert, id))
795 {
796 rsa_public_key_t *public_key = cert->get_public_key(cert);
797 cert_status_t cert_status = cert->get_status(cert);
798
799 DBG2(DBG_CFG, "found candidate peer certificate");
800
801 if (cert_status == CERT_UNDEFINED || cert->get_until(cert) < time(NULL))
802 {
803 bool found;
804
805 if (!verify(this, cert, &found))
806 {
807 sig_status = VERIFY_ERROR;
808 DBG1(DBG_CFG, "candidate peer certificate was not successfully verified");
809 continue;
810 }
811 *issuer_p = get_issuer(this, cert);
812 }
813 else
814 {
815 ca_info_t *issuer = get_issuer(this, cert);
816 chunk_t keyid = public_key->get_keyid(public_key);
817
818 DBG2(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
819 DBG2(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
820 DBG2(DBG_CFG, "keyid: %#B", &keyid);
821
822 if (issuer == NULL)
823 {
824 DBG1(DBG_CFG, "candidate peer certificate has no retrievable issuer");
825 sig_status = NOT_FOUND;
826 continue;
827 }
828 if (cert_status == CERT_REVOKED || cert_status == CERT_UNTRUSTED
829 || ((issuer)->is_strict(issuer) && cert_status != CERT_GOOD))
830 {
831 DBG1(DBG_CFG, "candidate peer certificate has an inacceptable status: %N", cert_status_names, cert_status);
832 sig_status = VERIFY_ERROR;
833 continue;
834 }
835 *issuer_p = issuer;
836 }
837 sig_status = public_key->verify_emsa_pkcs1_signature(public_key, HASH_UNKNOWN, hash, signature);
838 if (sig_status == SUCCESS)
839 {
840 DBG2(DBG_CFG, "candidate peer certificate has a matching RSA public key");
841 break;
842 }
843 else
844 {
845 DBG1(DBG_CFG, "candidate peer certificate has a non-matching RSA public key");
846 *issuer_p = NULL;
847 }
848 }
849 }
850 iterator->destroy(iterator);
851 if (sig_status == NOT_FOUND)
852 {
853 DBG1(DBG_CFG, "no candidate peer certificate found");
854 }
855 return sig_status;
856 }
857
858 /**
859 * Add a unique certificate to a linked list
860 */
861 static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
862 {
863 x509_t *found_cert = find_certificate(certs, cert);
864
865 if (found_cert)
866 {
867 /* add the authority flags */
868 found_cert->add_authority_flags(found_cert, cert->get_authority_flags(cert));
869
870 cert->destroy(cert);
871 return found_cert;
872 }
873 else
874 {
875 certs->insert_last(certs, (void*)cert);
876 return cert;
877 }
878 }
879
880 /**
881 * Add a unique ca info record to a linked list
882 */
883 static ca_info_t* add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
884 {
885 ca_info_t *current_ca_info;
886 ca_info_t *found_ca_info = NULL;
887
888 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
889
890 while (iterator->iterate(iterator, (void**)&current_ca_info))
891 {
892 if (current_ca_info->equals(current_ca_info, ca_info))
893 {
894 found_ca_info = current_ca_info;
895 break;
896 }
897 }
898 iterator->destroy(iterator);
899
900 if (found_ca_info)
901 {
902 current_ca_info->add_info(current_ca_info, ca_info);
903 ca_info->destroy(ca_info);
904 ca_info = found_ca_info;
905 }
906 else
907 {
908 this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
909 }
910 return ca_info;
911 }
912
913 /**
914 * Release ca info record of a given name
915 */
916 static status_t release_ca_info(private_local_credential_store_t *this, const char *name)
917 {
918 status_t status = NOT_FOUND;
919 ca_info_t *ca_info;
920
921 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
922
923 while (iterator->iterate(iterator, (void**)&ca_info))
924 {
925 if (ca_info->equals_name_release_info(ca_info, name))
926 {
927 status = SUCCESS;
928 break;
929 }
930 }
931 iterator->destroy(iterator);
932
933 return status;
934 }
935
936 /**
937 * Implements local_credential_store_t.add_end_certificate
938 */
939 static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
940 {
941 x509_t *ret_cert = add_certificate(this->certs, cert);
942
943 /* add crl and ocsp uris the first time the certificate is added */
944 if (ret_cert == cert)
945 {
946 ca_info_t *issuer = get_issuer(this, cert);
947
948 if (issuer)
949 {
950 add_uris(issuer, cert);
951 }
952 }
953 return ret_cert;
954 }
955
956 /**
957 * Implements local_credential_store_t.add_auth_certificate
958 */
959 static x509_t* add_auth_certificate(private_local_credential_store_t *this, x509_t *cert, u_int auth_flags)
960 {
961 cert->add_authority_flags(cert, auth_flags);
962 return add_certificate(this->auth_certs, cert);
963 }
964
965 /**
966 * Implements local_credential_store_t.create_cert_iterator
967 */
968 static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
969 {
970 return this->certs->create_iterator(this->certs, TRUE);
971 }
972
973 /**
974 * Implements local_credential_store_t.create_cacert_iterator
975 */
976 static iterator_t* create_auth_cert_iterator(private_local_credential_store_t *this)
977 {
978 return this->auth_certs->create_iterator(this->auth_certs, TRUE);
979 }
980
981 /**
982 * Implements local_credential_store_t.create_cainfo_iterator
983 */
984 static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
985 {
986 return this->ca_infos->create_iterator(this->ca_infos, TRUE);
987 }
988
989 /**
990 * Implements local_credential_store_t.create_acert_iterator
991 */
992 static iterator_t* create_acert_iterator(private_local_credential_store_t *this)
993 {
994 return this->acerts->create_iterator_locked(this->acerts, &this->acerts_mutex);
995 }
996
997 /**
998 * Implements local_credential_store_t.load_auth_certificates
999 */
1000 static void load_auth_certificates(private_local_credential_store_t *this,
1001 u_int auth_flag,
1002 const char* label,
1003 const char* path)
1004 {
1005 struct dirent* entry;
1006 struct stat stb;
1007 DIR* dir;
1008
1009 DBG1(DBG_CFG, "loading %s certificates from '%s'", label, path);
1010
1011 dir = opendir(path);
1012 if (dir == NULL)
1013 {
1014 DBG1(DBG_CFG, "error opening %s certs directory '%s'", label, path);
1015 return;
1016 }
1017
1018 while ((entry = readdir(dir)) != NULL)
1019 {
1020 char file[PATH_BUF];
1021
1022 snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
1023
1024 if (stat(file, &stb) == -1)
1025 {
1026 continue;
1027 }
1028 /* try to parse all regular files */
1029 if (stb.st_mode & S_IFREG)
1030 {
1031 x509_t *cert = x509_create_from_file(file, label);
1032
1033 if (cert)
1034 {
1035 err_t ugh = cert->is_valid(cert, NULL);
1036
1037 if (ugh != NULL)
1038 {
1039 DBG1(DBG_CFG, "warning: %s certificate %s", label, ugh);
1040 }
1041
1042 if (auth_flag == AUTH_CA && !cert->is_ca(cert))
1043 {
1044 DBG1(DBG_CFG, " CA basic constraints flag not set, cert discarded");
1045 cert->destroy(cert);
1046 }
1047 else
1048 {
1049 x509_t *ret_cert;
1050
1051 cert->add_authority_flags(cert, auth_flag);
1052
1053 ret_cert = add_certificate(this->auth_certs, cert);
1054
1055 if (auth_flag == AUTH_CA && ret_cert == cert)
1056 {
1057 ca_info_t *ca_info = ca_info_create(NULL, cert);
1058
1059 add_ca_info(this, ca_info);
1060 }
1061 }
1062 }
1063 }
1064 }
1065 closedir(dir);
1066 }
1067
1068 /**
1069 * Implements local_credential_store_t.load_ca_certificates
1070 */
1071 static void load_ca_certificates(private_local_credential_store_t *this)
1072 {
1073 load_auth_certificates(this, AUTH_CA, "ca", CA_CERTIFICATE_DIR);
1074
1075 /* add any crl and ocsp uris found in the ca certificates to the
1076 * corresponding issuer info record. We can do this only after all
1077 * ca certificates have been loaded and the ca hierarchy is known.
1078 */
1079 {
1080 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
1081 ca_info_t *ca_info;
1082
1083 while (iterator->iterate(iterator, (void **)&ca_info))
1084 {
1085 if (ca_info->is_ca(ca_info))
1086 {
1087 x509_t *cacert = ca_info->get_certificate(ca_info);
1088 ca_info_t *issuer = get_issuer(this, cacert);
1089
1090 if (issuer)
1091 {
1092 add_uris(issuer, cacert);
1093 }
1094 }
1095 }
1096 iterator->destroy(iterator);
1097 }
1098 }
1099
1100 /**
1101 * Implements local_credential_store_t.load_aa_certificates
1102 */
1103 static void load_aa_certificates(private_local_credential_store_t *this)
1104 {
1105 load_auth_certificates(this, AUTH_AA, "aa", AA_CERTIFICATE_DIR);
1106 }
1107
1108 /**
1109 * Add a unique attribute certificate to a linked list
1110 */
1111 static void add_attr_certificate(private_local_credential_store_t *this, x509ac_t *cert)
1112 {
1113 iterator_t *iterator;
1114 x509ac_t *current_cert;
1115 bool found = FALSE;
1116
1117 pthread_mutex_lock(&(this->acerts_mutex));
1118 iterator = this->acerts->create_iterator(this->acerts, TRUE);
1119
1120 while (iterator->iterate(iterator, (void **)&current_cert))
1121 {
1122 if (cert->equals_holder(cert, current_cert))
1123 {
1124 if (cert->is_newer(cert, current_cert))
1125 {
1126 iterator->replace(iterator, NULL, (void *)cert);
1127 current_cert->destroy(current_cert);
1128 DBG1(DBG_CFG, " this attr cert is newer - existing attr cert replaced");
1129 }
1130 else
1131 {
1132 cert->destroy(cert);
1133 DBG1(DBG_CFG, " this attr cert is not newer - existing attr cert retained");
1134 }
1135 found = TRUE;
1136 break;
1137 }
1138 }
1139 iterator->destroy(iterator);
1140
1141 if (!found)
1142 {
1143 this->acerts->insert_last(this->acerts, (void *)cert);
1144 }
1145 pthread_mutex_unlock(&(this->acerts_mutex));
1146 }
1147
1148 /**
1149 * Implements local_credential_store_t.load_attr_certificates
1150 */
1151 static void load_attr_certificates(private_local_credential_store_t *this)
1152 {
1153 struct dirent* entry;
1154 struct stat stb;
1155 DIR* dir;
1156
1157 const char *path = ATTR_CERTIFICATE_DIR;
1158
1159 DBG1(DBG_CFG, "loading attribute certificates from '%s'", path);
1160
1161 dir = opendir(ATTR_CERTIFICATE_DIR);
1162 if (dir == NULL)
1163 {
1164 DBG1(DBG_CFG, "error opening attribute certs directory '%s'", path);
1165 return;
1166 }
1167
1168 while ((entry = readdir(dir)) != NULL)
1169 {
1170 char file[PATH_BUF];
1171
1172 snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
1173
1174 if (stat(file, &stb) == -1)
1175 {
1176 continue;
1177 }
1178 /* try to parse all regular files */
1179 if (stb.st_mode & S_IFREG)
1180 {
1181 x509ac_t *cert = x509ac_create_from_file(file);
1182
1183 if (cert)
1184 {
1185 err_t ugh = cert->is_valid(cert, NULL);
1186
1187 if (ugh != NULL)
1188 {
1189 DBG1(DBG_CFG, "warning: attribute certificate %s", ugh);
1190 }
1191 add_attr_certificate(this, cert);
1192 }
1193 }
1194 }
1195 closedir(dir);
1196
1197
1198 }
1199
1200 /**
1201 * Implements local_credential_store_t.load_ocsp_certificates
1202 */
1203 static void load_ocsp_certificates(private_local_credential_store_t *this)
1204 {
1205 load_auth_certificates(this, AUTH_OCSP, "ocsp", OCSP_CERTIFICATE_DIR);
1206 }
1207
1208 /**
1209 * Add the latest crl to the issuing ca
1210 */
1211 static void add_crl(private_local_credential_store_t *this, crl_t *crl, const char *path)
1212 {
1213 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
1214 ca_info_t *ca_info;
1215 bool found = FALSE;
1216
1217 while (iterator->iterate(iterator, (void**)&ca_info))
1218 {
1219 if (ca_info->is_ca(ca_info) && ca_info->is_crl_issuer(ca_info, crl))
1220 {
1221 char buffer[BUF_LEN];
1222 chunk_t uri = { buffer, 7 + strlen(path) };
1223
1224 ca_info->add_crl(ca_info, crl);
1225 if (uri.len < BUF_LEN)
1226 {
1227 snprintf(buffer, BUF_LEN, "file://%s", path);
1228 ca_info->add_crluri(ca_info, uri);
1229 }
1230 found = TRUE;
1231 break;
1232 }
1233 }
1234 iterator->destroy(iterator);
1235
1236 if (!found)
1237 {
1238 crl->destroy(crl);
1239 DBG2(DBG_CFG, " no issuing ca found for this crl - discarded");
1240 }
1241 }
1242
1243 /**
1244 * Implements local_credential_store_t.load_crls
1245 */
1246 static void load_crls(private_local_credential_store_t *this)
1247 {
1248 struct dirent* entry;
1249 struct stat stb;
1250 DIR* dir;
1251 crl_t *crl;
1252
1253 DBG1(DBG_CFG, "loading crls from '%s'", CRL_DIR);
1254
1255 dir = opendir(CRL_DIR);
1256 if (dir == NULL)
1257 {
1258 DBG1(DBG_CFG, "error opening crl directory '%s'", CRL_DIR);
1259 return;
1260 }
1261
1262 while ((entry = readdir(dir)) != NULL)
1263 {
1264 char file[PATH_BUF];
1265
1266 snprintf(file, sizeof(file), "%s/%s", CRL_DIR, entry->d_name);
1267
1268 if (stat(file, &stb) == -1)
1269 {
1270 continue;
1271 }
1272 /* try to parse all regular files */
1273 if (stb.st_mode & S_IFREG)
1274 {
1275 crl = crl_create_from_file(file);
1276 if (crl)
1277 {
1278 DBG1(DBG_CFG, " crl is %s", crl->is_valid(crl)? "valid":"stale");
1279 add_crl(this, crl, file);
1280 }
1281 }
1282 }
1283 closedir(dir);
1284 }
1285
1286 /**
1287 * Convert a string of characters into a binary secret
1288 * A string between single or double quotes is treated as ASCII characters
1289 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
1290 */
1291 static err_t extract_secret(chunk_t *secret, chunk_t *line)
1292 {
1293 chunk_t raw_secret;
1294 char delimiter = ' ';
1295 bool quotes = FALSE;
1296
1297 if (!eat_whitespace(line))
1298 {
1299 return "missing secret";
1300 }
1301
1302 if (*line->ptr == '\'' || *line->ptr == '"')
1303 {
1304 quotes = TRUE;
1305 delimiter = *line->ptr;
1306 line->ptr++; line->len--;
1307 }
1308
1309 if (!extract_token(&raw_secret, delimiter, line))
1310 {
1311 if (delimiter == ' ')
1312 {
1313 raw_secret = *line;
1314 }
1315 else
1316 {
1317 return "missing second delimiter";
1318 }
1319 }
1320
1321 if (quotes)
1322 {
1323 /* treat as an ASCII string */
1324 *secret = chunk_clone(raw_secret);
1325 }
1326 else
1327 {
1328 size_t len;
1329 err_t ugh;
1330
1331 /* secret converted to binary form doesn't use more space than the raw_secret */
1332 *secret = chunk_alloc(raw_secret.len);
1333
1334 /* convert from HEX or Base64 to binary */
1335 ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
1336
1337 if (ugh != NULL)
1338 {
1339 chunk_free_randomized(secret);
1340 return ugh;
1341 }
1342 secret->len = len;
1343 }
1344 return NULL;
1345 }
1346
1347 /**
1348 * Implements local_credential_store_t.load_secrets
1349 */
1350 static void load_secrets(private_local_credential_store_t *this, bool reload)
1351 {
1352 FILE *fd = fopen(SECRETS_FILE, "r");
1353
1354 if (fd)
1355 {
1356 size_t bytes;
1357 int line_nr = 0;
1358 chunk_t chunk, src, line;
1359
1360 DBG1(DBG_CFG, "%sloading secrets from \"%s\"",
1361 reload? "re":"", SECRETS_FILE);
1362
1363 fseek(fd, 0, SEEK_END);
1364 chunk.len = ftell(fd);
1365 rewind(fd);
1366 chunk.ptr = malloc(chunk.len);
1367 bytes = fread(chunk.ptr, 1, chunk.len, fd);
1368 fclose(fd);
1369 src = chunk;
1370
1371 pthread_mutex_lock(&(this->keys_mutex));
1372 if (reload)
1373 {
1374 DBG1(DBG_CFG, " forgetting old secrets");
1375 this->private_keys->destroy_offset(this->private_keys,
1376 offsetof(rsa_private_key_t, destroy));
1377 this->private_keys = linked_list_create();
1378
1379 this->shared_keys->destroy_function(this->shared_keys,
1380 (void*)shared_key_destroy);
1381 this->shared_keys = linked_list_create();
1382
1383 this->eap_keys->destroy_function(this->eap_keys,
1384 (void*)shared_key_destroy);
1385 this->eap_keys = linked_list_create();
1386 }
1387
1388 while (fetchline(&src, &line))
1389 {
1390 chunk_t ids, token;
1391 bool is_eap = FALSE;
1392
1393 line_nr++;
1394
1395 if (!eat_whitespace(&line))
1396 {
1397 continue;
1398 }
1399 if (!extract_last_token(&ids, ':', &line))
1400 {
1401 DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
1402 goto error;
1403 }
1404 /* NULL terminate the ids string by replacing the : separator */
1405 *(ids.ptr + ids.len) = '\0';
1406
1407 if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
1408 {
1409 DBG1(DBG_CFG, "line %d: missing token", line_nr);
1410 goto error;
1411 }
1412 if (match("RSA", &token))
1413 {
1414 char path[PATH_BUF];
1415 chunk_t filename;
1416 chunk_t secret = chunk_empty;
1417 chunk_t *passphrase = NULL;
1418
1419 rsa_private_key_t *key;
1420
1421 err_t ugh = extract_value(&filename, &line);
1422
1423 if (ugh != NULL)
1424 {
1425 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1426 goto error;
1427 }
1428 if (filename.len == 0)
1429 {
1430 DBG1(DBG_CFG, "line %d: empty filename", line_nr);
1431 goto error;
1432 }
1433 if (*filename.ptr == '/')
1434 {
1435 /* absolute path name */
1436 snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
1437 }
1438 else
1439 {
1440 /* relative path name */
1441 snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
1442 filename.len, filename.ptr);
1443 }
1444
1445 /* check for optional passphrase */
1446 if (eat_whitespace(&line))
1447 {
1448 ugh = extract_secret(&secret, &line);
1449 if (ugh != NULL)
1450 {
1451 DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
1452 goto error;
1453 }
1454 if (secret.len > 0)
1455 passphrase = &secret;
1456 }
1457 key = rsa_private_key_create_from_file(path, passphrase);
1458 if (key)
1459 {
1460 this->private_keys->insert_last(this->private_keys, (void*)key);
1461 }
1462 chunk_free_randomized(&secret);
1463 }
1464 else if ( match("PSK", &token) ||
1465 ((match("EAP", &token) || match("XAUTH", &token)) && (is_eap = TRUE)))
1466 {
1467 shared_key_t *shared_key;
1468 chunk_t secret = chunk_empty;
1469
1470 err_t ugh = extract_secret(&secret, &line);
1471 if (ugh != NULL)
1472 {
1473 DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
1474 goto error;
1475 }
1476
1477 DBG1(DBG_CFG, " loading %s key for %s",
1478 is_eap ? "EAP" : "shared",
1479 ids.len > 0 ? (char*)ids.ptr : "%any");
1480
1481 DBG4(DBG_CFG, " secret:", secret);
1482
1483 shared_key = shared_key_create(secret);
1484 if (is_eap)
1485 {
1486 this->eap_keys->insert_last(this->eap_keys, (void*)shared_key);
1487 }
1488 else
1489 {
1490 this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
1491 }
1492 while (ids.len > 0)
1493 {
1494 chunk_t id;
1495 identification_t *peer_id;
1496
1497 ugh = extract_value(&id, &ids);
1498 if (ugh != NULL)
1499 {
1500 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1501 goto error;
1502 }
1503 if (id.len == 0)
1504 {
1505 continue;
1506 }
1507
1508 /* NULL terminate the ID string */
1509 *(id.ptr + id.len) = '\0';
1510
1511 peer_id = identification_create_from_string(id.ptr);
1512 if (peer_id == NULL)
1513 {
1514 DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
1515 goto error;
1516 }
1517
1518 if (peer_id->get_type(peer_id) == ID_ANY)
1519 {
1520 peer_id->destroy(peer_id);
1521 continue;
1522 }
1523 shared_key->peers->insert_last(shared_key->peers, (void*)peer_id);
1524 }
1525 }
1526 else if (match("PIN", &token))
1527 {
1528
1529 }
1530 else
1531 {
1532 DBG1(DBG_CFG, "line %d: token must be either "
1533 "RSA, PSK, EAP, or PIN", line_nr, token.len);
1534 goto error;
1535 }
1536 }
1537 error:
1538 chunk_free_randomized(&chunk);
1539 pthread_mutex_unlock(&(this->keys_mutex));
1540 }
1541 else
1542 {
1543 DBG1(DBG_CFG, "could not open file '%s': %s", SECRETS_FILE,
1544 strerror(errno));
1545 }
1546 }
1547
1548 /**
1549 * Implementation of local_credential_store_t.destroy.
1550 */
1551 static void destroy(private_local_credential_store_t *this)
1552 {
1553 this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
1554 this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy));
1555 this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
1556
1557 pthread_mutex_lock(&(this->acerts_mutex));
1558 this->acerts->destroy_offset(this->acerts, offsetof(x509ac_t, destroy));
1559 pthread_mutex_unlock(&(this->acerts_mutex));
1560
1561 pthread_mutex_lock(&(this->keys_mutex));
1562 this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
1563 this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
1564 this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy);
1565 pthread_mutex_unlock(&(this->keys_mutex));
1566
1567 free(this);
1568 }
1569
1570 /**
1571 * Described in header.
1572 */
1573 local_credential_store_t * local_credential_store_create(void)
1574 {
1575 private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
1576
1577 /* public functions */
1578 this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
1579 this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key;
1580 this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
1581 this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
1582 this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
1583 this->public.credential_store.get_auth_certificate = (x509_t* (*) (credential_store_t*,u_int,identification_t*))get_auth_certificate;
1584 this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
1585 this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,x509_t*))get_issuer;
1586 this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,const char*,x509_t*))is_trusted;
1587 this->public.credential_store.rsa_signature = (status_t (*) (credential_store_t*,rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t*))rsa_signature;
1588 this->public.credential_store.verify_signature = (status_t (*) (credential_store_t*,chunk_t,chunk_t,identification_t*,ca_info_t**))verify_signature;
1589 this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
1590 this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
1591 this->public.credential_store.add_auth_certificate = (x509_t* (*) (credential_store_t*,x509_t*,u_int))add_auth_certificate;
1592 this->public.credential_store.add_ca_info = (ca_info_t* (*) (credential_store_t*,ca_info_t*))add_ca_info;
1593 this->public.credential_store.release_ca_info = (status_t (*) (credential_store_t*,const char*))release_ca_info;
1594 this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
1595 this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator;
1596 this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
1597 this->public.credential_store.create_acert_iterator = (iterator_t* (*) (credential_store_t*))create_acert_iterator;
1598 this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
1599 this->public.credential_store.load_aa_certificates = (void (*) (credential_store_t*))load_aa_certificates;
1600 this->public.credential_store.load_attr_certificates = (void (*) (credential_store_t*))load_attr_certificates;
1601 this->public.credential_store.load_ocsp_certificates = (void (*) (credential_store_t*))load_ocsp_certificates;
1602 this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
1603 this->public.credential_store.load_secrets = (void (*) (credential_store_t*,bool))load_secrets;
1604 this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
1605
1606 /* initialize the mutexes */
1607 pthread_mutex_init(&(this->keys_mutex), NULL);
1608 pthread_mutex_init(&(this->acerts_mutex), NULL);
1609
1610 /* private variables */
1611 this->shared_keys = linked_list_create();
1612 this->eap_keys = linked_list_create();
1613 this->private_keys = linked_list_create();
1614 this->certs = linked_list_create();
1615 this->auth_certs = linked_list_create();
1616 this->ca_infos = linked_list_create();
1617 this->acerts = linked_list_create();
1618
1619 return (&this->public);
1620 }