diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-08-09 08:09:54 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-08-09 08:09:54 +0000 |
commit | b8064f4099997a9e2179f3ad4ace605f5ccac3a1 (patch) | |
tree | 81778e976b476374c48b4fe83d084b986b890421 /src/libstrongswan/credentials/sets | |
parent | 1ac70afcc1f7d6d2738a34308810719b0976d29f (diff) | |
download | vyos-strongswan-b8064f4099997a9e2179f3ad4ace605f5ccac3a1.tar.gz vyos-strongswan-b8064f4099997a9e2179f3ad4ace605f5ccac3a1.zip |
[svn-upgrade] new version strongswan (4.4.1)
Diffstat (limited to 'src/libstrongswan/credentials/sets')
-rw-r--r-- | src/libstrongswan/credentials/sets/auth_cfg_wrapper.c | 223 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/auth_cfg_wrapper.h | 53 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/cert_cache.c | 389 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/cert_cache.h | 71 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/ocsp_response_wrapper.c | 146 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/ocsp_response_wrapper.h | 53 |
6 files changed, 935 insertions, 0 deletions
diff --git a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c new file mode 100644 index 000000000..5e8458616 --- /dev/null +++ b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2008-2009 Martin Willi + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * 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 <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include <library.h> +#include <debug.h> + +#include "auth_cfg_wrapper.h" + +typedef struct private_auth_cfg_wrapper_t private_auth_cfg_wrapper_t; + +/** + * private data of auth_cfg_wrapper + */ +struct private_auth_cfg_wrapper_t { + + /** + * public functions + */ + auth_cfg_wrapper_t public; + + /** + * wrapped auth info + */ + auth_cfg_t *auth; +}; + +/** + * enumerator for auth_cfg_wrapper_t.create_cert_enumerator() + */ +typedef struct { + /** implements enumerator_t */ + enumerator_t public; + /** inner enumerator from auth_cfg */ + enumerator_t *inner; + /** wrapped auth round */ + auth_cfg_t *auth; + /** enumerated cert type */ + certificate_type_t cert; + /** enumerated key type */ + key_type_t key; + /** enumerated id */ + identification_t *id; +} wrapper_enumerator_t; + +/** + * Tries to fetch a certificate that was supplied as "Hash and URL" + * (replaces rule type and value in place). + */ +static bool fetch_cert(wrapper_enumerator_t *enumerator, + auth_rule_t *rule, void **value) +{ + char *url = (char*)*value; + if (!url) + { + /* fetching the certificate previously failed */ + return FALSE; + } + + chunk_t data; + certificate_t *cert; + + DBG1(DBG_CFG, " fetching certificate from '%s' ...", url); + if (lib->fetcher->fetch(lib->fetcher, url, &data, FETCH_END) != SUCCESS) + { + DBG1(DBG_CFG, " fetching certificate failed"); + /* we set the item to NULL, so we can skip it */ + enumerator->auth->replace(enumerator->auth, enumerator->inner, + *rule, NULL); + return FALSE; + } + + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_BLOB_ASN1_DER, data, BUILD_END); + free(data.ptr); + + if (!cert) + { + DBG1(DBG_CFG, " parsing fetched certificate failed"); + /* we set the item to NULL, so we can skip it */ + enumerator->auth->replace(enumerator->auth, enumerator->inner, + *rule, NULL); + return FALSE; + } + + DBG1(DBG_CFG, " fetched certificate \"%Y\"", cert->get_subject(cert)); + lib->credmgr->cache_cert(lib->credmgr, cert); + + if (*rule == AUTH_HELPER_IM_HASH_URL) + { + *rule = AUTH_HELPER_IM_CERT; + } + else + { + *rule = AUTH_HELPER_SUBJECT_CERT; + } + *value = cert; + enumerator->auth->replace(enumerator->auth, enumerator->inner, + *rule, cert->get_ref(cert)); + return TRUE; +} + +/** + * enumerate function for wrapper_enumerator_t + */ +static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) +{ + auth_rule_t rule; + certificate_t *current; + public_key_t *public; + + while (this->inner->enumerate(this->inner, &rule, ¤t)) + { + if (rule == AUTH_HELPER_IM_HASH_URL || + rule == AUTH_HELPER_SUBJECT_HASH_URL) + { /* on-demand fetching of hash and url certificates */ + if (!fetch_cert(this, &rule, (void**)¤t)) + { + continue; + } + } + else if (rule != AUTH_HELPER_SUBJECT_CERT && + rule != AUTH_HELPER_IM_CERT) + { /* handle only HELPER certificates */ + continue; + } + if (this->cert != CERT_ANY && this->cert != current->get_type(current)) + { /* CERT type requested, but does not match */ + continue; + } + public = current->get_public_key(current); + if (this->key != KEY_ANY && !public) + { /* key type requested, but no public key */ + DESTROY_IF(public); + continue; + } + if (this->key != KEY_ANY && public && this->key != public->get_type(public)) + { /* key type requested, but public key has another type */ + DESTROY_IF(public); + continue; + } + DESTROY_IF(public); + if (this->id && !current->has_subject(current, this->id)) + { /* subject requested, but does not match */ + continue; + } + *cert = current; + return TRUE; + } + return FALSE; +} + +/** + * destroy function for wrapper_enumerator_t + */ +static void wrapper_enumerator_destroy(wrapper_enumerator_t *this) +{ + this->inner->destroy(this->inner); + free(this); +} + +/** + * implementation of auth_cfg_wrapper_t.set.create_cert_enumerator + */ +static enumerator_t *create_enumerator(private_auth_cfg_wrapper_t *this, + certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) +{ + wrapper_enumerator_t *enumerator; + + if (trusted) + { + return NULL; + } + enumerator = malloc_thing(wrapper_enumerator_t); + enumerator->auth = this->auth; + enumerator->cert = cert; + enumerator->key = key; + enumerator->id = id; + enumerator->inner = this->auth->create_enumerator(this->auth); + enumerator->public.enumerate = (void*)enumerate; + enumerator->public.destroy = (void*)wrapper_enumerator_destroy; + return &enumerator->public; +} + +/** + * Implementation of auth_cfg_wrapper_t.destroy + */ +static void destroy(private_auth_cfg_wrapper_t *this) +{ + free(this); +} + +/* + * see header file + */ +auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth) +{ + private_auth_cfg_wrapper_t *this = malloc_thing(private_auth_cfg_wrapper_t); + + this->public.set.create_private_enumerator = (void*)return_null; + this->public.set.create_cert_enumerator = (void*)create_enumerator; + this->public.set.create_shared_enumerator = (void*)return_null; + this->public.set.create_cdp_enumerator = (void*)return_null; + this->public.set.cache_cert = (void*)nop; + this->public.destroy = (void(*)(auth_cfg_wrapper_t*))destroy; + + this->auth = auth; + + return &this->public; +} diff --git a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.h b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.h new file mode 100644 index 000000000..3a4b197ac --- /dev/null +++ b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * 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 <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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 auth_cfg_wrapper auth_cfg_wrapper + * @{ @ingroup sets + */ + +#ifndef AUTH_CFG_WRAPPER_H_ +#define AUTH_CFG_WRAPPER_H_ + +#include <credentials/auth_cfg.h> +#include <credentials/credential_set.h> + +typedef struct auth_cfg_wrapper_t auth_cfg_wrapper_t; + +/** + * A wrapper around auth_cfg_t to handle it as a credential set. + */ +struct auth_cfg_wrapper_t { + + /** + * implements credential_set_t + */ + credential_set_t set; + + /** + * Destroy a auth_cfg_wrapper instance. + */ + void (*destroy)(auth_cfg_wrapper_t *this); +}; + +/** + * Create a auth_cfg_wrapper instance. + * + * @param auth the wrapped auth info + * @return wrapper around auth + */ +auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth); + +#endif /** AUTH_CFG_WRAPPER_H_ @}*/ diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c new file mode 100644 index 000000000..7161ac9ac --- /dev/null +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * 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 <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include "cert_cache.h" + +#include <time.h> +#include <sched.h> + +#include <library.h> +#include <threading/rwlock.h> +#include <utils/linked_list.h> + +/** cache size, a power of 2 for fast modulo */ +#define CACHE_SIZE 32 + +/** attempts to acquire a cache lock */ +#define REPLACE_TRIES 5 + +typedef struct private_cert_cache_t private_cert_cache_t; +typedef struct relation_t relation_t; + +/** + * A trusted relation between subject and issuer + */ +struct relation_t { + + /** + * subject of this relation + */ + certificate_t *subject; + + /** + * issuer of this relation + */ + certificate_t *issuer; + + /** + * Cache hits + */ + u_int hits; + + /** + * Lock for this relation + */ + rwlock_t *lock; +}; + +/** + * private data of cert_cache + */ +struct private_cert_cache_t { + + /** + * public functions + */ + cert_cache_t public; + + /** + * array of trusted subject-issuer relations + */ + relation_t relations[CACHE_SIZE]; +}; + +/** + * Cache relation in a free slot/replace an other + */ +static void cache(private_cert_cache_t *this, + certificate_t *subject, certificate_t *issuer) +{ + relation_t *rel; + int i, offset, try; + u_int total_hits = 0; + + /* check for a unused relation slot first */ + for (i = 0; i < CACHE_SIZE; i++) + { + rel = &this->relations[i]; + + if (!rel->subject && rel->lock->try_write_lock(rel->lock)) + { + /* double-check having lock */ + if (!rel->subject) + { + rel->subject = subject->get_ref(subject); + rel->issuer = issuer->get_ref(issuer); + return rel->lock->unlock(rel->lock); + } + rel->lock->unlock(rel->lock); + } + total_hits += rel->hits; + } + /* run several attempts to replace a random slot, never block. */ + for (try = 0; try < REPLACE_TRIES; try++) + { + /* replace a random relation */ + offset = random(); + for (i = 0; i < CACHE_SIZE; i++) + { + rel = &this->relations[(i + offset) % CACHE_SIZE]; + + if (rel->hits > total_hits / CACHE_SIZE) + { /* skip often used slots */ + continue; + } + if (rel->lock->try_write_lock(rel->lock)) + { + if (rel->subject) + { + rel->subject->destroy(rel->subject); + rel->issuer->destroy(rel->issuer); + } + rel->subject = subject->get_ref(subject); + rel->issuer = issuer->get_ref(issuer); + rel->hits = 0; + return rel->lock->unlock(rel->lock); + } + } + /* give other threads a chance to release locks */ + sched_yield(); + } +} + +/** + * Implementation of cert_cache_t.issued_by. + */ +static bool issued_by(private_cert_cache_t *this, + certificate_t *subject, certificate_t *issuer) +{ + relation_t *found = NULL, *current; + int i; + + for (i = 0; i < CACHE_SIZE; i++) + { + current = &this->relations[i]; + + current->lock->read_lock(current->lock); + if (current->subject) + { + /* check for equal issuer */ + if (issuer->equals(issuer, current->issuer)) + { + /* reuse issuer instance in cache() */ + issuer = current->issuer; + if (subject->equals(subject, current->subject)) + { + /* write hit counter is not locked, but not critical */ + current->hits++; + found = current; + } + } + } + current->lock->unlock(current->lock); + if (found) + { + return TRUE; + } + } + /* no cache hit, check and cache signature */ + if (subject->issued_by(subject, issuer)) + { + cache(this, subject, issuer); + return TRUE; + } + return FALSE; +} + +/** + * certificate enumerator implemenation + */ +typedef struct { + /** implements enumerator_t interface */ + enumerator_t public; + /** type of requested certificate */ + certificate_type_t cert; + /** type of requested key */ + key_type_t key; + /** ID to get a cert for */ + identification_t *id; + /** cache */ + relation_t *relations; + /** current position in array cache */ + int index; + /** currently locked relation */ + int locked; +} cert_enumerator_t; + +/** + * filter function for certs enumerator + */ +static bool cert_enumerate(cert_enumerator_t *this, certificate_t **out) +{ + public_key_t *public; + relation_t *rel; + + if (this->locked >= 0) + { + rel = &this->relations[this->locked]; + rel->lock->unlock(rel->lock); + this->locked = -1; + } + + while (++this->index < CACHE_SIZE) + { + rel = &this->relations[this->index]; + rel->lock->read_lock(rel->lock); + this->locked = this->index; + if (rel->subject) + { + /* CRL lookup is done using issuer/authkeyidentifier */ + if (this->key == KEY_ANY && this->id && + (this->cert == CERT_ANY || this->cert == CERT_X509_CRL) && + rel->subject->get_type(rel->subject) == CERT_X509_CRL && + rel->subject->has_issuer(rel->subject, this->id)) + { + *out = rel->subject; + return TRUE; + } + if ((this->cert == CERT_ANY || + rel->subject->get_type(rel->subject) == this->cert) && + (!this->id || rel->subject->has_subject(rel->subject, this->id))) + { + if (this->key == KEY_ANY) + { + *out = rel->subject; + return TRUE; + } + public = rel->subject->get_public_key(rel->subject); + if (public) + { + if (public->get_type(public) == this->key) + { + public->destroy(public); + *out = rel->subject; + return TRUE; + } + public->destroy(public); + } + } + } + this->locked = -1; + rel->lock->unlock(rel->lock); + } + return FALSE; +} + +/** + * clean up enumeration data + */ +static void cert_enumerator_destroy(cert_enumerator_t *this) +{ + relation_t *rel; + + if (this->locked >= 0) + { + rel = &this->relations[this->locked]; + rel->lock->unlock(rel->lock); + } + free(this); +} + +/** + * implementation of credential_set_t.create_cert_enumerator + */ +static enumerator_t *create_enumerator(private_cert_cache_t *this, + certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) +{ + cert_enumerator_t *enumerator; + + if (trusted) + { + return NULL; + } + enumerator = malloc_thing(cert_enumerator_t); + enumerator->public.enumerate = (void*)cert_enumerate; + enumerator->public.destroy = (void*)cert_enumerator_destroy; + enumerator->cert = cert; + enumerator->key = key; + enumerator->id = id; + enumerator->relations = this->relations; + enumerator->index = -1; + enumerator->locked = -1; + + return &enumerator->public; +} + +/** + * Implementation of cert_cache_t.flush. + */ +static void flush(private_cert_cache_t *this, certificate_type_t type) +{ + relation_t *rel; + int i; + + for (i = 0; i < CACHE_SIZE; i++) + { + rel = &this->relations[i]; + if (!rel->subject) + { + continue; + } + /* check with cheap read lock first */ + if (type != CERT_ANY) + { + rel->lock->read_lock(rel->lock); + if (!rel->subject || type != rel->subject->get_type(rel->subject)) + { + rel->lock->unlock(rel->lock); + continue; + } + rel->lock->unlock(rel->lock); + } + /* double check in write lock */ + rel->lock->write_lock(rel->lock); + if (rel->subject) + { + if (type == CERT_ANY || type == rel->subject->get_type(rel->subject)) + { + rel->subject->destroy(rel->subject); + rel->issuer->destroy(rel->issuer); + rel->subject = NULL; + rel->issuer = NULL; + rel->hits = 0; + } + } + rel->lock->unlock(rel->lock); + } +} + +/** + * Implementation of cert_cache_t.destroy + */ +static void destroy(private_cert_cache_t *this) +{ + relation_t *rel; + int i; + + for (i = 0; i < CACHE_SIZE; i++) + { + rel = &this->relations[i]; + if (rel->subject) + { + rel->subject->destroy(rel->subject); + rel->issuer->destroy(rel->issuer); + } + rel->lock->destroy(rel->lock); + } + free(this); +} + +/* + * see header file + */ +cert_cache_t *cert_cache_create() +{ + private_cert_cache_t *this; + int i; + + this = malloc_thing(private_cert_cache_t); + this->public.set.create_private_enumerator = (void*)return_null; + this->public.set.create_cert_enumerator = (void*)create_enumerator; + this->public.set.create_shared_enumerator = (void*)return_null; + this->public.set.create_cdp_enumerator = (void*)return_null; + this->public.set.cache_cert = (void*)nop; + this->public.issued_by = (bool(*)(cert_cache_t*, certificate_t *subject, certificate_t *issuer))issued_by; + this->public.flush = (void(*)(cert_cache_t*, certificate_type_t type))flush; + this->public.destroy = (void(*)(cert_cache_t*))destroy; + + for (i = 0; i < CACHE_SIZE; i++) + { + this->relations[i].subject = NULL; + this->relations[i].issuer = NULL; + this->relations[i].hits = 0; + this->relations[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT); + } + return &this->public; +} diff --git a/src/libstrongswan/credentials/sets/cert_cache.h b/src/libstrongswan/credentials/sets/cert_cache.h new file mode 100644 index 000000000..d2721866e --- /dev/null +++ b/src/libstrongswan/credentials/sets/cert_cache.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * 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 <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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_cache cert_cache + * @{ @ingroup sets + */ + +#ifndef CERT_CACHE_H_ +#define CERT_CACHE_H_ + +#include <credentials/credential_set.h> + +typedef struct cert_cache_t cert_cache_t; + +/** + * Certificate signature verification and certificate cache. + * + * This cache serves all certificates seen in its issued_by method + * and serves them as untrusted through the credential set interface. Further, + * it caches valid subject-issuer relationships to speed up the issued_by + * method. + */ +struct cert_cache_t { + + /** + * Implements credential_set_t. + */ + credential_set_t set; + + /** + * Caching wrapper around certificate_t.issued_by. + * + * @param subject certificate to verify + * @param issuer issuing certificate to verify subject + * @return TRUE if subject issued by issuer + */ + bool (*issued_by)(cert_cache_t *this, + certificate_t *subject, certificate_t *issuer); + + /** + * Flush the certificate cache. + * + * @param type type of certificate to flush, or CERT_ANY + */ + void (*flush)(cert_cache_t *this, certificate_type_t type); + + /** + * Destroy a cert_cache instance. + */ + void (*destroy)(cert_cache_t *this); +}; + +/** + * Create a cert_cache instance. + */ +cert_cache_t *cert_cache_create(); + +#endif /** CERT_CACHE_H_ @}*/ diff --git a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c new file mode 100644 index 000000000..4786495da --- /dev/null +++ b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * 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 <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include "ocsp_response_wrapper.h" + +typedef struct private_ocsp_response_wrapper_t private_ocsp_response_wrapper_t; + +/** + * private data of ocsp_response_wrapper + */ +struct private_ocsp_response_wrapper_t { + + /** + * public functions + */ + ocsp_response_wrapper_t public; + + /** + * wrapped OCSP response + */ + ocsp_response_t *response; +}; + +/** + * enumerator for ocsp_response_wrapper_t.create_cert_enumerator() + */ +typedef struct { + /** implements enumerator_t */ + enumerator_t public; + /** enumerator over ocsp response */ + enumerator_t *inner; + /** type of cert */ + certificate_type_t cert; + /** type of key */ + key_type_t key; + /** filtering identity */ + identification_t *id; +} wrapper_enumerator_t; + +/** + * enumerate function wrapper_enumerator_t + */ +static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) +{ + certificate_t *current; + public_key_t *public; + + while (this->inner->enumerate(this->inner, ¤t)) + { + if (this->cert != CERT_ANY && this->cert != current->get_type(current)) + { /* CERT type requested, but does not match */ + continue; + } + public = current->get_public_key(current); + if (this->key != KEY_ANY && !public) + { /* key type requested, but no public key */ + DESTROY_IF(public); + continue; + } + if (this->key != KEY_ANY && public && this->key != public->get_type(public)) + { /* key type requested, but public key has another type */ + DESTROY_IF(public); + continue; + } + DESTROY_IF(public); + if (this->id && !current->has_subject(current, this->id)) + { /* subject requested, but does not match */ + continue; + } + *cert = current; + return TRUE; + } + return FALSE; +} + +/** + * destroy function for wrapper_enumerator_t + */ +static void enumerator_destroy(wrapper_enumerator_t *this) +{ + this->inner->destroy(this->inner); + free(this); +} + +/** + * implementation of ocsp_response_wrapper_t.set.create_cert_enumerator + */ +static enumerator_t *create_enumerator(private_ocsp_response_wrapper_t *this, + certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) +{ + wrapper_enumerator_t *enumerator; + + if (trusted) + { + return NULL; + } + + enumerator = malloc_thing(wrapper_enumerator_t); + enumerator->cert = cert; + enumerator->key = key; + enumerator->id = id; + enumerator->inner = this->response->create_cert_enumerator(this->response); + enumerator->public.enumerate = (void*)enumerate; + enumerator->public.destroy = (void*)enumerator_destroy; + return &enumerator->public; +} + +/** + * Implementation of ocsp_response_wrapper_t.destroy + */ +static void destroy(private_ocsp_response_wrapper_t *this) +{ + free(this); +} + +/* + * see header file + */ +ocsp_response_wrapper_t *ocsp_response_wrapper_create(ocsp_response_t *response) +{ + private_ocsp_response_wrapper_t *this = malloc_thing(private_ocsp_response_wrapper_t); + + this->public.set.create_private_enumerator = (void*)return_null; + this->public.set.create_cert_enumerator = (void*)create_enumerator; + this->public.set.create_shared_enumerator = (void*)return_null; + this->public.set.create_cdp_enumerator = (void*)return_null; + this->public.set.cache_cert = (void*)nop; + this->public.destroy = (void(*)(ocsp_response_wrapper_t*))destroy; + + this->response = response; + + return &this->public; +} diff --git a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.h b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.h new file mode 100644 index 000000000..dc4b451df --- /dev/null +++ b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * 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 <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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 ocsp_response_wrapper ocsp_response_wrapper + * @{ @ingroup sets + */ + +#ifndef OCSP_RESPONSE_WRAPPER_H_ +#define OCSP_RESPONSE_WRAPPER_H_ + +#include <credentials/credential_set.h> +#include <credentials/certificates/ocsp_response.h> + +typedef struct ocsp_response_wrapper_t ocsp_response_wrapper_t; + +/** + * A wrapper around ocsp_response_t to handle it like a credential set. + */ +struct ocsp_response_wrapper_t { + + /** + * implements credential_set_t + */ + credential_set_t set; + + /** + * Destroy a ocsp_response_wrapper instance. + */ + void (*destroy)(ocsp_response_wrapper_t *this); +}; + +/** + * Create a ocsp_response_wrapper instance. + * + * @param response the wrapped OCSP response + * @return wrapper around response + */ +ocsp_response_wrapper_t *ocsp_response_wrapper_create(ocsp_response_t *response); + +#endif /** OCSP_RESPONSE_WRAPPER_H_ @}*/ |