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