diff options
author | Reto Buerki <reet@codelabs.ch> | 2012-12-18 15:35:40 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2013-03-19 15:23:50 +0100 |
commit | f47ea969f88ad0d8a827cf99bf73472a7f29f07c (patch) | |
tree | 26b91e6131d54cf656df53e26aec640794d97f96 /src | |
parent | ec169572a0092cbcd43c4f712f9b99d52f0326da (diff) | |
download | strongswan-f47ea969f88ad0d8a827cf99bf73472a7f29f07c.tar.bz2 strongswan-f47ea969f88ad0d8a827cf99bf73472a7f29f07c.tar.xz |
Implement TKM-specific credential set
The TKM credential set extends the in-memory credential set. It
provides a private key enumerator which is used to instantiate private
key proxy objects on-demand. This allows the usage of private keys with
arbitrary identifiers.
Diffstat (limited to 'src')
-rw-r--r-- | src/charon-tkm/src/charon-tkm.c | 15 | ||||
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_cred.c | 146 | ||||
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_cred.h | 46 | ||||
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_private_key.c | 16 | ||||
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_private_key.h | 4 |
5 files changed, 206 insertions, 21 deletions
diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c index eac9a27e2..7afde6e18 100644 --- a/src/charon-tkm/src/charon-tkm.c +++ b/src/charon-tkm/src/charon-tkm.c @@ -32,7 +32,7 @@ #include <utils/backtrace.h> #include <threading/thread.h> #include <sa/keymat.h> -#include <credentials/sets/mem_cred.h> +#include <credentials/credential_manager.h> #include "tkm.h" #include "tkm_nonceg.h" @@ -41,7 +41,7 @@ #include "tkm_listener.h" #include "tkm_kernel_ipsec.h" #include "tkm_public_key.h" -#include "tkm_private_key.h" +#include "tkm_cred.h" /** * TKM bus listener for IKE authorize events. @@ -240,9 +240,8 @@ int main(int argc, char *argv[]) dmn_name = "charon-tkm"; } - /* credential set and TKM private key */ - mem_cred_t *creds; - tkm_private_key_t *key; + /* TKM credential set */ + tkm_cred_t *creds; struct sigaction action; int status = SS_RC_INITIALIZATION_FAILED; @@ -347,10 +346,8 @@ int main(int argc, char *argv[]) listener = tkm_listener_create(); charon->bus->add_listener(charon->bus, &listener->listener); - /* register TKM private key */ - creds = mem_cred_create(); - key = tkm_private_key_init(); - creds->add_key(creds, (private_key_t *)key); + /* register TKM credential set */ + creds = tkm_cred_create(); lib->credmgr->add_set(lib->credmgr, (credential_set_t*)creds); /* add handler for SEGV and ILL, diff --git a/src/charon-tkm/src/tkm/tkm_cred.c b/src/charon-tkm/src/tkm/tkm_cred.c new file mode 100644 index 000000000..cf591d4e3 --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_cred.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012 Adrian-Ken Rueegsegger + * 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 <credentials/sets/mem_cred.h> +#include <collections/hashtable.h> +#include <threading/rwlock.h> +#include <utils/debug.h> + +#include "tkm_private_key.h" +#include "tkm_cred.h" + +typedef struct private_tkm_cred_t private_tkm_cred_t; + +/** + * Private data of a tkm_cred_t object. + */ +struct private_tkm_cred_t { + + /** + * Public tkm_cred_t interface. + */ + tkm_cred_t public; + + /** + * In-memory credential set. + */ + mem_cred_t *creds; + + /** + * Key-id hashtable. + */ + hashtable_t *known_keys; + + /** + * rwlock for hashtable. + */ + rwlock_t *lock; + +}; + +METHOD(credential_set_t, create_private_enumerator, enumerator_t*, + private_tkm_cred_t *this, key_type_t type, identification_t *id) +{ + if (!id) + { + return this->known_keys->create_enumerator(this->known_keys); + } + + identification_t *entry; + this->lock->write_lock(this->lock); + entry = this->known_keys->get(this->known_keys, id); + + if (!entry) + { + identification_t *clone = id->clone(id); + DBG1(DBG_CFG, "adding private key proxy for id '%Y'", clone); + tkm_private_key_t *key = tkm_private_key_init(id); + if (!key) + { + DBG1(DBG_CFG, "unable to create private key for id '%Y'", clone); + this->lock->unlock(this->lock); + return NULL; + } + this->creds->add_key(this->creds, (private_key_t *)key); + entry = this->known_keys->put(this->known_keys, clone, clone); + } + this->lock->unlock(this->lock); + + return this->creds->set.create_private_enumerator(&this->creds->set, + type, id); +} + +METHOD(tkm_cred_t, destroy, void, + private_tkm_cred_t *this) +{ + enumerator_t *enumerator; + identification_t *entry; + + enumerator = this->known_keys->create_enumerator(this->known_keys); + while (enumerator->enumerate(enumerator, NULL, &entry)) + { + entry->destroy(entry); + } + enumerator->destroy(enumerator); + this->known_keys->destroy(this->known_keys); + + this->creds->destroy(this->creds); + this->lock->destroy(this->lock); + free(this); +} + +/** + * Hashtable hash function. + */ +static u_int hash(identification_t *id) +{ + return chunk_hash(id->get_encoding(id)); +} + +/** + * Hashtable equals function. + */ +static bool equals(identification_t *a, identification_t *b) +{ + return a->equals(a, b); +} + +/** + * See header + */ +tkm_cred_t *tkm_cred_create() +{ + private_tkm_cred_t *this; + + INIT(this, + .public = { + .set = { + .create_shared_enumerator = (void*)return_null, + .create_private_enumerator = _create_private_enumerator, + .create_cert_enumerator = (void*)return_null, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)nop, + }, + .destroy = _destroy, + }, + .creds = mem_cred_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .known_keys = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 4), + ); + + return &this->public; +} diff --git a/src/charon-tkm/src/tkm/tkm_cred.h b/src/charon-tkm/src/tkm/tkm_cred.h new file mode 100644 index 000000000..362e228c8 --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_cred.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012 Adrian-Ken Rueegsegger + * 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. + */ + +#ifndef TKM_CRED_H_ +#define TKM_CRED_H_ + +typedef struct tkm_cred_t tkm_cred_t; + +#include <credentials/credential_set.h> + +/** + * TKM in-memory credential set. + */ +struct tkm_cred_t { + + /** + * Implements credential_set_t. + */ + credential_set_t set; + + /** + * Destroy a tkm_cred_t. + */ + void (*destroy)(tkm_cred_t *this); + +}; + +/** + * Create a tkm_cred instance. + */ +tkm_cred_t *tkm_cred_create(); + +#endif /** TKM_CRED_H_ */ diff --git a/src/charon-tkm/src/tkm/tkm_private_key.c b/src/charon-tkm/src/tkm/tkm_private_key.c index d728f8d7e..616941454 100644 --- a/src/charon-tkm/src/tkm/tkm_private_key.c +++ b/src/charon-tkm/src/tkm/tkm_private_key.c @@ -35,9 +35,9 @@ struct private_tkm_private_key_t { tkm_private_key_t public; /** - * Key fingerprint. + * Key ID. */ - chunk_t fingerprint; + identification_t *id; /** * Reference count. @@ -109,7 +109,7 @@ METHOD(private_key_t, get_encoding, bool, METHOD(private_key_t, get_fingerprint, bool, private_tkm_private_key_t *this, cred_encoding_type_t type, chunk_t *fp) { - *fp = this->fingerprint; + *fp = this->id->get_encoding(this->id); return TRUE; } @@ -125,7 +125,7 @@ METHOD(private_key_t, destroy, void, { if (ref_put(&this->ref)) { - chunk_free(&this->fingerprint); + this->id->destroy(this->id); free(this); } } @@ -133,7 +133,7 @@ METHOD(private_key_t, destroy, void, /** * See header. */ -tkm_private_key_t *tkm_private_key_init(void) +tkm_private_key_t *tkm_private_key_init(identification_t * const id) { private_tkm_private_key_t *this; @@ -155,12 +155,8 @@ tkm_private_key_t *tkm_private_key_init(void) }, }, .ref = 1, + .id = id->clone(id), ); - /* fingerprint of alice@strongswan.org keypair */ - const char fake_fp[] = "05da04208c02f428470acf6c772d066613da863c"; - this->fingerprint = chunk_create((u_char *)fake_fp, strlen(fake_fp)); - this->fingerprint = chunk_from_hex(this->fingerprint, NULL); - return &this->public; } diff --git a/src/charon-tkm/src/tkm/tkm_private_key.h b/src/charon-tkm/src/tkm/tkm_private_key.h index aa472a1a8..343752f28 100644 --- a/src/charon-tkm/src/tkm/tkm_private_key.h +++ b/src/charon-tkm/src/tkm/tkm_private_key.h @@ -33,8 +33,8 @@ struct tkm_private_key_t { }; /** - * Initialize TKM private key. + * Initialize TKM private key with given key ID. */ -tkm_private_key_t *tkm_private_key_init(void); +tkm_private_key_t *tkm_private_key_init(identification_t * const id); #endif /** TKM_PRIVATE_KEY_H_ */ |