427fef2904b9a4669d2f62677d0322dd034bb182
[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 <library.h>
29 #include <utils/lexparser.h>
30 #include <utils/linked_list.h>
31 #include <crypto/certinfo.h>
32 #include <crypto/rsa/rsa_public_key.h>
33 #include <crypto/x509.h>
34 #include <crypto/ca.h>
35 #include <crypto/crl.h>
36 #include <asn1/ttodata.h>
37
38 #include "local_credential_store.h"
39
40 #define PATH_BUF 256
41 #define MAX_CA_PATH_LEN 7
42
43 typedef struct shared_key_t shared_key_t;
44
45 /**
46 * Private date of a shared_key_t object
47 */
48 struct shared_key_t {
49
50 /**
51 * shared secret
52 */
53 chunk_t secret;
54
55 /**
56 * list of peer IDs
57 */
58 linked_list_t *peers;
59 };
60
61
62 /**
63 * Implementation of shared_key_t.destroy.
64 */
65 static void shared_key_destroy(shared_key_t *this)
66 {
67 this->peers->destroy_offset(this->peers, offsetof(identification_t, destroy));
68 chunk_free(&this->secret);
69 free(this);
70 }
71
72 /**
73 * @brief Creates a shared_key_t object.
74 *
75 * @param shared_key shared key value
76 * @return shared_key_t object
77 *
78 * @ingroup config
79 */
80 static shared_key_t *shared_key_create(chunk_t secret)
81 {
82 shared_key_t *this = malloc_thing(shared_key_t);
83
84 /* private data */
85 this->secret = chunk_clone(secret);
86 this->peers = linked_list_create();
87
88 return (this);
89 }
90
91
92 typedef struct private_local_credential_store_t private_local_credential_store_t;
93
94 /**
95 * Private data of an local_credential_store_t object
96 */
97 struct private_local_credential_store_t {
98
99 /**
100 * Public part
101 */
102 local_credential_store_t public;
103
104 /**
105 * list of shared keys
106 */
107 linked_list_t *shared_keys;
108
109 /**
110 * list of key_entry_t's with private keys
111 */
112 linked_list_t *private_keys;
113
114 /**
115 * list of X.509 certificates with public keys
116 */
117 linked_list_t *certs;
118
119 /**
120 * list of X.509 CA certificates with public keys
121 */
122 linked_list_t *ca_certs;
123
124 /**
125 * list of X.509 CA information records
126 */
127 linked_list_t *ca_infos;
128
129 /**
130 * mutex controlling the access to the ca_infos linked list
131 */
132 pthread_mutex_t ca_infos_mutex;
133
134 /**
135 * list of X.509 CRLs
136 */
137 linked_list_t *crls;
138
139 /**
140 * mutex controlling the access to the crls linked list
141 */
142 pthread_mutex_t crls_mutex;
143
144 /**
145 * enforce strict crl policy
146 */
147 bool strict;
148 };
149
150
151 /**
152 * Implementation of local_credential_store_t.get_shared_key.
153 */
154 static status_t get_shared_key(private_local_credential_store_t *this,
155 identification_t *my_id,
156 identification_t *other_id, chunk_t *secret)
157 {
158 typedef enum {
159 PRIO_UNDEFINED= 0x00,
160 PRIO_ANY_MATCH= 0x01,
161 PRIO_MY_MATCH= 0x02,
162 PRIO_OTHER_MATCH= 0x04,
163 } prio_t;
164
165 prio_t best_prio = PRIO_UNDEFINED;
166 chunk_t found = chunk_empty;
167 shared_key_t *shared_key;
168
169 iterator_t *iterator = this->shared_keys->create_iterator(this->shared_keys, TRUE);
170
171 while (iterator->iterate(iterator, (void**)&shared_key))
172 {
173 iterator_t *peer_iterator;
174 identification_t *peer_id;
175 prio_t prio = PRIO_UNDEFINED;
176
177 peer_iterator = shared_key->peers->create_iterator(shared_key->peers, TRUE);
178
179 if (peer_iterator->get_count(peer_iterator) == 0)
180 {
181 /* this is a wildcard shared key */
182 prio = PRIO_ANY_MATCH;
183 }
184 else
185 {
186 while (peer_iterator->iterate(peer_iterator, (void**)&peer_id))
187 {
188 if (my_id->equals(my_id, peer_id))
189 {
190 prio |= PRIO_MY_MATCH;
191 }
192 if (other_id->equals(other_id, peer_id))
193 {
194 prio |= PRIO_OTHER_MATCH;
195 }
196 }
197 }
198 peer_iterator->destroy(peer_iterator);
199
200 if (prio > best_prio)
201 {
202 best_prio = prio;
203 found = shared_key->secret;
204 }
205 }
206 iterator->destroy(iterator);
207
208 if (best_prio == PRIO_UNDEFINED)
209 {
210 return NOT_FOUND;
211 }
212 else
213 {
214 *secret = chunk_clone(found);
215 return SUCCESS;
216 }
217 }
218
219 /**
220 * Implementation of credential_store_t.get_certificate.
221 */
222 static x509_t* get_certificate(private_local_credential_store_t *this,
223 identification_t *id)
224 {
225 x509_t *found = NULL;
226 x509_t *current_cert;
227
228 iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
229
230 while (iterator->iterate(iterator, (void**)&current_cert))
231 {
232 if (id->equals(id, current_cert->get_subject(current_cert)) ||
233 current_cert->equals_subjectAltName(current_cert, id))
234 {
235 found = current_cert;
236 break;
237 }
238 }
239 iterator->destroy(iterator);
240 return found;
241 }
242
243 /**
244 * Implementation of local_credential_store_t.get_rsa_public_key.
245 */
246 static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this,
247 identification_t *id)
248 {
249 x509_t *cert = get_certificate(this, id);
250
251 return (cert == NULL)? NULL:cert->get_public_key(cert);
252 }
253
254 /**
255 * Implementation of local_credential_store_t.get_trusted_public_key.
256 */
257 static rsa_public_key_t *get_trusted_public_key(private_local_credential_store_t *this,
258 identification_t *id)
259 {
260 cert_status_t status;
261 err_t ugh;
262
263 x509_t *cert = get_certificate(this, id);
264
265 if (cert == NULL)
266 return NULL;
267
268 ugh = cert->is_valid(cert, NULL);
269 if (ugh != NULL)
270 {
271 DBG1(DBG_CFG, "certificate %s", ugh);
272 return NULL;
273 }
274
275 status = cert->get_status(cert);
276 if (status == CERT_REVOKED || status == CERT_UNTRUSTED || (this->strict && status != CERT_GOOD))
277 {
278 DBG1(DBG_CFG, "certificate status: %N", cert_status_names, status);
279 return NULL;
280 }
281 if (status == CERT_GOOD && cert->get_until(cert) < time(NULL))
282 {
283 DBG1(DBG_CFG, "certificate is good but crl is stale");
284 return NULL;
285 }
286
287 return cert->get_public_key(cert);
288 }
289
290 /**
291 * Implementation of local_credential_store_t.get_rsa_private_key.
292 */
293 static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this,
294 rsa_public_key_t *pubkey)
295 {
296 rsa_private_key_t *found = NULL, *current;
297
298 iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
299
300 while (iterator->iterate(iterator, (void**)&current))
301 {
302 if (current->belongs_to(current, pubkey))
303 {
304 found = current->clone(current);
305 break;
306 }
307 }
308 iterator->destroy(iterator);
309 return found;
310 }
311
312 /**
313 * Implementation of local_credential_store_t.has_rsa_private_key.
314 */
315 static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
316 {
317 bool found = FALSE;
318 rsa_private_key_t *current;
319
320 iterator_t *iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
321
322 while (iterator->iterate(iterator, (void**)&current))
323 {
324 if (current->belongs_to(current, pubkey))
325 {
326 found = TRUE;
327 break;
328 }
329 }
330 iterator->destroy(iterator);
331 return found;
332 }
333
334 /**
335 * Implementation of credential_store_t.get_ca_certificate.
336 */
337 static x509_t* get_ca_certificate(private_local_credential_store_t *this,
338 identification_t *id)
339 {
340 x509_t *found = NULL;
341 x509_t *current_cert;
342
343 iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE);
344
345 while (iterator->iterate(iterator, (void**)&current_cert))
346 {
347 if (id->equals(id, current_cert->get_subject(current_cert)))
348 {
349 found = current_cert;
350 break;
351 }
352 }
353 iterator->destroy(iterator);
354
355 return found;
356 }
357
358 /**
359 * Implementation of credential_store_t.get_ca_certificate_by_keyid.
360 */
361 static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *this,
362 chunk_t keyid)
363 {
364 x509_t *found = NULL;
365 x509_t *current_cert;
366
367 iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE);
368
369 while (iterator->iterate(iterator, (void**)&current_cert))
370 {
371 rsa_public_key_t *pubkey = current_cert->get_public_key(current_cert);
372
373 if (chunk_equals(keyid, pubkey->get_keyid(pubkey)))
374 {
375 found = current_cert;
376 break;
377 }
378 }
379 iterator->destroy(iterator);
380
381 return found;
382 }
383
384 /**
385 * Implementation of credential_store_t.get_issuer_certificate.
386 */
387 static x509_t* get_issuer_certificate(private_local_credential_store_t *this,
388 const x509_t *cert)
389 {
390 x509_t *found = NULL;
391 x509_t *current_cert;
392
393 iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE);
394
395 while (iterator->iterate(iterator, (void**)&current_cert))
396 {
397 if (cert->is_issuer(cert, current_cert))
398 {
399 found = current_cert;
400 break;
401 }
402 }
403 iterator->destroy(iterator);
404
405 return found;
406 }
407
408 /**
409 * Implementation of credential_store_t.get_crl.
410 */
411 static crl_t* get_crl(private_local_credential_store_t *this, const x509_t *issuer)
412 {
413 crl_t *crl = NULL, *current_crl;
414
415 iterator_t *iterator = this->crls->create_iterator(this->crls, TRUE);
416
417 while (iterator->iterate(iterator, (void**)&current_crl))
418 {
419 if (current_crl->is_issuer(current_crl, issuer))
420 {
421 crl = current_crl;
422 break;
423 }
424 }
425 iterator->destroy(iterator);
426
427 return crl;
428 }
429
430 /**
431 * Verify the certificate status using CRLs
432 */
433 static cert_status_t verify_by_crl(private_local_credential_store_t* this, const x509_t *cert,
434 const x509_t *issuer_cert, certinfo_t *certinfo)
435 {
436 crl_t *crl;
437 bool valid_signature;
438 rsa_public_key_t *issuer_public_key;
439
440
441 pthread_mutex_lock(&(this->crls_mutex));
442
443 crl = get_crl(this, issuer_cert);
444 if (crl == NULL)
445 {
446 DBG1(DBG_CFG, "crl not found");
447 goto err;
448 }
449 DBG2(DBG_CFG, "crl found");
450
451 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
452 valid_signature = crl->verify(crl, issuer_public_key);
453
454 if (!valid_signature)
455 {
456 DBG1(DBG_CFG, "crl signature is invalid");
457 goto err;
458 }
459 DBG2(DBG_CFG, "crl signature is valid");
460
461 crl->get_status(crl, certinfo);
462
463 err:
464 pthread_mutex_unlock(&(this->crls_mutex));
465 return certinfo->get_status(certinfo);
466 }
467
468 /**
469 * Verify the certificate status using OCSP
470 */
471 static cert_status_t verify_by_ocsp(private_local_credential_store_t* this,
472 const x509_t *cert, certinfo_t *certinfo)
473 {
474 /* TODO implement function */
475 return CERT_UNDEFINED;
476 }
477
478 /**
479 * Find an exact copy of a certificate in a linked list
480 */
481 static x509_t* find_certificate(linked_list_t *certs, x509_t *cert)
482 {
483 x509_t *found_cert = NULL, *current_cert;
484
485 iterator_t *iterator = certs->create_iterator(certs, TRUE);
486
487 while (iterator->iterate(iterator, (void**)&current_cert))
488 {
489 if (cert->equals(cert, current_cert))
490 {
491 found_cert = current_cert;
492 break;
493 }
494 }
495 iterator->destroy(iterator);
496
497 return found_cert;
498 }
499
500 /**
501 * Implementation of credential_store_t.verify.
502 */
503 static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *found)
504 {
505 int pathlen;
506 time_t until = UNDEFINED_TIME;
507
508 x509_t *end_cert = cert;
509 x509_t *cert_copy = find_certificate(this->certs, end_cert);
510
511 *found = (cert_copy != NULL);
512 if (*found)
513 {
514 DBG2(DBG_CFG,
515 "end entitity certificate is already in credential store");
516 }
517
518 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
519 {
520 err_t ugh = NULL;
521 x509_t *issuer_cert;
522 rsa_public_key_t *issuer_public_key;
523 bool valid_signature;
524
525 DBG2(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
526 DBG2(DBG_CFG, "issuer: '%D'", cert->get_issuer(cert));
527
528 ugh = cert->is_valid(cert, &until);
529 if (ugh != NULL)
530 {
531 DBG1(DBG_CFG, "certificate %s", ugh);
532 return FALSE;
533 }
534 DBG2(DBG_CFG, "certificate is valid");
535
536 issuer_cert = get_issuer_certificate(this, cert);
537 if (issuer_cert == NULL)
538 {
539 DBG1(DBG_CFG, "issuer certificate not found");
540 return FALSE;
541 }
542 DBG2(DBG_CFG, "issuer certificate found");
543
544 issuer_public_key = issuer_cert->get_public_key(issuer_cert);
545 valid_signature = cert->verify(cert, issuer_public_key);
546
547 if (!valid_signature)
548 {
549 DBG1(DBG_CFG, "certificate signature is invalid");
550 return FALSE;
551 }
552 DBG2(DBG_CFG, "certificate signature is valid");
553
554 /* check if cert is a self-signed root ca */
555 if (pathlen > 0 && cert->is_self_signed(cert))
556 {
557 DBG2(DBG_CFG, "reached self-signed root ca");
558
559 /* set the definite status and trust interval of the end entity certificate */
560 end_cert->set_until(end_cert, until);
561 if (cert_copy)
562 {
563 cert_copy->set_status(cert_copy, end_cert->get_status(end_cert));
564 cert_copy->set_until(cert_copy, until);
565 }
566 return TRUE;
567 }
568 else
569 {
570 time_t nextUpdate;
571 cert_status_t status;
572 certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
573
574 certinfo->set_nextUpdate(certinfo, until);
575
576 /* first check certificate revocation using ocsp */
577 status = verify_by_ocsp(this, cert, certinfo);
578
579 /* if ocsp service is not available then fall back to crl */
580 if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && this->strict))
581 {
582 status = verify_by_crl(this, cert, issuer_cert, certinfo);
583 }
584
585 nextUpdate = certinfo->get_nextUpdate(certinfo);
586 cert->set_status(cert, status);
587
588 switch (status)
589 {
590 case CERT_GOOD:
591 /* set nextUpdate */
592 cert->set_until(cert, nextUpdate);
593
594 /* if status information is stale */
595 if (this->strict && nextUpdate < time(NULL))
596 {
597 DBG2(DBG_CFG, "certificate is good but status is stale");
598 return FALSE;
599 }
600 DBG2(DBG_CFG, "certificate is good");
601
602 /* with strict crl policy the public key must have the same
603 * lifetime as the validity of the ocsp status or crl lifetime
604 */
605 if (this->strict && nextUpdate < until)
606 until = nextUpdate;
607 break;
608 case CERT_REVOKED:
609 {
610 time_t revocationTime = certinfo->get_revocationTime(certinfo);
611 DBG1(DBG_CFG,
612 "certificate was revoked on %T, reason: %N",
613 &revocationTime, crl_reason_names,
614 certinfo->get_revocationReason(certinfo));
615
616 /* set revocationTime */
617 cert->set_until(cert, revocationTime);
618
619 /* update status of end certificate in the credential store */
620 if (cert_copy)
621 {
622 if (pathlen > 0)
623 {
624 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
625 }
626 else
627 {
628 cert_copy->set_status(cert_copy, CERT_REVOKED);
629 cert_copy->set_until(cert_copy,
630 certinfo->get_revocationTime(certinfo));
631 }
632 }
633 return FALSE;
634 }
635 case CERT_UNKNOWN:
636 case CERT_UNDEFINED:
637 default:
638 DBG2(DBG_CFG, "certificate status unknown");
639 if (this->strict)
640 {
641 /* update status of end certificate in the credential store */
642 if (cert_copy)
643 {
644 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
645 }
646 return FALSE;
647 }
648 break;
649 }
650 certinfo->destroy(certinfo);
651 }
652 /* go up one step in the trust chain */
653 cert = issuer_cert;
654 }
655 DBG1(DBG_CFG, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
656 return FALSE;
657 }
658
659 /**
660 * Add a unique certificate to a linked list
661 */
662 static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
663 {
664 x509_t *found_cert = find_certificate(certs, cert);
665
666 if (found_cert)
667 {
668 cert->destroy(cert);
669 return found_cert;
670 }
671 else
672 {
673 certs->insert_last(certs, (void*)cert);
674 return cert;
675 }
676 }
677
678 /**
679 * Add a unique ca info record to a linked list
680 */
681 static void add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
682 {
683 ca_info_t *current_ca_info;
684 ca_info_t *found_ca_info = NULL;
685
686 iterator_t *iterator = this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex));
687
688 while (iterator->iterate(iterator, (void**)&current_ca_info))
689 {
690 if (current_ca_info->equals(current_ca_info, ca_info))
691 {
692 found_ca_info = current_ca_info;
693 break;
694 }
695 }
696 if (found_ca_info)
697 {
698 current_ca_info->add_info(current_ca_info, ca_info);
699 ca_info->destroy(ca_info);
700 }
701 else
702 {
703 this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
704 }
705 iterator->destroy(iterator);
706 }
707
708 /**
709 * Release ca info record of a given name
710 */
711 static status_t release_ca_info(private_local_credential_store_t *this, const char *name)
712 {
713 status_t status = NOT_FOUND;
714 ca_info_t *ca_info;
715
716 iterator_t *iterator = this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex));
717
718 while (iterator->iterate(iterator, (void**)&ca_info))
719 {
720 if (ca_info->equals_name(ca_info, name))
721 {
722 ca_info->release_info(ca_info);
723 status = SUCCESS;
724 break;
725 }
726 }
727 iterator->destroy(iterator);
728
729 return status;
730 }
731
732 /**
733 * Implements local_credential_store_t.add_end_certificate
734 */
735 static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
736 {
737 x509_t *ret_cert = add_certificate(this->certs, cert);
738
739 if (ret_cert == cert)
740 {
741 x509_t *issuer_cert = get_issuer_certificate(this, cert);
742
743 if (issuer_cert)
744 {
745 ca_info_t *ca_info = ca_info_create(NULL, issuer_cert);
746
747 {
748 iterator_t *iterator = cert->create_crluri_iterator(cert);
749 identification_t *uri;
750
751 while (iterator->iterate(iterator, (void**)&uri))
752 {
753 ca_info->add_crluri(ca_info, uri->get_encoding(uri));
754 }
755 iterator->destroy(iterator);
756 }
757 {
758 iterator_t *iterator = cert->create_ocspuri_iterator(cert);
759 identification_t *uri;
760
761 while (iterator->iterate(iterator, (void**)&uri))
762 {
763 ca_info->add_ocspuri(ca_info, uri->get_encoding(uri));
764 }
765 iterator->destroy(iterator);
766 }
767
768 add_ca_info(this, ca_info);
769 }
770 }
771 return ret_cert;
772 }
773
774 /**
775 * Implements local_credential_store_t.add_ca_certificate
776 */
777 static x509_t* add_ca_certificate(private_local_credential_store_t *this, x509_t *cert)
778 {
779 return add_certificate(this->ca_certs, cert);
780 }
781
782 /**
783 * Implements local_credential_store_t.create_cert_iterator
784 */
785 static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
786 {
787 return this->certs->create_iterator(this->certs, TRUE);
788 }
789
790 /**
791 * Implements local_credential_store_t.create_cacert_iterator
792 */
793 static iterator_t* create_cacert_iterator(private_local_credential_store_t *this)
794 {
795 return this->ca_certs->create_iterator(this->ca_certs, TRUE);
796 }
797
798 /**
799 * Implements local_credential_store_t.create_cainfo_iterator
800 */
801 static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
802 {
803 return this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex));
804 }
805
806 /**
807 * Implements local_credential_store_t.create_crl_iterator
808 */
809 static iterator_t* create_crl_iterator(private_local_credential_store_t *this)
810 {
811 return this->crls->create_iterator_locked(this->crls, &(this->crls_mutex));
812 }
813
814 /**
815 * Implements local_credential_store_t.load_ca_certificates
816 */
817 static void load_ca_certificates(private_local_credential_store_t *this)
818 {
819 struct dirent* entry;
820 struct stat stb;
821 DIR* dir;
822
823 DBG1(DBG_CFG, "loading ca certificates from '%s/'", CA_CERTIFICATE_DIR);
824
825 dir = opendir(CA_CERTIFICATE_DIR);
826 if (dir == NULL)
827 {
828 DBG1(DBG_CFG, "error opening ca certs directory %s'", CA_CERTIFICATE_DIR);
829 return;
830 }
831
832 while ((entry = readdir(dir)) != NULL)
833 {
834 char file[PATH_BUF];
835
836 snprintf(file, sizeof(file), "%s/%s", CA_CERTIFICATE_DIR, entry->d_name);
837
838 if (stat(file, &stb) == -1)
839 {
840 continue;
841 }
842 /* try to parse all regular files */
843 if (stb.st_mode & S_IFREG)
844 {
845 x509_t *cert = x509_create_from_file(file, "ca certificate");
846
847 if (cert)
848 {
849 err_t ugh = cert->is_valid(cert, NULL);
850
851 if (ugh != NULL)
852 {
853 DBG1(DBG_CFG, "warning: ca certificate %s", ugh);
854 }
855 if (cert->is_ca(cert))
856 {
857 x509_t *ret_cert = add_certificate(this->ca_certs, cert);
858
859 if (ret_cert == cert)
860 {
861 ca_info_t *ca_info = ca_info_create(NULL, cert);
862
863 add_ca_info(this, ca_info);
864 }
865 }
866 else
867 {
868 DBG1(DBG_CFG, " CA basic constraints flag not set, cert discarded");
869 cert->destroy(cert);
870 }
871 }
872 }
873 }
874 closedir(dir);
875 }
876
877 /**
878 * Add the latest crl to a linked list
879 */
880 static crl_t* add_crl(linked_list_t *crls, crl_t *crl)
881 {
882 bool found = FALSE;
883 crl_t *current_crl;
884
885 iterator_t *iterator = crls->create_iterator(crls, TRUE);
886
887 while (iterator->iterate(iterator, (void**)&current_crl))
888 {
889 if (crl->equals_issuer(crl, current_crl))
890 {
891 found = TRUE;
892 if (crl->is_newer(crl, current_crl))
893 {
894 crl_t *old_crl = NULL;
895
896 iterator->replace(iterator, (void**)&old_crl, (void*)crl);
897 if (old_crl != NULL)
898 {
899 old_crl->destroy(old_crl);
900 }
901 DBG2(DBG_CFG, " thisUpdate is newer - existing crl replaced");
902 }
903 else
904 {
905 crl->destroy(crl);
906 crl = current_crl;
907 DBG2(DBG_CFG, " thisUpdate is not newer - existing crl retained");
908 }
909 break;
910 }
911 }
912 iterator->destroy(iterator);
913
914 if (!found)
915 {
916 crls->insert_last(crls, (void*)crl);
917 DBG2(DBG_CFG, " crl added");
918 }
919 return crl;
920 }
921
922 /**
923 * Implements local_credential_store_t.load_crls
924 */
925 static void load_crls(private_local_credential_store_t *this)
926 {
927 struct dirent* entry;
928 struct stat stb;
929 DIR* dir;
930 crl_t *crl;
931
932 DBG1(DBG_CFG, "loading crls from '%s/'", CRL_DIR);
933
934 dir = opendir(CRL_DIR);
935 if (dir == NULL)
936 {
937 DBG1(DBG_CFG, "error opening crl directory %s'", CRL_DIR);
938 return;
939 }
940
941 while ((entry = readdir(dir)) != NULL)
942 {
943 char file[PATH_BUF];
944
945 snprintf(file, sizeof(file), "%s/%s", CRL_DIR, entry->d_name);
946
947 if (stat(file, &stb) == -1)
948 {
949 continue;
950 }
951 /* try to parse all regular files */
952 if (stb.st_mode & S_IFREG)
953 {
954 crl = crl_create_from_file(file);
955 if (crl)
956 {
957 err_t ugh = crl->is_valid(crl, NULL, this->strict);
958
959 if (ugh != NULL)
960 {
961 DBG1(DBG_CFG, "warning: crl %s", ugh);
962 }
963 pthread_mutex_lock(&(this->crls_mutex));
964 crl = add_crl(this->crls, crl);
965 pthread_mutex_unlock(&(this->crls_mutex));
966 }
967 }
968 }
969 closedir(dir);
970 }
971
972 /**
973 * Convert a string of characters into a binary secret
974 * A string between single or double quotes is treated as ASCII characters
975 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
976 */
977 static err_t extract_secret(chunk_t *secret, chunk_t *line)
978 {
979 chunk_t raw_secret;
980 char delimiter = ' ';
981 bool quotes = FALSE;
982
983 if (!eat_whitespace(line))
984 {
985 return "missing secret";
986 }
987
988 if (*line->ptr == '\'' || *line->ptr == '"')
989 {
990 quotes = TRUE;
991 delimiter = *line->ptr;
992 line->ptr++; line->len--;
993 }
994
995 if (!extract_token(&raw_secret, delimiter, line))
996 {
997 if (delimiter == ' ')
998 {
999 raw_secret = *line;
1000 }
1001 else
1002 {
1003 return "missing second delimiter";
1004 }
1005 }
1006
1007 if (quotes)
1008 { /* treat as an ASCII string */
1009 if (raw_secret.len > secret->len)
1010 return "secret larger than buffer";
1011 memcpy(secret->ptr, raw_secret.ptr, raw_secret.len);
1012 secret->len = raw_secret.len;
1013 }
1014 else
1015 { /* convert from HEX or Base64 to binary */
1016 size_t len;
1017 err_t ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
1018
1019 if (ugh != NULL)
1020 return ugh;
1021 if (len > secret->len)
1022 return "secret larger than buffer";
1023 secret->len = len;
1024 }
1025 return NULL;
1026 }
1027
1028 /**
1029 * Implements local_credential_store_t.load_secrets
1030 */
1031 static void load_secrets(private_local_credential_store_t *this)
1032 {
1033 FILE *fd = fopen(SECRETS_FILE, "r");
1034
1035 if (fd)
1036 {
1037 int bytes;
1038 int line_nr = 0;
1039 chunk_t chunk, src, line;
1040
1041 DBG1(DBG_CFG, "loading secrets from \"%s\"", SECRETS_FILE);
1042
1043 fseek(fd, 0, SEEK_END);
1044 chunk.len = ftell(fd);
1045 rewind(fd);
1046 chunk.ptr = malloc(chunk.len);
1047 bytes = fread(chunk.ptr, 1, chunk.len, fd);
1048 fclose(fd);
1049
1050 src = chunk;
1051
1052 while (fetchline(&src, &line))
1053 {
1054 chunk_t ids, token;
1055
1056 line_nr++;
1057
1058 if (!eat_whitespace(&line))
1059 {
1060 continue;
1061 }
1062 if (!extract_token(&ids, ':', &line))
1063 {
1064 DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
1065 goto error;
1066 }
1067 /* NULL terminate the ids string by replacing the : separator */
1068 *(ids.ptr + ids.len) = '\0';
1069
1070 if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
1071 {
1072 DBG1(DBG_CFG, "line %d: missing token", line_nr);
1073 goto error;
1074 }
1075 if (match("RSA", &token))
1076 {
1077 char path[PATH_BUF];
1078 chunk_t filename;
1079
1080 char buf[BUF_LEN];
1081 chunk_t secret = { buf, BUF_LEN };
1082 chunk_t *passphrase = NULL;
1083
1084 rsa_private_key_t *key;
1085
1086 err_t ugh = extract_value(&filename, &line);
1087
1088 if (ugh != NULL)
1089 {
1090 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1091 goto error;
1092 }
1093 if (filename.len == 0)
1094 {
1095 DBG1(DBG_CFG, "line %d: empty filename", line_nr);
1096 goto error;
1097 }
1098 if (*filename.ptr == '/')
1099 {
1100 /* absolute path name */
1101 snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
1102 }
1103 else
1104 {
1105 /* relative path name */
1106 snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
1107 filename.len, filename.ptr);
1108 }
1109
1110 /* check for optional passphrase */
1111 if (eat_whitespace(&line))
1112 {
1113 ugh = extract_secret(&secret, &line);
1114 if (ugh != NULL)
1115 {
1116 DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
1117 goto error;
1118 }
1119 if (secret.len > 0)
1120 passphrase = &secret;
1121 }
1122 key = rsa_private_key_create_from_file(path, passphrase);
1123 if (key)
1124 {
1125 this->private_keys->insert_last(this->private_keys, (void*)key);
1126 }
1127 }
1128 else if (match("PSK", &token))
1129 {
1130 shared_key_t *shared_key;
1131
1132 char buf[BUF_LEN];
1133 chunk_t secret = { buf, BUF_LEN };
1134
1135 err_t ugh = extract_secret(&secret, &line);
1136 if (ugh != NULL)
1137 {
1138 DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
1139 goto error;
1140 }
1141
1142 if (ids.len > 0)
1143 {
1144 DBG1(DBG_CFG, " loading shared key for %s", ids.ptr);
1145 }
1146 else
1147 {
1148 DBG1(DBG_CFG, " loading shared key for %%any");
1149 }
1150
1151 DBG4(DBG_CFG, " secret:", secret);
1152
1153 shared_key = shared_key_create(secret);
1154 if (shared_key)
1155 {
1156 this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
1157 }
1158 while (ids.len > 0)
1159 {
1160 chunk_t id;
1161 identification_t *peer_id;
1162
1163 ugh = extract_value(&id, &ids);
1164 if (ugh != NULL)
1165 {
1166 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1167 goto error;
1168 }
1169 if (id.len == 0)
1170 {
1171 continue;
1172 }
1173
1174 /* NULL terminate the ID string */
1175 *(id.ptr + id.len) = '\0';
1176
1177 peer_id = identification_create_from_string(id.ptr);
1178 if (peer_id == NULL)
1179 {
1180 DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
1181 goto error;
1182 }
1183
1184 if (peer_id->get_type(peer_id) == ID_ANY)
1185 {
1186 peer_id->destroy(peer_id);
1187 continue;
1188 }
1189 shared_key->peers->insert_last(shared_key->peers, (void*)peer_id);
1190 }
1191 }
1192 else if (match("PIN", &token))
1193 {
1194
1195 }
1196 else
1197 {
1198 DBG1(DBG_CFG, "line %d: token must be either "
1199 "RSA, PSK, or PIN", line_nr, token.len);
1200 goto error;
1201 }
1202 }
1203 error:
1204 free(chunk.ptr);
1205 }
1206 else
1207 {
1208 DBG1(DBG_CFG, "could not open file '%s'", SECRETS_FILE);
1209 }
1210 }
1211
1212 /**
1213 * Implementation of local_credential_store_t.destroy.
1214 */
1215 static void destroy(private_local_credential_store_t *this)
1216 {
1217 this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
1218 this->ca_certs->destroy_offset(this->ca_certs, offsetof(x509_t, destroy));
1219 this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
1220 this->crls->destroy_offset(this->crls, offsetof(crl_t, destroy));
1221 this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
1222 this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
1223 free(this);
1224 }
1225
1226 /**
1227 * Described in header.
1228 */
1229 local_credential_store_t * local_credential_store_create(bool strict)
1230 {
1231 private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
1232
1233 this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
1234 this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
1235 this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
1236 this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
1237 this->public.credential_store.get_trusted_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_trusted_public_key;
1238 this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
1239 this->public.credential_store.get_ca_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_ca_certificate;
1240 this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
1241 this->public.credential_store.get_issuer_certificate = (x509_t* (*) (credential_store_t*,const x509_t*))get_issuer_certificate;
1242 this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
1243 this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
1244 this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate;
1245 this->public.credential_store.add_ca_info = (void (*) (credential_store_t*,ca_info_t*))add_ca_info;
1246 this->public.credential_store.release_ca_info = (status_t (*) (credential_store_t*,const char*))release_ca_info;
1247 this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
1248 this->public.credential_store.create_cacert_iterator = (iterator_t* (*) (credential_store_t*))create_cacert_iterator;
1249 this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
1250 this->public.credential_store.create_crl_iterator = (iterator_t* (*) (credential_store_t*))create_crl_iterator;
1251 this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
1252 this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
1253 this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets;
1254 this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
1255
1256 /* initialize mutexes */
1257 pthread_mutex_init(&(this->crls_mutex), NULL);
1258 pthread_mutex_init(&(this->ca_infos_mutex), NULL);
1259
1260 /* private variables */
1261 this->shared_keys = linked_list_create();
1262 this->private_keys = linked_list_create();
1263 this->certs = linked_list_create();
1264 this->ca_certs = linked_list_create();
1265 this->ca_infos = linked_list_create();
1266 this->crls = linked_list_create();
1267 this->strict = strict;
1268
1269 return (&this->public);
1270 }