diff options
-rwxr-xr-x | src/charon/config/credentials/credential_store.h | 21 | ||||
-rw-r--r-- | src/charon/config/credentials/local_credential_store.c | 159 | ||||
-rw-r--r-- | src/charon/config/credentials/local_credential_store.h | 23 |
3 files changed, 188 insertions, 15 deletions
diff --git a/src/charon/config/credentials/credential_store.h b/src/charon/config/credentials/credential_store.h index e7f606699..f364ebddf 100755 --- a/src/charon/config/credentials/credential_store.h +++ b/src/charon/config/credentials/credential_store.h @@ -92,15 +92,23 @@ struct credential_store_t { bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey); /** - * @brief If a certificate does not already exists in the credential store then add it. + * @brief If an end certificate does not already exists in the credential store then add it. * * @param this calling object * @param cert certificate to be added * @return pointer to the added or already existing certificate */ - x509_t* (*add_certificate) (credential_store_t *this, x509_t *cert); + x509_t* (*add_end_certificate) (credential_store_t *this, x509_t *cert); /** + * @brief If a ca certificate does not already exists in the credential store then add it. + * + * @param this calling object + * @param cert ca certificate to be added + * @return pointer to the added or already existing certificate + */ + x509_t* (*add_ca_certificate) (credential_store_t *this, x509_t *cert); + /** * @brief Lists all certificates kept in the local credential store. * * @param this calling object @@ -119,6 +127,15 @@ struct credential_store_t { void (*log_ca_certificates) (credential_store_t *this, logger_t *logger, bool utc); /** + * @brief Lists all CRLs kept in the local credential store. + * + * @param this calling object + * @param logger logger to be used + * @param utc log dates either in UTC or local time + */ + void (*log_crls) (credential_store_t *this, logger_t *logger, bool utc); + + /** * @brief Destroys a credential_store_t object. * * @param this calling object diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c index 660657beb..ab6eeca36 100644 --- a/src/charon/config/credentials/local_credential_store.c +++ b/src/charon/config/credentials/local_credential_store.c @@ -30,6 +30,7 @@ #include <utils/linked_list.h> #include <utils/logger_manager.h> #include <crypto/x509.h> +#include <crypto/crl.h> #define PATH_BUF 256 @@ -59,6 +60,17 @@ struct private_local_credential_store_t { * list of X.509 CA certificates with public keys */ linked_list_t *ca_certs; + + /** + * list of X.509 CRLs + */ + linked_list_t *crls; + + /** + * enforce strict crl policy + */ + bool strict; + /** * Assigned logger */ @@ -148,13 +160,13 @@ static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_publ } /** - * Implements credential_store_t.add_certificate + * Add a unique certificate to a linked list */ -static x509_t* add_certificate(private_local_credential_store_t *this, x509_t *cert) +static x509_t* add_certificate(linked_list_t *certs, x509_t *cert) { bool found = FALSE; - iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE); + iterator_t *iterator = certs->create_iterator(certs, TRUE); while (iterator->has_next(iterator)) { @@ -173,12 +185,28 @@ static x509_t* add_certificate(private_local_credential_store_t *this, x509_t *c if (!found) { - this->certs->insert_last(this->certs, (void*)cert); + certs->insert_last(certs, (void*)cert); } return cert; } /** + * Implements credential_store_t.add_end_certificate + */ +static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert) +{ + return add_certificate(this->certs, cert); +} + +/** + * Implements credential_store_t.add_ca_certificate + */ +static x509_t* add_ca_certificate(private_local_credential_store_t *this, x509_t *cert) +{ + return add_certificate(this->ca_certs, cert); +} + +/** * Implements credential_store_t.log_certificates */ static void log_certificates(private_local_credential_store_t *this, logger_t *logger, bool utc) @@ -227,6 +255,31 @@ static void log_ca_certificates(private_local_credential_store_t *this, logger_t } iterator->destroy(iterator); } + +/** + * Implements credential_store_t.log_crls + */ +static void log_crls(private_local_credential_store_t *this, logger_t *logger, bool utc) +{ + iterator_t *iterator = this->crls->create_iterator(this->crls, TRUE); + + if (iterator->get_count(iterator)) + { + logger->log(logger, CONTROL, ""); + logger->log(logger, CONTROL, "List of X.509 CRLs:"); + logger->log(logger, CONTROL, ""); + } + + while (iterator->has_next(iterator)) + { + crl_t *crl; + + iterator->current(iterator, (void**)&crl); + crl->log_crl(crl, logger, utc, this->strict); + } + iterator->destroy(iterator); +} + /** * Implements local_credential_store_t.load_ca_certificates */ @@ -270,7 +323,7 @@ static void load_ca_certificates(private_local_credential_store_t *this, const c } if (cert->is_ca(cert)) { - this->ca_certs->insert_last(this->ca_certs, (void*)cert); + cert = add_certificate(this->ca_certs, cert); } else { @@ -285,6 +338,85 @@ static void load_ca_certificates(private_local_credential_store_t *this, const c } /** + * Add the latest crl to a linked list + */ +static crl_t* add_crl(linked_list_t *crls, crl_t *crl) +{ + bool found = FALSE; + + iterator_t *iterator = crls->create_iterator(crls, TRUE); + + while (iterator->has_next(iterator)) + { + crl_t *current_crl; + + iterator->current(iterator, (void**)¤t_crl); + if (crl->equals_issuer(crl, current_crl)) + { + found = TRUE; + crl->destroy(crl); + crl = current_crl; + break; + } + } + iterator->destroy(iterator); + + if (!found) + { + crls->insert_last(crls, (void*)crl); + } + return crl; +} + +/** + * Implements local_credential_store_t.load_crls + */ +static void load_crls(private_local_credential_store_t *this, const char *path) +{ + struct dirent* entry; + struct stat stb; + DIR* dir; + crl_t *crl; + + this->logger->log(this->logger, CONTROL, "loading crls from '%s/'", path); + + dir = opendir(path); + if (dir == NULL) + { + this->logger->log(this->logger, ERROR, "error opening crl directory %s'", path); + return; + } + + while ((entry = readdir(dir)) != NULL) + { + char file[PATH_BUF]; + + snprintf(file, sizeof(file), "%s/%s", path, entry->d_name); + + if (stat(file, &stb) == -1) + { + continue; + } + /* try to parse all regular files */ + if (stb.st_mode & S_IFREG) + { + crl = crl_create_from_file(file); + if (crl) + { + err_t ugh = crl->is_valid(crl, NULL, this->strict); + + if (ugh != NULL) + { + this->logger->log(this->logger, ERROR, "warning: crl %s", ugh); + } + crl = add_crl(this->crls, crl); + } + } + } + closedir(dir); +} + +/** * Implements local_credential_store_t.load_private_keys */ static void load_private_keys(private_local_credential_store_t *this, const char *secretsfile, const char *defaultpath) @@ -394,6 +526,7 @@ error: static void destroy(private_local_credential_store_t *this) { x509_t *cert; + crl_t *crl; rsa_private_key_t *key; /* destroy cert list */ @@ -410,6 +543,13 @@ static void destroy(private_local_credential_store_t *this) } this->ca_certs->destroy(this->ca_certs); + /* destroy crl list */ + while (this->crls->remove_last(this->crls, (void**)&crl) == SUCCESS) + { + crl->destroy(crl); + } + this->crls->destroy(this->crls); + /* destroy private key list */ while (this->private_keys->remove_last(this->private_keys, (void**)&key) == SUCCESS) { @@ -423,7 +563,7 @@ static void destroy(private_local_credential_store_t *this) /** * Described in header. */ -local_credential_store_t * local_credential_store_create(void) +local_credential_store_t * local_credential_store_create(bool strict) { private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t); @@ -431,10 +571,13 @@ local_credential_store_t * local_credential_store_create(void) this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,rsa_public_key_t*))get_rsa_private_key; this->public.credential_store.has_rsa_private_key = (bool(*)(credential_store_t*,rsa_public_key_t*))has_rsa_private_key; this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key; - this->public.credential_store.add_certificate = (x509_t*(*)(credential_store_t*,x509_t*))add_certificate; + 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; this->public.credential_store.log_certificates = (void(*)(credential_store_t*,logger_t*,bool))log_certificates; this->public.credential_store.log_ca_certificates = (void(*)(credential_store_t*,logger_t*,bool))log_ca_certificates; + this->public.credential_store.log_crls = (void(*)(credential_store_t*,logger_t*,bool))log_crls; this->public.load_ca_certificates = (void(*)(local_credential_store_t*,const char*))load_ca_certificates; + this->public.load_crls = (void(*)(local_credential_store_t*,const char*))load_crls; this->public.load_private_keys = (void(*)(local_credential_store_t*,const char*, const char*))load_private_keys; this->public.credential_store.destroy = (void(*)(credential_store_t*))destroy; @@ -442,6 +585,8 @@ local_credential_store_t * local_credential_store_create(void) this->private_keys = linked_list_create(); this->certs = linked_list_create(); this->ca_certs = linked_list_create(); + this->crls = linked_list_create(); + this->strict = strict; this->logger = logger_manager->get_logger(logger_manager, CONFIG); return (&this->public); diff --git a/src/charon/config/credentials/local_credential_store.h b/src/charon/config/credentials/local_credential_store.h index 3d3494def..be2128a6f 100644 --- a/src/charon/config/credentials/local_credential_store.h +++ b/src/charon/config/credentials/local_credential_store.h @@ -38,7 +38,7 @@ typedef struct local_credential_store_t local_credential_store_t; * Shared secret are not handled yet, so get_shared_secret always returns NOT_FOUND. * * @b Constructors: - * - local_credential_store_create() + * - local_credential_store_create(bool strict) * * @ingroup config */ @@ -50,7 +50,7 @@ struct local_credential_store_t { credential_store_t credential_store; /** - * @brief Loads trusted certificates from a folder. + * @brief Loads trusted CA certificates from a default directory. * * Certificates in both DER and PEM format are accepted * @@ -60,6 +60,16 @@ struct local_credential_store_t { void (*load_ca_certificates) (local_credential_store_t *this, const char *path); /** + * @brief Loads CRLs from a default directory. + * + * Certificates in both DER and PEM format are accepted + * + * @param this calling object + * @param path directory to load crls from + */ + void (*load_crls) (local_credential_store_t *this, const char *path); + + /** * @brief Loads RSA private keys defined in ipsec.secrets * * Currently, all keys must be unencrypted in either DER or PEM format. @@ -68,18 +78,19 @@ struct local_credential_store_t { * * @param this calling object * @param secretsfile file where secrets are stored - * @param defaultpath default directory for private keys + * @param path default directory for private keys */ - void (*load_private_keys) (local_credential_store_t *this, const char *secretsfile, const char *defaultpath); + void (*load_private_keys) (local_credential_store_t *this, const char *secretsfile, const char *path); }; /** * @brief Creates a local_credential_store_t instance. * - * @return credential store instance. + * @param strict enforce a strict crl policy + * @return credential store instance. * * @ingroup config */ -local_credential_store_t *local_credential_store_create(void); +local_credential_store_t *local_credential_store_create(bool strict); #endif /* LOCAL_CREDENTIAL_H_ */ |