50fc53b325b965073e2312c0a7403de55c1b0715
[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.credential_store);
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 certinfo->destroy(certinfo);
646 return FALSE;
647 }
648 DBG1(DBG_CFG, "certificate is good");
649
650 /* with strict crl policy the public key must have the same
651 * lifetime as the validity of the ocsp status or crl lifetime
652 */
653 if (this->strict && nextUpdate < until)
654 until = nextUpdate;
655 break;
656 case CERT_REVOKED:
657 {
658 time_t revocationTime = certinfo->get_revocationTime(certinfo);
659 DBG1(DBG_CFG,
660 "certificate was revoked on %T, reason: %N",
661 &revocationTime, crl_reason_names,
662 certinfo->get_revocationReason(certinfo));
663
664 /* set revocationTime */
665 cert->set_until(cert, revocationTime);
666
667 /* update status of end certificate in the credential store */
668 if (cert_copy)
669 {
670 if (pathlen > 0)
671 {
672 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
673 }
674 else
675 {
676 cert_copy->set_status(cert_copy, CERT_REVOKED);
677 cert_copy->set_until(cert_copy,
678 certinfo->get_revocationTime(certinfo));
679 }
680 }
681 certinfo->destroy(certinfo);
682 return FALSE;
683 }
684 case CERT_UNKNOWN:
685 case CERT_UNDEFINED:
686 default:
687 DBG1(DBG_CFG, "certificate status unknown");
688 if (this->strict)
689 {
690 /* update status of end certificate in the credential store */
691 if (cert_copy)
692 {
693 cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
694 }
695 certinfo->destroy(certinfo);
696 return FALSE;
697 }
698 break;
699 }
700 certinfo->destroy(certinfo);
701 }
702 /* go up one step in the trust chain */
703 cert = issuer_cert;
704 }
705 DBG1(DBG_CFG, "maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
706 return FALSE;
707 }
708
709 /**
710 * Add a unique certificate to a linked list
711 */
712 static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
713 {
714 x509_t *found_cert = find_certificate(certs, cert);
715
716 if (found_cert)
717 {
718 /* add the authority flags */
719 found_cert->add_authority_flags(found_cert, cert->get_authority_flags(cert));
720
721 cert->destroy(cert);
722 return found_cert;
723 }
724 else
725 {
726 certs->insert_last(certs, (void*)cert);
727 return cert;
728 }
729 }
730
731 /**
732 * Add a unique ca info record to a linked list
733 */
734 static void add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
735 {
736 ca_info_t *current_ca_info;
737 ca_info_t *found_ca_info = NULL;
738
739 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
740
741 while (iterator->iterate(iterator, (void**)&current_ca_info))
742 {
743 if (current_ca_info->equals(current_ca_info, ca_info))
744 {
745 found_ca_info = current_ca_info;
746 break;
747 }
748 }
749 iterator->destroy(iterator);
750
751 if (found_ca_info)
752 {
753 current_ca_info->add_info(current_ca_info, ca_info);
754 ca_info->destroy(ca_info);
755 }
756 else
757 {
758 this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
759 }
760 }
761
762 /**
763 * Release ca info record of a given name
764 */
765 static status_t release_ca_info(private_local_credential_store_t *this, const char *name)
766 {
767 status_t status = NOT_FOUND;
768 ca_info_t *ca_info;
769
770 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
771
772 while (iterator->iterate(iterator, (void**)&ca_info))
773 {
774 if (ca_info->equals_name_release_info(ca_info, name))
775 {
776 status = SUCCESS;
777 break;
778 }
779 }
780 iterator->destroy(iterator);
781
782 return status;
783 }
784
785 /**
786 * Implements local_credential_store_t.add_end_certificate
787 */
788 static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
789 {
790 x509_t *ret_cert = add_certificate(this->certs, cert);
791
792 /* add crl and ocsp uris the first time the certificate is added */
793 if (ret_cert == cert)
794 {
795 ca_info_t *issuer = get_issuer(this, cert);
796
797 if (issuer)
798 {
799 add_uris(issuer, cert);
800 }
801 }
802 return ret_cert;
803 }
804
805 /**
806 * Implements local_credential_store_t.add_auth_certificate
807 */
808 static x509_t* add_auth_certificate(private_local_credential_store_t *this, x509_t *cert, u_int auth_flags)
809 {
810 cert->add_authority_flags(cert, auth_flags);
811 return add_certificate(this->auth_certs, cert);
812 }
813
814 /**
815 * Implements local_credential_store_t.create_cert_iterator
816 */
817 static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
818 {
819 return this->certs->create_iterator(this->certs, TRUE);
820 }
821
822 /**
823 * Implements local_credential_store_t.create_cacert_iterator
824 */
825 static iterator_t* create_auth_cert_iterator(private_local_credential_store_t *this)
826 {
827 return this->auth_certs->create_iterator(this->auth_certs, TRUE);
828 }
829
830 /**
831 * Implements local_credential_store_t.create_cainfo_iterator
832 */
833 static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
834 {
835 return this->ca_infos->create_iterator(this->ca_infos, TRUE);
836 }
837
838 /**
839 * Implements local_credential_store_t.list_crls
840 */
841 static void list_crls(private_local_credential_store_t *this, FILE *out, bool utc)
842 {
843 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
844 ca_info_t *ca_info;
845 bool first = TRUE;
846
847 while (iterator->iterate(iterator, (void **)&ca_info))
848 {
849 if (ca_info->has_crl(ca_info))
850 {
851 if (first)
852 {
853 fprintf(out, "\n");
854 fprintf(out, "List of X.509 CRLs:\n");
855 fprintf(out, "\n");
856 first = FALSE;
857 }
858 ca_info->list_crl(ca_info, out, utc);
859 break;
860 }
861 }
862 iterator->destroy(iterator);
863 }
864
865 /**
866 * Implements local_credential_store_t.load_auth_certificates
867 */
868 static void load_auth_certificates(private_local_credential_store_t *this,
869 u_int auth_flag,
870 const char* label,
871 const char* path)
872 {
873 struct dirent* entry;
874 struct stat stb;
875 DIR* dir;
876
877 DBG1(DBG_CFG, "loading %s certificates from '%s/'", label, path);
878
879 dir = opendir(path);
880 if (dir == NULL)
881 {
882 DBG1(DBG_CFG, "error opening %s certs directory %s'", label, path);
883 return;
884 }
885
886 while ((entry = readdir(dir)) != NULL)
887 {
888 char file[PATH_BUF];
889
890 snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
891
892 if (stat(file, &stb) == -1)
893 {
894 continue;
895 }
896 /* try to parse all regular files */
897 if (stb.st_mode & S_IFREG)
898 {
899 x509_t *cert = x509_create_from_file(file, label);
900
901 if (cert)
902 {
903 err_t ugh = cert->is_valid(cert, NULL);
904
905 if (ugh != NULL)
906 {
907 DBG1(DBG_CFG, "warning: %s certificate %s", label, ugh);
908 }
909
910 if (auth_flag == AUTH_CA && !cert->is_ca(cert))
911 {
912 DBG1(DBG_CFG, " CA basic constraints flag not set, cert discarded");
913 cert->destroy(cert);
914 }
915 else
916 {
917 x509_t *ret_cert;
918
919 cert->add_authority_flags(cert, auth_flag);
920
921 ret_cert = add_certificate(this->auth_certs, cert);
922
923 if (auth_flag == AUTH_CA && ret_cert == cert)
924 {
925 ca_info_t *ca_info = ca_info_create(NULL, cert);
926
927 add_ca_info(this, ca_info);
928 }
929 }
930 }
931 }
932 }
933 closedir(dir);
934 }
935
936 /**
937 * Implements local_credential_store_t.load_ca_certificates
938 */
939 static void load_ca_certificates(private_local_credential_store_t *this)
940 {
941 load_auth_certificates(this, AUTH_CA, "ca", CA_CERTIFICATE_DIR);
942 }
943
944 /**
945 * Implements local_credential_store_t.load_ca_certificates
946 */
947 static void load_ocsp_certificates(private_local_credential_store_t *this)
948 {
949 load_auth_certificates(this, AUTH_OCSP, "ocsp", OCSP_CERTIFICATE_DIR);
950 }
951
952 /**
953 * Add the latest crl to the issuing ca
954 */
955 static void add_crl(private_local_credential_store_t *this, crl_t *crl)
956 {
957 iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
958 ca_info_t *ca_info;
959 bool found = FALSE;
960
961 while (iterator->iterate(iterator, (void**)&ca_info))
962 {
963 if (ca_info->is_crl_issuer(ca_info, crl))
964 {
965 found = TRUE;
966 ca_info->add_crl(ca_info, crl);
967 break;
968 }
969 }
970 iterator->destroy(iterator);
971
972 if (!found)
973 {
974 crl->destroy(crl);
975 DBG2(DBG_CFG, " no issuing ca found for this crl - discarded");
976 }
977 }
978
979 /**
980 * Implements local_credential_store_t.load_crls
981 */
982 static void load_crls(private_local_credential_store_t *this)
983 {
984 struct dirent* entry;
985 struct stat stb;
986 DIR* dir;
987 crl_t *crl;
988
989 DBG1(DBG_CFG, "loading crls from '%s/'", CRL_DIR);
990
991 dir = opendir(CRL_DIR);
992 if (dir == NULL)
993 {
994 DBG1(DBG_CFG, "error opening crl directory %s'", CRL_DIR);
995 return;
996 }
997
998 while ((entry = readdir(dir)) != NULL)
999 {
1000 char file[PATH_BUF];
1001
1002 snprintf(file, sizeof(file), "%s/%s", CRL_DIR, entry->d_name);
1003
1004 if (stat(file, &stb) == -1)
1005 {
1006 continue;
1007 }
1008 /* try to parse all regular files */
1009 if (stb.st_mode & S_IFREG)
1010 {
1011 crl = crl_create_from_file(file);
1012 if (crl)
1013 {
1014 err_t ugh = crl->is_valid(crl, NULL, this->strict);
1015
1016 if (ugh != NULL)
1017 {
1018 DBG1(DBG_CFG, " warning: crl %s", ugh);
1019 }
1020 add_crl(this, crl);
1021 }
1022 }
1023 }
1024 closedir(dir);
1025 }
1026
1027 /**
1028 * Convert a string of characters into a binary secret
1029 * A string between single or double quotes is treated as ASCII characters
1030 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
1031 */
1032 static err_t extract_secret(chunk_t *secret, chunk_t *line)
1033 {
1034 chunk_t raw_secret;
1035 char delimiter = ' ';
1036 bool quotes = FALSE;
1037
1038 if (!eat_whitespace(line))
1039 {
1040 return "missing secret";
1041 }
1042
1043 if (*line->ptr == '\'' || *line->ptr == '"')
1044 {
1045 quotes = TRUE;
1046 delimiter = *line->ptr;
1047 line->ptr++; line->len--;
1048 }
1049
1050 if (!extract_token(&raw_secret, delimiter, line))
1051 {
1052 if (delimiter == ' ')
1053 {
1054 raw_secret = *line;
1055 }
1056 else
1057 {
1058 return "missing second delimiter";
1059 }
1060 }
1061
1062 if (quotes)
1063 { /* treat as an ASCII string */
1064 if (raw_secret.len > secret->len)
1065 return "secret larger than buffer";
1066 memcpy(secret->ptr, raw_secret.ptr, raw_secret.len);
1067 secret->len = raw_secret.len;
1068 }
1069 else
1070 { /* convert from HEX or Base64 to binary */
1071 size_t len;
1072 err_t ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
1073
1074 if (ugh != NULL)
1075 return ugh;
1076 if (len > secret->len)
1077 return "secret larger than buffer";
1078 secret->len = len;
1079 }
1080 return NULL;
1081 }
1082
1083 /**
1084 * Implements local_credential_store_t.load_secrets
1085 */
1086 static void load_secrets(private_local_credential_store_t *this)
1087 {
1088 FILE *fd = fopen(SECRETS_FILE, "r");
1089
1090 if (fd)
1091 {
1092 int bytes;
1093 int line_nr = 0;
1094 chunk_t chunk, src, line;
1095
1096 DBG1(DBG_CFG, "loading secrets from \"%s\"", SECRETS_FILE);
1097
1098 fseek(fd, 0, SEEK_END);
1099 chunk.len = ftell(fd);
1100 rewind(fd);
1101 chunk.ptr = malloc(chunk.len);
1102 bytes = fread(chunk.ptr, 1, chunk.len, fd);
1103 fclose(fd);
1104
1105 src = chunk;
1106
1107 while (fetchline(&src, &line))
1108 {
1109 chunk_t ids, token;
1110
1111 line_nr++;
1112
1113 if (!eat_whitespace(&line))
1114 {
1115 continue;
1116 }
1117 if (!extract_token(&ids, ':', &line))
1118 {
1119 DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
1120 goto error;
1121 }
1122 /* NULL terminate the ids string by replacing the : separator */
1123 *(ids.ptr + ids.len) = '\0';
1124
1125 if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
1126 {
1127 DBG1(DBG_CFG, "line %d: missing token", line_nr);
1128 goto error;
1129 }
1130 if (match("RSA", &token))
1131 {
1132 char path[PATH_BUF];
1133 chunk_t filename;
1134
1135 char buf[BUF_LEN];
1136 chunk_t secret = { buf, BUF_LEN };
1137 chunk_t *passphrase = NULL;
1138
1139 rsa_private_key_t *key;
1140
1141 err_t ugh = extract_value(&filename, &line);
1142
1143 if (ugh != NULL)
1144 {
1145 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1146 goto error;
1147 }
1148 if (filename.len == 0)
1149 {
1150 DBG1(DBG_CFG, "line %d: empty filename", line_nr);
1151 goto error;
1152 }
1153 if (*filename.ptr == '/')
1154 {
1155 /* absolute path name */
1156 snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
1157 }
1158 else
1159 {
1160 /* relative path name */
1161 snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
1162 filename.len, filename.ptr);
1163 }
1164
1165 /* check for optional passphrase */
1166 if (eat_whitespace(&line))
1167 {
1168 ugh = extract_secret(&secret, &line);
1169 if (ugh != NULL)
1170 {
1171 DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
1172 goto error;
1173 }
1174 if (secret.len > 0)
1175 passphrase = &secret;
1176 }
1177 key = rsa_private_key_create_from_file(path, passphrase);
1178 if (key)
1179 {
1180 this->private_keys->insert_last(this->private_keys, (void*)key);
1181 }
1182 }
1183 else if (match("PSK", &token))
1184 {
1185 shared_key_t *shared_key;
1186
1187 char buf[BUF_LEN];
1188 chunk_t secret = { buf, BUF_LEN };
1189
1190 err_t ugh = extract_secret(&secret, &line);
1191 if (ugh != NULL)
1192 {
1193 DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
1194 goto error;
1195 }
1196
1197 if (ids.len > 0)
1198 {
1199 DBG1(DBG_CFG, " loading shared key for %s", ids.ptr);
1200 }
1201 else
1202 {
1203 DBG1(DBG_CFG, " loading shared key for %%any");
1204 }
1205
1206 DBG4(DBG_CFG, " secret:", secret);
1207
1208 shared_key = shared_key_create(secret);
1209 if (shared_key)
1210 {
1211 this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
1212 }
1213 while (ids.len > 0)
1214 {
1215 chunk_t id;
1216 identification_t *peer_id;
1217
1218 ugh = extract_value(&id, &ids);
1219 if (ugh != NULL)
1220 {
1221 DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
1222 goto error;
1223 }
1224 if (id.len == 0)
1225 {
1226 continue;
1227 }
1228
1229 /* NULL terminate the ID string */
1230 *(id.ptr + id.len) = '\0';
1231
1232 peer_id = identification_create_from_string(id.ptr);
1233 if (peer_id == NULL)
1234 {
1235 DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
1236 goto error;
1237 }
1238
1239 if (peer_id->get_type(peer_id) == ID_ANY)
1240 {
1241 peer_id->destroy(peer_id);
1242 continue;
1243 }
1244 shared_key->peers->insert_last(shared_key->peers, (void*)peer_id);
1245 }
1246 }
1247 else if (match("PIN", &token))
1248 {
1249
1250 }
1251 else
1252 {
1253 DBG1(DBG_CFG, "line %d: token must be either "
1254 "RSA, PSK, or PIN", line_nr, token.len);
1255 goto error;
1256 }
1257 }
1258 error:
1259 free(chunk.ptr);
1260 }
1261 else
1262 {
1263 DBG1(DBG_CFG, "could not open file '%s'", SECRETS_FILE);
1264 }
1265 }
1266
1267 /**
1268 * Implementation of local_credential_store_t.destroy.
1269 */
1270 static void destroy(private_local_credential_store_t *this)
1271 {
1272 this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
1273 this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy));
1274 this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
1275 this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
1276 this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
1277 free(this);
1278 }
1279
1280 /**
1281 * Described in header.
1282 */
1283 local_credential_store_t * local_credential_store_create(bool strict)
1284 {
1285 private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
1286
1287 this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
1288 this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
1289 this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
1290 this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
1291 this->public.credential_store.get_trusted_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_trusted_public_key;
1292 this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
1293 this->public.credential_store.get_auth_certificate = (x509_t* (*) (credential_store_t*,u_int,identification_t*))get_auth_certificate;
1294 this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
1295 this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,const x509_t*))get_issuer;
1296 this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,x509_t*))is_trusted;
1297 this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
1298 this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
1299 this->public.credential_store.add_auth_certificate = (x509_t* (*) (credential_store_t*,x509_t*,u_int))add_auth_certificate;
1300 this->public.credential_store.add_ca_info = (void (*) (credential_store_t*,ca_info_t*))add_ca_info;
1301 this->public.credential_store.release_ca_info = (status_t (*) (credential_store_t*,const char*))release_ca_info;
1302 this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
1303 this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator;
1304 this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
1305 this->public.credential_store.list_crls = (void (*) (credential_store_t*,FILE*,bool))list_crls;
1306 this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
1307 this->public.credential_store.load_ocsp_certificates = (void (*) (credential_store_t*))load_ocsp_certificates;
1308 this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
1309 this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets;
1310 this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
1311
1312 /* private variables */
1313 this->shared_keys = linked_list_create();
1314 this->private_keys = linked_list_create();
1315 this->certs = linked_list_create();
1316 this->auth_certs = linked_list_create();
1317 this->ca_infos = linked_list_create();
1318 this->strict = strict;
1319
1320 return (&this->public);
1321 }