149 lines
3.4 KiB
C
149 lines
3.4 KiB
C
/*
|
|
* Copyright (C) 2012 Reto Buerki
|
|
* Copyright (C) 2012 Adrian-Ken Rueegsegger
|
|
* HSR 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)
|
|
{
|
|
identification_t *entry;
|
|
|
|
if (!id)
|
|
{
|
|
return this->known_keys->create_enumerator(this->known_keys);
|
|
}
|
|
|
|
this->lock->write_lock(this->lock);
|
|
entry = this->known_keys->get(this->known_keys, id);
|
|
|
|
if (!entry)
|
|
{
|
|
identification_t *clone = id->clone(id);
|
|
tkm_private_key_t *key = tkm_private_key_init(id);
|
|
|
|
DBG1(DBG_CFG, "adding private key proxy for id '%Y'", clone);
|
|
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;
|
|
}
|