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