Moved card/provider enumeration to SIM manager, providing wrapped functions for both SIM and AKA plugins
This commit is contained in:
@@ -81,7 +81,6 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
|
|||||||
simaka_message_t *message;
|
simaka_message_t *message;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
simaka_attribute_t type;
|
simaka_attribute_t type;
|
||||||
sim_card_t *card;
|
|
||||||
chunk_t data, rand = chunk_empty, autn = chunk_empty, mk;
|
chunk_t data, rand = chunk_empty, autn = chunk_empty, mk;
|
||||||
u_char res[AKA_RES_LEN], ck[AKA_CK_LEN], ik[AKA_IK_LEN], auts[AKA_AUTS_LEN];
|
u_char res[AKA_RES_LEN], ck[AKA_CK_LEN], ik[AKA_IK_LEN], auts[AKA_AUTS_LEN];
|
||||||
status_t status = NOT_FOUND;
|
status_t status = NOT_FOUND;
|
||||||
@@ -116,20 +115,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
|
|||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enumerator = charon->sim->create_card_enumerator(charon->sim);
|
status = charon->sim->card_get_quintuplet(charon->sim, this->peer,
|
||||||
while (enumerator->enumerate(enumerator, &card))
|
rand.ptr, autn.ptr, ck, ik, res);
|
||||||
{
|
|
||||||
status = card->get_quintuplet(card, this->peer, rand.ptr, autn.ptr,
|
|
||||||
ck, ik, res);
|
|
||||||
if (status != FAILED)
|
|
||||||
{ /* try next on error */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
|
|
||||||
if (status == INVALID_STATE &&
|
if (status == INVALID_STATE &&
|
||||||
card->resync(card, this->peer, rand.ptr, auts))
|
charon->sim->card_resync(charon->sim, this->peer, rand.ptr, auts))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "received SQN invalid, sending %N",
|
DBG1(DBG_IKE, "received SQN invalid, sending %N",
|
||||||
simaka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
|
simaka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
|
||||||
|
|||||||
@@ -94,31 +94,17 @@ static bool attribute_skippable(simaka_attribute_t attribute)
|
|||||||
static status_t initiate(private_eap_aka_server_t *this, eap_payload_t **out)
|
static status_t initiate(private_eap_aka_server_t *this, eap_payload_t **out)
|
||||||
{
|
{
|
||||||
simaka_message_t *message;
|
simaka_message_t *message;
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_provider_t *provider;
|
|
||||||
char rand[AKA_RAND_LEN], xres[AKA_RES_LEN];
|
char rand[AKA_RAND_LEN], xres[AKA_RES_LEN];
|
||||||
char ck[AKA_CK_LEN], ik[AKA_IK_LEN], autn[AKA_AUTN_LEN];
|
char ck[AKA_CK_LEN], ik[AKA_IK_LEN], autn[AKA_AUTN_LEN];
|
||||||
chunk_t data, mk;
|
chunk_t data, mk;
|
||||||
bool found = FALSE;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_provider_enumerator(charon->sim);
|
if (!charon->sim->provider_get_quintuplet(charon->sim, this->peer,
|
||||||
while (enumerator->enumerate(enumerator, &provider))
|
rand, xres, ck, ik, autn))
|
||||||
{
|
|
||||||
if (provider->get_quintuplet(provider, this->peer,
|
|
||||||
rand, xres, ck, ik, autn))
|
|
||||||
{
|
|
||||||
found = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
if (!found)
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "no AKA provider found with quintuplets for '%Y'",
|
DBG1(DBG_IKE, "no AKA provider found with quintuplets for '%Y'",
|
||||||
this->peer);
|
this->peer);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = chunk_cata("cc", chunk_create(ik, AKA_IK_LEN),
|
data = chunk_cata("cc", chunk_create(ik, AKA_IK_LEN),
|
||||||
chunk_create(ck, AKA_CK_LEN));
|
chunk_create(ck, AKA_CK_LEN));
|
||||||
free(this->msk.ptr);
|
free(this->msk.ptr);
|
||||||
@@ -197,11 +183,9 @@ static status_t process_challenge(private_eap_aka_server_t *this,
|
|||||||
static status_t process_synchronize(private_eap_aka_server_t *this,
|
static status_t process_synchronize(private_eap_aka_server_t *this,
|
||||||
simaka_message_t *in, eap_payload_t **out)
|
simaka_message_t *in, eap_payload_t **out)
|
||||||
{
|
{
|
||||||
sim_provider_t *provider;
|
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
simaka_attribute_t type;
|
simaka_attribute_t type;
|
||||||
chunk_t data, auts = chunk_empty;
|
chunk_t data, auts = chunk_empty;
|
||||||
bool found = FALSE;
|
|
||||||
|
|
||||||
if (this->synchronized)
|
if (this->synchronized)
|
||||||
{
|
{
|
||||||
@@ -239,18 +223,8 @@ static status_t process_synchronize(private_eap_aka_server_t *this,
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
enumerator = charon->sim->create_provider_enumerator(charon->sim);
|
if (!charon->sim->provider_resync(charon->sim, this->peer,
|
||||||
while (enumerator->enumerate(enumerator, &provider))
|
this->rand.ptr, auts.ptr))
|
||||||
{
|
|
||||||
if (provider->resync(provider, this->peer, this->rand.ptr, auts.ptr))
|
|
||||||
{
|
|
||||||
found = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "no AKA provider found supporting "
|
DBG1(DBG_IKE, "no AKA provider found supporting "
|
||||||
"resynchronization for '%Y'", this->peer);
|
"resynchronization for '%Y'", this->peer);
|
||||||
|
|||||||
@@ -94,124 +94,34 @@ struct private_eap_sim_peer_t {
|
|||||||
/* version of SIM protocol we speak */
|
/* version of SIM protocol we speak */
|
||||||
static chunk_t version = chunk_from_chars(0x00,0x01);
|
static chunk_t version = chunk_from_chars(0x00,0x01);
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a triplet from the SIM card
|
|
||||||
*/
|
|
||||||
static bool get_triplet(private_eap_sim_peer_t *this, identification_t *peer,
|
|
||||||
char *rand, char *sres, char *kc)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_card_t *card;
|
|
||||||
bool success = FALSE;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_card_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &card))
|
|
||||||
{
|
|
||||||
if (card->get_triplet(card, peer, rand, sres, kc))
|
|
||||||
{
|
|
||||||
success = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "no SIM card found with triplets for '%Y'", peer);
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a stored reauthentication identity on a SIM card
|
|
||||||
*/
|
|
||||||
static identification_t *get_reauth(private_eap_sim_peer_t *this)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_card_t *card;
|
|
||||||
identification_t *reauth = NULL;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_card_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &card))
|
|
||||||
{
|
|
||||||
reauth = card->get_reauth(card, this->permanent,
|
|
||||||
this->mk, &this->counter);
|
|
||||||
if (reauth)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "using stored reauthentication identity '%Y' "
|
|
||||||
"instead of '%Y'", reauth, this->permanent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return reauth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store received next fast reauthentication identity, along with mk/counter
|
* Store received next fast reauthentication identity, along with mk/counter
|
||||||
*/
|
*/
|
||||||
static void set_reauth(private_eap_sim_peer_t *this, chunk_t data)
|
static void set_reauth(private_eap_sim_peer_t *this, chunk_t data)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_card_t *card;
|
|
||||||
identification_t *reauth;
|
identification_t *reauth;
|
||||||
char buf[data.len + 1];
|
char buf[data.len + 1];
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%.*s", data.len, data.ptr);
|
snprintf(buf, sizeof(buf), "%.*s", data.len, data.ptr);
|
||||||
reauth = identification_create_from_string(buf);
|
reauth = identification_create_from_string(buf);
|
||||||
DBG1(DBG_IKE, "received next reauthentication identity '%Y'", reauth);
|
DBG1(DBG_IKE, "received next reauthentication identity '%Y'", reauth);
|
||||||
|
charon->sim->card_set_reauth(charon->sim, this->permanent, reauth,
|
||||||
enumerator = charon->sim->create_card_enumerator(charon->sim);
|
this->mk, this->counter);
|
||||||
while (enumerator->enumerate(enumerator, &card))
|
|
||||||
{
|
|
||||||
card->set_reauth(card, this->permanent, reauth, this->mk, this->counter);
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
reauth->destroy(reauth);
|
reauth->destroy(reauth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a stored pseudonym on a SIM card
|
|
||||||
*/
|
|
||||||
static identification_t *get_pseudonym(private_eap_sim_peer_t *this)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_card_t *card;
|
|
||||||
identification_t *pseudonym = NULL;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_card_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &card))
|
|
||||||
{
|
|
||||||
pseudonym = card->get_pseudonym(card, this->permanent);
|
|
||||||
if (pseudonym)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "using stored pseudonym identity '%Y' "
|
|
||||||
"instead of '%Y'", pseudonym, this->permanent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return pseudonym;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a pseudonym in a SIM card
|
* Store a pseudonym in a SIM card
|
||||||
*/
|
*/
|
||||||
static void set_pseudonym(private_eap_sim_peer_t *this, chunk_t data)
|
static void set_pseudonym(private_eap_sim_peer_t *this, chunk_t data)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_card_t *card;
|
|
||||||
identification_t *pseudonym;
|
identification_t *pseudonym;
|
||||||
char buf[data.len + 1];
|
char buf[data.len + 1];
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%.*s", data.len, data.ptr);
|
snprintf(buf, sizeof(buf), "%.*s", data.len, data.ptr);
|
||||||
pseudonym = identification_create_from_string(buf);
|
pseudonym = identification_create_from_string(buf);
|
||||||
DBG1(DBG_IKE, "received pseudonym '%Y' for next authentication", pseudonym);
|
DBG1(DBG_IKE, "received pseudonym '%Y' for next authentication", pseudonym);
|
||||||
enumerator = charon->sim->create_card_enumerator(charon->sim);
|
charon->sim->card_set_pseudonym(charon->sim, this->permanent, pseudonym);
|
||||||
while (enumerator->enumerate(enumerator, &card))
|
|
||||||
{
|
|
||||||
card->set_pseudonym(card, this->permanent, pseudonym);
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
pseudonym->destroy(pseudonym);
|
pseudonym->destroy(pseudonym);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +216,8 @@ static status_t process_start(private_eap_sim_peer_t *this,
|
|||||||
switch (id_req)
|
switch (id_req)
|
||||||
{
|
{
|
||||||
case AT_ANY_ID_REQ:
|
case AT_ANY_ID_REQ:
|
||||||
this->reauth = get_reauth(this);
|
this->reauth = charon->sim->card_get_reauth(charon->sim,
|
||||||
|
this->permanent, this->mk, &this->counter);
|
||||||
if (this->reauth)
|
if (this->reauth)
|
||||||
{
|
{
|
||||||
id = this->reauth->get_encoding(this->reauth);
|
id = this->reauth->get_encoding(this->reauth);
|
||||||
@@ -314,7 +225,8 @@ static status_t process_start(private_eap_sim_peer_t *this,
|
|||||||
}
|
}
|
||||||
/* FALL */
|
/* FALL */
|
||||||
case AT_FULLAUTH_ID_REQ:
|
case AT_FULLAUTH_ID_REQ:
|
||||||
this->pseudonym = get_pseudonym(this);
|
this->pseudonym = charon->sim->card_get_pseudonym(charon->sim,
|
||||||
|
this->permanent);
|
||||||
if (this->pseudonym)
|
if (this->pseudonym)
|
||||||
{
|
{
|
||||||
id = this->pseudonym->get_encoding(this->pseudonym);
|
id = this->pseudonym->get_encoding(this->pseudonym);
|
||||||
@@ -405,7 +317,8 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
|
|||||||
sreses = sres = chunk_alloca(rands.len / 4);
|
sreses = sres = chunk_alloca(rands.len / 4);
|
||||||
while (rands.len >= SIM_RAND_LEN)
|
while (rands.len >= SIM_RAND_LEN)
|
||||||
{
|
{
|
||||||
if (!get_triplet(this, this->permanent, rands.ptr, sres.ptr, kc.ptr))
|
if (!charon->sim->card_get_triplet(charon->sim, this->permanent,
|
||||||
|
rands.ptr, sres.ptr, kc.ptr))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "unable to get EAP-SIM triplet");
|
DBG1(DBG_IKE, "unable to get EAP-SIM triplet");
|
||||||
*out = create_client_error(this, in->get_identifier(in),
|
*out = create_client_error(this, in->get_identifier(in),
|
||||||
|
|||||||
@@ -107,126 +107,6 @@ struct private_eap_sim_server_t {
|
|||||||
/* version of SIM protocol we speak */
|
/* version of SIM protocol we speak */
|
||||||
static chunk_t version = chunk_from_chars(0x00,0x01);
|
static chunk_t version = chunk_from_chars(0x00,0x01);
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch a triplet from a provider
|
|
||||||
*/
|
|
||||||
static bool get_triplet(private_eap_sim_server_t *this, identification_t *peer,
|
|
||||||
char *rand, char *sres, char *kc)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_provider_t *provider;
|
|
||||||
int tried = 0;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_provider_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &provider))
|
|
||||||
{
|
|
||||||
if (provider->get_triplet(provider, peer, rand, sres, kc))
|
|
||||||
{
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
tried++;
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%Y'",
|
|
||||||
tried, peer);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a new reauthentication identity for next fast reauthentication
|
|
||||||
*/
|
|
||||||
static identification_t* gen_reauth(private_eap_sim_server_t *this,
|
|
||||||
char mk[HASH_SIZE_SHA1])
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_provider_t *provider;
|
|
||||||
identification_t *reauth = NULL;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_provider_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &provider))
|
|
||||||
{
|
|
||||||
reauth = provider->gen_reauth(provider, this->permanent, mk);
|
|
||||||
if (reauth)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "proposing new reauthentication identity '%Y'", reauth);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return reauth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an identity is a known reauthentication identity
|
|
||||||
*/
|
|
||||||
static identification_t* is_reauth(private_eap_sim_server_t *this,
|
|
||||||
identification_t *id, char mk[HASH_SIZE_SHA1],
|
|
||||||
u_int16_t *counter)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_provider_t *provider;
|
|
||||||
identification_t *permanent = NULL;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_provider_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &provider))
|
|
||||||
{
|
|
||||||
permanent = provider->is_reauth(provider, id, mk, counter);
|
|
||||||
if (permanent)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return permanent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a new pseudonym for next authentication
|
|
||||||
*/
|
|
||||||
static identification_t* gen_pseudonym(private_eap_sim_server_t *this)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_provider_t *provider;
|
|
||||||
identification_t *pseudonym = NULL;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_provider_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &provider))
|
|
||||||
{
|
|
||||||
pseudonym = provider->gen_pseudonym(provider, this->permanent);
|
|
||||||
if (pseudonym)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "proposing new pseudonym '%Y'", pseudonym);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return pseudonym;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an identity is a known pseudonym
|
|
||||||
*/
|
|
||||||
static identification_t* is_pseudonym(private_eap_sim_server_t *this,
|
|
||||||
identification_t *pseudonym)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
sim_provider_t *provider;
|
|
||||||
identification_t *permanent = NULL;
|
|
||||||
|
|
||||||
enumerator = charon->sim->create_provider_enumerator(charon->sim);
|
|
||||||
while (enumerator->enumerate(enumerator, &provider))
|
|
||||||
{
|
|
||||||
permanent = provider->is_pseudonym(provider, pseudonym);
|
|
||||||
if (permanent)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return permanent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of eap_method_t.initiate
|
* Implementation of eap_method_t.initiate
|
||||||
*/
|
*/
|
||||||
@@ -285,7 +165,7 @@ static status_t reauthenticate(private_eap_sim_server_t *this,
|
|||||||
SIM_REAUTHENTICATION, this->crypto);
|
SIM_REAUTHENTICATION, this->crypto);
|
||||||
message->add_attribute(message, AT_COUNTER, this->counter);
|
message->add_attribute(message, AT_COUNTER, this->counter);
|
||||||
message->add_attribute(message, AT_NONCE_S, this->nonce);
|
message->add_attribute(message, AT_NONCE_S, this->nonce);
|
||||||
next = gen_reauth(this, mk);
|
next = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk);
|
||||||
if (next)
|
if (next)
|
||||||
{
|
{
|
||||||
message->add_attribute(message, AT_NEXT_REAUTH_ID,
|
message->add_attribute(message, AT_NEXT_REAUTH_ID,
|
||||||
@@ -424,7 +304,8 @@ static status_t process_start(private_eap_sim_server_t *this,
|
|||||||
char mk[HASH_SIZE_SHA1];
|
char mk[HASH_SIZE_SHA1];
|
||||||
u_int16_t counter;
|
u_int16_t counter;
|
||||||
|
|
||||||
permanent = is_reauth(this, id, mk, &counter);
|
permanent = charon->sim->provider_is_reauth(charon->sim, id,
|
||||||
|
mk, &counter);
|
||||||
if (permanent)
|
if (permanent)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "received reauthentication identity '%Y' "
|
DBG1(DBG_IKE, "received reauthentication identity '%Y' "
|
||||||
@@ -442,7 +323,7 @@ static status_t process_start(private_eap_sim_server_t *this,
|
|||||||
}
|
}
|
||||||
if (this->use_pseudonym)
|
if (this->use_pseudonym)
|
||||||
{
|
{
|
||||||
permanent = is_pseudonym(this, id);
|
permanent = charon->sim->provider_is_pseudonym(charon->sim, id);
|
||||||
if (permanent)
|
if (permanent)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "received pseudonym identity '%Y' "
|
DBG1(DBG_IKE, "received pseudonym identity '%Y' "
|
||||||
@@ -477,7 +358,8 @@ static status_t process_start(private_eap_sim_server_t *this,
|
|||||||
rands.len = kcs.len = sreses.len = 0;
|
rands.len = kcs.len = sreses.len = 0;
|
||||||
for (i = 0; i < TRIPLET_COUNT; i++)
|
for (i = 0; i < TRIPLET_COUNT; i++)
|
||||||
{
|
{
|
||||||
if (!get_triplet(this, this->permanent, rand.ptr, sres.ptr, kc.ptr))
|
if (!charon->sim->provider_get_triplet(charon->sim, this->permanent,
|
||||||
|
rand.ptr, sres.ptr, kc.ptr))
|
||||||
{
|
{
|
||||||
if (this->use_pseudonym)
|
if (this->use_pseudonym)
|
||||||
{
|
{
|
||||||
@@ -514,7 +396,7 @@ static status_t process_start(private_eap_sim_server_t *this,
|
|||||||
message = simaka_message_create(TRUE, this->identifier++, EAP_SIM,
|
message = simaka_message_create(TRUE, this->identifier++, EAP_SIM,
|
||||||
SIM_CHALLENGE, this->crypto);
|
SIM_CHALLENGE, this->crypto);
|
||||||
message->add_attribute(message, AT_RAND, rands);
|
message->add_attribute(message, AT_RAND, rands);
|
||||||
id = gen_reauth(this, mk.ptr);
|
id = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk.ptr);
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
message->add_attribute(message, AT_NEXT_REAUTH_ID,
|
message->add_attribute(message, AT_NEXT_REAUTH_ID,
|
||||||
@@ -523,7 +405,7 @@ static status_t process_start(private_eap_sim_server_t *this,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id = gen_pseudonym(this);
|
id = charon->sim->provider_gen_pseudonym(charon->sim, this->permanent);
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
message->add_attribute(message, AT_NEXT_PSEUDONYM,
|
message->add_attribute(message, AT_NEXT_PSEUDONYM,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "sim_manager.h"
|
#include "sim_manager.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
|
|
||||||
typedef struct private_sim_manager_t private_sim_manager_t;
|
typedef struct private_sim_manager_t private_sim_manager_t;
|
||||||
@@ -37,7 +38,7 @@ struct private_sim_manager_t {
|
|||||||
/**
|
/**
|
||||||
* list of added provider
|
* list of added provider
|
||||||
*/
|
*/
|
||||||
linked_list_t *provider;
|
linked_list_t *providers;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,37 +58,356 @@ static void remove_card(private_sim_manager_t *this, sim_card_t *card)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of sim_manager_t.create_card_enumerator
|
* Implementation of sim_manager_t.card_get_triplet
|
||||||
*/
|
*/
|
||||||
static enumerator_t* create_card_enumerator(private_sim_manager_t *this)
|
static bool card_get_triplet(private_sim_manager_t *this, identification_t *id,
|
||||||
|
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
|
||||||
|
char kc[SIM_KC_LEN])
|
||||||
{
|
{
|
||||||
return this->cards->create_enumerator(this->cards);
|
enumerator_t *enumerator;
|
||||||
|
sim_card_t *card;
|
||||||
|
int tried = 0;
|
||||||
|
|
||||||
|
enumerator = this->cards->create_enumerator(this->cards);
|
||||||
|
while (enumerator->enumerate(enumerator, &card))
|
||||||
|
{
|
||||||
|
if (card->get_triplet(card, id, rand, sres, kc))
|
||||||
|
{
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
tried++;
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
DBG1(DBG_IKE, "tried %d SIM cards, but none has triplets for '%Y'",
|
||||||
|
tried, id);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.card_get_quintuplet
|
||||||
|
*/
|
||||||
|
static status_t card_get_quintuplet(private_sim_manager_t *this,
|
||||||
|
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])
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_card_t *card;
|
||||||
|
status_t status = NOT_FOUND;
|
||||||
|
int tried = 0;
|
||||||
|
|
||||||
|
enumerator = this->cards->create_enumerator(this->cards);
|
||||||
|
while (enumerator->enumerate(enumerator, &card))
|
||||||
|
{
|
||||||
|
status = card->get_quintuplet(card, id, rand, autn, ck, ik, res);
|
||||||
|
if (status != FAILED)
|
||||||
|
{ /* try next on error, but not on INVALID_STATE */
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
tried++;
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
DBG1(DBG_IKE, "tried %d SIM cards, but none has quintuplets for '%Y'",
|
||||||
|
tried, id);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.card_resync
|
||||||
|
*/
|
||||||
|
static bool card_resync(private_sim_manager_t *this, identification_t *id,
|
||||||
|
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_card_t *card;
|
||||||
|
|
||||||
|
enumerator = this->cards->create_enumerator(this->cards);
|
||||||
|
while (enumerator->enumerate(enumerator, &card))
|
||||||
|
{
|
||||||
|
if (card->resync(card, id, rand, auts))
|
||||||
|
{
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.card_set_pseudonym
|
||||||
|
*/
|
||||||
|
static void card_set_pseudonym(private_sim_manager_t *this,
|
||||||
|
identification_t *id, identification_t *pseudonym)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_card_t *card;
|
||||||
|
|
||||||
|
enumerator = this->cards->create_enumerator(this->cards);
|
||||||
|
while (enumerator->enumerate(enumerator, &card))
|
||||||
|
{
|
||||||
|
card->set_pseudonym(card, id, pseudonym);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.card_get_pseudonym
|
||||||
|
*/
|
||||||
|
static identification_t* card_get_pseudonym(private_sim_manager_t *this,
|
||||||
|
identification_t *id)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_card_t *card;
|
||||||
|
identification_t *pseudonym = NULL;
|
||||||
|
|
||||||
|
enumerator = this->cards->create_enumerator(this->cards);
|
||||||
|
while (enumerator->enumerate(enumerator, &card))
|
||||||
|
{
|
||||||
|
pseudonym = card->get_pseudonym(card, id);
|
||||||
|
if (pseudonym)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "using stored pseudonym identity '%Y' "
|
||||||
|
"instead of '%Y'", pseudonym, id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return pseudonym;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.card_set_reauth
|
||||||
|
*/
|
||||||
|
static void card_set_reauth(private_sim_manager_t *this, identification_t *id,
|
||||||
|
identification_t *next, char mk[HASH_SIZE_SHA1],
|
||||||
|
u_int16_t counter)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_card_t *card;
|
||||||
|
|
||||||
|
enumerator = this->cards->create_enumerator(this->cards);
|
||||||
|
while (enumerator->enumerate(enumerator, &card))
|
||||||
|
{
|
||||||
|
card->set_reauth(card, id, next, mk, counter);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.card_get_reauth
|
||||||
|
*/
|
||||||
|
static identification_t* card_get_reauth(private_sim_manager_t *this,
|
||||||
|
identification_t *id, char mk[HASH_SIZE_SHA1],
|
||||||
|
u_int16_t *counter)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_card_t *card;
|
||||||
|
identification_t *reauth = NULL;
|
||||||
|
|
||||||
|
enumerator = this->cards->create_enumerator(this->cards);
|
||||||
|
while (enumerator->enumerate(enumerator, &card))
|
||||||
|
{
|
||||||
|
reauth = card->get_reauth(card, id, mk, counter);
|
||||||
|
if (reauth)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "using stored reauthentication identity '%Y' "
|
||||||
|
"instead of '%Y'", reauth, id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return reauth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of sim_manager_t.add_provider
|
* Implementation of sim_manager_t.add_provider
|
||||||
*/
|
*/
|
||||||
static void add_provider(private_sim_manager_t *this,
|
static void add_provider(private_sim_manager_t *this, sim_provider_t *provider)
|
||||||
sim_provider_t *provider)
|
|
||||||
{
|
{
|
||||||
this->provider->insert_last(this->provider, provider);
|
this->providers->insert_last(this->providers, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of sim_manager_t.remove_provider
|
* Implementation of sim_manager_t.remove_provider
|
||||||
*/
|
*/
|
||||||
static void remove_provider(private_sim_manager_t *this,
|
static void remove_provider(private_sim_manager_t *this,
|
||||||
sim_provider_t *provider)
|
sim_provider_t *provider)
|
||||||
{
|
{
|
||||||
this->provider->remove(this->provider, provider, NULL);
|
this->providers->remove(this->providers, provider, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of sim_manager_t.create_provider_enumerator
|
* Implementation of sim_manager_t.provider_get_triplet
|
||||||
*/
|
*/
|
||||||
static enumerator_t* create_provider_enumerator(private_sim_manager_t *this)
|
static bool provider_get_triplet(private_sim_manager_t *this,
|
||||||
|
identification_t *id, char rand[SIM_RAND_LEN],
|
||||||
|
char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
|
||||||
{
|
{
|
||||||
return this->provider->create_enumerator(this->provider);
|
enumerator_t *enumerator;
|
||||||
|
sim_provider_t *provider;
|
||||||
|
int tried = 0;
|
||||||
|
|
||||||
|
enumerator = this->providers->create_enumerator(this->providers);
|
||||||
|
while (enumerator->enumerate(enumerator, &provider))
|
||||||
|
{
|
||||||
|
if (provider->get_triplet(provider, id, rand, sres, kc))
|
||||||
|
{
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
tried++;
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%Y'",
|
||||||
|
tried, id);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.provider_get_quintuplet
|
||||||
|
*/
|
||||||
|
static bool provider_get_quintuplet(private_sim_manager_t *this,
|
||||||
|
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])
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_provider_t *provider;
|
||||||
|
int tried = 0;
|
||||||
|
|
||||||
|
enumerator = this->providers->create_enumerator(this->providers);
|
||||||
|
while (enumerator->enumerate(enumerator, &provider))
|
||||||
|
{
|
||||||
|
if (provider->get_quintuplet(provider, id, rand, xres, ck, ik, autn))
|
||||||
|
{
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
DBG1(DBG_IKE, "tried %d SIM providers, but none had a quintuplet for '%Y'",
|
||||||
|
tried, id);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.provider_resync
|
||||||
|
*/
|
||||||
|
static bool provider_resync(private_sim_manager_t *this, identification_t *id,
|
||||||
|
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_provider_t *provider;
|
||||||
|
|
||||||
|
enumerator = this->providers->create_enumerator(this->providers);
|
||||||
|
while (enumerator->enumerate(enumerator, &provider))
|
||||||
|
{
|
||||||
|
if (provider->resync(provider, id, rand, auts))
|
||||||
|
{
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.provider_is_pseudonym
|
||||||
|
*/
|
||||||
|
static identification_t* provider_is_pseudonym(private_sim_manager_t *this,
|
||||||
|
identification_t *id)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_provider_t *provider;
|
||||||
|
identification_t *permanent = NULL;
|
||||||
|
|
||||||
|
enumerator = this->providers->create_enumerator(this->providers);
|
||||||
|
while (enumerator->enumerate(enumerator, &provider))
|
||||||
|
{
|
||||||
|
permanent = provider->is_pseudonym(provider, id);
|
||||||
|
if (permanent)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.provider_gen_pseudonym
|
||||||
|
*/
|
||||||
|
static identification_t* provider_gen_pseudonym(private_sim_manager_t *this,
|
||||||
|
identification_t *id)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_provider_t *provider;
|
||||||
|
identification_t *pseudonym = NULL;
|
||||||
|
|
||||||
|
enumerator = this->providers->create_enumerator(this->providers);
|
||||||
|
while (enumerator->enumerate(enumerator, &provider))
|
||||||
|
{
|
||||||
|
pseudonym = provider->gen_pseudonym(provider, id);
|
||||||
|
if (pseudonym)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "proposing new pseudonym '%Y'", pseudonym);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return pseudonym;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.provider_is_reauth
|
||||||
|
*/
|
||||||
|
static identification_t* provider_is_reauth(private_sim_manager_t *this,
|
||||||
|
identification_t *id, char mk[HASH_SIZE_SHA1],
|
||||||
|
u_int16_t *counter)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_provider_t *provider;
|
||||||
|
identification_t *permanent = NULL;
|
||||||
|
|
||||||
|
enumerator = this->providers->create_enumerator(this->providers);
|
||||||
|
while (enumerator->enumerate(enumerator, &provider))
|
||||||
|
{
|
||||||
|
permanent = provider->is_reauth(provider, id, mk, counter);
|
||||||
|
if (permanent)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of sim_manager_t.provider_gen_reauth
|
||||||
|
*/
|
||||||
|
static identification_t* provider_gen_reauth(private_sim_manager_t *this,
|
||||||
|
identification_t *id, char mk[HASH_SIZE_SHA1])
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
sim_provider_t *provider;
|
||||||
|
identification_t *reauth = NULL;
|
||||||
|
|
||||||
|
enumerator = this->providers->create_enumerator(this->providers);
|
||||||
|
while (enumerator->enumerate(enumerator, &provider))
|
||||||
|
{
|
||||||
|
reauth = provider->gen_reauth(provider, id, mk);
|
||||||
|
if (reauth)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "proposing new reauthentication identity '%Y'", reauth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return reauth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +416,7 @@ static enumerator_t* create_provider_enumerator(private_sim_manager_t *this)
|
|||||||
static void destroy(private_sim_manager_t *this)
|
static void destroy(private_sim_manager_t *this)
|
||||||
{
|
{
|
||||||
this->cards->destroy(this->cards);
|
this->cards->destroy(this->cards);
|
||||||
this->provider->destroy(this->provider);
|
this->providers->destroy(this->providers);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,14 +429,26 @@ sim_manager_t *sim_manager_create()
|
|||||||
|
|
||||||
this->public.add_card = (void(*)(sim_manager_t*, sim_card_t *card))add_card;
|
this->public.add_card = (void(*)(sim_manager_t*, sim_card_t *card))add_card;
|
||||||
this->public.remove_card = (void(*)(sim_manager_t*, sim_card_t *card))remove_card;
|
this->public.remove_card = (void(*)(sim_manager_t*, sim_card_t *card))remove_card;
|
||||||
this->public.create_card_enumerator = (enumerator_t*(*)(sim_manager_t*))create_card_enumerator;
|
this->public.card_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))card_get_triplet;
|
||||||
|
this->public.card_get_quintuplet = (status_t(*)(sim_manager_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]))card_get_quintuplet;
|
||||||
|
this->public.card_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))card_resync;
|
||||||
|
this->public.card_set_pseudonym = (void(*)(sim_manager_t*, identification_t *id, identification_t *pseudonym))card_set_pseudonym;
|
||||||
|
this->public.card_get_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))card_get_pseudonym;
|
||||||
|
this->public.card_set_reauth = (void(*)(sim_manager_t*, identification_t *id, identification_t *next, char mk[HASH_SIZE_SHA1], u_int16_t counter))card_set_reauth;
|
||||||
|
this->public.card_get_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))card_get_reauth;
|
||||||
this->public.add_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))add_provider;
|
this->public.add_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))add_provider;
|
||||||
this->public.remove_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))remove_provider;
|
this->public.remove_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))remove_provider;
|
||||||
this->public.create_provider_enumerator = (enumerator_t*(*)(sim_manager_t*))create_provider_enumerator;
|
this->public.provider_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))provider_get_triplet;
|
||||||
|
this->public.provider_get_quintuplet = (bool(*)(sim_manager_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]))provider_get_quintuplet;
|
||||||
|
this->public.provider_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))provider_resync;
|
||||||
|
this->public.provider_is_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_is_pseudonym;
|
||||||
|
this->public.provider_gen_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_gen_pseudonym;
|
||||||
|
this->public.provider_is_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))provider_is_reauth;
|
||||||
|
this->public.provider_gen_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))provider_gen_reauth;
|
||||||
this->public.destroy = (void(*)(sim_manager_t*))destroy;
|
this->public.destroy = (void(*)(sim_manager_t*))destroy;
|
||||||
|
|
||||||
this->cards = linked_list_create();
|
this->cards = linked_list_create();
|
||||||
this->provider = linked_list_create();
|
this->providers = linked_list_create();
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ struct sim_card_t {
|
|||||||
* @param id permanent identity of the peer
|
* @param id permanent identity of the peer
|
||||||
* @param mk buffer receiving master key MK
|
* @param mk buffer receiving master key MK
|
||||||
* @param counter pointer receiving counter value, in host order
|
* @param counter pointer receiving counter value, in host order
|
||||||
|
* @return fast reauthentication identity, NULL if not found
|
||||||
*/
|
*/
|
||||||
identification_t* (*get_reauth)(sim_card_t *this, identification_t *id,
|
identification_t* (*get_reauth)(sim_card_t *this, identification_t *id,
|
||||||
char mk[HASH_SIZE_SHA1], u_int16_t *counter);
|
char mk[HASH_SIZE_SHA1], u_int16_t *counter);
|
||||||
@@ -244,11 +245,86 @@ struct sim_manager_t {
|
|||||||
void (*remove_card)(sim_manager_t *this, sim_card_t *card);
|
void (*remove_card)(sim_manager_t *this, sim_card_t *card);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an enumerator over all registered cards.
|
* Calculate SIM triplets on one of the registered SIM cards.
|
||||||
*
|
*
|
||||||
* @return enumerator over sim_card_t's
|
* @param id permanent identity to get a triplet for
|
||||||
|
* @param rand RAND input buffer, fixed size 16 bytes
|
||||||
|
* @param sres SRES output buffer, fixed size 4 byte
|
||||||
|
* @param kc KC output buffer, fixed size 8 bytes
|
||||||
|
* @return TRUE if calculated, FALSE if no matching card found
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_card_enumerator)(sim_manager_t *this);
|
bool (*card_get_triplet)(sim_manager_t *this, identification_t *id,
|
||||||
|
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
|
||||||
|
char kc[SIM_KC_LEN]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate AKA quitpulets on one of the registered SIM cards.
|
||||||
|
*
|
||||||
|
* @param id permanent identity to request quintuplet for
|
||||||
|
* @param rand random value rand
|
||||||
|
* @param autn authentication token autn
|
||||||
|
* @param ck buffer receiving encryption key ck
|
||||||
|
* @param ik buffer receiving integrity key ik
|
||||||
|
* @param res buffer receiving authentication result res
|
||||||
|
* @return SUCCESS, FAILED, or INVALID_STATE if out of sync
|
||||||
|
*/
|
||||||
|
status_t (*card_get_quintuplet)(sim_manager_t *this, 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]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate resynchronization data on one of the registered SIM cards.
|
||||||
|
*
|
||||||
|
* @param id permanent identity to request quintuplet for
|
||||||
|
* @param rand random value rand
|
||||||
|
* @param auts resynchronization parameter auts
|
||||||
|
* @return TRUE if calculated, FALSE if no matcing card found
|
||||||
|
*/
|
||||||
|
bool (*card_resync)(sim_manager_t *this, identification_t *id,
|
||||||
|
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a received pseudonym on one of the registered SIM cards.
|
||||||
|
*
|
||||||
|
* @param id permanent identity of the peer
|
||||||
|
* @param pseudonym pseudonym identity received from the server
|
||||||
|
*/
|
||||||
|
void (*card_set_pseudonym)(sim_manager_t *this, identification_t *id,
|
||||||
|
identification_t *pseudonym);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a stored pseudonym from one of the registerd SIM cards.
|
||||||
|
*
|
||||||
|
* @param id permanent identity of the peer
|
||||||
|
* @return associated pseudonym identity, NULL if none found
|
||||||
|
*/
|
||||||
|
identification_t* (*card_get_pseudonym)(sim_manager_t *this,
|
||||||
|
identification_t *id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store fast reauthentication parameters on one of the registered cards.
|
||||||
|
*
|
||||||
|
* @param id permanent identity of the peer
|
||||||
|
* @param next next fast reauthentication identity to use
|
||||||
|
* @param mk master key MK to store for reauthentication
|
||||||
|
* @param counter counter value to store, host order
|
||||||
|
*/
|
||||||
|
void (*card_set_reauth)(sim_manager_t *this, identification_t *id,
|
||||||
|
identification_t *next, char mk[HASH_SIZE_SHA1],
|
||||||
|
u_int16_t counter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve fast reauthentication parameters from one of the registerd cards.
|
||||||
|
*
|
||||||
|
* @param id permanent identity of the peer
|
||||||
|
* @param mk buffer receiving master key MK
|
||||||
|
* @param counter pointer receiving counter value, in host order
|
||||||
|
* @return fast reauthentication identity, NULL if none found
|
||||||
|
*/
|
||||||
|
identification_t* (*card_get_reauth)(sim_manager_t *this,
|
||||||
|
identification_t *id, char mk[HASH_SIZE_SHA1],
|
||||||
|
u_int16_t *counter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a triplet provider (server) at the manager.
|
* Register a triplet provider (server) at the manager.
|
||||||
@@ -265,11 +341,84 @@ struct sim_manager_t {
|
|||||||
void (*remove_provider)(sim_manager_t *this, sim_provider_t *provider);
|
void (*remove_provider)(sim_manager_t *this, sim_provider_t *provider);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an enumerator over all registered provider.
|
* Get a SIM triplet from one of the registered providers.
|
||||||
*
|
*
|
||||||
* @return enumerator over sim_provider_t's
|
* @param id permanent identity of peer to gen triplet for
|
||||||
|
* @param rand RAND output buffer, fixed size 16 bytes
|
||||||
|
* @param sres SRES output buffer, fixed size 4 byte
|
||||||
|
* @param kc KC output buffer, fixed size 8 bytes
|
||||||
|
* @return TRUE if triplet received, FALSE if no match found
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_provider_enumerator)(sim_manager_t *this);
|
bool (*provider_get_triplet)(sim_manager_t *this, identification_t *id,
|
||||||
|
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
|
||||||
|
char kc[SIM_KC_LEN]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a AKA quintuplet from one of the registered providers.
|
||||||
|
*
|
||||||
|
* @param id permanent identity of peer to create challenge for
|
||||||
|
* @param rand buffer receiving random value rand
|
||||||
|
* @param xres buffer receiving expected authentication result xres
|
||||||
|
* @param ck buffer receiving encryption key ck
|
||||||
|
* @param ik buffer receiving integrity key ik
|
||||||
|
* @param autn authentication token autn
|
||||||
|
* @return TRUE if quintuplet received, FALSE if no match found
|
||||||
|
*/
|
||||||
|
bool (*provider_get_quintuplet)(sim_manager_t *this, 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]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass AKA resynchronization data to one of the registered providers.
|
||||||
|
*
|
||||||
|
* @param id permanent identity of peer requesting resynchronisation
|
||||||
|
* @param rand random value rand
|
||||||
|
* @param auts synchronization parameter auts
|
||||||
|
* @return TRUE if resynchronized, FALSE if not handled
|
||||||
|
*/
|
||||||
|
bool (*provider_resync)(sim_manager_t *this, identification_t *id,
|
||||||
|
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a peer uses a pseudonym using one of the registered providers.
|
||||||
|
*
|
||||||
|
* @param id pseudonym identity candidate
|
||||||
|
* @return permanent identity, NULL if id not a pseudonym
|
||||||
|
*/
|
||||||
|
identification_t* (*provider_is_pseudonym)(sim_manager_t *this,
|
||||||
|
identification_t *id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a new pseudonym using one of the registered providers.
|
||||||
|
*
|
||||||
|
* @param id permanent identity to generate a pseudonym for
|
||||||
|
* @return generated pseudonym, NULL to not use a pseudonym identity
|
||||||
|
*/
|
||||||
|
identification_t* (*provider_gen_pseudonym)(sim_manager_t *this,
|
||||||
|
identification_t *id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a peer uses a reauth id using one of the registered providers.
|
||||||
|
*
|
||||||
|
* @param id reauthentication identity (candidate)
|
||||||
|
* @param mk buffer receiving master key MK
|
||||||
|
* @param counter pointer receiving current counter value, host order
|
||||||
|
* @return permanent identity, NULL if not a known reauth identity
|
||||||
|
*/
|
||||||
|
identification_t* (*provider_is_reauth)(sim_manager_t *this,
|
||||||
|
identification_t *id, char mk[HASH_SIZE_SHA1],
|
||||||
|
u_int16_t *counter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a fast reauth id using one of the registered providers.
|
||||||
|
*
|
||||||
|
* @param id permanent peer identity
|
||||||
|
* @param mk master key to store along with generated identity
|
||||||
|
* @return fast reauthentication identity, NULL to not use reauth
|
||||||
|
*/
|
||||||
|
identification_t* (*provider_gen_reauth)(sim_manager_t *this,
|
||||||
|
identification_t *id, char mk[HASH_SIZE_SHA1]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a manager instance.
|
* Destroy a manager instance.
|
||||||
|
|||||||
Reference in New Issue
Block a user