support of cert payloads
[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
23 #include <sys/stat.h>
24 #include <dirent.h>
25 #include <string.h>
26 #include <pthread.h>
27
28 #include <types.h>
29 #include <utils/lexparser.h>
30 #include <utils/linked_list.h>
31 #include <utils/logger_manager.h>
32 #include <crypto/certinfo.h>
33 #include <crypto/rsa/rsa_public_key.h>
34 #include <crypto/x509.h>
35 #include <crypto/crl.h>
36
37 #include "local_credential_store.h"
38
39 #define PATH_BUF 256
40 #define MAX_CA_PATH_LEN 7
41
42 typedef struct private_local_credential_store_t private_local_credential_store_t;
43
44 /**
45 * Private data of an local_credential_store_t object
46 */
47 struct private_local_credential_store_t {
48
49 /**
50 * Public part
51 */
52 local_credential_store_t public;
53
54 /**
55 * list of key_entry_t's with private keys
56 */
57 linked_list_t *private_keys;
58
59 /**
60 * list of X.509 certificates with public keys
61 */
62 linked_list_t *certs;
63
64 /**
65 * list of X.509 CA certificates with public keys
66 */
67 linked_list_t *ca_certs;
68
69 /**
70 * list of X.509 CRLs
71 */
72 linked_list_t *crls;
73
74 /**
75 * mutex controlling the access to the crls linked list
76 */
77 pthread_mutex_t crls_mutex;
78
79 /**
80 * enforce strict crl policy
81 */
82 bool strict;
83
84 /**
85 * Assigned logger
86 */
87 logger_t *logger;
88 };
89
90
91 /**
92 * Implementation of local_credential_store_t.get_shared_secret.
93 */
94 static status_t get_shared_secret(private_local_credential_store_t *this, identification_t *id, chunk_t *secret)
95 {
96 return FAILED;
97 }
98
99 /**
100 * Implementation of credential_store_t.get_certificate.
101 */
102 static x509_t* get_certificate(private_local_credential_store_t *this, identification_t * id)
103 {
104 x509_t *found = NULL;
105
106 iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
107
108 while (iterator->has_next(iterator))
109 {
110 x509_t *cert;
111
112 iterator->current(iterator, (void**)&cert);
113
114 if (id->equals(id, cert->get_subject(cert)) || cert->equals_subjectAltName(cert, id))
115 {
116 found = cert;
117 break;
118 }
119 }
120 iterator->destroy(iterator);
121 return found;
122 }
123
124 /**
125 * Implementation of local_credential_store_t.get_rsa_public_key.
126 */
127 static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this, identification_t *id)
128 {
129 x509_t *cert = get_certificate(this, id);
130
131 return (cert == NULL)? NULL:cert->get_public_key(cert);
132 }
133
134 /**
135 * Implementation of local_credential_store_t.get_trusted_public_key.
136 */
137 static rsa_public_key_t *get_trusted_public_key(private_local_credential_store_t *this, identification_t *id)
138 {
139 cert_status_t status;
140 err_t ugh;
141
142 x509_t *cert = get_certificate(this, id);
143
144 if (cert == NULL)
145 return NULL;
146
147 ugh = cert->is_valid(cert, NULL);
148 if (ugh != NULL)
149 {
150 this->logger->log(this->logger, ERROR, "certificate %s");
151 return NULL;
152 }
153
154 status = cert->get_status(cert);
155 if (status == CERT_REVOKED || status == CERT_UNTRUSTED || (this->strict && status != CERT_GOOD))
156 {
157 this->logger->log(this->logger, ERROR, "certificate status: %s",
158 enum_name(&cert_status_names, status));
159 return NULL;
160 }
161 if (status == CERT_GOOD && cert->get_until(cert) < time(NULL))
162 {
163 this->logger->log(this->logger, ERROR, "certificate is good but crl is stale");
164 return NULL;
165 }
166
167 return cert->get_public_key(cert);
168 }
169
170 /**
171 * Implementation of local_credential_store_t.get_rsa_private_key.
172 */
173 static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
174 {
175 rsa_private_key_t *found = NULL;
176 rsa_private_key_t *current;
177
178 iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
179
180 while (iterator->has_next(iterator))
181 {
182 iterator->current(iterator, (void**)&current);
183
184 if (current->belongs_to(current, pubkey))
185 {
186 found = current->clone(current);
187 break;
188 }
189 }
190 iterator->destroy(iterator);
191 return found;
192 }
193
194 /**
195 * Implementation of local_credential_store_t.has_rsa_private_key.
196 */
197 static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
198 {
199 bool found = FALSE;
200 rsa_private_key_t *current;
201
202 iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
203
204 while (iterator->has_next(iterator))
205 {
206 iterator->current(iterator, (void**)&current);
207
208 if (current->belongs_to(current, pubkey))
209 {
210 found = TRUE;
211 break;
212 }
213 }
214 iterator->destroy(iterator);
215 return found;
216 }
217
218 /**
219 * Implementation of credential_store_t.get_issuer_certificate.
220 */
221 static x509_t* get_issuer_certificate(private_local_credential_store_t *this, const x509_t *cert)
222 {
223 x509_t *issuer_cert = NULL;
224
225 iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE);
226
227 while (iterator->has_next(iterator))
228 {
229 x509_t *current_cert;
230
231 iterator->current(iterator, (void**)&current_cert);
232 if (cert->is_issuer(cert, current_cert))
233 {
234 issuer_cert = current_cert;
235 break;
236 }
237 }
238 iterator->destroy(iterator);
239
240 return issuer_cert;
241 }
242
243 /**
244 * Implementation of credential_store_t.get_crl.
245 */
246 static crl_t* get_crl(private_local_credential_store_t *this, const x509_t *issuer)
247 {
248 crl_t *crl = NULL;
249
250 iterator_t *iterator = this->crls->create_iterator(this->crls, TRUE);
251
252 while (iterator->has_next(iterator))
253 {
254 crl_t *current_crl;
255
256 iterator->current(iterator, (void**)&current_crl);
257 if (current_crl->is_issuer(current_crl, issuer))
258 {
259 crl = current_crl;
260 break;
261 }
262 }
263 iterator->destroy(iterator);
264
265 return crl;
266 }
267
268 /**
269 * Verify the certificate status using CRLs
270 */
271 static cert_status_t verify_by_crl(private_local_credential_store_t* this, const x509_t *cert,
272 const x509_t *issuer_cert, certinfo_t *certinfo)
273 {
274 crl_t *crl;
275 bool valid_signature;
276 rsa_public_key_t *issuer_public_key;
277
278
279 pthread_mutex_lock(&(this->crls_mutex));
280
281 crl = get_crl(this, issuer_cert);
282 if (crl == NULL)
283 {
284 this->logger->log(this->logger, ERROR, "crl not found");
285 goto err;
286 }
287 this->logger->log(this->logger, CONTROL|LEVEL1, "crl found");
288
289 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
290 valid_signature = crl->verify(crl, issuer_public_key);
291
292 if (!valid_signature)
293 {
294 this->logger->log(this->logger, ERROR, "crl signature is invalid");
295 goto err;
296 }
297 this->logger->log(this->logger, CONTROL|LEVEL1, "crl signature is valid");
298
299 crl->get_status(crl, certinfo);
300
301 err:
302 pthread_mutex_unlock(&(this->crls_mutex));
303 return certinfo->get_status(certinfo);
304 }
305
306 /**
307 * Verify the certificate status using OCSP
308 */
309 static cert_status_t verify_by_ocsp(private_local_credential_store_t* this,
310 const x509_t *cert, certinfo_t *certinfo)
311 {
312 /* TODO implement function */
313 return CERT_UNDEFINED;
314 }
315
316 /**
317 * Find an exact copy of a certificate in a linked list
318 */
319 static x509_t* find_certificate_copy(linked_list_t *certs, x509_t *cert)
320 {
321 x509_t *found_cert = NULL;
322
323 iterator_t *iterator = certs->create_iterator(certs, TRUE);
324
325 while (iterator->has_next(iterator))
326 {
327 x509_t *current_cert;
328
329 iterator->current(iterator, (void**)&current_cert);
330 if (cert->equals(cert, current_cert))
331 {
332 found_cert = current_cert;
333 break;
334 }
335 }
336 iterator->destroy(iterator);
337
338 return found_cert;
339 }
340
341 /**
342 * Implementation of credential_store_t.verify.
343 */
344 static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *found)
345 {
346 int pathlen;
347 time_t until = UNDEFINED_TIME;
348
349 x509_t *end_cert = cert;
350 x509_t *cert_copy = find_certificate_copy(this->certs, end_cert);
351
352 *found = (cert_copy != NULL);
353 if (*found)
354 {
355 this->logger->log(this->logger, CONTROL|LEVEL1,
356 "end entitity certificate is already in credential store");
357 }
358
359 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
360 {
361 err_t ugh = NULL;
362 x509_t *issuer_cert;
363 rsa_public_key_t *issuer_public_key;
364 bool valid_signature;
365
366 identification_t *subject = cert->get_subject(cert);
367 identification_t *issuer = cert->get_issuer(cert);
368
369 this->logger->log(this->logger, CONTROL|LEVEL1, "subject: '%s'", subject->get_string(subject));
370 this->logger->log(this->logger, CONTROL|LEVEL1, "issuer: '%s'", issuer->get_string(issuer));
371
372 ugh = cert->is_valid(cert, &until);
373 if (ugh != NULL)
374 {
375 this->logger->log(this->logger, ERROR, "certificate %s", ugh);
376 return FALSE;
377 }
378 this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is valid");
379
380 issuer_cert = get_issuer_certificate(this, cert);
381 if (issuer_cert == NULL)
382 {
383 this->logger->log(this->logger, ERROR, "issuer certificate not found");
384 return FALSE;
385 }
386 this->logger->log(this->logger, CONTROL|LEVEL1, "issuer certificate found");
387
388 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
389 valid_signature = cert->verify(cert, issuer_public_key);
390
391 if (!valid_signature)
392 {
393 this->logger->log(this->logger, ERROR, "certificate signature is invalid");
394 return FALSE;
395 }
396 this->logger->log(this->logger, CONTROL|LEVEL1, "certificate signature is valid");
397
398 /* check if cert is a self-signed root ca */
399 if (pathlen > 0 && cert->is_self_signed(cert))
400 {
401 this->logger->log(this->logger, CONTROL|LEVEL1, "reached self-signed root ca");
402
403 /* set the definite status and trust interval of the end entity certificate */
404 end_cert->set_until(end_cert, until);
405 if (cert_copy)
406 {
407 cert_copy->set_status(cert_copy, end_cert->get_status(end_cert));
408 cert_copy->set_until(cert_copy, until);
409 }
410 return TRUE;
411 }
412 else
413 {
414 time_t nextUpdate;
415 cert_status_t status;
416 certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
417
418 certinfo->set_nextUpdate(certinfo, until);
419
420 /* first check certificate revocation using ocsp */
421 status = verify_by_ocsp(this, cert, certinfo);
422
423 /* if ocsp service is not available then fall back to crl */
424 if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && this->strict))
425 {
426 status = verify_by_crl(this, cert, issuer_cert, certinfo);
427 }
428
429 nextUpdate = certinfo->get_nextUpdate(certinfo);
430 cert->set_status(cert, status);
431
432 switch (status)
433 {
434 case CERT_GOOD:
435 /* set nextUpdate */
436 cert->set_until(cert, nextUpdate);
437
438 /* if status information is stale */
439 if (this->strict && nextUpdate < time(NULL))
440 {
441 this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good but status is stale");
442 return FALSE;
443 }
444 this->logger->log(this->logger, CONTROL|LEVEL1, "certificate is good");
445
446 /* with strict crl policy the public key must have the same
447 * lifetime as the validity of the ocsp status or crl lifetime
448 */
449 if (this->strict && nextUpdate < until)
450 until = nextUpdate;
451 break;
452 case CERT_REVOKED:
453 {
454 u_char buf[TIMETOA_BUF];
455 time_t revocationTime = certinfo->get_revocationTime(certinfo);
456
457 timetoa(buf, TIMETOA_BUF, &revocationTime, TRUE);
458 this->logger->log(this->logger, ERROR, "certificate was revoked on %s, reason: %s",
459 buf, certinfo->get_revocationReason(certinfo));
460
461 /* set revocationTime */
462 cert->set_until(cert, revocationTime);
463
464 /* update status of end certificate in the credential store */
465 if (cert_copy)
466 {
467 if (pathlen > 0)
468 {
469 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
470 }
471 else
472 {
473 cert_copy->set_status(cert_copy, CERT_REVOKED);
474 cert_copy->set_until(cert_copy, certinfo->get_revocationTime(certinfo));
475 }
476 }
477 return FALSE;
478 }
479 case CERT_UNKNOWN:
480 case CERT_UNDEFINED:
481 default:
482 this->logger->log(this->logger, CONTROL|LEVEL1, "certificate status unknown");
483 if (this->strict)
484 {
485 /* update status of end certificate in the credential store */
486 if (cert_copy)
487 {
488 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
489 }
490 return FALSE;
491 }
492 break;
493 }
494 certinfo->destroy(certinfo);
495 }
496 /* go up one step in the trust chain */
497 cert = issuer_cert;
498 }
499 this->logger->log(this->logger, ERROR, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
500 return FALSE;
501 }
502
503 /**
504 * Add a unique certificate to a linked list
505 */
506 static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
507 {
508 x509_t *found_cert = find_certificate_copy(certs, cert);
509
510 if (found_cert)
511 {
512 cert->destroy(cert);
513 return found_cert;
514 }
515 else
516 {
517 certs->insert_last(certs, (void*)cert);
518 return cert;
519 }
520 }
521
522 /**
523 * Implements local_credential_store_t.add_end_certificate
524 */
525 static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
526 {
527 return add_certificate(this->certs, cert);
528 }
529
530 /**
531 * Implements local_credential_store_t.add_ca_certificate
532 */
533 static x509_t* add_ca_certificate(private_local_credential_store_t *this, x509_t *cert)
534 {
535 return add_certificate(this->ca_certs, cert);
536 }
537
538 /**
539 * Implements local_credential_store_t.log_certificates
540 */
541 static void log_certificates(private_local_credential_store_t *this, logger_t *logger, bool utc)
542 {
543 iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
544
545 if (iterator->get_count(iterator))
546 {
547 logger->log(logger, CONTROL, "");
548 logger->log(logger, CONTROL, "List of X.509 End Entity Certificates:");
549 logger->log(logger, CONTROL, "");
550 }
551
552 while (iterator->has_next(iterator))
553 {
554 x509_t *cert;
555 bool has_key;
556
557 iterator->current(iterator, (void**)&cert);
558 has_key = has_rsa_private_key(this, cert->get_public_key(cert));
559 cert->log_certificate(cert, logger, utc, has_key);
560 }
561 iterator->destroy(iterator);
562 }
563
564 /**
565 * Implements local_credential_store_t.log_ca_certificates
566 */
567 static void log_ca_certificates(private_local_credential_store_t *this, logger_t *logger, bool utc)
568 {
569 iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE);
570
571 if (iterator->get_count(iterator))
572 {
573 logger->log(logger, CONTROL, "");
574 logger->log(logger, CONTROL, "List of X.509 CA Certificates:");
575 logger->log(logger, CONTROL, "");
576 }
577
578 while (iterator->has_next(iterator))
579 {
580 x509_t *cert;
581
582 iterator->current(iterator, (void**)&cert);
583 cert->log_certificate(cert, logger, utc, FALSE);
584 }
585 iterator->destroy(iterator);
586 }
587
588 /**
589 * Implements local_credential_store_t.log_crls
590 */
591 static void log_crls(private_local_credential_store_t *this, logger_t *logger, bool utc)
592 {
593 iterator_t *iterator = this->crls->create_iterator(this->crls, TRUE);
594
595 pthread_mutex_lock(&(this->crls_mutex));
596 if (iterator->get_count(iterator))
597 {
598 logger->log(logger, CONTROL, "");
599 logger->log(logger, CONTROL, "List of X.509 CRLs:");
600 logger->log(logger, CONTROL, "");
601 }
602
603 while (iterator->has_next(iterator))
604 {
605 crl_t *crl;
606
607 iterator->current(iterator, (void**)&crl);
608 crl->log_crl(crl, logger, utc, this->strict);
609 }
610 pthread_mutex_unlock(&(this->crls_mutex));
611
612 iterator->destroy(iterator);
613 }
614
615 /**
616 * Implements local_credential_store_t.load_ca_certificates
617 */
618 static void load_ca_certificates(private_local_credential_store_t *this)
619 {
620 struct dirent* entry;
621 struct stat stb;
622 DIR* dir;
623 x509_t *cert;
624
625 this->logger->log(this->logger, CONTROL, "loading ca certificates from '%s/'", CA_CERTIFICATE_DIR);
626
627 dir = opendir(CA_CERTIFICATE_DIR);
628 if (dir == NULL)
629 {
630 this->logger->log(this->logger, ERROR, "error opening ca certs directory %s'", CA_CERTIFICATE_DIR);
631 return;
632 }
633
634 while ((entry = readdir(dir)) != NULL)
635 {
636 char file[PATH_BUF];
637
638 snprintf(file, sizeof(file), "%s/%s", CA_CERTIFICATE_DIR, entry->d_name);
639
640 if (stat(file, &stb) == -1)
641 {
642 continue;
643 }
644 /* try to parse all regular files */
645 if (stb.st_mode & S_IFREG)
646 {
647 cert = x509_create_from_file(file, "ca certificate");
648 if (cert)
649 {
650 err_t ugh = cert->is_valid(cert, NULL);
651
652 if (ugh != NULL)
653 {
654 this->logger->log(this->logger, ERROR, "warning: ca certificate %s", ugh);
655 }
656 if (cert->is_ca(cert))
657 {
658 cert = add_certificate(this->ca_certs, cert);
659 }
660 else
661 {
662 this->logger->log(this->logger, ERROR,
663 " CA basic constraints flag not set, cert discarded");
664 cert->destroy(cert);
665 }
666 }
667 }
668 }
669 closedir(dir);
670 }
671
672 /**
673 * Add the latest crl to a linked list
674 */
675 static crl_t* add_crl(linked_list_t *crls, crl_t *crl, logger_t *logger)
676 {
677 bool found = FALSE;
678
679 iterator_t *iterator = crls->create_iterator(crls, TRUE);
680
681 while (iterator->has_next(iterator))
682 {
683 crl_t *current_crl;
684
685 iterator->current(iterator, (void**)&current_crl);
686 if (crl->equals_issuer(crl, current_crl))
687 {
688 found = TRUE;
689 if (crl->is_newer(crl, current_crl))
690 {
691 crl_t *old_crl = NULL;
692
693 iterator->replace(iterator, (void**)&old_crl, (void*)crl);
694 if (old_crl != NULL)
695 {
696 old_crl->destroy(old_crl);
697 }
698 logger->log(logger, CONTROL|LEVEL1, " thisUpdate is newer - existing crl replaced");
699 }
700 else
701 {
702 crl->destroy(crl);
703 crl = current_crl;
704 logger->log(logger, CONTROL|LEVEL1, " thisUpdate is not newer - existing crl retained");
705 }
706 break;
707 }
708 }
709 iterator->destroy(iterator);
710
711 if (!found)
712 {
713 crls->insert_last(crls, (void*)crl);
714 logger->log(logger, CONTROL|LEVEL1, " crl added");
715 }
716 return crl;
717 }
718
719 /**
720 * Implements local_credential_store_t.load_crls
721 */
722 static void load_crls(private_local_credential_store_t *this)
723 {
724 struct dirent* entry;
725 struct stat stb;
726 DIR* dir;
727 crl_t *crl;
728
729 this->logger->log(this->logger, CONTROL, "loading crls from '%s/'", CRL_DIR);
730
731 dir = opendir(CRL_DIR);
732 if (dir == NULL)
733 {
734 this->logger->log(this->logger, ERROR, "error opening crl directory %s'", CRL_DIR);
735 return;
736 }
737
738 while ((entry = readdir(dir)) != NULL)
739 {
740 char file[PATH_BUF];
741
742 snprintf(file, sizeof(file), "%s/%s", CRL_DIR, entry->d_name);
743
744 if (stat(file, &stb) == -1)
745 {
746 continue;
747 }
748 /* try to parse all regular files */
749 if (stb.st_mode & S_IFREG)
750 {
751 crl = crl_create_from_file(file);
752 if (crl)
753 {
754 err_t ugh = crl->is_valid(crl, NULL, this->strict);
755
756 if (ugh != NULL)
757 {
758 this->logger->log(this->logger, ERROR, "warning: crl %s", ugh);
759 }
760 pthread_mutex_lock(&(this->crls_mutex));
761 crl = add_crl(this->crls, crl, this->logger);
762 pthread_mutex_unlock(&(this->crls_mutex));
763 }
764 }
765 }
766 closedir(dir);
767 }
768
769 /**
770 * Implements local_credential_store_t.load_private_keys
771 */
772 static void load_private_keys(private_local_credential_store_t *this)
773 {
774 FILE *fd = fopen(SECRETS_FILE, "r");
775
776 if (fd)
777 {
778 int bytes;
779 int line_nr = 0;
780 chunk_t chunk, src, line;
781
782 this->logger->log(this->logger, CONTROL, "loading secrets from \"%s\"", SECRETS_FILE);
783
784 fseek(fd, 0, SEEK_END);
785 chunk.len = ftell(fd);
786 rewind(fd);
787 chunk.ptr = malloc(chunk.len);
788 bytes = fread(chunk.ptr, 1, chunk.len, fd);
789 fclose(fd);
790
791 src = chunk;
792
793 while (fetchline(&src, &line))
794 {
795 chunk_t ids, token;
796
797 line_nr++;
798
799 if (!eat_whitespace(&line))
800 {
801 continue;
802 }
803 if (!extract_token(&ids, ':', &line))
804 {
805 this->logger->log(this->logger, ERROR, "line %d: missing ':' separator", line_nr);
806 goto error;
807 }
808 if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
809 {
810 this->logger->log(this->logger, ERROR, "line %d: missing token", line_nr);
811 goto error;
812 }
813 if (match("RSA", &token))
814 {
815 char path[PATH_BUF];
816 chunk_t filename;
817
818 err_t ugh = extract_value(&filename, &line);
819
820 if (ugh != NULL)
821 {
822 this->logger->log(this->logger, ERROR, "line %d: %s", line_nr, ugh);
823 goto error;
824 }
825 if (filename.len == 0)
826 {
827 this->logger->log(this->logger, ERROR,
828 "line %d: empty filename", line_nr);
829 goto error;
830 }
831 if (*filename.ptr == '/')
832 {
833 /* absolute path name */
834 snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
835 }
836 else
837 {
838 /* relative path name */
839 snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR, filename.len, filename.ptr);
840 }
841
842 rsa_private_key_t *key = rsa_private_key_create_from_file(path, NULL);
843 if (key)
844 {
845 this->private_keys->insert_last(this->private_keys, (void*)key);
846 }
847 }
848 else if (match("PSK", &token))
849 {
850
851 }
852 else if (match("PIN", &token))
853 {
854
855 }
856 else
857 {
858 this->logger->log(this->logger, ERROR,
859 "line %d: token must be either RSA, PSK, or PIN",
860 line_nr, token.len);
861 goto error;
862 }
863 }
864 error:
865 free(chunk.ptr);
866 }
867 else
868 {
869 this->logger->log(this->logger, ERROR, "could not open file '%s'", SECRETS_FILE);
870 }
871 }
872
873 /**
874 * Implementation of local_credential_store_t.destroy.
875 */
876 static void destroy(private_local_credential_store_t *this)
877 {
878 x509_t *cert;
879 crl_t *crl;
880 rsa_private_key_t *key;
881
882 /* destroy cert list */
883 while (this->certs->remove_last(this->certs, (void**)&cert) == SUCCESS)
884 {
885 cert->destroy(cert);
886 }
887 this->certs->destroy(this->certs);
888
889 /* destroy ca cert list */
890 while (this->ca_certs->remove_last(this->ca_certs, (void**)&cert) == SUCCESS)
891 {
892 cert->destroy(cert);
893 }
894 this->ca_certs->destroy(this->ca_certs);
895
896 /* destroy crl list */
897 pthread_mutex_lock(&(this->crls_mutex));
898 while (this->crls->remove_last(this->crls, (void**)&crl) == SUCCESS)
899 {
900 crl->destroy(crl);
901 }
902 this->crls->destroy(this->crls);
903 pthread_mutex_unlock(&(this->crls_mutex));
904
905 /* destroy private key list */
906 while (this->private_keys->remove_last(this->private_keys, (void**)&key) == SUCCESS)
907 {
908 key->destroy(key);
909 }
910 this->private_keys->destroy(this->private_keys);
911
912 free(this);
913 }
914
915 /**
916 * Described in header.
917 */
918 local_credential_store_t * local_credential_store_create(bool strict)
919 {
920 private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
921
922 this->public.credential_store.get_shared_secret = (status_t (*) (credential_store_t*,identification_t*,chunk_t*))get_shared_secret;
923 this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
924 this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
925 this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
926 this->public.credential_store.get_trusted_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_trusted_public_key;
927 this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
928 this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
929 this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
930 this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate;
931 this->public.credential_store.log_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_certificates;
932 this->public.credential_store.log_ca_certificates = (void (*) (credential_store_t*,logger_t*,bool))log_ca_certificates;
933 this->public.credential_store.log_crls = (void (*) (credential_store_t*,logger_t*,bool))log_crls;
934 this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
935 this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
936 this->public.credential_store.load_private_keys = (void (*) (credential_store_t*))load_private_keys;
937 this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
938
939 /* initialize mutexes */
940 pthread_mutex_init(&(this->crls_mutex), NULL);
941
942 /* private variables */
943 this->private_keys = linked_list_create();
944 this->certs = linked_list_create();
945 this->ca_certs = linked_list_create();
946 this->crls = linked_list_create();
947 this->strict = strict;
948 this->logger = logger_manager->get_logger(logger_manager, CONFIG);
949
950 return (&this->public);
951 }