diff options
author | Martin Willi <martin@strongswan.org> | 2009-10-28 14:18:33 +0100 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-11-12 10:34:01 +0100 |
commit | acb561373a0a0be3d2781ffb47045a0d309d10db (patch) | |
tree | af01033b1ea18988da8796f128e4eab1ec55c79c | |
parent | c5ec0f48e748f94c6074309f8d87155426bf6db4 (diff) | |
download | strongswan-acb561373a0a0be3d2781ffb47045a0d309d10db.tar.bz2 strongswan-acb561373a0a0be3d2781ffb47045a0d309d10db.tar.xz |
eap-sim-file plugin supports volatile in-memory storage of fast reauthentication data
-rw-r--r-- | src/charon/plugins/eap_sim_file/eap_sim_file_card.c | 96 | ||||
-rw-r--r-- | src/charon/plugins/eap_sim_file/eap_sim_file_provider.c | 128 |
2 files changed, 199 insertions, 25 deletions
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 1413d97d3..077163a82 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 @@ -36,16 +36,32 @@ struct private_eap_sim_file_card_t { eap_sim_file_triplets_t *triplets; /** - * Permanent -> pseudonym mappongs + * Permanent -> pseudonym mappings */ hashtable_t *pseudonym; /** - * Pseudonym -> permanent mappings + * 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 */ @@ -131,6 +147,55 @@ static void set_pseudonym(private_eap_sim_file_card_t *this, } /** + * 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() @@ -144,24 +209,36 @@ static bool get_quintuplet() static void destroy(private_eap_sim_file_card_t *this) { enumerator_t *enumerator; - identification_t *key, *value; + identification_t *id; + reauth_data_t *data; + void *key; enumerator = this->pseudonym->create_enumerator(this->pseudonym); - while (enumerator->enumerate(enumerator, &key, &value)) + while (enumerator->enumerate(enumerator, &key, &id)) { - value->destroy(value); + id->destroy(id); } enumerator->destroy(enumerator); enumerator = this->permanent->create_enumerator(this->permanent); - while (enumerator->enumerate(enumerator, &key, &value)) + 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)) { - value->destroy(value); + 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); } @@ -177,13 +254,14 @@ eap_sim_file_card_t *eap_sim_file_card_create(eap_sim_file_triplets_t *triplets) 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.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_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 22c4f26e3..aa2eabc43 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 @@ -36,21 +36,35 @@ struct private_eap_sim_file_provider_t { eap_sim_file_triplets_t *triplets; /** - * Permanent -> pseudonym mappongs + * Permanent -> pseudonym mappings */ hashtable_t *pseudonym; /** - * Pseudonym -> permanent mappings + * Permanent -> reauth_data_t mappings + */ + hashtable_t *reauth; + + /** + * Reverse pseudonym/reauth -> permanent mappings */ hashtable_t *permanent; /** - * RNG for pseudonyms + * 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 */ @@ -110,13 +124,25 @@ static identification_t* is_pseudonym(private_eap_sim_file_provider_t *this, } /** - * Implementation of sim_provider_t.get_triplet + * 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; - char buf[8], hex[sizeof(buf) * 2 + 1]; /* remove old entry */ pseudonym = this->pseudonym->remove(this->pseudonym, id); @@ -130,10 +156,7 @@ static identification_t* gen_pseudonym(private_eap_sim_file_provider_t *this, pseudonym->destroy(pseudonym); } - /* generate new pseudonym */ - this->rng->get_bytes(this->rng, sizeof(buf), buf); - chunk_to_hex(chunk_create(buf, sizeof(buf)), hex, FALSE); - pseudonym = identification_create_from_string(hex); + pseudonym = gen_identity(this); /* create new entries */ id = id->clone(id); @@ -144,29 +167,101 @@ static identification_t* gen_pseudonym(private_eap_sim_file_provider_t *this, } /** + * 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 *key, *value; + identification_t *id; + reauth_data_t *data; + void *key; enumerator = this->pseudonym->create_enumerator(this->pseudonym); - while (enumerator->enumerate(enumerator, &key, &value)) + while (enumerator->enumerate(enumerator, &key, &id)) { - value->destroy(value); + id->destroy(id); } enumerator->destroy(enumerator); enumerator = this->permanent->create_enumerator(this->permanent); - while (enumerator->enumerate(enumerator, &key, &value)) + 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)) { - value->destroy(value); + 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); } @@ -184,8 +279,8 @@ eap_sim_file_provider_t *eap_sim_file_provider_create( 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.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_sim_file_provider_t*))destroy; this->triplets = triplets; @@ -197,6 +292,7 @@ eap_sim_file_provider_t *eap_sim_file_provider_create( } 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; } |