diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/charon/config/credentials/credential_store.h | 17 | ||||
-rw-r--r-- | src/charon/config/credentials/local_credential_store.c | 264 |
2 files changed, 115 insertions, 166 deletions
diff --git a/src/charon/config/credentials/credential_store.h b/src/charon/config/credentials/credential_store.h index 54c04c4da..f20d9b902 100755 --- a/src/charon/config/credentials/credential_store.h +++ b/src/charon/config/credentials/credential_store.h @@ -126,14 +126,14 @@ struct credential_store_t { x509_t* (*get_ca_certificate_by_keyid) (credential_store_t *this, chunk_t keyid); /** - * @brief Returns the issuer certificate of a given certificate. + * @brief Returns the issuing ca of a given certificate. * * @param this calling object - * @param id certificate for which issuer cert is required - * @return certificate, or NULL if not found + * @param cert certificate for which issuer ca info is required + * @return ca info, or NULL if not found */ - x509_t* (*get_issuer_certificate) (credential_store_t *this, const x509_t* cert); - + ca_info_t* (*get_issuer) (credential_store_t *this, const x509_t* cert); + /** * @brief Verify an X.509 certificate up to trust anchor including revocation checks * @@ -206,12 +206,13 @@ struct credential_store_t { iterator_t* (*create_cainfo_iterator) (credential_store_t *this); /** - * @brief Create an iterator over all CRLs. + * @brief Check if there are any CRLs. * * @param this calling object - * @return iterator + * @param out output stream + * @param utc either utc or local time */ - iterator_t* (*create_crl_iterator) (credential_store_t *this); + void (*list_crls) (credential_store_t *this, FILE *out, bool utc); /** * @brief Loads trusted CA certificates from a default directory. diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c index 427fef290..53957b72a 100644 --- a/src/charon/config/credentials/local_credential_store.c +++ b/src/charon/config/credentials/local_credential_store.c @@ -28,8 +28,8 @@ #include <library.h> #include <utils/lexparser.h> #include <utils/linked_list.h> -#include <crypto/certinfo.h> #include <crypto/rsa/rsa_public_key.h> +#include <crypto/certinfo.h> #include <crypto/x509.h> #include <crypto/ca.h> #include <crypto/crl.h> @@ -88,6 +88,47 @@ static shared_key_t *shared_key_create(chunk_t secret) return (this); } +/* ---------------------------------------------------------------------- * + * the ca_info_t object as a central control element + ++------------------------------------------------------+ +| local_credential_store_t | ++------------------------------------------------------+ + | | ++-------------------------+ +-------------------------+ +| linked_list_t *ca_certs | | linked_list_t *ca_infos | ++-------------------------+ +-------------------------+ + | | + | +------------------------- + + | | ca_info_t | + | +--------------------------+ ++---------------+ | char *name | +| x509_t |<--| x509_t *cacert | +----------------------+ ++---------------+ | linked_list_t *certinfos |-->| certinfo_t | +| chunk_t keyid | | linked_list_t *ocspuris | +----------------------+ ++---------------+ | bool ocsp_fetch_pending | | chunk_t serialNumber | + | | crl_t *crl | | cert_status_t status | + | | linked_list_t *crluris | | time_t thisUpdate | + | | bool crl_fetch_pending | | time_t nextUpdate | + | | pthread_mutex_t mutex | | bool once | + | +--------------------------+ +----------------------+ + | | | + | +------------------------- + +----------------------+ + | | ca_info_t | | certinfo_t | + | +--------------------------+ +----------------------+ ++---------------+ | char *name | | chunk_t serialNumber | +| x509_t |<--| x509_t *cacert | | cert_status_t status | ++---------------+ | linked_list_t *certinfos | | time_t thisUpdate | +| chunk_t keyid | | linked_list_t *ocspuris | | time_t nextUpdate | ++---------------+ | bool ocsp_fetch_pending | | bool once | + | | crl_t *crl | +----------------------+ + | | linked_list_t *crluris | | + | | bool crl_fetch_pending | + | | pthread_mutex_t mutex; | + | +--------------------------+ + | | + + * ---------------------------------------------------------------------- */ typedef struct private_local_credential_store_t private_local_credential_store_t; @@ -127,21 +168,6 @@ struct private_local_credential_store_t { linked_list_t *ca_infos; /** - * mutex controlling the access to the ca_infos linked list - */ - pthread_mutex_t ca_infos_mutex; - - /** - * list of X.509 CRLs - */ - linked_list_t *crls; - - /** - * mutex controlling the access to the crls linked list - */ - pthread_mutex_t crls_mutex; - - /** * enforce strict crl policy */ bool strict; @@ -382,21 +408,20 @@ static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *thi } /** - * Implementation of credential_store_t.get_issuer_certificate. + * Implementation of credential_store_t.get_issuer. */ -static x509_t* get_issuer_certificate(private_local_credential_store_t *this, - const x509_t *cert) +static ca_info_t* get_issuer(private_local_credential_store_t *this, const x509_t *cert) { - x509_t *found = NULL; - x509_t *current_cert; + ca_info_t *found = NULL; + ca_info_t *ca_info; - iterator_t *iterator = this->ca_certs->create_iterator(this->ca_certs, TRUE); + iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE); - while (iterator->iterate(iterator, (void**)¤t_cert)) + while (iterator->iterate(iterator, (void**)&ca_info)) { - if (cert->is_issuer(cert, current_cert)) + if (ca_info->is_cert_issuer(ca_info, cert)) { - found = current_cert; + found = ca_info; break; } } @@ -406,76 +431,6 @@ static x509_t* get_issuer_certificate(private_local_credential_store_t *this, } /** - * Implementation of credential_store_t.get_crl. - */ -static crl_t* get_crl(private_local_credential_store_t *this, const x509_t *issuer) -{ - crl_t *crl = NULL, *current_crl; - - iterator_t *iterator = this->crls->create_iterator(this->crls, TRUE); - - while (iterator->iterate(iterator, (void**)¤t_crl)) - { - if (current_crl->is_issuer(current_crl, issuer)) - { - crl = current_crl; - break; - } - } - iterator->destroy(iterator); - - return crl; -} - -/** - * Verify the certificate status using CRLs - */ -static cert_status_t verify_by_crl(private_local_credential_store_t* this, const x509_t *cert, - const x509_t *issuer_cert, certinfo_t *certinfo) -{ - crl_t *crl; - bool valid_signature; - rsa_public_key_t *issuer_public_key; - - - pthread_mutex_lock(&(this->crls_mutex)); - - crl = get_crl(this, issuer_cert); - if (crl == NULL) - { - DBG1(DBG_CFG, "crl not found"); - goto err; - } - DBG2(DBG_CFG, "crl found"); - - issuer_public_key = issuer_cert->get_public_key(issuer_cert); - valid_signature = crl->verify(crl, issuer_public_key); - - if (!valid_signature) - { - DBG1(DBG_CFG, "crl signature is invalid"); - goto err; - } - DBG2(DBG_CFG, "crl signature is valid"); - - crl->get_status(crl, certinfo); - -err: - pthread_mutex_unlock(&(this->crls_mutex)); - return certinfo->get_status(certinfo); -} - -/** - * Verify the certificate status using OCSP - */ -static cert_status_t verify_by_ocsp(private_local_credential_store_t* this, - const x509_t *cert, certinfo_t *certinfo) -{ - /* TODO implement function */ - return CERT_UNDEFINED; -} - -/** * Find an exact copy of a certificate in a linked list */ static x509_t* find_certificate(linked_list_t *certs, x509_t *cert) @@ -518,6 +473,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++) { err_t ugh = NULL; + ca_info_t *issuer; x509_t *issuer_cert; rsa_public_key_t *issuer_public_key; bool valid_signature; @@ -533,14 +489,15 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f } DBG2(DBG_CFG, "certificate is valid"); - issuer_cert = get_issuer_certificate(this, cert); - if (issuer_cert == NULL) + issuer = get_issuer(this, cert); + if (issuer == NULL) { - DBG1(DBG_CFG, "issuer certificate not found"); + DBG1(DBG_CFG, "issuer info not found"); return FALSE; } - DBG2(DBG_CFG, "issuer certificate found"); + DBG2(DBG_CFG, "issuer info found"); + issuer_cert = issuer->get_certificate(issuer); issuer_public_key = issuer_cert->get_public_key(issuer_cert); valid_signature = cert->verify(cert, issuer_public_key); @@ -574,12 +531,12 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f certinfo->set_nextUpdate(certinfo, until); /* first check certificate revocation using ocsp */ - status = verify_by_ocsp(this, cert, certinfo); + status = issuer->verify_by_ocsp(issuer, cert, certinfo); /* if ocsp service is not available then fall back to crl */ if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && this->strict)) { - status = verify_by_crl(this, cert, issuer_cert, certinfo); + status = issuer->verify_by_crl(issuer, cert, certinfo); } nextUpdate = certinfo->get_nextUpdate(certinfo); @@ -683,7 +640,7 @@ static void add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_in ca_info_t *current_ca_info; ca_info_t *found_ca_info = NULL; - iterator_t *iterator = this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex)); + iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE); while (iterator->iterate(iterator, (void**)¤t_ca_info)) { @@ -693,6 +650,8 @@ static void add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_in break; } } + iterator->destroy(iterator); + if (found_ca_info) { current_ca_info->add_info(current_ca_info, ca_info); @@ -702,7 +661,6 @@ static void add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_in { this->ca_infos->insert_last(this->ca_infos, (void*)ca_info); } - iterator->destroy(iterator); } /** @@ -713,13 +671,12 @@ static status_t release_ca_info(private_local_credential_store_t *this, const ch status_t status = NOT_FOUND; ca_info_t *ca_info; - iterator_t *iterator = this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex)); + iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE); while (iterator->iterate(iterator, (void**)&ca_info)) { - if (ca_info->equals_name(ca_info, name)) + if (ca_info->equals_name_release_info(ca_info, name)) { - ca_info->release_info(ca_info); status = SUCCESS; break; } @@ -738,34 +695,32 @@ static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_ if (ret_cert == cert) { - x509_t *issuer_cert = get_issuer_certificate(this, cert); + ca_info_t *issuer = get_issuer(this, cert); - if (issuer_cert) + if (issuer) { - ca_info_t *ca_info = ca_info_create(NULL, issuer_cert); - + /* add any crl distribution points to the issuer ca info record */ { iterator_t *iterator = cert->create_crluri_iterator(cert); identification_t *uri; while (iterator->iterate(iterator, (void**)&uri)) { - ca_info->add_crluri(ca_info, uri->get_encoding(uri)); + issuer->add_crluri(issuer, uri->get_encoding(uri)); } iterator->destroy(iterator); } + /* add any ocsp access points to the issuer ca info record */ { iterator_t *iterator = cert->create_ocspuri_iterator(cert); identification_t *uri; while (iterator->iterate(iterator, (void**)&uri)) { - ca_info->add_ocspuri(ca_info, uri->get_encoding(uri)); + issuer->add_ocspuri(issuer, uri->get_encoding(uri)); } iterator->destroy(iterator); } - - add_ca_info(this, ca_info); } } return ret_cert; @@ -800,15 +755,34 @@ static iterator_t* create_cacert_iterator(private_local_credential_store_t *this */ static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this) { - return this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex)); + return this->ca_infos->create_iterator(this->ca_infos, TRUE); } /** - * Implements local_credential_store_t.create_crl_iterator + * Implements local_credential_store_t.list_crls */ -static iterator_t* create_crl_iterator(private_local_credential_store_t *this) +static void list_crls(private_local_credential_store_t *this, FILE *out, bool utc) { - return this->crls->create_iterator_locked(this->crls, &(this->crls_mutex)); + iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE); + ca_info_t *ca_info; + bool first = TRUE; + + while (iterator->iterate(iterator, (void **)&ca_info)) + { + if (ca_info->has_crl(ca_info)) + { + if (first) + { + fprintf(out, "\n"); + fprintf(out, "List of X.509 CRLs:\n"); + fprintf(out, "\n"); + first = FALSE; + } + ca_info->list_crl(ca_info, out, utc); + break; + } + } + iterator->destroy(iterator); } /** @@ -875,48 +849,30 @@ static void load_ca_certificates(private_local_credential_store_t *this) } /** - * Add the latest crl to a linked list + * Add the latest crl to the issuing ca */ -static crl_t* add_crl(linked_list_t *crls, crl_t *crl) +static void add_crl(private_local_credential_store_t *this, crl_t *crl) { + iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE); + ca_info_t *ca_info; bool found = FALSE; - crl_t *current_crl; - iterator_t *iterator = crls->create_iterator(crls, TRUE); - - while (iterator->iterate(iterator, (void**)¤t_crl)) + while (iterator->iterate(iterator, (void**)&ca_info)) { - if (crl->equals_issuer(crl, current_crl)) + if (ca_info->is_crl_issuer(ca_info, crl)) { found = TRUE; - if (crl->is_newer(crl, current_crl)) - { - crl_t *old_crl = NULL; - - iterator->replace(iterator, (void**)&old_crl, (void*)crl); - if (old_crl != NULL) - { - old_crl->destroy(old_crl); - } - DBG2(DBG_CFG, " thisUpdate is newer - existing crl replaced"); - } - else - { - crl->destroy(crl); - crl = current_crl; - DBG2(DBG_CFG, " thisUpdate is not newer - existing crl retained"); - } + ca_info->add_crl(ca_info, crl); break; } } iterator->destroy(iterator); - + if (!found) { - crls->insert_last(crls, (void*)crl); - DBG2(DBG_CFG, " crl added"); + crl->destroy(crl); + DBG2(DBG_CFG, " no issuing ca found for this crl - discarded"); } - return crl; } /** @@ -958,11 +914,9 @@ static void load_crls(private_local_credential_store_t *this) if (ugh != NULL) { - DBG1(DBG_CFG, "warning: crl %s", ugh); + DBG1(DBG_CFG, " warning: crl %s", ugh); } - pthread_mutex_lock(&(this->crls_mutex)); - crl = add_crl(this->crls, crl); - pthread_mutex_unlock(&(this->crls_mutex)); + add_crl(this, crl); } } } @@ -1217,7 +1171,6 @@ static void destroy(private_local_credential_store_t *this) this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy)); this->ca_certs->destroy_offset(this->ca_certs, offsetof(x509_t, destroy)); this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy)); - this->crls->destroy_offset(this->crls, offsetof(crl_t, destroy)); this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy)); this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy); free(this); @@ -1238,7 +1191,7 @@ local_credential_store_t * local_credential_store_create(bool strict) this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate; this->public.credential_store.get_ca_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_ca_certificate; this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid; - this->public.credential_store.get_issuer_certificate = (x509_t* (*) (credential_store_t*,const x509_t*))get_issuer_certificate; + this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,const x509_t*))get_issuer; this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify; this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate; this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate; @@ -1247,23 +1200,18 @@ local_credential_store_t * local_credential_store_create(bool strict) this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator; this->public.credential_store.create_cacert_iterator = (iterator_t* (*) (credential_store_t*))create_cacert_iterator; this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator; - this->public.credential_store.create_crl_iterator = (iterator_t* (*) (credential_store_t*))create_crl_iterator; + this->public.credential_store.list_crls = (void (*) (credential_store_t*,FILE*,bool))list_crls; this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates; this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls; this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets; this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy; - /* initialize mutexes */ - pthread_mutex_init(&(this->crls_mutex), NULL); - pthread_mutex_init(&(this->ca_infos_mutex), NULL); - /* private variables */ this->shared_keys = linked_list_create(); this->private_keys = linked_list_create(); this->certs = linked_list_create(); this->ca_certs = linked_list_create(); this->ca_infos = linked_list_create(); - this->crls = linked_list_create(); this->strict = strict; return (&this->public); |