2 * @file local_credential_store.c
4 * @brief Implementation of local_credential_store_t.
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
30 #include <utils/lexparser.h>
31 #include <utils/linked_list.h>
32 #include <crypto/rsa/rsa_public_key.h>
33 #include <crypto/certinfo.h>
34 #include <crypto/x509.h>
35 #include <crypto/ca.h>
36 #include <crypto/ac.h>
37 #include <crypto/crl.h>
38 #include <asn1/ttodata.h>
40 #include "local_credential_store.h"
44 typedef struct shared_key_t shared_key_t
;
47 * Private date of a shared_key_t object
64 * Implementation of shared_key_t.destroy.
66 static void shared_key_destroy(shared_key_t
*this)
68 this->peers
->destroy_offset(this->peers
, offsetof(identification_t
, destroy
));
69 chunk_free(&this->secret
);
74 * @brief Creates a shared_key_t object.
76 * @param shared_key shared key value
77 * @return shared_key_t object
81 static shared_key_t
*shared_key_create(chunk_t secret
)
83 shared_key_t
*this = malloc_thing(shared_key_t
);
86 this->secret
= chunk_clone(secret
);
87 this->peers
= linked_list_create();
92 /* ------------------------------------------------------------------------ *
93 * the ca_info_t object as a central control element
95 +--------------------------------------------------------+
96 | local_credential_store_t |
97 +--------------------------------------------------------+
99 +---------------------------+ +-------------------------+
100 | linked_list_t *auth_certs | | linked_list_t *ca_infos |
101 +---------------------------+ +-------------------------+
103 | +------------------------- +
105 | +--------------------------+
106 +---------------+ | char *name |
107 | x509_t |<--| x509_t *cacert |
108 +---------------+ | linked_list_t *attrcerts | +----------------------+
109 | chunk_t keyid | | linked_list_t *certinfos |-->| certinfo_t |
110 +---------------+ | linked_list_t *ocspuris | +----------------------+
111 | | crl_t *crl | | chunk_t serialNumber |
112 | | linked_list_t *crluris | | cert_status_t status |
113 +---------------+ | pthread_mutex_t mutex | | time_t thisUpdate |
114 | x509_t | +--------------------------+ | time_t nextUpdate |
115 +---------------+ | | bool once |
116 | chunk_t keyid | | +----------------------+
117 +---------------+ +------------------------- + |
118 | | ca_info_t | +----------------------+
119 | +--------------------------+ | certinfo_t |
120 +---------------+ | char *name | +----------------------+
121 | x509_t |<--| x509_t *cacert | | chunk_t serialNumber |
122 +---------------+ | linked_list_t *attrcerts | | cert_status_t status |
123 | chunk_t keyid | | linked_list_t *certinfos | | time_t thisUpdate |
124 +---------------+ | linked_list_t *ocspuris | | time_t nextUpdate |
125 | | crl_t *crl | | bool once |
126 | | linked_list_t *crluris | +----------------------+
127 | | pthread_mutex_t mutex; | |
128 | +--------------------------+
131 * ------------------------------------------------------------------------ */
133 typedef struct private_local_credential_store_t private_local_credential_store_t
;
136 * Private data of an local_credential_store_t object
138 struct private_local_credential_store_t
{
143 local_credential_store_t
public;
146 * list of shared keys
148 linked_list_t
*shared_keys
;
153 linked_list_t
*eap_keys
;
156 * list of key_entry_t's with private keys
158 linked_list_t
*private_keys
;
161 * list of X.509 certificates with public keys
163 linked_list_t
*certs
;
166 * list of X.509 authority certificates with public keys
168 linked_list_t
*auth_certs
;
171 * list of X.509 CA information records
173 linked_list_t
*ca_infos
;
178 * Get a key from a list with shared_key_t's
180 static status_t
get_key(linked_list_t
*keys
,
181 identification_t
*my_id
,
182 identification_t
*other_id
, chunk_t
*secret
)
185 PRIO_UNDEFINED
= 0x00,
186 PRIO_ANY_MATCH
= 0x01,
188 PRIO_OTHER_MATCH
= 0x04,
191 prio_t best_prio
= PRIO_UNDEFINED
;
192 chunk_t found
= chunk_empty
;
193 shared_key_t
*shared_key
;
195 iterator_t
*iterator
= keys
->create_iterator(keys
, TRUE
);
197 while (iterator
->iterate(iterator
, (void**)&shared_key
))
199 iterator_t
*peer_iterator
;
200 identification_t
*peer_id
;
201 prio_t prio
= PRIO_UNDEFINED
;
203 peer_iterator
= shared_key
->peers
->create_iterator(shared_key
->peers
, TRUE
);
205 if (peer_iterator
->get_count(peer_iterator
) == 0)
207 /* this is a wildcard shared key */
208 prio
= PRIO_ANY_MATCH
;
212 while (peer_iterator
->iterate(peer_iterator
, (void**)&peer_id
))
214 if (my_id
->equals(my_id
, peer_id
))
216 prio
|= PRIO_MY_MATCH
;
218 if (other_id
->equals(other_id
, peer_id
))
220 prio
|= PRIO_OTHER_MATCH
;
224 peer_iterator
->destroy(peer_iterator
);
226 if (prio
> best_prio
)
229 found
= shared_key
->secret
;
232 iterator
->destroy(iterator
);
234 if (best_prio
== PRIO_UNDEFINED
)
240 *secret
= chunk_clone(found
);
247 * Implementation of local_credential_store_t.get_shared_key.
249 static status_t
get_shared_key(private_local_credential_store_t
*this,
250 identification_t
*my_id
,
251 identification_t
*other_id
, chunk_t
*secret
)
253 return get_key(this->shared_keys
, my_id
, other_id
, secret
);
257 * Implementation of local_credential_store_t.get_eap_key.
259 static status_t
get_eap_key(private_local_credential_store_t
*this,
260 identification_t
*my_id
,
261 identification_t
*other_id
, chunk_t
*secret
)
263 return get_key(this->eap_keys
, my_id
, other_id
, secret
);
267 * Implementation of credential_store_t.get_certificate.
269 static x509_t
* get_certificate(private_local_credential_store_t
*this,
270 identification_t
*id
)
272 x509_t
*found
= NULL
;
273 x509_t
*current_cert
;
275 iterator_t
*iterator
= this->certs
->create_iterator(this->certs
, TRUE
);
277 while (iterator
->iterate(iterator
, (void**)¤t_cert
))
279 if (id
->equals(id
, current_cert
->get_subject(current_cert
)) ||
280 current_cert
->equals_subjectAltName(current_cert
, id
))
282 found
= current_cert
;
286 iterator
->destroy(iterator
);
291 * Implementation of local_credential_store_t.get_rsa_public_key.
293 static rsa_public_key_t
*get_rsa_public_key(private_local_credential_store_t
*this,
294 identification_t
*id
)
296 x509_t
*cert
= get_certificate(this, id
);
298 return (cert
== NULL
)? NULL
:cert
->get_public_key(cert
);
302 * Implementation of credential_store_t.get_issuer.
304 static ca_info_t
* get_issuer(private_local_credential_store_t
*this, x509_t
*cert
)
306 ca_info_t
*found
= cert
->get_ca_info(cert
);
310 iterator_t
*iterator
= this->ca_infos
->create_iterator(this->ca_infos
, TRUE
);
313 while (iterator
->iterate(iterator
, (void**)&ca_info
))
315 if (ca_info
->is_cert_issuer(ca_info
, cert
))
318 cert
->set_ca_info(cert
, found
);
322 iterator
->destroy(iterator
);
328 * Implementation of local_credential_store_t.get_rsa_private_key.
330 static rsa_private_key_t
*get_rsa_private_key(private_local_credential_store_t
*this,
331 rsa_public_key_t
*pubkey
)
333 rsa_private_key_t
*found
= NULL
, *current
;
335 iterator_t
*iterator
= this->private_keys
->create_iterator(this->private_keys
, TRUE
);
337 while (iterator
->iterate(iterator
, (void**)¤t
))
339 if (current
->belongs_to(current
, pubkey
))
341 found
= current
->clone(current
);
345 iterator
->destroy(iterator
);
350 * Implementation of local_credential_store_t.has_rsa_private_key.
352 static bool has_rsa_private_key(private_local_credential_store_t
*this, rsa_public_key_t
*pubkey
)
355 rsa_private_key_t
*current
;
357 iterator_t
*iterator
= this->private_keys
->create_iterator(this->private_keys
, TRUE
);
359 while (iterator
->iterate(iterator
, (void**)¤t
))
361 if (current
->belongs_to(current
, pubkey
))
367 iterator
->destroy(iterator
);
372 * Implementation of credential_store_t.get_auth_certificate.
374 static x509_t
* get_auth_certificate(private_local_credential_store_t
*this,
376 identification_t
*id
)
378 x509_t
*found
= NULL
;
379 x509_t
*current_cert
;
381 iterator_t
*iterator
= this->auth_certs
->create_iterator(this->auth_certs
, TRUE
);
383 while (iterator
->iterate(iterator
, (void**)¤t_cert
))
385 if (current_cert
->has_authority_flag(current_cert
, auth_flags
)
386 && id
->equals(id
, current_cert
->get_subject(current_cert
)))
388 found
= current_cert
;
392 iterator
->destroy(iterator
);
398 * Implementation of credential_store_t.get_ca_certificate_by_keyid.
400 static x509_t
* get_ca_certificate_by_keyid(private_local_credential_store_t
*this,
403 x509_t
*found
= NULL
;
404 x509_t
*current_cert
;
406 iterator_t
*iterator
= this->auth_certs
->create_iterator(this->auth_certs
, TRUE
);
408 while (iterator
->iterate(iterator
, (void**)¤t_cert
))
410 rsa_public_key_t
*pubkey
= current_cert
->get_public_key(current_cert
);
412 if (current_cert
->has_authority_flag(current_cert
, AUTH_CA
)
413 && chunk_equals(keyid
, pubkey
->get_keyid(pubkey
)))
415 found
= current_cert
;
419 iterator
->destroy(iterator
);
425 * Find an exact copy of a certificate in a linked list
427 static x509_t
* find_certificate(linked_list_t
*certs
, x509_t
*cert
)
429 x509_t
*found_cert
= NULL
, *current_cert
;
431 iterator_t
*iterator
= certs
->create_iterator(certs
, TRUE
);
433 while (iterator
->iterate(iterator
, (void**)¤t_cert
))
435 if (cert
->equals(cert
, current_cert
))
437 found_cert
= current_cert
;
441 iterator
->destroy(iterator
);
447 * Adds crl and ocsp uris to the corresponding issuer info record
449 static void add_uris(ca_info_t
*issuer
, x509_t
*cert
)
451 iterator_t
*iterator
;
452 identification_t
*uri
;
454 /* add any crl distribution points to the issuer ca info record */
455 iterator
= cert
->create_crluri_iterator(cert
);
457 while (iterator
->iterate(iterator
, (void**)&uri
))
459 issuer
->add_crluri(issuer
, uri
->get_encoding(uri
));
461 iterator
->destroy(iterator
);
463 /* add any ocsp access points to the issuer ca info record */
464 iterator
= cert
->create_ocspuri_iterator(cert
);
466 while (iterator
->iterate(iterator
, (void**)&uri
))
468 issuer
->add_ocspuri(issuer
, uri
->get_encoding(uri
));
470 iterator
->destroy(iterator
);
474 * Implementation of credential_store_t.is_trusted
476 static bool is_trusted(private_local_credential_store_t
*this, const char *label
, x509_t
*cert
)
479 time_t until
= UNDEFINED_TIME
;
480 x509_t
*cert_to_be_trusted
= cert
;
482 DBG1(DBG_CFG
, "establishing trust in %s certificate:", label
);
484 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
489 rsa_public_key_t
*issuer_public_key
;
490 bool valid_signature
;
492 DBG1(DBG_CFG
, "subject: '%D'", cert
->get_subject(cert
));
493 DBG1(DBG_CFG
, "issuer: '%D'", cert
->get_issuer(cert
));
495 ugh
= cert
->is_valid(cert
, &until
);
498 DBG1(DBG_CFG
, "certificate %s", ugh
);
501 DBG2(DBG_CFG
, "certificate is valid");
503 issuer
= get_issuer(this, cert
);
506 DBG1(DBG_CFG
, "issuer not found");
509 DBG2(DBG_CFG
, "issuer found");
511 issuer_cert
= issuer
->get_certificate(issuer
);
512 issuer_public_key
= issuer_cert
->get_public_key(issuer_cert
);
513 valid_signature
= cert
->verify(cert
, issuer_public_key
);
515 if (!valid_signature
)
517 DBG1(DBG_CFG
, "certificate signature is invalid");
520 DBG2(DBG_CFG
, "certificate signature is valid");
522 /* check if cert is a self-signed root ca */
523 if (pathlen
> 0 && cert
->is_self_signed(cert
))
525 DBG1(DBG_CFG
, "reached self-signed root ca");
526 cert_to_be_trusted
->set_until(cert_to_be_trusted
, until
);
527 cert_to_be_trusted
->set_status(cert_to_be_trusted
, CERT_GOOD
);
532 DBG1(DBG_CFG
, "going up one step in the certificate trust chain (%d)",
537 DBG1(DBG_CFG
, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN
);
542 * Implementation of credential_store_t.verify.
544 static bool verify(private_local_credential_store_t
*this, x509_t
*cert
, bool *found
)
547 time_t until
= UNDEFINED_TIME
;
549 x509_t
*end_cert
= cert
;
550 x509_t
*cert_copy
= find_certificate(this->certs
, end_cert
);
552 DBG1(DBG_CFG
, "verifying end entity certificate up to trust anchor:");
554 *found
= (cert_copy
!= NULL
);
558 "end entitity certificate is already in credential store");
561 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
563 bool valid_signature
;
567 rsa_public_key_t
*issuer_public_key
;
568 chunk_t keyid
= cert
->get_keyid(cert
);
570 DBG1(DBG_CFG
, "subject: '%D'", cert
->get_subject(cert
));
571 DBG1(DBG_CFG
, "issuer: '%D'", cert
->get_issuer(cert
));
572 DBG1(DBG_CFG
, "keyid: %#B", &keyid
);
574 ugh
= cert
->is_valid(cert
, &until
);
577 DBG1(DBG_CFG
, "certificate %s", ugh
);
580 DBG2(DBG_CFG
, "certificate is valid");
582 issuer
= get_issuer(this, cert
);
585 DBG1(DBG_CFG
, "issuer not found");
588 DBG2(DBG_CFG
, "issuer found");
590 issuer_cert
= issuer
->get_certificate(issuer
);
591 issuer_public_key
= issuer_cert
->get_public_key(issuer_cert
);
592 valid_signature
= cert
->verify(cert
, issuer_public_key
);
594 if (!valid_signature
)
596 DBG1(DBG_CFG
, "certificate signature is invalid");
599 DBG2(DBG_CFG
, "certificate signature is valid");
601 /* check if cert is a self-signed root ca */
602 if (pathlen
> 0 && cert
->is_self_signed(cert
))
604 DBG1(DBG_CFG
, "reached self-signed root ca");
606 /* set the definite status and trust interval of the end entity certificate */
607 end_cert
->set_until(end_cert
, until
);
610 cert_copy
->set_status(cert_copy
, end_cert
->get_status(end_cert
));
611 cert_copy
->set_until(cert_copy
, until
);
619 cert_status_t status
;
620 certinfo_t
*certinfo
= certinfo_create(cert
->get_serialNumber(cert
));
622 certinfo
->set_status(certinfo
, CERT_UNKNOWN
);
626 /* add any crl and ocsp uris contained in the certificate under test */
627 add_uris(issuer
, cert
);
630 strict
= issuer
->is_strict(issuer
);
631 DBG1(DBG_CFG
, "issuer %s a strict crl policy",
632 strict ?
"enforces":"does not enforce");
634 /* first check certificate revocation using ocsp */
635 status
= issuer
->verify_by_ocsp(issuer
, certinfo
, &this->public.credential_store
);
637 /* if ocsp service is not available then fall back to crl */
638 if ((status
== CERT_UNDEFINED
) || (status
== CERT_UNKNOWN
&& strict
))
640 status
= issuer
->verify_by_crl(issuer
, certinfo
, CRL_DIR
);
643 nextUpdate
= certinfo
->get_nextUpdate(certinfo
);
644 cert
->set_status(cert
, status
);
649 /* with strict crl policy the public key must have the same
650 * lifetime as the validity of the ocsp status or crl lifetime
654 cert
->set_until(cert
, nextUpdate
);
655 until
= (nextUpdate
< until
)? nextUpdate
: until
;
658 /* if status information is stale */
659 if (strict
&& nextUpdate
< time(NULL
))
661 DBG2(DBG_CFG
, "certificate is good but status is stale");
662 certinfo
->destroy(certinfo
);
665 DBG1(DBG_CFG
, "certificate is good");
669 time_t revocationTime
= certinfo
->get_revocationTime(certinfo
);
671 "certificate was revoked on %T, reason: %N",
672 &revocationTime
, crl_reason_names
,
673 certinfo
->get_revocationReason(certinfo
));
675 /* set revocationTime */
676 cert
->set_until(cert
, revocationTime
);
678 /* update status of end certificate in the credential store */
683 cert_copy
->set_status(cert_copy
, CERT_UNTRUSTED
);
687 cert_copy
->set_status(cert_copy
, CERT_REVOKED
);
688 cert_copy
->set_until(cert_copy
,
689 certinfo
->get_revocationTime(certinfo
));
692 certinfo
->destroy(certinfo
);
698 DBG1(DBG_CFG
, "certificate status unknown");
701 /* update status of end certificate in the credential store */
704 cert_copy
->set_status(cert_copy
, CERT_UNTRUSTED
);
706 certinfo
->destroy(certinfo
);
711 certinfo
->destroy(certinfo
);
713 DBG1(DBG_CFG
, "going up one step in the certificate trust chain (%d)",
717 DBG1(DBG_CFG
, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN
);
722 * Implementation of local_credential_store_t.verify_signature.
724 static status_t
verify_signature(private_local_credential_store_t
*this,
725 chunk_t hash
, chunk_t sig
,
726 identification_t
*id
, ca_info_t
**issuer_p
)
728 iterator_t
*iterator
= this->certs
->create_iterator(this->certs
, TRUE
);
732 /* default return values in case of failure */
733 sig_status
= NOT_FOUND
;
736 while (iterator
->iterate(iterator
, (void**)&cert
))
738 if (id
->equals(id
, cert
->get_subject(cert
))
739 || cert
->equals_subjectAltName(cert
, id
))
741 rsa_public_key_t
*public_key
= cert
->get_public_key(cert
);
742 cert_status_t cert_status
= cert
->get_status(cert
);
744 DBG2(DBG_CFG
, "found candidate peer certificate");
746 if (cert_status
== CERT_UNDEFINED
|| cert
->get_until(cert
) < time(NULL
))
750 if (!verify(this, cert
, &found
))
752 sig_status
= VERIFY_ERROR
;
753 DBG1(DBG_CFG
, "candidate peer certificate was not successfully verified");
756 *issuer_p
= get_issuer(this, cert
);
760 ca_info_t
*issuer
= get_issuer(this, cert
);
761 chunk_t keyid
= public_key
->get_keyid(public_key
);
763 DBG2(DBG_CFG
, "subject: '%D'", cert
->get_subject(cert
));
764 DBG2(DBG_CFG
, "issuer: '%D'", cert
->get_issuer(cert
));
765 DBG2(DBG_CFG
, "keyid: %#B", &keyid
);
769 DBG1(DBG_CFG
, "candidate peer certificate has no retrievable issuer");
770 sig_status
= NOT_FOUND
;
773 if (cert_status
== CERT_REVOKED
|| cert_status
== CERT_UNTRUSTED
774 || ((issuer
)->is_strict(issuer
) && cert_status
!= CERT_GOOD
))
776 DBG1(DBG_CFG
, "candidate peer certificate has an inacceptable status: %N", cert_status_names
, cert_status
);
777 sig_status
= VERIFY_ERROR
;
782 sig_status
= public_key
->verify_emsa_pkcs1_signature(public_key
, hash
, sig
);
783 if (sig_status
== SUCCESS
)
785 DBG2(DBG_CFG
, "candidate peer certificate has a matching RSA public key");
790 DBG1(DBG_CFG
, "candidate peer certificate has a non-matching RSA public key");
795 iterator
->destroy(iterator
);
796 if (sig_status
== NOT_FOUND
)
798 DBG1(DBG_CFG
, "no candidate peer certificate found");
804 * Add a unique certificate to a linked list
806 static x509_t
* add_certificate(linked_list_t
*certs
, x509_t
*cert
)
808 x509_t
*found_cert
= find_certificate(certs
, cert
);
812 /* add the authority flags */
813 found_cert
->add_authority_flags(found_cert
, cert
->get_authority_flags(cert
));
820 certs
->insert_last(certs
, (void*)cert
);
826 * Add a unique ca info record to a linked list
828 static ca_info_t
* add_ca_info(private_local_credential_store_t
*this, ca_info_t
*ca_info
)
830 ca_info_t
*current_ca_info
;
831 ca_info_t
*found_ca_info
= NULL
;
833 iterator_t
*iterator
= this->ca_infos
->create_iterator(this->ca_infos
, TRUE
);
835 while (iterator
->iterate(iterator
, (void**)¤t_ca_info
))
837 if (current_ca_info
->equals(current_ca_info
, ca_info
))
839 found_ca_info
= current_ca_info
;
843 iterator
->destroy(iterator
);
847 current_ca_info
->add_info(current_ca_info
, ca_info
);
848 ca_info
->destroy(ca_info
);
849 ca_info
= found_ca_info
;
853 this->ca_infos
->insert_last(this->ca_infos
, (void*)ca_info
);
859 * Release ca info record of a given name
861 static status_t
release_ca_info(private_local_credential_store_t
*this, const char *name
)
863 status_t status
= NOT_FOUND
;
866 iterator_t
*iterator
= this->ca_infos
->create_iterator(this->ca_infos
, TRUE
);
868 while (iterator
->iterate(iterator
, (void**)&ca_info
))
870 if (ca_info
->equals_name_release_info(ca_info
, name
))
876 iterator
->destroy(iterator
);
882 * Implements local_credential_store_t.add_end_certificate
884 static x509_t
* add_end_certificate(private_local_credential_store_t
*this, x509_t
*cert
)
886 x509_t
*ret_cert
= add_certificate(this->certs
, cert
);
888 /* add crl and ocsp uris the first time the certificate is added */
889 if (ret_cert
== cert
)
891 ca_info_t
*issuer
= get_issuer(this, cert
);
895 add_uris(issuer
, cert
);
902 * Implements local_credential_store_t.add_auth_certificate
904 static x509_t
* add_auth_certificate(private_local_credential_store_t
*this, x509_t
*cert
, u_int auth_flags
)
906 cert
->add_authority_flags(cert
, auth_flags
);
907 return add_certificate(this->auth_certs
, cert
);
911 * Implements local_credential_store_t.create_cert_iterator
913 static iterator_t
* create_cert_iterator(private_local_credential_store_t
*this)
915 return this->certs
->create_iterator(this->certs
, TRUE
);
919 * Implements local_credential_store_t.create_cacert_iterator
921 static iterator_t
* create_auth_cert_iterator(private_local_credential_store_t
*this)
923 return this->auth_certs
->create_iterator(this->auth_certs
, TRUE
);
927 * Implements local_credential_store_t.create_cainfo_iterator
929 static iterator_t
* create_cainfo_iterator(private_local_credential_store_t
*this)
931 return this->ca_infos
->create_iterator(this->ca_infos
, TRUE
);
935 * Implements local_credential_store_t.load_auth_certificates
937 static void load_auth_certificates(private_local_credential_store_t
*this,
942 struct dirent
* entry
;
946 DBG1(DBG_CFG
, "loading %s certificates from '%s'", label
, path
);
951 DBG1(DBG_CFG
, "error opening %s certs directory '%s'", label
, path
);
955 while ((entry
= readdir(dir
)) != NULL
)
959 snprintf(file
, sizeof(file
), "%s/%s", path
, entry
->d_name
);
961 if (stat(file
, &stb
) == -1)
965 /* try to parse all regular files */
966 if (stb
.st_mode
& S_IFREG
)
968 x509_t
*cert
= x509_create_from_file(file
, label
);
972 err_t ugh
= cert
->is_valid(cert
, NULL
);
976 DBG1(DBG_CFG
, "warning: %s certificate %s", label
, ugh
);
979 if (auth_flag
== AUTH_CA
&& !cert
->is_ca(cert
))
981 DBG1(DBG_CFG
, " CA basic constraints flag not set, cert discarded");
988 cert
->add_authority_flags(cert
, auth_flag
);
990 ret_cert
= add_certificate(this->auth_certs
, cert
);
992 if (auth_flag
== AUTH_CA
&& ret_cert
== cert
)
994 ca_info_t
*ca_info
= ca_info_create(NULL
, cert
);
996 add_ca_info(this, ca_info
);
1006 * Implements local_credential_store_t.load_ca_certificates
1008 static void load_ca_certificates(private_local_credential_store_t
*this)
1010 load_auth_certificates(this, AUTH_CA
, "ca", CA_CERTIFICATE_DIR
);
1012 /* add any crl and ocsp uris found in the ca certificates to the
1013 * corresponding issuer info record. We can do this only after all
1014 * ca certificates have been loaded and the ca hierarchy is known.
1017 iterator_t
*iterator
= this->ca_infos
->create_iterator(this->ca_infos
, TRUE
);
1020 while (iterator
->iterate(iterator
, (void **)&ca_info
))
1022 if (ca_info
->is_ca(ca_info
))
1024 x509_t
*cacert
= ca_info
->get_certificate(ca_info
);
1025 ca_info_t
*issuer
= get_issuer(this, cacert
);
1029 add_uris(issuer
, cacert
);
1033 iterator
->destroy(iterator
);
1038 * Implements local_credential_store_t.load_aa_certificates
1040 static void load_aa_certificates(private_local_credential_store_t
*this)
1042 load_auth_certificates(this, AUTH_AA
, "aa", AA_CERTIFICATE_DIR
);
1046 * Add a unique attribute certificate to a linked list
1048 static void add_attr_certificate(private_local_credential_store_t
*this, x509ac_t
*cert
)
1050 /* TODO add a new attribute certificate to the linked list */
1054 * Implements local_credential_store_t.load_attr_certificates
1056 static void load_attr_certificates(private_local_credential_store_t
*this)
1058 struct dirent
* entry
;
1062 const char *path
= ATTR_CERTIFICATE_DIR
;
1064 DBG1(DBG_CFG
, "loading attribute certificates from '%s'", path
);
1066 dir
= opendir(ATTR_CERTIFICATE_DIR
);
1069 DBG1(DBG_CFG
, "error opening attribute certs directory '%s'", path
);
1073 while ((entry
= readdir(dir
)) != NULL
)
1075 char file
[PATH_BUF
];
1077 snprintf(file
, sizeof(file
), "%s/%s", path
, entry
->d_name
);
1079 if (stat(file
, &stb
) == -1)
1083 /* try to parse all regular files */
1084 if (stb
.st_mode
& S_IFREG
)
1086 x509ac_t
*cert
= x509ac_create_from_file(file
);
1090 err_t ugh
= cert
->is_valid(cert
, NULL
);
1094 DBG1(DBG_CFG
, "warning: attribute certificate %s", ugh
);
1096 add_attr_certificate(this, cert
);
1106 * Implements local_credential_store_t.load_ocsp_certificates
1108 static void load_ocsp_certificates(private_local_credential_store_t
*this)
1110 load_auth_certificates(this, AUTH_OCSP
, "ocsp", OCSP_CERTIFICATE_DIR
);
1114 * Add the latest crl to the issuing ca
1116 static void add_crl(private_local_credential_store_t
*this, crl_t
*crl
, const char *path
)
1118 iterator_t
*iterator
= this->ca_infos
->create_iterator(this->ca_infos
, TRUE
);
1122 while (iterator
->iterate(iterator
, (void**)&ca_info
))
1124 if (ca_info
->is_ca(ca_info
) && ca_info
->is_crl_issuer(ca_info
, crl
))
1126 char buffer
[BUF_LEN
];
1127 chunk_t uri
= { buffer
, 7 + strlen(path
) };
1129 ca_info
->add_crl(ca_info
, crl
);
1130 if (uri
.len
< BUF_LEN
)
1132 snprintf(buffer
, BUF_LEN
, "file://%s", path
);
1133 ca_info
->add_crluri(ca_info
, uri
);
1139 iterator
->destroy(iterator
);
1144 DBG2(DBG_CFG
, " no issuing ca found for this crl - discarded");
1149 * Implements local_credential_store_t.load_crls
1151 static void load_crls(private_local_credential_store_t
*this)
1153 struct dirent
* entry
;
1158 DBG1(DBG_CFG
, "loading crls from '%s'", CRL_DIR
);
1160 dir
= opendir(CRL_DIR
);
1163 DBG1(DBG_CFG
, "error opening crl directory '%s'", CRL_DIR
);
1167 while ((entry
= readdir(dir
)) != NULL
)
1169 char file
[PATH_BUF
];
1171 snprintf(file
, sizeof(file
), "%s/%s", CRL_DIR
, entry
->d_name
);
1173 if (stat(file
, &stb
) == -1)
1177 /* try to parse all regular files */
1178 if (stb
.st_mode
& S_IFREG
)
1180 crl
= crl_create_from_file(file
);
1183 DBG1(DBG_CFG
, " crl is %s", crl
->is_valid(crl
)?
"valid":"stale");
1184 add_crl(this, crl
, file
);
1192 * Convert a string of characters into a binary secret
1193 * A string between single or double quotes is treated as ASCII characters
1194 * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
1196 static err_t
extract_secret(chunk_t
*secret
, chunk_t
*line
)
1199 char delimiter
= ' ';
1200 bool quotes
= FALSE
;
1202 if (!eat_whitespace(line
))
1204 return "missing secret";
1207 if (*line
->ptr
== '\'' || *line
->ptr
== '"')
1210 delimiter
= *line
->ptr
;
1211 line
->ptr
++; line
->len
--;
1214 if (!extract_token(&raw_secret
, delimiter
, line
))
1216 if (delimiter
== ' ')
1222 return "missing second delimiter";
1227 { /* treat as an ASCII string */
1228 if (raw_secret
.len
> secret
->len
)
1229 return "secret larger than buffer";
1230 memcpy(secret
->ptr
, raw_secret
.ptr
, raw_secret
.len
);
1231 secret
->len
= raw_secret
.len
;
1234 { /* convert from HEX or Base64 to binary */
1236 err_t ugh
= ttodata(raw_secret
.ptr
, raw_secret
.len
, 0, secret
->ptr
, secret
->len
, &len
);
1240 if (len
> secret
->len
)
1241 return "secret larger than buffer";
1248 * Implements local_credential_store_t.load_secrets
1250 static void load_secrets(private_local_credential_store_t
*this)
1252 FILE *fd
= fopen(SECRETS_FILE
, "r");
1258 chunk_t chunk
, src
, line
;
1260 DBG1(DBG_CFG
, "loading secrets from \"%s\"", SECRETS_FILE
);
1262 fseek(fd
, 0, SEEK_END
);
1263 chunk
.len
= ftell(fd
);
1265 chunk
.ptr
= malloc(chunk
.len
);
1266 bytes
= fread(chunk
.ptr
, 1, chunk
.len
, fd
);
1271 while (fetchline(&src
, &line
))
1274 bool is_eap
= FALSE
;
1278 if (!eat_whitespace(&line
))
1282 if (!extract_token(&ids
, ':', &line
))
1284 DBG1(DBG_CFG
, "line %d: missing ':' separator", line_nr
);
1287 /* NULL terminate the ids string by replacing the : separator */
1288 *(ids
.ptr
+ ids
.len
) = '\0';
1290 if (!eat_whitespace(&line
) || !extract_token(&token
, ' ', &line
))
1292 DBG1(DBG_CFG
, "line %d: missing token", line_nr
);
1295 if (match("RSA", &token
))
1297 char path
[PATH_BUF
];
1301 chunk_t secret
= { buf
, BUF_LEN
};
1302 chunk_t
*passphrase
= NULL
;
1304 rsa_private_key_t
*key
;
1306 err_t ugh
= extract_value(&filename
, &line
);
1310 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
1313 if (filename
.len
== 0)
1315 DBG1(DBG_CFG
, "line %d: empty filename", line_nr
);
1318 if (*filename
.ptr
== '/')
1320 /* absolute path name */
1321 snprintf(path
, sizeof(path
), "%.*s", filename
.len
, filename
.ptr
);
1325 /* relative path name */
1326 snprintf(path
, sizeof(path
), "%s/%.*s", PRIVATE_KEY_DIR
,
1327 filename
.len
, filename
.ptr
);
1330 /* check for optional passphrase */
1331 if (eat_whitespace(&line
))
1333 ugh
= extract_secret(&secret
, &line
);
1336 DBG1(DBG_CFG
, "line %d: malformed passphrase: %s", line_nr
, ugh
);
1340 passphrase
= &secret
;
1342 key
= rsa_private_key_create_from_file(path
, passphrase
);
1345 this->private_keys
->insert_last(this->private_keys
, (void*)key
);
1348 else if ( match("PSK", &token
) ||
1349 ((match("EAP", &token
) || match("XAUTH", &token
)) && (is_eap
= TRUE
)))
1351 shared_key_t
*shared_key
;
1354 chunk_t secret
= { buf
, BUF_LEN
};
1356 err_t ugh
= extract_secret(&secret
, &line
);
1359 DBG1(DBG_CFG
, "line %d: malformed secret: %s", line_nr
, ugh
);
1363 DBG1(DBG_CFG
, " loading %s key for %s",
1364 is_eap ?
"EAP" : "shared",
1365 ids
.len
> 0 ?
(char*)ids
.ptr
: "%any");
1367 DBG4(DBG_CFG
, " secret:", secret
);
1369 shared_key
= shared_key_create(secret
);
1374 this->eap_keys
->insert_last(this->eap_keys
, (void*)shared_key
);
1378 this->shared_keys
->insert_last(this->shared_keys
, (void*)shared_key
);
1384 identification_t
*peer_id
;
1386 ugh
= extract_value(&id
, &ids
);
1389 DBG1(DBG_CFG
, "line %d: %s", line_nr
, ugh
);
1397 /* NULL terminate the ID string */
1398 *(id
.ptr
+ id
.len
) = '\0';
1400 peer_id
= identification_create_from_string(id
.ptr
);
1401 if (peer_id
== NULL
)
1403 DBG1(DBG_CFG
, "line %d: malformed ID: %s", line_nr
, id
.ptr
);
1407 if (peer_id
->get_type(peer_id
) == ID_ANY
)
1409 peer_id
->destroy(peer_id
);
1412 shared_key
->peers
->insert_last(shared_key
->peers
, (void*)peer_id
);
1415 else if (match("PIN", &token
))
1421 DBG1(DBG_CFG
, "line %d: token must be either "
1422 "RSA, PSK, EAP, or PIN", line_nr
, token
.len
);
1431 DBG1(DBG_CFG
, "could not open file '%s': %s", SECRETS_FILE
,
1437 * Implementation of local_credential_store_t.destroy.
1439 static void destroy(private_local_credential_store_t
*this)
1441 this->certs
->destroy_offset(this->certs
, offsetof(x509_t
, destroy
));
1442 this->auth_certs
->destroy_offset(this->auth_certs
, offsetof(x509_t
, destroy
));
1443 this->ca_infos
->destroy_offset(this->ca_infos
, offsetof(ca_info_t
, destroy
));
1444 this->private_keys
->destroy_offset(this->private_keys
, offsetof(rsa_private_key_t
, destroy
));
1445 this->shared_keys
->destroy_function(this->shared_keys
, (void*)shared_key_destroy
);
1446 this->eap_keys
->destroy_function(this->eap_keys
, (void*)shared_key_destroy
);
1451 * Described in header.
1453 local_credential_store_t
* local_credential_store_create(void)
1455 private_local_credential_store_t
*this = malloc_thing(private_local_credential_store_t
);
1457 this->public.credential_store
.get_shared_key
= (status_t (*) (credential_store_t
*,identification_t
*,identification_t
*,chunk_t
*))get_shared_key
;
1458 this->public.credential_store
.get_eap_key
= (status_t (*) (credential_store_t
*,identification_t
*,identification_t
*,chunk_t
*))get_eap_key
;
1459 this->public.credential_store
.get_rsa_public_key
= (rsa_public_key_t
*(*)(credential_store_t
*,identification_t
*))get_rsa_public_key
;
1460 this->public.credential_store
.get_rsa_private_key
= (rsa_private_key_t
* (*) (credential_store_t
*,rsa_public_key_t
*))get_rsa_private_key
;
1461 this->public.credential_store
.has_rsa_private_key
= (bool (*) (credential_store_t
*,rsa_public_key_t
*))has_rsa_private_key
;
1462 this->public.credential_store
.get_certificate
= (x509_t
* (*) (credential_store_t
*,identification_t
*))get_certificate
;
1463 this->public.credential_store
.get_auth_certificate
= (x509_t
* (*) (credential_store_t
*,u_int
,identification_t
*))get_auth_certificate
;
1464 this->public.credential_store
.get_ca_certificate_by_keyid
= (x509_t
* (*) (credential_store_t
*,chunk_t
))get_ca_certificate_by_keyid
;
1465 this->public.credential_store
.get_issuer
= (ca_info_t
* (*) (credential_store_t
*,x509_t
*))get_issuer
;
1466 this->public.credential_store
.is_trusted
= (bool (*) (credential_store_t
*,const char*,x509_t
*))is_trusted
;
1467 this->public.credential_store
.verify_signature
= (status_t (*) (credential_store_t
*,chunk_t
,chunk_t
,identification_t
*,ca_info_t
**))verify_signature
;
1468 this->public.credential_store
.verify
= (bool (*) (credential_store_t
*,x509_t
*,bool*))verify
;
1469 this->public.credential_store
.add_end_certificate
= (x509_t
* (*) (credential_store_t
*,x509_t
*))add_end_certificate
;
1470 this->public.credential_store
.add_auth_certificate
= (x509_t
* (*) (credential_store_t
*,x509_t
*,u_int
))add_auth_certificate
;
1471 this->public.credential_store
.add_ca_info
= (ca_info_t
* (*) (credential_store_t
*,ca_info_t
*))add_ca_info
;
1472 this->public.credential_store
.release_ca_info
= (status_t (*) (credential_store_t
*,const char*))release_ca_info
;
1473 this->public.credential_store
.create_cert_iterator
= (iterator_t
* (*) (credential_store_t
*))create_cert_iterator
;
1474 this->public.credential_store
.create_auth_cert_iterator
= (iterator_t
* (*) (credential_store_t
*))create_auth_cert_iterator
;
1475 this->public.credential_store
.create_cainfo_iterator
= (iterator_t
* (*) (credential_store_t
*))create_cainfo_iterator
;
1476 this->public.credential_store
.load_ca_certificates
= (void (*) (credential_store_t
*))load_ca_certificates
;
1477 this->public.credential_store
.load_aa_certificates
= (void (*) (credential_store_t
*))load_aa_certificates
;
1478 this->public.credential_store
.load_attr_certificates
= (void (*) (credential_store_t
*))load_attr_certificates
;
1479 this->public.credential_store
.load_ocsp_certificates
= (void (*) (credential_store_t
*))load_ocsp_certificates
;
1480 this->public.credential_store
.load_crls
= (void (*) (credential_store_t
*))load_crls
;
1481 this->public.credential_store
.load_secrets
= (void (*) (credential_store_t
*))load_secrets
;
1482 this->public.credential_store
.destroy
= (void (*) (credential_store_t
*))destroy
;
1484 /* private variables */
1485 this->shared_keys
= linked_list_create();
1486 this->eap_keys
= linked_list_create();
1487 this->private_keys
= linked_list_create();
1488 this->certs
= linked_list_create();
1489 this->auth_certs
= linked_list_create();
1490 this->ca_infos
= linked_list_create();
1492 return (&this->public);