From 2feb16f5dd1a9a16bf7ec9b55aa279df75622948 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 5 Jul 2010 14:21:09 +0200 Subject: [PATCH] Added a certificate validation hook to the credential manager --- .../credentials/cert_validator.h | 49 +++++++++++++++++++ .../credentials/credential_manager.c | 39 +++++++++++++++ .../credentials/credential_manager.h | 15 ++++++ 3 files changed, 103 insertions(+) create mode 100644 src/libstrongswan/credentials/cert_validator.h diff --git a/src/libstrongswan/credentials/cert_validator.h b/src/libstrongswan/credentials/cert_validator.h new file mode 100644 index 000000000..1f192e1de --- /dev/null +++ b/src/libstrongswan/credentials/cert_validator.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup cert_validator cert_validator + * @{ @ingroup ccredentials + */ + +#ifndef CERT_VALIDATOR_H_ +#define CERT_VALIDATOR_H_ + +typedef struct cert_validator_t cert_validator_t; + +/** + * Certificate validator interface. + * + * A certificate validator checks constraints or revocation in a certificate + * or its issuing CA certificate. The interface allows plugins to do + * revocation checking or similar tasks. + */ +struct cert_validator_t { + + /** + * Validate a subject certificate in relation to its issuer. + * + * @param subject subject certificate to check + * @param issuer issuer of subject + * @param online wheter to do online revocation checking + * @param pathlen the current length of the path up to the root CA + * @param auth container for resulting authentication info + */ + bool (*validate)(cert_validator_t *this, certificate_t *subject, + certificate_t *issuer, bool online, int pathlen, + auth_cfg_t *auth); +}; + +#endif /** CERT_VALIDATOR_H_ @}*/ diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 466d86ff6..c5a681667 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -67,6 +67,11 @@ struct private_credential_manager_t { */ linked_list_t *cache_queue; + /** + * list of certificate validators, cert_validator_t + */ + linked_list_t *validators; + /** * read-write lock to sets list */ @@ -1000,6 +1005,8 @@ static bool check_certificate(private_credential_manager_t *this, bool online, int pathlen, auth_cfg_t *auth) { time_t not_before, not_after; + cert_validator_t *validator; + enumerator_t *enumerator; if (!subject->get_validity(subject, NULL, ¬_before, ¬_after)) { @@ -1075,6 +1082,18 @@ static bool check_certificate(private_credential_manager_t *this, } } } + + enumerator = this->validators->create_enumerator(this->validators); + while (enumerator->enumerate(enumerator, &validator)) + { + if (!validator->validate(validator, subject, issuer, + online, pathlen, auth)) + { + enumerator->destroy(enumerator); + return FALSE; + } + } + enumerator->destroy(enumerator); return TRUE; } @@ -1595,6 +1614,22 @@ METHOD(credential_manager_t, remove_set, void, this->lock->unlock(this->lock); } +METHOD(credential_manager_t, add_validator, void, + private_credential_manager_t *this, cert_validator_t *vdtr) +{ + this->lock->write_lock(this->lock); + this->sets->insert_last(this->validators, vdtr); + this->lock->unlock(this->lock); +} + +METHOD(credential_manager_t, remove_validator, void, + private_credential_manager_t *this, cert_validator_t *vdtr) +{ + this->lock->write_lock(this->lock); + this->validators->remove(this->validators, vdtr, NULL); + this->lock->unlock(this->lock); +} + METHOD(credential_manager_t, destroy, void, private_credential_manager_t *this) { @@ -1604,6 +1639,7 @@ METHOD(credential_manager_t, destroy, void, this->sets->destroy(this->sets); this->local_sets->destroy(this->local_sets); this->cache->destroy(this->cache); + this->validators->destroy(this->validators); this->lock->destroy(this->lock); this->queue_mutex->destroy(this->queue_mutex); free(this); @@ -1629,9 +1665,12 @@ credential_manager_t *credential_manager_create() .cache_cert = _cache_cert, .add_set = _add_set, .remove_set = _remove_set, + .add_validator = _add_validator, + .remove_validator = _remove_validator, .destroy = _destroy, }, .sets = linked_list_create(), + .validators = linked_list_create(), .cache = cert_cache_create(), .cache_queue = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), diff --git a/src/libstrongswan/credentials/credential_manager.h b/src/libstrongswan/credentials/credential_manager.h index aa0c48876..ed0c3fabf 100644 --- a/src/libstrongswan/credentials/credential_manager.h +++ b/src/libstrongswan/credentials/credential_manager.h @@ -30,6 +30,7 @@ typedef struct credential_manager_t credential_manager_t; #include #include #include +#include /** * Manages credentials using credential_sets. @@ -189,6 +190,20 @@ struct credential_manager_t { */ void (*remove_set)(credential_manager_t *this, credential_set_t *set); + /** + * Register a certificate validator to the manager. + * + * @param vdtr validator to register + */ + void (*add_validator)(credential_manager_t *this, cert_validator_t *vdtr); + + /** + * Remove a certificate validator from the manager. + * + * @param vdtr validator to unregister + */ + void (*remove_validator)(credential_manager_t *this, cert_validator_t *vdtr); + /** * Destroy a credential_manager instance. */