Migrated all SIM/AKA code to libsimaka, use SIM and AKA backend managers registered by name

This commit is contained in:
Martin Willi
2011-08-08 13:36:56 +02:00
parent 4c199e6f81
commit efee3ed80f
62 changed files with 674 additions and 440 deletions
-3
View File
@@ -63,9 +63,6 @@ sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \
sa/authenticators/eap/sim_manager.c sa/authenticators/eap/sim_manager.h \
sa/authenticators/eap/sim_card.h sa/authenticators/eap/sim_provider.h \
sa/authenticators/eap/sim_hooks.h \
sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \
sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \
sa/child_sa.c sa/child_sa.h \
+1 -4
View File
@@ -61,9 +61,6 @@ sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \
sa/authenticators/eap/sim_manager.c sa/authenticators/eap/sim_manager.h \
sa/authenticators/eap/sim_card.h sa/authenticators/eap/sim_provider.h \
sa/authenticators/eap/sim_hooks.h \
sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \
sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \
sa/child_sa.c sa/child_sa.h \
@@ -104,7 +101,7 @@ INCLUDES = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon \
-I$(top_srcdir)/src/libtncif
-I$(top_srcdir)/src/libtncif
AM_CFLAGS = \
-DIPSEC_DIR=\"${ipsecdir}\" \
-2
View File
@@ -119,7 +119,6 @@ static void destroy(private_daemon_t *this)
DESTROY_IF(this->public.ike_sa_manager);
DESTROY_IF(this->public.controller);
DESTROY_IF(this->public.eap);
DESTROY_IF(this->public.sim);
DESTROY_IF(this->public.tnccs);
#ifdef ME
DESTROY_IF(this->public.connect_manager);
@@ -290,7 +289,6 @@ private_daemon_t *daemon_create()
charon = &this->public;
this->public.controller = controller_create();
this->public.eap = eap_manager_create();
this->public.sim = sim_manager_create();
this->public.tnccs = tnccs_manager_create();
this->public.backends = backend_manager_create();
this->public.socket = socket_manager_create();
-6
View File
@@ -152,7 +152,6 @@ typedef struct daemon_t daemon_t;
#include <sa/shunt_manager.h>
#include <config/backend_manager.h>
#include <sa/authenticators/eap/eap_manager.h>
#include <sa/authenticators/eap/sim_manager.h>
#include <tnc/imc/imc_manager.h>
#include <tnc/imv/imv_manager.h>
#include <tnc/tnccs/tnccs_manager.h>
@@ -242,11 +241,6 @@ struct daemon_t {
*/
eap_manager_t *eap;
/**
* SIM manager to maintain (U)SIM cards/providers
*/
sim_manager_t *sim;
/**
* TNC IMC manager controlling Integrity Measurement Collectors
*/
+29 -19
View File
@@ -20,6 +20,7 @@
#include <simaka_message.h>
#include <simaka_crypto.h>
#include <simaka_manager.h>
typedef struct private_eap_aka_peer_t private_eap_aka_peer_t;
@@ -33,6 +34,11 @@ struct private_eap_aka_peer_t {
*/
eap_aka_peer_t public;
/**
* AKA backend manager
*/
simaka_manager_t *mgr;
/**
* EAP-AKA crypto helper
*/
@@ -91,7 +97,7 @@ static eap_payload_t* create_client_error(private_eap_aka_peer_t *this)
encoded = htons(AKA_UNABLE_TO_PROCESS);
message->add_attribute(message, AT_CLIENT_ERROR_CODE,
chunk_create((char*)&encoded, sizeof(encoded)));
out = message->generate(message, chunk_empty);
out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return out;
}
@@ -140,7 +146,7 @@ static status_t process_identity(private_eap_aka_peer_t *this,
switch (id_req)
{
case AT_ANY_ID_REQ:
this->reauth = charon->sim->card_get_reauth(charon->sim,
this->reauth = this->mgr->card_get_reauth(this->mgr,
this->permanent, this->mk, &this->counter);
if (this->reauth)
{
@@ -149,8 +155,8 @@ static status_t process_identity(private_eap_aka_peer_t *this,
}
/* FALL */
case AT_FULLAUTH_ID_REQ:
this->pseudonym = charon->sim->card_get_pseudonym(charon->sim,
this->permanent);
this->pseudonym = this->mgr->card_get_pseudonym(this->mgr,
this->permanent);
if (this->pseudonym)
{
id = this->pseudonym->get_encoding(this->pseudonym);
@@ -169,7 +175,7 @@ static status_t process_identity(private_eap_aka_peer_t *this,
{
message->add_attribute(message, AT_IDENTITY, id);
}
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return NEED_MORE;
@@ -220,10 +226,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
return NEED_MORE;
}
status = charon->sim->card_get_quintuplet(charon->sim, this->permanent,
status = this->mgr->card_get_quintuplet(this->mgr, this->permanent,
rand.ptr, autn.ptr, ck, ik, res, &res_len);
if (status == INVALID_STATE &&
charon->sim->card_resync(charon->sim, this->permanent, rand.ptr, auts))
this->mgr->card_resync(this->mgr, this->permanent, rand.ptr, auts))
{
DBG1(DBG_IKE, "received SQN invalid, sending %N",
simaka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
@@ -231,7 +237,8 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
AKA_SYNCHRONIZATION_FAILURE, this->crypto);
message->add_attribute(message, AT_AUTS,
chunk_create(auts, AKA_AUTS_LEN));
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message,
chunk_empty));
message->destroy(message);
return NEED_MORE;
}
@@ -241,7 +248,8 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
this->permanent, simaka_subtype_names, AKA_AUTHENTICATION_REJECT);
message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
AKA_AUTHENTICATION_REJECT, this->crypto);
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message,
chunk_empty));
message->destroy(message);
return NEED_MORE;
}
@@ -274,13 +282,13 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
case AT_NEXT_REAUTH_ID:
this->counter = 0;
id = identification_create_from_data(data);
charon->sim->card_set_reauth(charon->sim, this->permanent, id,
this->mk, this->counter);
this->mgr->card_set_reauth(this->mgr, this->permanent, id,
this->mk, this->counter);
id->destroy(id);
break;
case AT_NEXT_PSEUDONYM:
id = identification_create_from_data(data);
charon->sim->card_set_pseudonym(charon->sim, this->permanent, id);
this->mgr->card_set_pseudonym(this->mgr, this->permanent, id);
id->destroy(id);
break;
default:
@@ -292,7 +300,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RES, chunk_create(res, res_len));
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return NEED_MORE;
}
@@ -389,13 +397,13 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
identification_t *reauth;
reauth = identification_create_from_data(data);
charon->sim->card_set_reauth(charon->sim, this->permanent, reauth,
this->mk, this->counter);
this->mgr->card_set_reauth(this->mgr, this->permanent, reauth,
this->mk, this->counter);
reauth->destroy(reauth);
}
}
message->add_attribute(message, AT_COUNTER, counter);
*out = message->generate(message, nonce);
*out = eap_payload_create_data_own(message->generate(message, nonce));
message->destroy(message);
return NEED_MORE;
}
@@ -446,7 +454,8 @@ static status_t process_notification(private_eap_aka_peer_t *this,
{ /* empty notification reply */
message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_NOTIFICATION, this->crypto);
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message,
chunk_empty));
message->destroy(message);
}
else
@@ -466,7 +475,7 @@ METHOD(eap_method_t, process, status_t,
/* store received EAP message identifier */
this->identifier = in->get_identifier(in);
message = simaka_message_create_from_payload(in, this->crypto);
message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
*out = create_client_error(this);
@@ -578,7 +587,8 @@ eap_aka_peer_t *eap_aka_peer_create(identification_t *server,
.destroy = _destroy,
},
},
.crypto = simaka_crypto_create(),
.crypto = simaka_crypto_create(EAP_AKA),
.mgr = lib->get(lib, "aka-manager"),
);
if (!this->crypto)
+1 -1
View File
@@ -26,7 +26,7 @@ typedef struct eap_aka_peer_t eap_aka_peer_t;
#include <sa/authenticators/eap/eap_method.h>
/**
* Implementation of the eap_method_t interface using EAP-AKA as a client.
* EAP-AKA peer implementation.
*/
struct eap_aka_peer_t {
+33 -9
View File
@@ -19,20 +19,41 @@
#include "eap_aka_server.h"
#include <daemon.h>
#include <simaka_manager.h>
typedef struct private_eap_aka_plugin_t private_eap_aka_plugin_t;
/**
* Private data of an eap_sim_plugin_t object.
*/
struct private_eap_aka_plugin_t {
/**
* Public interface.
*/
eap_aka_plugin_t public;
/**
* EAP-AKA backend manager
*/
simaka_manager_t *mgr;
};
METHOD(plugin_t, get_name, char*,
eap_aka_plugin_t *this)
private_eap_aka_plugin_t *this)
{
return "eap-aka";
}
METHOD(plugin_t, destroy, void,
eap_aka_plugin_t *this)
private_eap_aka_plugin_t *this)
{
lib->set(lib, "aka-manager", NULL);
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_aka_server_create);
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_aka_peer_create);
this->mgr->destroy(this->mgr);
free(this);
}
@@ -41,21 +62,24 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *eap_aka_plugin_create()
{
eap_aka_plugin_t *this;
private_eap_aka_plugin_t *this;
INIT(this,
.plugin = {
.get_name = _get_name,
.reload = (void*)return_false,
.destroy = _destroy,
.public = {
.plugin = {
.get_name = _get_name,
.reload = (void*)return_false,
.destroy = _destroy,
},
},
.mgr = simaka_manager_create(),
);
charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_SERVER,
(eap_constructor_t)eap_aka_server_create);
charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_PEER,
(eap_constructor_t)eap_aka_peer_create);
lib->set(lib, "aka-manager", this->mgr);
return &this->plugin;
return &this->public.plugin;
}
@@ -33,6 +33,11 @@ typedef struct eap_aka_plugin_t eap_aka_plugin_t;
*
* EAP-AKA uses 3rd generation mobile phone standard authentication
* mechanism for authentication, as defined RFC4187.
*
* This plugin implements the protocol level of EAP-AKA and uses simaka_card_t
* and simaka_provider_t backends to provide triplets. It registers a
* simaka_manager_t on the library as "aka-manager", other plugins can use it
* to provide the required backends.
*/
struct eap_aka_plugin_t {
+20 -14
View File
@@ -20,6 +20,7 @@
#include <simaka_message.h>
#include <simaka_crypto.h>
#include <simaka_manager.h>
/** length of the AT_NONCE_S value */
#define NONCE_LEN 16
@@ -36,6 +37,11 @@ struct private_eap_aka_server_t {
*/
eap_aka_server_t public;
/**
* AKA backend manager
*/
simaka_manager_t *mgr;
/**
* EAP-AKA crypto helper
*/
@@ -133,7 +139,7 @@ static status_t identity(private_eap_aka_server_t *this, eap_payload_t **out)
{
message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty);
}
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = AKA_IDENTITY;
@@ -152,7 +158,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
chunk_t data, mk;
identification_t *id;
if (!charon->sim->provider_get_quintuplet(charon->sim, this->permanent,
if (!this->mgr->provider_get_quintuplet(this->mgr, this->permanent,
rand, xres, &xres_len, ck, ik, autn))
{
if (this->use_pseudonym)
@@ -183,7 +189,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
AKA_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RAND, this->rand);
message->add_attribute(message, AT_AUTN, chunk_create(autn, AKA_AUTN_LEN));
id = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk.ptr);
id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr);
if (id)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
@@ -192,7 +198,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
}
else
{
id = charon->sim->provider_gen_pseudonym(charon->sim, this->permanent);
id = this->mgr->provider_gen_pseudonym(this->mgr, this->permanent);
if (id)
{
message->add_attribute(message, AT_NEXT_PSEUDONYM,
@@ -200,7 +206,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
id->destroy(id);
}
}
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
free(mk.ptr);
@@ -237,14 +243,14 @@ static status_t reauthenticate(private_eap_aka_server_t *this,
AKA_REAUTHENTICATION, this->crypto);
message->add_attribute(message, AT_COUNTER, this->counter);
message->add_attribute(message, AT_NONCE_S, this->nonce);
next = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk);
next = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk);
if (next)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
next->get_encoding(next));
next->destroy(next);
}
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = SIM_REAUTHENTICATION;
@@ -310,8 +316,7 @@ static status_t process_identity(private_eap_aka_server_t *this,
char mk[HASH_SIZE_SHA1];
u_int16_t counter;
permanent = charon->sim->provider_is_reauth(charon->sim, id,
mk, &counter);
permanent = this->mgr->provider_is_reauth(this->mgr, id, mk, &counter);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -325,7 +330,7 @@ static status_t process_identity(private_eap_aka_server_t *this,
}
if (this->use_pseudonym)
{
permanent = charon->sim->provider_is_pseudonym(charon->sim, id);
permanent = this->mgr->provider_is_pseudonym(this->mgr, id);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -506,8 +511,8 @@ static status_t process_synchronize(private_eap_aka_server_t *this,
return FAILED;
}
if (!charon->sim->provider_resync(charon->sim, this->permanent,
this->rand.ptr, auts.ptr))
if (!this->mgr->provider_resync(this->mgr, this->permanent,
this->rand.ptr, auts.ptr))
{
DBG1(DBG_IKE, "no AKA provider found supporting "
"resynchronization for '%Y'", this->permanent);
@@ -564,7 +569,7 @@ METHOD(eap_method_t, process, status_t,
simaka_message_t *message;
status_t status;
message = simaka_message_create_from_payload(in, this->crypto);
message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
return FAILED;
@@ -676,7 +681,8 @@ eap_aka_server_t *eap_aka_server_create(identification_t *server,
.destroy = _destroy,
},
},
.crypto = simaka_crypto_create(),
.crypto = simaka_crypto_create(EAP_AKA),
.mgr = lib->get(lib, "aka-manager"),
);
if (!this->crypto)
@@ -26,7 +26,7 @@ typedef struct eap_aka_server_t eap_aka_server_t;
#include <sa/authenticators/eap/eap_method.h>
/**
* Implementation of the eap_method_t interface using EAP-AKA as server.
* EAP-AKA server implementation.
*/
struct eap_aka_server_t {
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
@@ -52,7 +52,7 @@ bool eap_aka_3gpp2_get_k(identification_t *id, char k[AKA_K_LEN]);
void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset);
/**
* Implementation of sim_card_t.get_quintuplet
* Implementation of simaka_card_t.get_quintuplet
*/
static status_t get_quintuplet(private_eap_aka_3gpp2_card_t *this,
identification_t *id, char rand[AKA_RAND_LEN],
@@ -113,7 +113,7 @@ static status_t get_quintuplet(private_eap_aka_3gpp2_card_t *this,
}
/**
* Implementation of sim_card_t.resync
* Implementation of simaka_card_t.resync
*/
static bool resync(private_eap_aka_3gpp2_card_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
@@ -153,13 +153,13 @@ eap_aka_3gpp2_card_t *eap_aka_3gpp2_card_create(eap_aka_3gpp2_functions_t *f)
{
private_eap_aka_3gpp2_card_t *this = malloc_thing(private_eap_aka_3gpp2_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_MAX], int *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]))resync;
this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *id))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.card.get_triplet = (bool(*)(simaka_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(*)(simaka_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_MAX], int *res_len))get_quintuplet;
this->public.card.resync = (bool(*)(simaka_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync;
this->public.card.get_pseudonym = (identification_t*(*)(simaka_card_t*, identification_t *id))return_null;
this->public.card.set_pseudonym = (void(*)(simaka_card_t*, identification_t *id, identification_t *pseudonym))nop;
this->public.card.get_reauth = (identification_t*(*)(simaka_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null;
this->public.card.set_reauth = (void(*)(simaka_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop;
this->public.destroy = (void(*)(eap_aka_3gpp2_card_t*))destroy;
this->f = f;
@@ -23,7 +23,7 @@
#include "eap_aka_3gpp2_functions.h"
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_card.h>
typedef struct eap_aka_3gpp2_card_t eap_aka_3gpp2_card_t;
@@ -33,9 +33,9 @@ typedef struct eap_aka_3gpp2_card_t eap_aka_3gpp2_card_t;
struct eap_aka_3gpp2_card_t {
/**
* Implements sim_card_t interface
* Implements simaka_card_t interface
*/
sim_card_t card;
simaka_card_t card;
/**
* Destroy a eap_aka_3gpp2_card_t.
@@ -21,7 +21,7 @@
#ifndef EAP_AKA_3GPP2_FUNCTIONS_H_
#define EAP_AKA_3GPP2_FUNCTIONS_H_
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_manager.h>
#define AKA_SQN_LEN 6
#define AKA_K_LEN 16
@@ -57,8 +57,14 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_eap_aka_3gpp2_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
simaka_manager_t *mgr;
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
this->card->destroy(this->card);
this->provider->destroy(this->provider);
this->functions->destroy(this->functions);
@@ -71,6 +77,7 @@ METHOD(plugin_t, destroy, void,
plugin_t *eap_aka_3gpp2_plugin_create()
{
private_eap_aka_3gpp2_t *this;
simaka_manager_t *mgr;
INIT(this,
.public = {
@@ -91,9 +98,12 @@ plugin_t *eap_aka_3gpp2_plugin_create()
this->card = eap_aka_3gpp2_card_create(this->functions);
this->provider = eap_aka_3gpp2_provider_create(this->functions);
charon->sim->add_card(charon->sim, &this->card->card);
charon->sim->add_provider(charon->sim, &this->provider->provider);
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
return &this->public.plugin;
}
@@ -81,7 +81,7 @@ void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset)
}
/**
* Implementation of usim_provider_t.get_quintuplet
* Implementation of simaka_provider_t.get_quintuplet
*/
static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this,
identification_t *id, char rand[AKA_RAND_LEN],
@@ -132,7 +132,7 @@ static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this,
}
/**
* Implementation of usim_provider_t.resync
* Implementation of simaka_provider_t.resync
*/
static bool resync(private_eap_aka_3gpp2_provider_t *this,
identification_t *id, char rand[AKA_RAND_LEN],
@@ -185,13 +185,13 @@ eap_aka_3gpp2_provider_t *eap_aka_3gpp2_provider_create(
{
private_eap_aka_3gpp2_provider_t *this = malloc_thing(private_eap_aka_3gpp2_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_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))get_quintuplet;
this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync;
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.provider.get_triplet = (bool(*)(simaka_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(*)(simaka_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))get_quintuplet;
this->public.provider.resync = (bool(*)(simaka_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync;
this->public.provider.is_pseudonym = (identification_t*(*)(simaka_provider_t*, identification_t *id))return_null;
this->public.provider.gen_pseudonym = (identification_t*(*)(simaka_provider_t*, identification_t *id))return_null;
this->public.provider.is_reauth = (identification_t*(*)(simaka_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null;
this->public.provider.gen_reauth = (identification_t*(*)(simaka_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null;
this->public.destroy = (void(*)(eap_aka_3gpp2_provider_t*))destroy;
this->f = f;
@@ -23,7 +23,7 @@
#include "eap_aka_3gpp2_functions.h"
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_provider.h>
typedef struct eap_aka_3gpp2_provider_t eap_aka_3gpp2_provider_t;
@@ -33,9 +33,9 @@ typedef struct eap_aka_3gpp2_provider_t eap_aka_3gpp2_provider_t;
struct eap_aka_3gpp2_provider_t {
/**
* Implements sim_provider_t interface.
* Implements simaka_provider_t interface.
*/
sim_provider_t provider;
simaka_provider_t provider;
/**
* Destroy a eap_aka_3gpp2_provider_t.
+25 -17
View File
@@ -18,6 +18,7 @@
#include <daemon.h>
#include <simaka_message.h>
#include <simaka_manager.h>
/* number of tries we do authenticate */
#define MAX_TRIES 3
@@ -40,6 +41,11 @@ struct private_eap_sim_peer_t {
*/
eap_sim_peer_t public;
/**
* SIM backend manager
*/
simaka_manager_t *mgr;
/**
* permanent ID of peer
*/
@@ -116,7 +122,7 @@ static eap_payload_t* create_client_error(private_eap_sim_peer_t *this,
encoded = htons(code);
message->add_attribute(message, AT_CLIENT_ERROR_CODE,
chunk_create((char*)&encoded, sizeof(encoded)));
out = message->generate(message, chunk_empty);
out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return out;
}
@@ -188,7 +194,7 @@ static status_t process_start(private_eap_sim_peer_t *this,
switch (id_req)
{
case AT_ANY_ID_REQ:
this->reauth = charon->sim->card_get_reauth(charon->sim,
this->reauth = this->mgr->card_get_reauth(this->mgr,
this->permanent, this->mk, &this->counter);
if (this->reauth)
{
@@ -197,8 +203,8 @@ static status_t process_start(private_eap_sim_peer_t *this,
}
/* FALL */
case AT_FULLAUTH_ID_REQ:
this->pseudonym = charon->sim->card_get_pseudonym(charon->sim,
this->permanent);
this->pseudonym = this->mgr->card_get_pseudonym(this->mgr,
this->permanent);
if (this->pseudonym)
{
id = this->pseudonym->get_encoding(this->pseudonym);
@@ -228,7 +234,7 @@ static status_t process_start(private_eap_sim_peer_t *this,
{
message->add_attribute(message, AT_IDENTITY, id);
}
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return NEED_MORE;
@@ -287,8 +293,8 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
sreses = sres = chunk_alloca(rands.len / 4);
while (rands.len >= SIM_RAND_LEN)
{
if (!charon->sim->card_get_triplet(charon->sim, this->permanent,
rands.ptr, sres.ptr, kc.ptr))
if (!this->mgr->card_get_triplet(this->mgr, this->permanent,
rands.ptr, sres.ptr, kc.ptr))
{
DBG1(DBG_IKE, "unable to get EAP-SIM triplet");
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
@@ -328,13 +334,13 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
case AT_NEXT_REAUTH_ID:
this->counter = 0;
id = identification_create_from_data(data);
charon->sim->card_set_reauth(charon->sim, this->permanent, id,
this->mk, this->counter);
this->mgr->card_set_reauth(this->mgr, this->permanent, id,
this->mk, this->counter);
id->destroy(id);
break;
case AT_NEXT_PSEUDONYM:
id = identification_create_from_data(data);
charon->sim->card_set_pseudonym(charon->sim, this->permanent, id);
this->mgr->card_set_pseudonym(this->mgr, this->permanent, id);
id->destroy(id);
break;
default:
@@ -346,7 +352,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
/* build response with AT_MAC, built over "EAP packet | n*SRES" */
message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_CHALLENGE, this->crypto);
*out = message->generate(message, sreses);
*out = eap_payload_create_data_own(message->generate(message, sreses));
message->destroy(message);
return NEED_MORE;
}
@@ -443,13 +449,13 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
identification_t *reauth;
reauth = identification_create_from_data(data);
charon->sim->card_set_reauth(charon->sim, this->permanent, reauth,
this->mk, this->counter);
this->mgr->card_set_reauth(this->mgr, this->permanent, reauth,
this->mk, this->counter);
reauth->destroy(reauth);
}
}
message->add_attribute(message, AT_COUNTER, counter);
*out = message->generate(message, nonce);
*out = eap_payload_create_data_own(message->generate(message, nonce));
message->destroy(message);
return NEED_MORE;
}
@@ -500,7 +506,8 @@ static status_t process_notification(private_eap_sim_peer_t *this,
{ /* empty notification reply */
message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_NOTIFICATION, this->crypto);
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message,
chunk_empty));
message->destroy(message);
}
else
@@ -519,7 +526,7 @@ METHOD(eap_method_t, process, status_t,
/* store received EAP message identifier */
this->identifier = in->get_identifier(in);
message = simaka_message_create_from_payload(in, this->crypto);
message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
@@ -633,7 +640,8 @@ eap_sim_peer_t *eap_sim_peer_create(identification_t *server,
.destroy = _destroy,
},
},
.crypto = simaka_crypto_create(),
.crypto = simaka_crypto_create(EAP_SIM),
.mgr = lib->get(lib, "sim-manager"),
);
if (!this->crypto)
@@ -27,9 +27,6 @@ typedef struct eap_sim_peer_t eap_sim_peer_t;
/**
* EAP-SIM peer implementation.
*
* This EAP-SIM module uses sim_card_t implementations for triplet calculation,
* found via the eap_sim_manager_t.
*/
struct eap_sim_peer_t {
+33 -8
View File
@@ -19,20 +19,41 @@
#include "eap_sim_peer.h"
#include <daemon.h>
#include <simaka_manager.h>
typedef struct private_eap_sim_plugin_t private_eap_sim_plugin_t;
/**
* Private data of an eap_sim_plugin_t object.
*/
struct private_eap_sim_plugin_t {
/**
* Public interface.
*/
eap_sim_plugin_t public;
/**
* EAP-SIM backend manager
*/
simaka_manager_t *mgr;
};
METHOD(plugin_t, get_name, char*,
eap_sim_plugin_t *this)
private_eap_sim_plugin_t *this)
{
return "eap-sim";
}
METHOD(plugin_t, destroy, void,
eap_sim_plugin_t *this)
private_eap_sim_plugin_t *this)
{
lib->set(lib, "sim-manager", NULL);
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_sim_server_create);
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_sim_peer_create);
this->mgr->destroy(this->mgr);
free(this);
}
@@ -41,21 +62,25 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *eap_sim_plugin_create()
{
eap_sim_plugin_t *this;
private_eap_sim_plugin_t *this;
INIT(this,
.plugin = {
.get_name = _get_name,
.reload = (void*)return_false,
.destroy = _destroy,
.public = {
.plugin = {
.get_name = _get_name,
.reload = (void*)return_false,
.destroy = _destroy,
},
},
.mgr = simaka_manager_create(),
);
charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_SERVER,
(eap_constructor_t)eap_sim_server_create);
charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_PEER,
(eap_constructor_t)eap_sim_peer_create);
lib->set(lib, "sim-manager", this->mgr);
return &this->plugin;
return &this->public.plugin;
}
@@ -30,6 +30,11 @@ typedef struct eap_sim_plugin_t eap_sim_plugin_t;
/**
* EAP-SIM plugin.
*
* This plugin implements the protocol level of EAP-SIM and uses simaka_card_t
* and simaka_provider_t backends to provide triplets. It registers a
* simaka_manager_t on the library as "sim-manager", other plugins can use it
* to provide the required backends.
*/
struct eap_sim_plugin_t {
+20 -13
View File
@@ -19,6 +19,7 @@
#include <simaka_message.h>
#include <simaka_crypto.h>
#include <simaka_manager.h>
/* number of triplets for one authentication */
#define TRIPLET_COUNT 3
@@ -38,6 +39,11 @@ struct private_eap_sim_server_t {
*/
eap_sim_server_t public;
/**
* SIM backend manager
*/
simaka_manager_t *mgr;
/**
* permanent ID of peer
*/
@@ -127,7 +133,7 @@ METHOD(eap_method_t, initiate, status_t,
{
message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty);
}
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = SIM_START;
@@ -163,14 +169,14 @@ static status_t reauthenticate(private_eap_sim_server_t *this,
SIM_REAUTHENTICATION, this->crypto);
message->add_attribute(message, AT_COUNTER, this->counter);
message->add_attribute(message, AT_NONCE_S, this->nonce);
next = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk);
next = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk);
if (next)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
next->get_encoding(next));
next->destroy(next);
}
*out = message->generate(message, chunk_empty);
*out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = SIM_REAUTHENTICATION;
@@ -298,8 +304,8 @@ static status_t process_start(private_eap_sim_server_t *this,
char mk[HASH_SIZE_SHA1];
u_int16_t counter;
permanent = charon->sim->provider_is_reauth(charon->sim, id,
mk, &counter);
permanent = this->mgr->provider_is_reauth(this->mgr, id,
mk, &counter);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -315,7 +321,7 @@ static status_t process_start(private_eap_sim_server_t *this,
}
if (this->use_pseudonym)
{
permanent = charon->sim->provider_is_pseudonym(charon->sim, id);
permanent = this->mgr->provider_is_pseudonym(this->mgr, id);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -348,8 +354,8 @@ static status_t process_start(private_eap_sim_server_t *this,
rands.len = kcs.len = sreses.len = 0;
for (i = 0; i < TRIPLET_COUNT; i++)
{
if (!charon->sim->provider_get_triplet(charon->sim, this->permanent,
rand.ptr, sres.ptr, kc.ptr))
if (!this->mgr->provider_get_triplet(this->mgr, this->permanent,
rand.ptr, sres.ptr, kc.ptr))
{
if (this->use_pseudonym)
{
@@ -386,7 +392,7 @@ static status_t process_start(private_eap_sim_server_t *this,
message = simaka_message_create(TRUE, this->identifier++, EAP_SIM,
SIM_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RAND, rands);
id = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk.ptr);
id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr);
if (id)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
@@ -395,7 +401,7 @@ static status_t process_start(private_eap_sim_server_t *this,
}
else
{
id = charon->sim->provider_gen_pseudonym(charon->sim, this->permanent);
id = this->mgr->provider_gen_pseudonym(this->mgr, this->permanent);
if (id)
{
message->add_attribute(message, AT_NEXT_PSEUDONYM,
@@ -403,7 +409,7 @@ static status_t process_start(private_eap_sim_server_t *this,
id->destroy(id);
}
}
*out = message->generate(message, nonce);
*out = eap_payload_create_data_own(message->generate(message, nonce));
message->destroy(message);
free(mk.ptr);
@@ -483,7 +489,7 @@ METHOD(eap_method_t, process, status_t,
simaka_message_t *message;
status_t status;
message = simaka_message_create_from_payload(in, this->crypto);
message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
return FAILED;
@@ -588,7 +594,8 @@ eap_sim_server_t *eap_sim_server_create(identification_t *server,
.destroy = _destroy,
},
},
.crypto = simaka_crypto_create(),
.crypto = simaka_crypto_create(EAP_SIM),
.mgr = lib->get(lib, "sim-manager"),
);
if (!this->crypto)
@@ -27,9 +27,6 @@ typedef struct eap_sim_server_t eap_sim_server_t;
/**
* EAP-SIM server implementation.
*
* This EAP-SIM module uses sim_provider_t implementations for triplet
* calculation, found via the eap_sim_manager_t.
*/
struct eap_sim_server_t {
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\"
@@ -35,7 +35,7 @@ struct private_eap_sim_file_card_t {
eap_sim_file_triplets_t *triplets;
};
METHOD(sim_card_t, get_triplet, bool,
METHOD(simaka_card_t, get_triplet, bool,
private_eap_sim_file_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -66,7 +66,7 @@ METHOD(sim_card_t, get_triplet, bool,
return FALSE;
}
METHOD(sim_card_t, get_quintuplet, status_t,
METHOD(simaka_card_t, get_quintuplet, status_t,
private_eap_sim_file_card_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_MAX], int *res_len)
@@ -23,7 +23,7 @@
#include "eap_sim_file_triplets.h"
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_card.h>
typedef struct eap_sim_file_card_t eap_sim_file_card_t;
@@ -33,9 +33,9 @@ typedef struct eap_sim_file_card_t eap_sim_file_card_t;
struct eap_sim_file_card_t {
/**
* Implements sim_card_t interface
* Implements simaka_card_t interface
*/
sim_card_t card;
simaka_card_t card;
/**
* Destroy a eap_sim_file_card_t.
@@ -59,8 +59,14 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_eap_sim_file_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
simaka_manager_t *mgr;
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
this->card->destroy(this->card);
this->provider->destroy(this->provider);
this->triplets->destroy(this->triplets);
@@ -73,6 +79,7 @@ METHOD(plugin_t, destroy, void,
plugin_t *eap_sim_file_plugin_create()
{
private_eap_sim_file_t *this;
simaka_manager_t *mgr;
INIT(this,
.public = {
@@ -94,9 +101,12 @@ plugin_t *eap_sim_file_plugin_create()
}
this->card = eap_sim_file_card_create(this->triplets);
charon->sim->add_card(charon->sim, &this->card->card);
charon->sim->add_provider(charon->sim, &this->provider->provider);
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
return &this->public.plugin;
}
@@ -35,7 +35,7 @@ struct private_eap_sim_file_provider_t {
eap_sim_file_triplets_t *triplets;
};
METHOD(sim_provider_t, get_triplet, bool,
METHOD(simaka_provider_t, get_triplet, bool,
private_eap_sim_file_provider_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -23,6 +23,8 @@
#include "eap_sim_file_triplets.h"
#include <simaka_provider.h>
typedef struct eap_sim_file_provider_t eap_sim_file_provider_t;
/**
@@ -31,9 +33,9 @@ typedef struct eap_sim_file_provider_t eap_sim_file_provider_t;
struct eap_sim_file_provider_t {
/**
* Implements sim_provider_t interface.
* Implements simaka_provider_t interface.
*/
sim_provider_t provider;
simaka_provider_t provider;
/**
* Destroy a eap_sim_file_provider_t.
@@ -21,6 +21,7 @@
#include <daemon.h>
#include <utils/linked_list.h>
#include <threading/mutex.h>
#include <simaka_manager.h>
typedef struct private_eap_sim_file_triplets_t private_eap_sim_file_triplets_t;
@@ -21,7 +21,7 @@
#ifndef EAP_SIM_FILE_TRIPLETS_H_
#define EAP_SIM_FILE_TRIPLETS_H_
#include <sa/authenticators/eap/sim_manager.h>
#include <utils/enumerator.h>
typedef struct eap_sim_file_triplets_t eap_sim_file_triplets_t;
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic ${pcsclite_CFLAGS}
@@ -87,7 +87,7 @@ static bool decode_imsi_ef(unsigned char *input, int input_len, char *output)
return TRUE;
}
METHOD(sim_card_t, get_triplet, bool,
METHOD(simaka_card_t, get_triplet, bool,
private_eap_sim_pcsc_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -351,7 +351,7 @@ METHOD(sim_card_t, get_triplet, bool,
return found;
}
METHOD(sim_card_t, get_quintuplet, status_t,
METHOD(simaka_card_t, get_quintuplet, status_t,
private_eap_sim_pcsc_card_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_MAX], int *res_len)
@@ -20,7 +20,7 @@
#ifndef EAP_SIM_PCSC_CARD_H_
#define EAP_SIM_PCSC_CARD_H_
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_card.h>
typedef struct eap_sim_pcsc_card_t eap_sim_pcsc_card_t;
@@ -30,9 +30,9 @@ typedef struct eap_sim_pcsc_card_t eap_sim_pcsc_card_t;
struct eap_sim_pcsc_card_t {
/**
* Implements sim_card_t interface
* Implements simaka_card_t interface
*/
sim_card_t card;
simaka_card_t card;
/**
* Destroy a eap_sim_pcsc_card_t.
@@ -44,7 +44,13 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_eap_sim_pcsc_plugin_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
simaka_manager_t *mgr;
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
}
this->card->destroy(this->card);
free(this);
}
@@ -55,6 +61,7 @@ METHOD(plugin_t, destroy, void,
plugin_t *eap_sim_pcsc_plugin_create()
{
private_eap_sim_pcsc_plugin_t *this;
simaka_manager_t *mgr;
INIT(this,
.public = {
@@ -66,8 +73,12 @@ plugin_t *eap_sim_pcsc_plugin_create()
},
.card = eap_sim_pcsc_card_create(),
);
charon->sim->add_card(charon->sim, &this->card->card);
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
}
return &this->public.plugin;
}
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
@@ -58,7 +58,7 @@ static bool equals(identification_t *key1, identification_t *key2)
}
/**
* Implementation of sim_card_t.get_pseudonym
* Implementation of simaka_card_t.get_pseudonym
*/
static identification_t *get_pseudonym(private_eap_simaka_pseudonym_card_t *this,
identification_t *id)
@@ -74,7 +74,7 @@ static identification_t *get_pseudonym(private_eap_simaka_pseudonym_card_t *this
}
/**
* Implementation of sim_card_t.set_pseudonym
* Implementation of simaka_card_t.set_pseudonym
*/
static void set_pseudonym(private_eap_simaka_pseudonym_card_t *this,
identification_t *id, identification_t *pseudonym)
@@ -93,7 +93,7 @@ static void set_pseudonym(private_eap_simaka_pseudonym_card_t *this,
}
/**
* Implementation of sim_card_t.get_quintuplet
* Implementation of simaka_card_t.get_quintuplet
*/
static status_t get_quintuplet()
{
@@ -137,13 +137,13 @@ eap_simaka_pseudonym_card_t *eap_simaka_pseudonym_card_create()
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_MAX], int *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.card.get_triplet = (bool(*)(simaka_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(*)(simaka_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_MAX], int *res_len))get_quintuplet;
this->public.card.resync = (bool(*)(simaka_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
this->public.card.get_pseudonym = (identification_t*(*)(simaka_card_t*, identification_t *perm))get_pseudonym;
this->public.card.set_pseudonym = (void(*)(simaka_card_t*, identification_t *id, identification_t *pseudonym))set_pseudonym;
this->public.card.get_reauth = (identification_t*(*)(simaka_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null;
this->public.card.set_reauth = (void(*)(simaka_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);
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_PSEUDONYM_CARD_H_
#define EAP_SIMAKA_PSEUDONYM_CARD_H_
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_card.h>
typedef struct eap_simaka_pseudonym_card_t eap_simaka_pseudonym_card_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_pseudonym_card_t eap_simaka_pseudonym_card_t;
struct eap_simaka_pseudonym_card_t {
/**
* Implements sim_card_t interface
* Implements simaka_card_t interface
*/
sim_card_t card;
simaka_card_t card;
/**
* Destroy a eap_simaka_pseudonym_card_t.
@@ -51,8 +51,20 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_eap_simaka_pseudonym_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
simaka_manager_t *mgr;
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
this->card->destroy(this->card);
this->provider->destroy(this->provider);
free(this);
@@ -64,6 +76,7 @@ METHOD(plugin_t, destroy, void,
plugin_t *eap_simaka_pseudonym_plugin_create()
{
private_eap_simaka_pseudonym_t *this;
simaka_manager_t *mgr;
INIT(this,
.public = {
@@ -83,9 +96,18 @@ plugin_t *eap_simaka_pseudonym_plugin_create()
}
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);
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
return &this->public.plugin;
}
@@ -62,7 +62,7 @@ static bool equals(identification_t *key1, identification_t *key2)
}
/**
* Implementation of sim_provider_t.is_pseudonym
* Implementation of simaka_provider_t.is_pseudonym
*/
static identification_t* is_pseudonym(
private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
@@ -92,7 +92,7 @@ static identification_t *gen_identity(
}
/**
* Implementation of sim_provider_t.get_pseudonym
* Implementation of simaka_provider_t.get_pseudonym
*/
static identification_t* gen_pseudonym(
private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
@@ -159,13 +159,13 @@ eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create()
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_MAX], int *xres_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.provider.get_triplet = (bool(*)(simaka_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(*)(simaka_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false;
this->public.provider.resync = (bool(*)(simaka_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
this->public.provider.is_pseudonym = (identification_t*(*)(simaka_provider_t*, identification_t *id))is_pseudonym;
this->public.provider.gen_pseudonym = (identification_t*(*)(simaka_provider_t*, identification_t *id))gen_pseudonym;
this->public.provider.is_reauth = (identification_t*(*)(simaka_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null;
this->public.provider.gen_reauth = (identification_t*(*)(simaka_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);
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_PSEDUONYM_PROVIDER_H_
#define EAP_SIMAKA_PSEDUONYM_PROVIDER_H_
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_provider.h>
typedef struct eap_simaka_pseudonym_provider_t eap_simaka_pseudonym_provider_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_pseudonym_provider_t eap_simaka_pseudonym_provider_t;
struct eap_simaka_pseudonym_provider_t {
/**
* Implements sim_provider_t interface.
* Implements simaka_provider_t interface.
*/
sim_provider_t provider;
simaka_provider_t provider;
/**
* Destroy a eap_simaka_pseudonym_provider_t.
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
@@ -67,7 +67,7 @@ static bool equals(identification_t *key1, identification_t *key2)
}
/**
* Implementation of sim_card_t.get_reauth
* Implementation of simaka_card_t.get_reauth
*/
static identification_t *get_reauth(private_eap_simaka_reauth_card_t *this,
identification_t *id, char mk[HASH_SIZE_SHA1],
@@ -91,7 +91,7 @@ static identification_t *get_reauth(private_eap_simaka_reauth_card_t *this,
}
/**
* Implementation of sim_card_t.set_reauth
* Implementation of simaka_card_t.set_reauth
*/
static void set_reauth(private_eap_simaka_reauth_card_t *this,
identification_t *id, identification_t* next,
@@ -116,7 +116,7 @@ static void set_reauth(private_eap_simaka_reauth_card_t *this,
}
/**
* Implementation of sim_card_t.get_quintuplet
* Implementation of simaka_card_t.get_quintuplet
*/
static status_t get_quintuplet()
{
@@ -154,13 +154,13 @@ eap_simaka_reauth_card_t *eap_simaka_reauth_card_create()
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_MAX], int *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.card.get_triplet = (bool(*)(simaka_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(*)(simaka_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_MAX], int *res_len))get_quintuplet;
this->public.card.resync = (bool(*)(simaka_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
this->public.card.get_pseudonym = (identification_t*(*)(simaka_card_t*, identification_t *perm))return_null;
this->public.card.set_pseudonym = (void(*)(simaka_card_t*, identification_t *id, identification_t *pseudonym))nop;
this->public.card.get_reauth = (identification_t*(*)(simaka_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))get_reauth;
this->public.card.set_reauth = (void(*)(simaka_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);
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_REAUTH_CARD_H_
#define EAP_SIMAKA_REAUTH_CARD_H_
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_provider.h>
typedef struct eap_simaka_reauth_card_t eap_simaka_reauth_card_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_reauth_card_t eap_simaka_reauth_card_t;
struct eap_simaka_reauth_card_t {
/**
* Implements sim_card_t interface
* Implements simaka_card_t interface
*/
sim_card_t card;
simaka_card_t card;
/**
* Destroy a eap_simaka_reauth_card_t.
@@ -51,8 +51,20 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_eap_simaka_reauth_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
simaka_manager_t *mgr;
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
this->card->destroy(this->card);
this->provider->destroy(this->provider);
free(this);
@@ -64,6 +76,7 @@ METHOD(plugin_t, destroy, void,
plugin_t *eap_simaka_reauth_plugin_create()
{
private_eap_simaka_reauth_t *this;
simaka_manager_t *mgr;
INIT(this,
.public = {
@@ -83,9 +96,18 @@ plugin_t *eap_simaka_reauth_plugin_create()
}
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);
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
return &this->public.plugin;
}
@@ -88,7 +88,7 @@ static identification_t *gen_identity(private_eap_simaka_reauth_provider_t *this
}
/**
* Implementation of sim_provider_t.is_reauth
* Implementation of simaka_provider_t.is_reauth
*/
static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this,
identification_t *id, char mk[HASH_SIZE_SHA1],
@@ -115,7 +115,7 @@ static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this,
}
/**
* Implementation of sim_provider_t.gen_reauth
* Implementation of simaka_provider_t.gen_reauth
*/
static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this,
identification_t *id, char mk[HASH_SIZE_SHA1])
@@ -186,13 +186,13 @@ 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_MAX], int *xres_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.provider.get_triplet = (bool(*)(simaka_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(*)(simaka_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false;
this->public.provider.resync = (bool(*)(simaka_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
this->public.provider.is_pseudonym = (identification_t*(*)(simaka_provider_t*, identification_t *id))return_null;
this->public.provider.gen_pseudonym = (identification_t*(*)(simaka_provider_t*, identification_t *id))return_null;
this->public.provider.is_reauth = (identification_t*(*)(simaka_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))is_reauth;
this->public.provider.gen_reauth = (identification_t*(*)(simaka_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);
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_REAUTH_PROVIDER_H_
#define EAP_SIMAKA_REAUTH_PROVIDER_H_
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_provider.h>
typedef struct eap_simaka_reauth_provider_t eap_simaka_reauth_provider_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_reauth_provider_t eap_simaka_reauth_provider_t;
struct eap_simaka_reauth_provider_t {
/**
* Implements sim_provider_t interface.
* Implements simaka_provider_t interface.
*/
sim_provider_t provider;
simaka_provider_t provider;
/**
* Destroy a eap_simaka_reauth_provider_t.
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\"
@@ -42,7 +42,7 @@ struct private_eap_simaka_sql_card_t {
bool remove_used;
};
METHOD(sim_card_t, get_triplet, bool,
METHOD(simaka_card_t, get_triplet, bool,
private_eap_simaka_sql_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -90,7 +90,7 @@ METHOD(sim_card_t, get_triplet, bool,
return found;
}
METHOD(sim_card_t, get_quintuplet, status_t,
METHOD(simaka_card_t, get_quintuplet, status_t,
private_eap_simaka_sql_card_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_MAX], int *res_len)
@@ -22,7 +22,7 @@
#define EAP_SIMAKA_SQL_CARD_H_
#include <database/database.h>
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_manager.h>
typedef struct eap_simaka_sql_card_t eap_simaka_sql_card_t;
@@ -32,9 +32,9 @@ typedef struct eap_simaka_sql_card_t eap_simaka_sql_card_t;
struct eap_simaka_sql_card_t {
/**
* Implements sim_card_t interface
* Implements simaka_card_t interface
*/
sim_card_t card;
simaka_card_t card;
/**
* Destroy a eap_simaka_sql_card_t.
@@ -56,8 +56,20 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_eap_simaka_sql_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
simaka_manager_t *mgr;
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->remove_card(mgr, &this->card->card);
mgr->remove_provider(mgr, &this->provider->provider);
}
this->card->destroy(this->card);
this->provider->destroy(this->provider);
this->db->destroy(this->db);
@@ -70,6 +82,7 @@ METHOD(plugin_t, destroy, void,
plugin_t *eap_simaka_sql_plugin_create()
{
private_eap_simaka_sql_t *this;
simaka_manager_t *mgr;
database_t *db;
bool remove_used;
char *uri;
@@ -103,8 +116,17 @@ plugin_t *eap_simaka_sql_plugin_create()
.card = eap_simaka_sql_card_create(db, remove_used),
);
charon->sim->add_card(charon->sim, &this->card->card);
charon->sim->add_provider(charon->sim, &this->provider->provider);
mgr = lib->get(lib, "sim-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
mgr = lib->get(lib, "aka-manager");
if (mgr)
{
mgr->add_card(mgr, &this->card->card);
mgr->add_provider(mgr, &this->provider->provider);
}
return &this->public.plugin;
}
@@ -42,7 +42,7 @@ struct private_eap_simaka_sql_provider_t {
bool remove_used;
};
METHOD(sim_provider_t, get_triplet, bool,
METHOD(simaka_provider_t, get_triplet, bool,
private_eap_simaka_sql_provider_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -90,7 +90,7 @@ METHOD(sim_provider_t, get_triplet, bool,
return found;
}
METHOD(sim_provider_t, get_quintuplet, bool,
METHOD(simaka_provider_t, get_quintuplet, bool,
private_eap_simaka_sql_provider_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len,
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
@@ -22,7 +22,7 @@
#define EAP_SIMAKA_SQL_PROVIDER_H_
#include <database/database.h>
#include <sa/authenticators/eap/sim_manager.h>
#include <simaka_provider.h>
typedef struct eap_simaka_sql_provider_t eap_simaka_sql_provider_t;
@@ -32,9 +32,9 @@ typedef struct eap_simaka_sql_provider_t eap_simaka_sql_provider_t;
struct eap_simaka_sql_provider_t {
/**
* Implements sim_provider_t interface
* Implements simaka_provider_t interface
*/
sim_provider_t provider;
simaka_provider_t provider;
/**
* Destroy a eap_simaka_sql_provider_t.
@@ -1,125 +0,0 @@
/*
* Copyright (C) 2008-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 sim_card sim_card
* @{ @ingroup eap
*/
#ifndef SIM_CARD_H_
#define SIM_CARD_H_
typedef struct sim_card_t sim_card_t;
/**
* Interface for a (U)SIM card (used as EAP client).
*
* The SIM card completes triplets/quintuplets requested in a challenge
* received from the server.
* An implementation supporting only one of SIM/AKA authentication may
* implement the other methods with return_false()/return NOT_SUPPORTED/NULL.
*/
struct sim_card_t {
/**
* Calculate SRES/KC from a RAND for SIM authentication.
*
* @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 SRES/KC calculated, FALSE on error/wrong identity
*/
bool (*get_triplet)(sim_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
char kc[SIM_KC_LEN]);
/**
* Calculate CK/IK/RES from RAND/AUTN for AKA authentication.
*
* If the received sequence number (in autn) is out of sync, INVALID_STATE
* is returned.
* The RES value is the only one with variable length. Pass a buffer
* of at least AKA_RES_MAX, the actual number of bytes is written to the
* res_len value. While the standard would allow any bit length between
* 32 and 128 bits, we support only full bytes for now.
*
* @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
* @param res_len nubmer of bytes written to res buffer
* @return SUCCESS, FAILED, or INVALID_STATE if out of sync
*/
status_t (*get_quintuplet)(sim_card_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_MAX], int *res_len);
/**
* Calculate AUTS from RAND for AKA resynchronization.
*
* @param id permanent identity to request quintuplet for
* @param rand random value rand
* @param auts resynchronization parameter auts
* @return TRUE if parameter generated successfully
*/
bool (*resync)(sim_card_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
/**
* Set the pseudonym to use for next authentication.
*
* @param id permanent identity of the peer
* @param pseudonym pseudonym identity received from the server
*/
void (*set_pseudonym)(sim_card_t *this, identification_t *id,
identification_t *pseudonym);
/**
* Get the pseudonym previously stored via set_pseudonym().
*
* @param id permanent identity of the peer
* @return associated pseudonym identity, NULL if none stored
*/
identification_t* (*get_pseudonym)(sim_card_t *this, identification_t *id);
/**
* Store parameters to use for the next fast reauthentication.
*
* @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 (*set_reauth)(sim_card_t *this, identification_t *id,
identification_t *next, char mk[HASH_SIZE_SHA1],
u_int16_t counter);
/**
* Retrieve parameters for fast reauthentication stored via set_reauth().
*
* @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 not found
*/
identification_t* (*get_reauth)(sim_card_t *this, identification_t *id,
char mk[HASH_SIZE_SHA1], u_int16_t *counter);
};
#endif /** SIM_CARD_H_ @}*/
@@ -1,53 +0,0 @@
/*
* Copyright (C) 2008-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 sim_hooks sim_hooks
* @{ @ingroup eap
*/
#ifndef SIM_HOOKS_H_
#define SIM_HOOKS_H_
typedef struct sim_hooks_t sim_hooks_t;
/**
* Additional hooks invoked during EAP-SIM/AKA message processing.
*/
struct sim_hooks_t {
/**
* SIM/AKA message parsing.
*
* As a SIM/AKA optionally contains encrypted attributes, the hook
* might get invoked twice, once before and once after decryption.
*
* @param message SIM/AKA message
* @param inbound TRUE for incoming messages, FALSE for outgoing
* @param decrypted TRUE if AT_ENCR_DATA has been decrypted
*/
void (*message)(sim_hooks_t *this, simaka_message_t *message,
bool inbound, bool decrypted);
/**
* SIM/AKA encryption/authentication key hooks.
*
* @param k_encr derived SIM/AKA encryption key k_encr
* @param k_auth derived SIM/AKA authentication key k_auth
*/
void (*keys)(sim_hooks_t *this, chunk_t k_encr, chunk_t k_auth);
};
#endif /** SIM_HOOKS_H_ @}*/
@@ -1,534 +0,0 @@
/*
* Copyright (C) 2008 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 "sim_manager.h"
#include <daemon.h>
#include <utils/linked_list.h>
#include <threading/rwlock.h>
typedef struct private_sim_manager_t private_sim_manager_t;
/**
* Private data of an sim_manager_t object.
*/
struct private_sim_manager_t {
/**
* Public sim_manager_t interface.
*/
sim_manager_t public;
/**
* list of added cards
*/
linked_list_t *cards;
/**
* list of added provider
*/
linked_list_t *providers;
/**
* list of added hooks
*/
linked_list_t *hooks;
/**
* lock for lists above
*/
rwlock_t *lock;
};
METHOD(sim_manager_t, add_card, void,
private_sim_manager_t *this, sim_card_t *card)
{
this->lock->write_lock(this->lock);
this->cards->insert_last(this->cards, card);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, remove_card, void,
private_sim_manager_t *this, sim_card_t *card)
{
this->lock->write_lock(this->lock);
this->cards->remove(this->cards, card, NULL);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, card_get_triplet, bool,
private_sim_manager_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
enumerator_t *enumerator;
sim_card_t *card;
int tried = 0;
this->lock->read_lock(this->lock);
enumerator = this->cards->create_enumerator(this->cards);
while (enumerator->enumerate(enumerator, &card))
{
if (card->get_triplet(card, id, rand, sres, kc))
{
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return TRUE;
}
tried++;
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
DBG1(DBG_IKE, "tried %d SIM cards, but none has triplets for '%Y'",
tried, id);
return FALSE;
}
METHOD(sim_manager_t, card_get_quintuplet, status_t,
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_MAX], int *res_len)
{
enumerator_t *enumerator;
sim_card_t *card;
status_t status = NOT_FOUND;
int tried = 0;
this->lock->read_lock(this->lock);
enumerator = this->cards->create_enumerator(this->cards);
while (enumerator->enumerate(enumerator, &card))
{
status = card->get_quintuplet(card, id, rand, autn, ck, ik, res, res_len);
switch (status)
{ /* try next on error, but not on INVALID_STATE */
case SUCCESS:
case INVALID_STATE:
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return status;
case NOT_SUPPORTED:
case FAILED:
default:
tried++;
continue;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
DBG1(DBG_IKE, "tried %d SIM cards, but none has quintuplets for '%Y'",
tried, id);
return status;
}
METHOD(sim_manager_t, card_resync, bool,
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;
this->lock->read_lock(this->lock);
enumerator = this->cards->create_enumerator(this->cards);
while (enumerator->enumerate(enumerator, &card))
{
if (card->resync(card, id, rand, auts))
{
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return TRUE;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return FALSE;
}
METHOD(sim_manager_t, card_set_pseudonym, void,
private_sim_manager_t *this, identification_t *id,
identification_t *pseudonym)
{
enumerator_t *enumerator;
sim_card_t *card;
DBG1(DBG_IKE, "storing pseudonym '%Y' for '%Y'", pseudonym, id);
this->lock->read_lock(this->lock);
enumerator = this->cards->create_enumerator(this->cards);
while (enumerator->enumerate(enumerator, &card))
{
card->set_pseudonym(card, id, pseudonym);
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, card_get_pseudonym, identification_t*,
private_sim_manager_t *this, identification_t *id)
{
enumerator_t *enumerator;
sim_card_t *card;
identification_t *pseudonym = NULL;
this->lock->read_lock(this->lock);
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);
this->lock->unlock(this->lock);
return pseudonym;
}
METHOD(sim_manager_t, card_set_reauth, void,
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;
DBG1(DBG_IKE, "storing next reauthentication identity '%Y' for '%Y'",
next, id);
this->lock->read_lock(this->lock);
enumerator = this->cards->create_enumerator(this->cards);
while (enumerator->enumerate(enumerator, &card))
{
card->set_reauth(card, id, next, mk, counter);
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, card_get_reauth, identification_t*,
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;
this->lock->read_lock(this->lock);
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);
this->lock->unlock(this->lock);
return reauth;
}
METHOD(sim_manager_t, add_provider, void,
private_sim_manager_t *this, sim_provider_t *provider)
{
this->lock->write_lock(this->lock);
this->providers->insert_last(this->providers, provider);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, remove_provider, void,
private_sim_manager_t *this, sim_provider_t *provider)
{
this->lock->write_lock(this->lock);
this->providers->remove(this->providers, provider, NULL);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, provider_get_triplet, bool,
private_sim_manager_t *this, identification_t *id, char rand[SIM_RAND_LEN],
char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
enumerator_t *enumerator;
sim_provider_t *provider;
int tried = 0;
this->lock->read_lock(this->lock);
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &provider))
{
if (provider->get_triplet(provider, id, rand, sres, kc))
{
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return TRUE;
}
tried++;
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%Y'",
tried, id);
return FALSE;
}
METHOD(sim_manager_t, provider_get_quintuplet, bool,
private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN],
char xres[AKA_RES_MAX], int *xres_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;
this->lock->read_lock(this->lock);
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &provider))
{
if (provider->get_quintuplet(provider, id, rand, xres, xres_len,
ck, ik, autn))
{
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return TRUE;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
DBG1(DBG_IKE, "tried %d SIM providers, but none had a quintuplet for '%Y'",
tried, id);
return FALSE;
}
METHOD(sim_manager_t, provider_resync, bool,
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;
this->lock->read_lock(this->lock);
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &provider))
{
if (provider->resync(provider, id, rand, auts))
{
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return TRUE;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return FALSE;
}
METHOD(sim_manager_t, provider_is_pseudonym, identification_t*,
private_sim_manager_t *this, identification_t *id)
{
enumerator_t *enumerator;
sim_provider_t *provider;
identification_t *permanent = NULL;
this->lock->read_lock(this->lock);
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &provider))
{
permanent = provider->is_pseudonym(provider, id);
if (permanent)
{
DBG1(DBG_IKE, "received pseudonym identity '%Y' "
"mapping to '%Y'", id, permanent);
break;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return permanent;
}
METHOD(sim_manager_t, provider_gen_pseudonym, identification_t*,
private_sim_manager_t *this, identification_t *id)
{
enumerator_t *enumerator;
sim_provider_t *provider;
identification_t *pseudonym = NULL;
this->lock->read_lock(this->lock);
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);
this->lock->unlock(this->lock);
return pseudonym;
}
METHOD(sim_manager_t, provider_is_reauth, identification_t*,
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;
this->lock->read_lock(this->lock);
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &provider))
{
permanent = provider->is_reauth(provider, id, mk, counter);
if (permanent)
{
DBG1(DBG_IKE, "received reauthentication identity '%Y' "
"mapping to '%Y'", id, permanent);
break;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
return permanent;
}
METHOD(sim_manager_t, provider_gen_reauth, identification_t*,
private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1])
{
enumerator_t *enumerator;
sim_provider_t *provider;
identification_t *reauth = NULL;
this->lock->read_lock(this->lock);
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);
this->lock->unlock(this->lock);
return reauth;
}
METHOD(sim_manager_t, add_hooks, void,
private_sim_manager_t *this, sim_hooks_t *hooks)
{
this->lock->write_lock(this->lock);
this->hooks->insert_last(this->hooks, hooks);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, remove_hooks, void,
private_sim_manager_t *this, sim_hooks_t *hooks)
{
this->lock->write_lock(this->lock);
this->hooks->remove(this->hooks, hooks, NULL);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, message_hook, void,
private_sim_manager_t *this, simaka_message_t *message,
bool inbound, bool decrypted)
{
enumerator_t *enumerator;
sim_hooks_t *hooks;
this->lock->read_lock(this->lock);
enumerator = this->hooks->create_enumerator(this->hooks);
while (enumerator->enumerate(enumerator, &hooks))
{
hooks->message(hooks, message, inbound, decrypted);
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, key_hook, void,
private_sim_manager_t *this, chunk_t k_encr, chunk_t k_auth)
{
enumerator_t *enumerator;
sim_hooks_t *hooks;
this->lock->read_lock(this->lock);
enumerator = this->hooks->create_enumerator(this->hooks);
while (enumerator->enumerate(enumerator, &hooks))
{
hooks->keys(hooks, k_encr, k_auth);
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
}
METHOD(sim_manager_t, destroy, void,
private_sim_manager_t *this)
{
this->cards->destroy(this->cards);
this->providers->destroy(this->providers);
this->hooks->destroy(this->hooks);
this->lock->destroy(this->lock);
free(this);
}
/**
* See header
*/
sim_manager_t *sim_manager_create()
{
private_sim_manager_t *this;
INIT(this,
.public = {
.add_card = _add_card,
.remove_card = _remove_card,
.card_get_triplet = _card_get_triplet,
.card_get_quintuplet = _card_get_quintuplet,
.card_resync = _card_resync,
.card_set_pseudonym = _card_set_pseudonym,
.card_get_pseudonym = _card_get_pseudonym,
.card_set_reauth = _card_set_reauth,
.card_get_reauth = _card_get_reauth,
.add_provider = _add_provider,
.remove_provider = _remove_provider,
.provider_get_triplet = _provider_get_triplet,
.provider_get_quintuplet = _provider_get_quintuplet,
.provider_resync = _provider_resync,
.provider_is_pseudonym = _provider_is_pseudonym,
.provider_gen_pseudonym = _provider_gen_pseudonym,
.provider_is_reauth = _provider_is_reauth,
.provider_gen_reauth = _provider_gen_reauth,
.add_hooks = _add_hooks,
.remove_hooks = _remove_hooks,
.message_hook = _message_hook,
.key_hook = _key_hook,
.destroy = _destroy,
},
.cards = linked_list_create(),
.providers = linked_list_create(),
.hooks = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
return &this->public;
}
@@ -1,291 +0,0 @@
/*
* Copyright (C) 2008-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 sim_manager sim_manager
* @{ @ingroup eap
*/
#ifndef SIM_MANAGER_H_
#define SIM_MANAGER_H_
#include <crypto/hashers/hasher.h>
#include <utils/identification.h>
#include <utils/enumerator.h>
#include <sa/authenticators/eap/eap_method.h>
typedef struct sim_manager_t sim_manager_t;
/** implemented in libsimaka, but we need it for the message hook */
typedef struct simaka_message_t simaka_message_t;
#define SIM_RAND_LEN 16
#define SIM_SRES_LEN 4
#define SIM_KC_LEN 8
#define AKA_RAND_LEN 16
#define AKA_RES_MAX 16
#define AKA_CK_LEN 16
#define AKA_IK_LEN 16
#define AKA_AUTN_LEN 16
#define AKA_AUTS_LEN 14
#include <sa/authenticators/eap/sim_card.h>
#include <sa/authenticators/eap/sim_provider.h>
#include <sa/authenticators/eap/sim_hooks.h>
/**
* The SIM manager handles multiple (U)SIM cards/providers and hooks.
*/
struct sim_manager_t {
/**
* Register a SIM card (client) at the manager.
*
* @param card sim card to register
*/
void (*add_card)(sim_manager_t *this, sim_card_t *card);
/**
* Unregister a previously registered card from the manager.
*
* @param card sim card to unregister
*/
void (*remove_card)(sim_manager_t *this, sim_card_t *card);
/**
* Calculate SIM triplets on one of the registered SIM cards.
*
* @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
*/
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
* @param res_len nubmer of bytes written to res buffer
* @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_MAX], int *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.
*
* @param card sim card to register
*/
void (*add_provider)(sim_manager_t *this, sim_provider_t *provider);
/**
* Unregister a previously registered provider from the manager.
*
* @param card sim card to unregister
*/
void (*remove_provider)(sim_manager_t *this, sim_provider_t *provider);
/**
* Get a SIM triplet from one of the registered providers.
*
* @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
*/
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_MAX], int *xres_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]);
/**
* Register a set of hooks to the manager.
*
* @param hooks hook interface implementation to register
*/
void (*add_hooks)(sim_manager_t *this, sim_hooks_t *hooks);
/**
* Unregister a set of hooks from the manager.
*
* @param hooks hook interface implementation to unregister
*/
void (*remove_hooks)(sim_manager_t *this, sim_hooks_t *hooks);
/**
* Invoke SIM/AKA message hook.
*
* @param message SIM message
* @param inbound TRUE for incoming messages, FALSE for outgoing
* @param decrypted TRUE if AT_ENCR_DATA has been decrypted
*/
void (*message_hook)(sim_manager_t *this, simaka_message_t *message,
bool inbound, bool decrypted);
/**
* Invoke SIM/AKA key hook.
*
* @param k_encr SIM/AKA encryption key k_encr
* @param k_auth SIM/AKA authentication key k_auth
*/
void (*key_hook)(sim_manager_t *this, chunk_t k_encr, chunk_t k_auth);
/**
* Destroy a manager instance.
*/
void (*destroy)(sim_manager_t *this);
};
/**
* Create an SIM manager to handle multiple (U)SIM cards/providers.
*
* @return sim_t object
*/
sim_manager_t *sim_manager_create();
#endif /** SIM_MANAGER_H_ @}*/
@@ -1,124 +0,0 @@
/*
* Copyright (C) 2008-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 sim_provider sim_provider
* @{ @ingroup eap
*/
#ifndef SIM_PROVIDER_H_
#define SIM_PROVIDER_H_
typedef struct sim_provider_t sim_provider_t;
/**
* Interface for a triplet/quintuplet provider (used as EAP server).
*
* A SIM provider hands out triplets for SIM authentication and quintuplets
* for AKA authentication. Multiple SIM provider instances can serve as
* authentication backend to authenticate clients using SIM/AKA.
* An implementation supporting only one of SIM/AKA authentication may
* implement the other methods with return_false().
*/
struct sim_provider_t {
/**
* Create a challenge for SIM authentication.
*
* @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 otherwise
*/
bool (*get_triplet)(sim_provider_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
char kc[SIM_KC_LEN]);
/**
* Create a challenge for AKA authentication.
*
* The XRES value is the only one with variable length. Pass a buffer
* of at least AKA_RES_MAX, the actual number of bytes is written to the
* xres_len value. While the standard would allow any bit length between
* 32 and 128 bits, we support only full bytes for now.
*
* @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 xres_len nubmer of bytes written to xres buffer
* @param ck buffer receiving encryption key ck
* @param ik buffer receiving integrity key ik
* @param autn authentication token autn
* @return TRUE if quintuplet generated successfully
*/
bool (*get_quintuplet)(sim_provider_t *this, identification_t *id,
char rand[AKA_RAND_LEN],
char xres[AKA_RES_MAX], int *xres_len,
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
char autn[AKA_AUTN_LEN]);
/**
* Process AKA resynchroniusation request of a peer.
*
* @param id permanent identity of peer requesting resynchronisation
* @param rand random value rand
* @param auts synchronization parameter auts
* @return TRUE if resynchronized successfully
*/
bool (*resync)(sim_provider_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
/**
* Check if peer uses a pseudonym, get permanent identity.
*
* @param id pseudonym identity candidate
* @return permanent identity, NULL if id not a pseudonym
*/
identification_t* (*is_pseudonym)(sim_provider_t *this,
identification_t *id);
/**
* Generate a pseudonym identitiy for a given peer identity.
*
* @param id permanent identity to generate a pseudonym for
* @return generated pseudonym, NULL to not use a pseudonym identity
*/
identification_t* (*gen_pseudonym)(sim_provider_t *this,
identification_t *id);
/**
* Check if peer uses reauthentication, retrieve reauth parameters.
*
* @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 id not a reauth identity
*/
identification_t* (*is_reauth)(sim_provider_t *this, identification_t *id,
char mk[HASH_SIZE_SHA1], u_int16_t *counter);
/**
* Generate a fast reauthentication identity, associated to a master key.
*
* @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* (*gen_reauth)(sim_provider_t *this, identification_t *id,
char mk[HASH_SIZE_SHA1]);
};
#endif /** SIM_CARD_H_ @}*/