diff options
Diffstat (limited to 'src')
17 files changed, 1209 insertions, 375 deletions
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index 4a50ec006..9302b63c3 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -200,6 +200,16 @@ if USE_EAP_SIM_FILE PLUGINS += eap-sim-file endif +if USE_EAP_SIMAKA_PSEUDONYM + SUBDIRS += plugins/eap_simaka_pseudonym + PLUGINS += eap-simaka-pseudonym +endif + +if USE_EAP_SIMAKA_REAUTH + SUBDIRS += plugins/eap_simaka_reauth + PLUGINS += eap-simaka-reauth +endif + if USE_EAP_MD5 SUBDIRS += plugins/eap_md5 PLUGINS += eap-md5 diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_card.c b/src/charon/plugins/eap_sim_file/eap_sim_file_card.c index 077163a82..f6ff20710 100644 --- a/src/charon/plugins/eap_sim_file/eap_sim_file_card.c +++ b/src/charon/plugins/eap_sim_file/eap_sim_file_card.c @@ -16,7 +16,6 @@ #include "eap_sim_file_card.h" #include <daemon.h> -#include <utils/hashtable.h> typedef struct private_eap_sim_file_card_t private_eap_sim_file_card_t; @@ -34,50 +33,8 @@ struct private_eap_sim_file_card_t { * source of triplets */ eap_sim_file_triplets_t *triplets; - - /** - * Permanent -> pseudonym mappings - */ - hashtable_t *pseudonym; - - /** - * Permanent -> reauth_data_t mappings - */ - hashtable_t *reauth; - - /** - * Reverse pseudonym -> permanent mappings - */ - hashtable_t *permanent; }; -typedef struct { - /** currently used reauthentication identity */ - identification_t *id; - /** associated permanent identity */ - identification_t *permanent; - /** counter value */ - u_int16_t counter; - /** master key */ - char mk[HASH_SIZE_SHA1]; -} reauth_data_t; - -/** - * hashtable hash function - */ -static u_int hash(identification_t *key) -{ - return chunk_hash(key->get_encoding(key)); -} - -/** - * hashtable equals function - */ -static bool equals(identification_t *key1, identification_t *key2) -{ - return key1->equals(key1, key2); -} - /** * Implementation of sim_card_t.get_triplet */ @@ -112,90 +69,6 @@ static bool get_triplet(private_eap_sim_file_card_t *this, } /** - * Implementation of sim_card_t.get_pseudonym - */ -static identification_t *get_pseudonym(private_eap_sim_file_card_t *this, - identification_t *id) -{ - identification_t *pseudonym; - - pseudonym = this->pseudonym->get(this->pseudonym, id); - if (pseudonym) - { - return pseudonym->clone(pseudonym); - } - return NULL; -} - -/** - * Implementation of sim_card_t.set_pseudonym - */ -static void set_pseudonym(private_eap_sim_file_card_t *this, - identification_t *id, identification_t *pseudonym) -{ - identification_t *permanent; - - /* create new entries */ - id = id->clone(id); - pseudonym = pseudonym->clone(pseudonym); - permanent = this->permanent->put(this->permanent, pseudonym, id); - pseudonym = this->pseudonym->put(this->pseudonym, id, pseudonym); - - /* delete old entries */ - DESTROY_IF(permanent); - DESTROY_IF(pseudonym); -} - -/** - * Implementation of sim_card_t.get_reauth - */ -static identification_t *get_reauth(private_eap_sim_file_card_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) -{ - reauth_data_t *data; - identification_t *reauth; - - /* look up reauthentication data */ - data = this->reauth->remove(this->reauth, id); - if (!data) - { - return NULL; - } - *counter = ++data->counter; - memcpy(mk, data->mk, HASH_SIZE_SHA1); - reauth = data->id; - data->permanent->destroy(data->permanent); - free(data); - return reauth; -} - -/** - * Implementation of sim_card_t.set_reauth - */ -static void set_reauth(private_eap_sim_file_card_t *this, - identification_t *id, identification_t* next, - char mk[HASH_SIZE_SHA1], u_int16_t counter) -{ - reauth_data_t *data; - - data = this->reauth->get(this->reauth, id); - if (data) - { - data->id->destroy(data->id); - } - else - { - data = malloc_thing(reauth_data_t); - data->permanent = id->clone(id); - this->reauth->put(this->reauth, data->permanent, data); - } - data->counter = counter; - data->id = next->clone(next); - memcpy(data->mk, mk, HASH_SIZE_SHA1); -} - -/** * Implementation of sim_card_t.get_quintuplet */ static bool get_quintuplet() @@ -208,37 +81,6 @@ static bool get_quintuplet() */ static void destroy(private_eap_sim_file_card_t *this) { - enumerator_t *enumerator; - identification_t *id; - reauth_data_t *data; - void *key; - - enumerator = this->pseudonym->create_enumerator(this->pseudonym); - while (enumerator->enumerate(enumerator, &key, &id)) - { - id->destroy(id); - } - enumerator->destroy(enumerator); - - enumerator = this->permanent->create_enumerator(this->permanent); - while (enumerator->enumerate(enumerator, &key, &id)) - { - id->destroy(id); - } - enumerator->destroy(enumerator); - - enumerator = this->reauth->create_enumerator(this->reauth); - while (enumerator->enumerate(enumerator, &key, &data)) - { - data->id->destroy(data->id); - data->permanent->destroy(data->permanent); - free(data); - } - enumerator->destroy(enumerator); - - this->pseudonym->destroy(this->pseudonym); - this->permanent->destroy(this->permanent); - this->reauth->destroy(this->reauth); free(this); } @@ -252,16 +94,13 @@ eap_sim_file_card_t *eap_sim_file_card_create(eap_sim_file_triplets_t *triplets) this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))get_triplet; this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_LEN]))get_quintuplet; this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; - this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))get_pseudonym; - this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))set_pseudonym; - this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))get_reauth; - this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))set_reauth; + this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))return_null; + this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop; + this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null; + this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop; this->public.destroy = (void(*)(eap_sim_file_card_t*))destroy; this->triplets = triplets; - this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0); - this->permanent = hashtable_create((void*)hash, (void*)equals, 0); - this->reauth = hashtable_create((void*)hash, (void*)equals, 0); return &this->public; } diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c index aa2eabc43..9e791e94c 100644 --- a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c +++ b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c @@ -16,7 +16,6 @@ #include "eap_sim_file_provider.h" #include <daemon.h> -#include <utils/hashtable.h> typedef struct private_eap_sim_file_provider_t private_eap_sim_file_provider_t; @@ -34,53 +33,8 @@ struct private_eap_sim_file_provider_t { * source of triplets */ eap_sim_file_triplets_t *triplets; - - /** - * Permanent -> pseudonym mappings - */ - hashtable_t *pseudonym; - - /** - * Permanent -> reauth_data_t mappings - */ - hashtable_t *reauth; - - /** - * Reverse pseudonym/reauth -> permanent mappings - */ - hashtable_t *permanent; - - /** - * RNG for pseudonyms/reauth identities - */ - rng_t *rng; }; -typedef struct { - /** currently used reauthentication identity */ - identification_t *id; - /** counter value */ - u_int16_t counter; - /** master key */ - char mk[HASH_SIZE_SHA1]; -} reauth_data_t; - -/** - * hashtable hash function - */ -static u_int hash(identification_t *key) -{ - return chunk_hash(key->get_encoding(key)); -} - -/** - * hashtable equals function - */ -static bool equals(identification_t *key1, identification_t *key2) -{ - return key1->equals(key1, key2); -} - /** * Implementation of sim_provider_t.get_triplet */ @@ -108,161 +62,10 @@ static bool get_triplet(private_eap_sim_file_provider_t *this, } /** - * Implementation of sim_provider_t.is_pseudonym - */ -static identification_t* is_pseudonym(private_eap_sim_file_provider_t *this, - identification_t *id) -{ - identification_t *permanent; - - permanent = this->permanent->get(this->permanent, id); - if (permanent) - { - return permanent->clone(permanent); - } - return NULL; -} - -/** - * Generate a random identity - */ -static identification_t *gen_identity(private_eap_sim_file_provider_t *this) -{ - char buf[8], hex[sizeof(buf) * 2 + 1]; - - this->rng->get_bytes(this->rng, sizeof(buf), buf); - chunk_to_hex(chunk_create(buf, sizeof(buf)), hex, FALSE); - - return identification_create_from_string(hex); -} - -/** - * Implementation of sim_provider_t.get_pseudonym - */ -static identification_t* gen_pseudonym(private_eap_sim_file_provider_t *this, - identification_t *id) -{ - identification_t *pseudonym, *permanent; - - /* remove old entry */ - pseudonym = this->pseudonym->remove(this->pseudonym, id); - if (pseudonym) - { - permanent = this->permanent->remove(this->permanent, pseudonym); - if (permanent) - { - permanent->destroy(permanent); - } - pseudonym->destroy(pseudonym); - } - - pseudonym = gen_identity(this); - - /* create new entries */ - id = id->clone(id); - this->pseudonym->put(this->pseudonym, id, pseudonym); - this->permanent->put(this->permanent, pseudonym, id); - - return pseudonym->clone(pseudonym); -} - -/** - * Implementation of sim_provider_t.is_reauth - */ -static identification_t *is_reauth(private_eap_sim_file_provider_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) -{ - identification_t *permanent; - reauth_data_t *data; - - /* look up permanent identity */ - permanent = this->permanent->get(this->permanent, id); - if (!permanent) - { - return NULL; - } - /* look up reauthentication data */ - data = this->reauth->get(this->reauth, permanent); - if (!data) - { - return NULL; - } - *counter = ++data->counter; - memcpy(mk, data->mk, HASH_SIZE_SHA1); - return permanent->clone(permanent); -} - -/** - * Implementation of sim_provider_t.gen_reauth - */ -static identification_t *gen_reauth(private_eap_sim_file_provider_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1]) -{ - reauth_data_t *data; - identification_t *permanent; - - data = this->reauth->get(this->reauth, id); - id = id->clone(id); - if (data) - { /* update existing entry */ - permanent = this->permanent->remove(this->permanent, data->id); - if (permanent) - { - permanent->destroy(permanent); - } - data->id->destroy(data->id); - } - else - { /* generate new entry */ - data = malloc_thing(reauth_data_t); - data->counter = 0; - this->reauth->put(this->reauth, id, data); - } - memcpy(data->mk, mk, HASH_SIZE_SHA1); - data->id = gen_identity(this); - - this->permanent->put(this->permanent, data->id, id); - - return data->id->clone(data->id); -} - -/** * Implementation of eap_sim_file_provider_t.destroy. */ static void destroy(private_eap_sim_file_provider_t *this) { - enumerator_t *enumerator; - identification_t *id; - reauth_data_t *data; - void *key; - - enumerator = this->pseudonym->create_enumerator(this->pseudonym); - while (enumerator->enumerate(enumerator, &key, &id)) - { - id->destroy(id); - } - enumerator->destroy(enumerator); - - enumerator = this->permanent->create_enumerator(this->permanent); - while (enumerator->enumerate(enumerator, &key, &id)) - { - id->destroy(id); - } - enumerator->destroy(enumerator); - - enumerator = this->reauth->create_enumerator(this->reauth); - while (enumerator->enumerate(enumerator, &key, &data)) - { - data->id->destroy(data->id); - free(data); - } - enumerator->destroy(enumerator); - - this->pseudonym->destroy(this->pseudonym); - this->permanent->destroy(this->permanent); - this->reauth->destroy(this->reauth); - this->rng->destroy(this->rng); free(this); } @@ -277,22 +80,13 @@ eap_sim_file_provider_t *eap_sim_file_provider_create( this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))get_triplet; this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; - this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))is_pseudonym; - this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))gen_pseudonym; - this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))is_reauth; - this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))gen_reauth; + this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; + this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; + this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null; + this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null; this->public.destroy = (void(*)(eap_sim_file_provider_t*))destroy; this->triplets = triplets; - this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); - if (!this->rng) - { - free(this); - return NULL; - } - this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0); - this->permanent = hashtable_create((void*)hash, (void*)equals, 0); - this->reauth = hashtable_create((void*)hash, (void*)equals, 0); return &this->public; } diff --git a/src/charon/plugins/eap_simaka_pseudonym/Makefile.am b/src/charon/plugins/eap_simaka_pseudonym/Makefile.am new file mode 100644 index 000000000..fe87d6d62 --- /dev/null +++ b/src/charon/plugins/eap_simaka_pseudonym/Makefile.am @@ -0,0 +1,13 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la + +libstrongswan_eap_simaka_pseudonym_la_SOURCES = \ + eap_simaka_pseudonym_plugin.h eap_simaka_pseudonym_plugin.c \ + eap_simaka_pseudonym_card.h eap_simaka_pseudonym_card.c \ + eap_simaka_pseudonym_provider.h eap_simaka_pseudonym_provider.c +libstrongswan_eap_simaka_pseudonym_la_LDFLAGS = -module -avoid-version + diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c new file mode 100644 index 000000000..babe12835 --- /dev/null +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 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. + */ + +#include "eap_simaka_pseudonym_card.h" + +#include <daemon.h> +#include <utils/hashtable.h> + +typedef struct private_eap_simaka_pseudonym_card_t private_eap_simaka_pseudonym_card_t; + +/** + * Private data of an eap_simaka_pseudonym_card_t object. + */ +struct private_eap_simaka_pseudonym_card_t { + + /** + * Public eap_simaka_pseudonym_card_t interface. + */ + eap_simaka_pseudonym_card_t public; + + /** + * Permanent -> pseudonym mappings + */ + hashtable_t *pseudonym; + + /** + * Reverse pseudonym -> permanent mappings + */ + hashtable_t *permanent; +}; + +/** + * hashtable hash function + */ +static u_int hash(identification_t *key) +{ + return chunk_hash(key->get_encoding(key)); +} + +/** + * hashtable equals function + */ +static bool equals(identification_t *key1, identification_t *key2) +{ + return key1->equals(key1, key2); +} + +/** + * Implementation of sim_card_t.get_pseudonym + */ +static identification_t *get_pseudonym(private_eap_simaka_pseudonym_card_t *this, + identification_t *id) +{ + identification_t *pseudonym; + + pseudonym = this->pseudonym->get(this->pseudonym, id); + if (pseudonym) + { + return pseudonym->clone(pseudonym); + } + return NULL; +} + +/** + * Implementation of sim_card_t.set_pseudonym + */ +static void set_pseudonym(private_eap_simaka_pseudonym_card_t *this, + identification_t *id, identification_t *pseudonym) +{ + identification_t *permanent; + + /* create new entries */ + id = id->clone(id); + pseudonym = pseudonym->clone(pseudonym); + permanent = this->permanent->put(this->permanent, pseudonym, id); + pseudonym = this->pseudonym->put(this->pseudonym, id, pseudonym); + + /* delete old entries */ + DESTROY_IF(permanent); + DESTROY_IF(pseudonym); +} + +/** + * Implementation of sim_card_t.get_quintuplet + */ +static bool get_quintuplet() +{ + return NOT_SUPPORTED; +} + +/** + * Implementation of eap_simaka_pseudonym_card_t.destroy. + */ +static void destroy(private_eap_simaka_pseudonym_card_t *this) +{ + enumerator_t *enumerator; + identification_t *id; + void *key; + + enumerator = this->pseudonym->create_enumerator(this->pseudonym); + while (enumerator->enumerate(enumerator, &key, &id)) + { + id->destroy(id); + } + enumerator->destroy(enumerator); + + enumerator = this->permanent->create_enumerator(this->permanent); + while (enumerator->enumerate(enumerator, &key, &id)) + { + id->destroy(id); + } + enumerator->destroy(enumerator); + + this->pseudonym->destroy(this->pseudonym); + this->permanent->destroy(this->permanent); + free(this); +} + +/** + * See header + */ +eap_simaka_pseudonym_card_t *eap_simaka_pseudonym_card_create() +{ + private_eap_simaka_pseudonym_card_t *this; + + this = malloc_thing(private_eap_simaka_pseudonym_card_t); + + this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; + this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_LEN]))get_quintuplet; + this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; + this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))get_pseudonym; + this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))set_pseudonym; + this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null; + this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop; + this->public.destroy = (void(*)(eap_simaka_pseudonym_card_t*))destroy; + + this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0); + this->permanent = hashtable_create((void*)hash, (void*)equals, 0); + + return &this->public; +} + diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h new file mode 100644 index 000000000..1b5940fdc --- /dev/null +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 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 eap_simaka_pseudonym_card eap_simaka_pseudonym_card + * @{ @ingroup eap_simaka_pseudonym + */ + +#ifndef EAP_SIMAKA_PSEUDONYM_CARD_H_ +#define EAP_SIMAKA_PSEUDONYM_CARD_H_ + +#include <sa/authenticators/eap/sim_manager.h> + +typedef struct eap_simaka_pseudonym_card_t eap_simaka_pseudonym_card_t; + +/** + * SIM card implementing volatile in-memory pseudonym storage. + */ +struct eap_simaka_pseudonym_card_t { + + /** + * Implements sim_card_t interface + */ + sim_card_t card; + + /** + * Destroy a eap_simaka_pseudonym_card_t. + */ + void (*destroy)(eap_simaka_pseudonym_card_t *this); +}; + +/** + * Create a eap_simaka_pseudonym_card instance. + */ +eap_simaka_pseudonym_card_t *eap_simaka_pseudonym_card_create(); + +#endif /** EAP_SIMAKA_PSEUDONYM_CARD_H_ @}*/ diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c new file mode 100644 index 000000000..e4e179a7d --- /dev/null +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 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. + */ + +#include "eap_simaka_pseudonym_plugin.h" +#include "eap_simaka_pseudonym_card.h" +#include "eap_simaka_pseudonym_provider.h" + +#include <daemon.h> + +typedef struct private_eap_simaka_pseudonym_t private_eap_simaka_pseudonym_t; + +/** + * Private data of an eap_simaka_pseudonym_t object. + */ +struct private_eap_simaka_pseudonym_t { + + /** + * Public eap_simaka_pseudonym_plugin_t interface. + */ + eap_simaka_pseudonym_plugin_t public; + + /** + * SIM card + */ + eap_simaka_pseudonym_card_t *card; + + /** + * SIM provider + */ + eap_simaka_pseudonym_provider_t *provider; +}; + +/** + * Implementation of eap_simaka_pseudonym_t.destroy. + */ +static void destroy(private_eap_simaka_pseudonym_t *this) +{ + charon->sim->remove_card(charon->sim, &this->card->card); + charon->sim->remove_provider(charon->sim, &this->provider->provider); + this->card->destroy(this->card); + this->provider->destroy(this->provider); + free(this); +} + +/** + * See header + */ +plugin_t *plugin_create() +{ + private_eap_simaka_pseudonym_t *this; + + this = malloc_thing(private_eap_simaka_pseudonym_t); + + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; + + this->provider = eap_simaka_pseudonym_provider_create(); + if (!this->provider) + { + free(this); + return NULL; + } + this->card = eap_simaka_pseudonym_card_create(); + + charon->sim->add_card(charon->sim, &this->card->card); + charon->sim->add_provider(charon->sim, &this->provider->provider); + + return &this->public.plugin; +} + diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.h b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.h new file mode 100644 index 000000000..032604eb1 --- /dev/null +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 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 eap_simaka_pseudonym eap_simaka_pseudonym + * @ingroup cplugins + * + * @defgroup eap_simaka_pseudonym_plugin eap_simaka_pseudonym_plugin + * @{ @ingroup eap_simaka_pseudonym + */ + +#ifndef EAP_SIMAKA_PSEUDONYM_PLUGIN_H_ +#define EAP_SIMAKA_PSEUDONYM_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct eap_simaka_pseudonym_plugin_t eap_simaka_pseudonym_plugin_t; + +/** + * Plugin to provide in-memory storage of EAP-SIM/AKA pseudonyms. + */ +struct eap_simaka_pseudonym_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +/** + * Create a eap_simaka_pseudonym_plugin instance. + */ +plugin_t *plugin_create(); + +#endif /** EAP_SIMAKA_PSEUDONYM_PLUGIN_H_ @}*/ diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c new file mode 100644 index 000000000..851f42889 --- /dev/null +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 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. + */ + +#include "eap_simaka_pseudonym_provider.h" + +#include <utils/hashtable.h> + +typedef struct private_eap_simaka_pseudonym_provider_t private_eap_simaka_pseudonym_provider_t; + +/** + * Private data of an eap_simaka_pseudonym_provider_t object. + */ +struct private_eap_simaka_pseudonym_provider_t { + + /** + * Public eap_simaka_pseudonym_provider_t interface. + */ + eap_simaka_pseudonym_provider_t public; + + /** + * Permanent -> pseudonym mappings + */ + hashtable_t *pseudonym; + + /** + * Reverse pseudonym -> permanent mappings + */ + hashtable_t *permanent; + + /** + * RNG for pseudonyms/reauth identities + */ + rng_t *rng; +}; + +/** + * hashtable hash function + */ +static u_int hash(identification_t *key) +{ + return chunk_hash(key->get_encoding(key)); +} + +/** + * hashtable equals function + */ +static bool equals(identification_t *key1, identification_t *key2) +{ + return key1->equals(key1, key2); +} + +/** + * Implementation of sim_provider_t.is_pseudonym + */ +static identification_t* is_pseudonym( + private_eap_simaka_pseudonym_provider_t *this, identification_t *id) +{ + identification_t *permanent; + + permanent = this->permanent->get(this->permanent, id); + if (permanent) + { + return permanent->clone(permanent); + } + return NULL; +} + +/** + * Generate a random identity + */ +static identification_t *gen_identity( + private_eap_simaka_pseudonym_provider_t *this) +{ + char buf[8], hex[sizeof(buf) * 2 + 1]; + + this->rng->get_bytes(this->rng, sizeof(buf), buf); + chunk_to_hex(chunk_create(buf, sizeof(buf)), hex, FALSE); + + return identification_create_from_string(hex); +} + +/** + * Implementation of sim_provider_t.get_pseudonym + */ +static identification_t* gen_pseudonym( + private_eap_simaka_pseudonym_provider_t *this, identification_t *id) +{ + identification_t *pseudonym, *permanent; + + /* remove old entry */ + pseudonym = this->pseudonym->remove(this->pseudonym, id); + if (pseudonym) + { + permanent = this->permanent->remove(this->permanent, pseudonym); + if (permanent) + { + permanent->destroy(permanent); + } + pseudonym->destroy(pseudonym); + } + + pseudonym = gen_identity(this); + + /* create new entries */ + id = id->clone(id); + this->pseudonym->put(this->pseudonym, id, pseudonym); + this->permanent->put(this->permanent, pseudonym, id); + + return pseudonym->clone(pseudonym); +} + +/** + * Implementation of eap_simaka_pseudonym_provider_t.destroy. + */ +static void destroy(private_eap_simaka_pseudonym_provider_t *this) +{ + enumerator_t *enumerator; + identification_t *id; + void *key; + + enumerator = this->pseudonym->create_enumerator(this->pseudonym); + while (enumerator->enumerate(enumerator, &key, &id)) + { + id->destroy(id); + } + enumerator->destroy(enumerator); + + enumerator = this->permanent->create_enumerator(this->permanent); + while (enumerator->enumerate(enumerator, &key, &id)) + { + id->destroy(id); + } + enumerator->destroy(enumerator); + + this->pseudonym->destroy(this->pseudonym); + this->permanent->destroy(this->permanent); + this->rng->destroy(this->rng); + free(this); +} + +/** + * See header + */ +eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create() +{ + private_eap_simaka_pseudonym_provider_t *this; + + this = malloc_thing(private_eap_simaka_pseudonym_provider_t); + + this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; + this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; + this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; + this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))is_pseudonym; + this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))gen_pseudonym; + this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null; + this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null; + this->public.destroy = (void(*)(eap_simaka_pseudonym_provider_t*))destroy; + + this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); + if (!this->rng) + { + free(this); + return NULL; + } + this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0); + this->permanent = hashtable_create((void*)hash, (void*)equals, 0); + + return &this->public; +} + diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h new file mode 100644 index 000000000..5d8e6d221 --- /dev/null +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 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 eap_simaka_pseudonym_provider eap_simaka_pseudonym_provider + * @{ @ingroup eap_simaka_pseudonym + */ + +#ifndef EAP_SIMAKA_PSEDUONYM_PROVIDER_H_ +#define EAP_SIMAKA_PSEDUONYM_PROVIDER_H_ + +#include <sa/authenticators/eap/sim_manager.h> + +typedef struct eap_simaka_pseudonym_provider_t eap_simaka_pseudonym_provider_t; + +/** + * SIM provider implementing volatile in-memory pseudonym storage. + */ +struct eap_simaka_pseudonym_provider_t { + + /** + * Implements sim_provider_t interface. + */ + sim_provider_t provider; + + /** + * Destroy a eap_simaka_pseudonym_provider_t. + */ + void (*destroy)(eap_simaka_pseudonym_provider_t *this); +}; + +/** + * Create a eap_simaka_pseudonym_provider instance. + */ +eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create(); + +#endif /** EAP_SIMAKA_PSEDUONYM_PROVIDER_H_ @}*/ diff --git a/src/charon/plugins/eap_simaka_reauth/Makefile.am b/src/charon/plugins/eap_simaka_reauth/Makefile.am new file mode 100644 index 000000000..0ba727136 --- /dev/null +++ b/src/charon/plugins/eap_simaka_reauth/Makefile.am @@ -0,0 +1,13 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la + +libstrongswan_eap_simaka_reauth_la_SOURCES = \ + eap_simaka_reauth_plugin.h eap_simaka_reauth_plugin.c \ + eap_simaka_reauth_card.h eap_simaka_reauth_card.c \ + eap_simaka_reauth_provider.h eap_simaka_reauth_provider.c +libstrongswan_eap_simaka_reauth_la_LDFLAGS = -module -avoid-version + diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c new file mode 100644 index 000000000..8455c2071 --- /dev/null +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c @@ -0,0 +1,170 @@ +/* + * Copyright (C) 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. + */ + +#include "eap_simaka_reauth_card.h" + +#include <daemon.h> +#include <utils/hashtable.h> + +typedef struct private_eap_simaka_reauth_card_t private_eap_simaka_reauth_card_t; + +/** + * Private data of an eap_simaka_reauth_card_t object. + */ +struct private_eap_simaka_reauth_card_t { + + /** + * Public eap_simaka_reauth_card_t interface. + */ + eap_simaka_reauth_card_t public; + + /** + * Permanent -> reauth_data_t mappings + */ + hashtable_t *reauth; +}; + +/** + * Data associated to a reauthentication identity + */ +typedef struct { + /** currently used reauthentication identity */ + identification_t *id; + /** associated permanent identity */ + identification_t *permanent; + /** counter value */ + u_int16_t counter; + /** master key */ + char mk[HASH_SIZE_SHA1]; +} reauth_data_t; + +/** + * hashtable hash function + */ +static u_int hash(identification_t *key) +{ + return chunk_hash(key->get_encoding(key)); +} + +/** + * hashtable equals function + */ +static bool equals(identification_t *key1, identification_t *key2) +{ + return key1->equals(key1, key2); +} + +/** + * Implementation of sim_card_t.get_reauth + */ +static identification_t *get_reauth(private_eap_simaka_reauth_card_t *this, + identification_t *id, char mk[HASH_SIZE_SHA1], + u_int16_t *counter) +{ + reauth_data_t *data; + identification_t *reauth; + + /* look up reauthentication data */ + data = this->reauth->remove(this->reauth, id); + if (!data) + { + return NULL; + } + *counter = ++data->counter; + memcpy(mk, data->mk, HASH_SIZE_SHA1); + reauth = data->id; + data->permanent->destroy(data->permanent); + free(data); + return reauth; +} + +/** + * Implementation of sim_card_t.set_reauth + */ +static void set_reauth(private_eap_simaka_reauth_card_t *this, + identification_t *id, identification_t* next, + char mk[HASH_SIZE_SHA1], u_int16_t counter) +{ + reauth_data_t *data; + + data = this->reauth->get(this->reauth, id); + if (data) + { + data->id->destroy(data->id); + } + else + { + data = malloc_thing(reauth_data_t); + data->permanent = id->clone(id); + this->reauth->put(this->reauth, data->permanent, data); + } + data->counter = counter; + data->id = next->clone(next); + memcpy(data->mk, mk, HASH_SIZE_SHA1); +} + +/** + * Implementation of sim_card_t.get_quintuplet + */ +static bool get_quintuplet() +{ + return NOT_SUPPORTED; +} + +/** + * Implementation of eap_simaka_reauth_card_t.destroy. + */ +static void destroy(private_eap_simaka_reauth_card_t *this) +{ + enumerator_t *enumerator; + reauth_data_t *data; + void *key; + + enumerator = this->reauth->create_enumerator(this->reauth); + while (enumerator->enumerate(enumerator, &key, &data)) + { + data->id->destroy(data->id); + data->permanent->destroy(data->permanent); + free(data); + } + enumerator->destroy(enumerator); + + this->reauth->destroy(this->reauth); + free(this); +} + +/** + * See header + */ +eap_simaka_reauth_card_t *eap_simaka_reauth_card_create() +{ + private_eap_simaka_reauth_card_t *this; + + this = malloc_thing(private_eap_simaka_reauth_card_t); + + this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_null; + this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_LEN]))get_quintuplet; + this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; + this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))return_null; + this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop; + this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))get_reauth; + this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))set_reauth; + this->public.destroy = (void(*)(eap_simaka_reauth_card_t*))destroy; + + this->reauth = hashtable_create((void*)hash, (void*)equals, 0); + + return &this->public; +} + diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h new file mode 100644 index 000000000..f24dc8a15 --- /dev/null +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 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 eap_simaka_reauth_card eap_simaka_reauth_card + * @{ @ingroup eap_simaka_reauth + */ + +#ifndef EAP_SIMAKA_REAUTH_CARD_H_ +#define EAP_SIMAKA_REAUTH_CARD_H_ + +#include <sa/authenticators/eap/sim_manager.h> + +typedef struct eap_simaka_reauth_card_t eap_simaka_reauth_card_t; + +/** + * SIM card implementing volatile in-memory reauthentication data storage. + */ +struct eap_simaka_reauth_card_t { + + /** + * Implements sim_card_t interface + */ + sim_card_t card; + + /** + * Destroy a eap_simaka_reauth_card_t. + */ + void (*destroy)(eap_simaka_reauth_card_t *this); +}; + +/** + * Create a eap_simaka_reauth_card instance. + */ +eap_simaka_reauth_card_t *eap_simaka_reauth_card_create(); + +#endif /** EAP_SIMAKA_REAUTH_CARD_H_ @}*/ diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c new file mode 100644 index 000000000..b2e853e21 --- /dev/null +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 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. + */ + +#include "eap_simaka_reauth_plugin.h" +#include "eap_simaka_reauth_card.h" +#include "eap_simaka_reauth_provider.h" + +#include <daemon.h> + +typedef struct private_eap_simaka_reauth_t private_eap_simaka_reauth_t; + +/** + * Private data of an eap_simaka_reauth_t object. + */ +struct private_eap_simaka_reauth_t { + + /** + * Public eap_simaka_reauth_plugin_t interface. + */ + eap_simaka_reauth_plugin_t public; + + /** + * SIM card + */ + eap_simaka_reauth_card_t *card; + + /** + * SIM provider + */ + eap_simaka_reauth_provider_t *provider; +}; + +/** + * Implementation of eap_simaka_reauth_t.destroy. + */ +static void destroy(private_eap_simaka_reauth_t *this) +{ + charon->sim->remove_card(charon->sim, &this->card->card); + charon->sim->remove_provider(charon->sim, &this->provider->provider); + this->card->destroy(this->card); + this->provider->destroy(this->provider); + free(this); +} + +/** + * See header + */ +plugin_t *plugin_create() +{ + private_eap_simaka_reauth_t *this = malloc_thing(private_eap_simaka_reauth_t); + + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; + + this->provider = eap_simaka_reauth_provider_create(); + if (!this->provider) + { + free(this); + return NULL; + } + this->card = eap_simaka_reauth_card_create(); + + charon->sim->add_card(charon->sim, &this->card->card); + charon->sim->add_provider(charon->sim, &this->provider->provider); + + return &this->public.plugin; +} + diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.h b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.h new file mode 100644 index 000000000..e86832c0e --- /dev/null +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 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 eap_simaka_reauth eap_simaka_reauth + * @ingroup cplugins + * + * @defgroup eap_simaka_reauth_plugin eap_simaka_reauth_plugin + * @{ @ingroup eap_simaka_reauth + */ + +#ifndef EAP_SIMAKA_REAUTH_PLUGIN_H_ +#define EAP_SIMAKA_REAUTH_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct eap_simaka_reauth_plugin_t eap_simaka_reauth_plugin_t; + +/** + * Plugin to provide in-memory EAP-SIM/AKA reauthentication data storage. + */ +struct eap_simaka_reauth_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +/** + * Create a eap_simaka_reauth_plugin instance. + */ +plugin_t *plugin_create(); + +#endif /** EAP_SIMAKA_REAUTH_PLUGIN_H_ @}*/ diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c new file mode 100644 index 000000000..a27af54f1 --- /dev/null +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 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. + */ + +#include "eap_simaka_reauth_provider.h" + +#include <daemon.h> +#include <utils/hashtable.h> + +typedef struct private_eap_simaka_reauth_provider_t private_eap_simaka_reauth_provider_t; + +/** + * Private data of an eap_simaka_reauth_provider_t object. + */ +struct private_eap_simaka_reauth_provider_t { + + /** + * Public eap_simaka_reauth_provider_t interface. + */ + eap_simaka_reauth_provider_t public; + + /** + * Permanent -> reauth_data_t mappings + */ + hashtable_t *reauth; + + /** + * Reverse reauth -> permanent mappings + */ + hashtable_t *permanent; + + /** + * RNG for pseudonyms/reauth identities + */ + rng_t *rng; +}; + +/** + * Data associated to a reauthentication identity + */ +typedef struct { + /** currently used reauthentication identity */ + identification_t *id; + /** counter value */ + u_int16_t counter; + /** master key */ + char mk[HASH_SIZE_SHA1]; +} reauth_data_t; + +/** + * hashtable hash function + */ +static u_int hash(identification_t *key) +{ + return chunk_hash(key->get_encoding(key)); +} + +/** + * hashtable equals function + */ +static bool equals(identification_t *key1, identification_t *key2) +{ + return key1->equals(key1, key2); +} + +/** + * Generate a random identity + */ +static identification_t *gen_identity(private_eap_simaka_reauth_provider_t *this) +{ + char buf[8], hex[sizeof(buf) * 2 + 1]; + + this->rng->get_bytes(this->rng, sizeof(buf), buf); + chunk_to_hex(chunk_create(buf, sizeof(buf)), hex, FALSE); + + return identification_create_from_string(hex); +} + +/** + * Implementation of sim_provider_t.is_reauth + */ +static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this, + identification_t *id, char mk[HASH_SIZE_SHA1], + u_int16_t *counter) +{ + identification_t *permanent; + reauth_data_t *data; + + /* look up permanent identity */ + permanent = this->permanent->get(this->permanent, id); + if (!permanent) + { + return NULL; + } + /* look up reauthentication data */ + data = this->reauth->get(this->reauth, permanent); + if (!data) + { + return NULL; + } + *counter = ++data->counter; + memcpy(mk, data->mk, HASH_SIZE_SHA1); + return permanent->clone(permanent); +} + +/** + * Implementation of sim_provider_t.gen_reauth + */ +static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this, + identification_t *id, char mk[HASH_SIZE_SHA1]) +{ + reauth_data_t *data; + identification_t *permanent; + + data = this->reauth->get(this->reauth, id); + id = id->clone(id); + if (data) + { /* update existing entry */ + permanent = this->permanent->remove(this->permanent, data->id); + if (permanent) + { + permanent->destroy(permanent); + } + data->id->destroy(data->id); + } + else + { /* generate new entry */ + data = malloc_thing(reauth_data_t); + data->counter = 0; + this->reauth->put(this->reauth, id, data); + } + memcpy(data->mk, mk, HASH_SIZE_SHA1); + data->id = gen_identity(this); + + this->permanent->put(this->permanent, data->id, id); + + return data->id->clone(data->id); +} + +/** + * Implementation of eap_simaka_reauth_provider_t.destroy. + */ +static void destroy(private_eap_simaka_reauth_provider_t *this) +{ + enumerator_t *enumerator; + identification_t *id; + reauth_data_t *data; + void *key; + + enumerator = this->permanent->create_enumerator(this->permanent); + while (enumerator->enumerate(enumerator, &key, &id)) + { + id->destroy(id); + } + enumerator->destroy(enumerator); + + enumerator = this->reauth->create_enumerator(this->reauth); + while (enumerator->enumerate(enumerator, &key, &data)) + { + data->id->destroy(data->id); + free(data); + } + enumerator->destroy(enumerator); + + this->permanent->destroy(this->permanent); + this->reauth->destroy(this->reauth); + this->rng->destroy(this->rng); + free(this); +} + +/** + * See header + */ +eap_simaka_reauth_provider_t *eap_simaka_reauth_provider_create() +{ + private_eap_simaka_reauth_provider_t *this = malloc_thing(private_eap_simaka_reauth_provider_t); + + this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; + this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; + this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; + this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; + this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; + this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))is_reauth; + this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))gen_reauth; + this->public.destroy = (void(*)(eap_simaka_reauth_provider_t*))destroy; + + this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); + if (!this->rng) + { + free(this); + return NULL; + } + this->permanent = hashtable_create((void*)hash, (void*)equals, 0); + this->reauth = hashtable_create((void*)hash, (void*)equals, 0); + + return &this->public; +} + diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h new file mode 100644 index 000000000..7ae151a27 --- /dev/null +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 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 eap_simaka_reauth_provider eap_simaka_reauth_provider + * @{ @ingroup eap_simaka_reauth + */ + +#ifndef EAP_SIMAKA_REAUTH_PROVIDER_H_ +#define EAP_SIMAKA_REAUTH_PROVIDER_H_ + +#include <sa/authenticators/eap/sim_manager.h> + +typedef struct eap_simaka_reauth_provider_t eap_simaka_reauth_provider_t; + +/** + * SIM provider implementing volatile in-memory reauthentication data storage. + */ +struct eap_simaka_reauth_provider_t { + + /** + * Implements sim_provider_t interface. + */ + sim_provider_t provider; + + /** + * Destroy a eap_simaka_reauth_provider_t. + */ + void (*destroy)(eap_simaka_reauth_provider_t *this); +}; + +/** + * Create a eap_simaka_reauth_provider instance. + */ +eap_simaka_reauth_provider_t *eap_simaka_reauth_provider_create(); + +#endif /** EAP_SIMAKA_REAUTH_PROVIDER_H_ @}*/ |