Migrated all SIM/AKA code to libsimaka, use SIM and AKA backend managers registered...
authorMartin Willi <martin@revosec.ch>
Thu, 7 Jul 2011 10:31:45 +0000 (12:31 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 8 Aug 2011 11:36:56 +0000 (13:36 +0200)
67 files changed:
src/libcharon/Android.mk
src/libcharon/Makefile.am
src/libcharon/daemon.c
src/libcharon/daemon.h
src/libcharon/plugins/eap_aka/eap_aka_peer.c
src/libcharon/plugins/eap_aka/eap_aka_peer.h
src/libcharon/plugins/eap_aka/eap_aka_plugin.c
src/libcharon/plugins/eap_aka/eap_aka_plugin.h
src/libcharon/plugins/eap_aka/eap_aka_server.c
src/libcharon/plugins/eap_aka/eap_aka_server.h
src/libcharon/plugins/eap_aka_3gpp2/Makefile.am
src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c
src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h
src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h
src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c
src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c
src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h
src/libcharon/plugins/eap_sim/eap_sim_peer.c
src/libcharon/plugins/eap_sim/eap_sim_peer.h
src/libcharon/plugins/eap_sim/eap_sim_plugin.c
src/libcharon/plugins/eap_sim/eap_sim_plugin.h
src/libcharon/plugins/eap_sim/eap_sim_server.c
src/libcharon/plugins/eap_sim/eap_sim_server.h
src/libcharon/plugins/eap_sim_file/Makefile.am
src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c
src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h
src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c
src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c
src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h
src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h
src/libcharon/plugins/eap_sim_pcsc/Makefile.am
src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c
src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h
src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c
src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am
src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c
src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h
src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c
src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c
src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h
src/libcharon/plugins/eap_simaka_reauth/Makefile.am
src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c
src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h
src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c
src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c
src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h
src/libcharon/plugins/eap_simaka_sql/Makefile.am
src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c
src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h
src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c
src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c
src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h
src/libcharon/sa/authenticators/eap/sim_card.h [deleted file]
src/libcharon/sa/authenticators/eap/sim_hooks.h [deleted file]
src/libcharon/sa/authenticators/eap/sim_manager.c [deleted file]
src/libcharon/sa/authenticators/eap/sim_manager.h [deleted file]
src/libcharon/sa/authenticators/eap/sim_provider.h [deleted file]
src/libsimaka/Makefile.am
src/libsimaka/simaka_card.h [new file with mode: 0644]
src/libsimaka/simaka_crypto.c
src/libsimaka/simaka_hooks.h [new file with mode: 0644]
src/libsimaka/simaka_manager.c [new file with mode: 0644]
src/libsimaka/simaka_manager.h [new file with mode: 0644]
src/libsimaka/simaka_message.c
src/libsimaka/simaka_message.h
src/libsimaka/simaka_provider.h [new file with mode: 0644]

index 0bb16f8..4eb43f7 100644 (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 \
index f027937..85299e4 100644 (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}\" \
index 9bdced1..12c6b2a 100644 (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();
index 3d74038..0005cd1 100644 (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>
@@ -243,11 +242,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
         */
        imc_manager_t *imcs;
index df0c4c5..8c39240 100644 (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;
 
@@ -34,6 +35,11 @@ struct private_eap_aka_peer_t {
        eap_aka_peer_t public;
 
        /**
+        * AKA backend manager
+        */
+       simaka_manager_t *mgr;
+
+       /**
         * EAP-AKA crypto helper
         */
        simaka_crypto_t *crypto;
@@ -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)
index 65a2104..974ba27 100644 (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 {
 
index 394a14b..361ebbe 100644 (file)
 #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;
 }
-
index d011904..8d4fbad 100644 (file)
@@ -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 {
 
index bf0020a..3dc9c9c 100644 (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
@@ -37,6 +38,11 @@ struct private_eap_aka_server_t {
        eap_aka_server_t public;
 
        /**
+        * AKA backend manager
+        */
+       simaka_manager_t *mgr;
+
+       /**
         * EAP-AKA crypto helper
         */
        simaka_crypto_t *crypto;
@@ -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)
index d48fc4c..5ab1c4d 100644 (file)
@@ -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 {
 
index 598799e..4534fa3 100644 (file)
@@ -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
 
index 5c0fe38..a380e0a 100644 (file)
@@ -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;
index b95bc52..eb6b1f7 100644 (file)
@@ -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.
index 95c6da6..855efec 100644 (file)
@@ -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
index ef5f62e..44ebd37 100644 (file)
@@ -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;
 }
 
index a9767ad..ce6ae37 100644 (file)
@@ -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;
index 22ac0a9..0e1af85 100644 (file)
@@ -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.
index 083bf73..1d1ab99 100644 (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
@@ -41,6 +42,11 @@ struct private_eap_sim_peer_t {
        eap_sim_peer_t public;
 
        /**
+        * SIM backend manager
+        */
+       simaka_manager_t *mgr;
+
+       /**
         * permanent ID of peer
         */
        identification_t *permanent;
@@ -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)
index 89f8130..ba72ce4 100644 (file)
@@ -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 {
 
index b152925..c148025 100644 (file)
 #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;
 }
 
index 4e10380..0c71ca5 100644 (file)
@@ -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 {
 
index d1dfde5..a6704a7 100644 (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
@@ -39,6 +40,11 @@ struct private_eap_sim_server_t {
        eap_sim_server_t public;
 
        /**
+        * SIM backend manager
+        */
+       simaka_manager_t *mgr;
+
+       /**
         * permanent ID of peer
         */
        identification_t *permanent;
@@ -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)
index 978e1e1..c0ed64f 100644 (file)
@@ -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 {
 
index 2b59a7c..0606550 100644 (file)
@@ -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}\"
 
index 5397c41..bd47e50 100644 (file)
@@ -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)
index 1a54709..45b0e51 100644 (file)
@@ -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.
index 0ab5a18..6d84d59 100644 (file)
@@ -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;
 }
 
index 38b6514..4ca1eb9 100644 (file)
@@ -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])
 {
index 10fda28..577345d 100644 (file)
@@ -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.
index c693923..618ae9e 100644 (file)
@@ -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;
 
index 8f81308..c8e9e03 100644 (file)
@@ -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;
 
index 2d75fe3..fb527c6 100644 (file)
@@ -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}
 
index d0a2718..6297924 100644 (file)
@@ -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)
index e765965..6b69f76 100644 (file)
@@ -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.
index 4409645..53a1626 100644 (file)
@@ -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;
 }
 
index a158d6d..f8761ba 100644 (file)
@@ -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
 
index 9b0f1bc..0d78b88 100644 (file)
@@ -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);
index 1b5940f..6c73a8c 100644 (file)
@@ -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.
index 06631b1..7e4c908 100644 (file)
@@ -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;
 }
 
index 0613b88..d4a2cb3 100644 (file)
@@ -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);
index 5d8e6d2..2dea516 100644 (file)
@@ -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.
index fbcd544..0191c9d 100644 (file)
@@ -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
 
index 14d0416..09dc62e 100644 (file)
@@ -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);
index f24dc8a..683de75 100644 (file)
@@ -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.
index 343e4ee..2a0377c 100644 (file)
@@ -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;
 }
 
index f962b2d..7ef454d 100644 (file)
@@ -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);
index 7ae151a..bc6376d 100644 (file)
@@ -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.
index 73768be..bc6a4e5 100644 (file)
@@ -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}\"
 
index b759040..90627b5 100644 (file)
@@ -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)
index 46b7de2..760755a 100644 (file)
@@ -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.
index 5a52815..10b4885 100644 (file)
@@ -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;
 }
index 73cccf5..51e9966 100644 (file)
@@ -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])
index ecb0c8c..88a8b1f 100644 (file)
@@ -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.
diff --git a/src/libcharon/sa/authenticators/eap/sim_card.h b/src/libcharon/sa/authenticators/eap/sim_card.h
deleted file mode 100644 (file)
index 5f5dc58..0000000
+++ /dev/null
@@ -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_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap/sim_hooks.h b/src/libcharon/sa/authenticators/eap/sim_hooks.h
deleted file mode 100644 (file)
index 0a675e4..0000000
+++ /dev/null
@@ -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_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.c b/src/libcharon/sa/authenticators/eap/sim_manager.c
deleted file mode 100644 (file)
index 9ccaf52..0000000
+++ /dev/null
@@ -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;
-}
-
diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.h b/src/libcharon/sa/authenticators/eap/sim_manager.h
deleted file mode 100644 (file)
index db4a650..0000000
+++ /dev/null
@@ -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_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap/sim_provider.h b/src/libcharon/sa/authenticators/eap/sim_provider.h
deleted file mode 100644 (file)
index 191e094..0000000
+++ /dev/null
@@ -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_ @}*/
index d5fc68e..80d4fb8 100644 (file)
@@ -3,4 +3,5 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra -I$(to
 
 ipseclib_LTLIBRARIES = libsimaka.la
 libsimaka_la_SOURCES = simaka_message.h simaka_message.c \
-  simaka_crypto.h simaka_crypto.c
+  simaka_crypto.h simaka_crypto.c simaka_manager.h simaka_manager.c \
+  simaka_card.h simaka_provider.h simaka_hooks.h
diff --git a/src/libsimaka/simaka_card.h b/src/libsimaka/simaka_card.h
new file mode 100644 (file)
index 0000000..52cb325
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008-2011 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 simaka_card simaka_card
+ * @{ @ingroup libsimaka
+ */
+
+#ifndef SIMAKA_CARD_H_
+#define SIMAKA_CARD_H_
+
+typedef struct simaka_card_t simaka_card_t;
+
+#include "simaka_manager.h"
+
+#include <utils/identification.h>
+
+/**
+ * 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 simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_card_t *this, identification_t *id,
+                                                                       char mk[HASH_SIZE_SHA1], u_int16_t *counter);
+};
+
+#endif /** SIMAKA_CARD_H_ @}*/
index b855020..4dd971c 100644 (file)
@@ -15,7 +15,9 @@
 
 #include "simaka_crypto.h"
 
-#include <daemon.h>
+#include "simaka_manager.h"
+
+#include <debug.h>
 
 /** length of the k_encr key */
 #define KENCR_LEN 16
@@ -39,6 +41,11 @@ struct private_simaka_crypto_t {
        simaka_crypto_t public;
 
        /**
+        * EAP type this crypto is used, SIM or AKA
+        */
+       eap_type_t type;
+
+       /**
         * signer to create/verify AT_MAC
         */
        signer_t *signer;
@@ -94,6 +101,27 @@ static rng_t* get_rng(private_simaka_crypto_t *this)
 }
 
 /**
+ * Call SIM/AKA key hook
+ */
+static void call_hook(private_simaka_crypto_t *this, chunk_t encr, chunk_t auth)
+{
+       simaka_manager_t *mgr;
+
+       switch (this->type)
+       {
+               case EAP_SIM:
+                       mgr = lib->get(lib, "sim-manager");
+                       break;
+               case EAP_AKA:
+                       mgr = lib->get(lib, "aka-manager");
+                       break;
+               default:
+                       return;
+       }
+       mgr->key_hook(mgr, encr, auth);
+}
+
+/**
  * Implementation of simaka_crypto_t.derive_keys_full
  */
 static chunk_t derive_keys_full(private_simaka_crypto_t *this,
@@ -106,7 +134,7 @@ static chunk_t derive_keys_full(private_simaka_crypto_t *this,
         * For AKA: MK = SHA1(Identity|IK|CK) */
        this->hasher->get_hash(this->hasher, id->get_encoding(id), NULL);
        this->hasher->allocate_hash(this->hasher, data, mk);
-       DBG3(DBG_IKE, "MK %B", mk);
+       DBG3(DBG_LIB, "MK %B", mk);
 
        /* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf() */
        this->prf->set_key(this->prf, *mk);
@@ -119,12 +147,12 @@ static chunk_t derive_keys_full(private_simaka_crypto_t *this,
        k_encr = chunk_create(str.ptr, KENCR_LEN);
        k_auth = chunk_create(str.ptr + KENCR_LEN, KAUTH_LEN);
        msk = chunk_create(str.ptr + KENCR_LEN + KAUTH_LEN, MSK_LEN);
-       DBG3(DBG_IKE, "K_encr %B\nK_auth %B\nMSK %B", &k_encr, &k_auth, &msk);
+       DBG3(DBG_LIB, "K_encr %B\nK_auth %B\nMSK %B", &k_encr, &k_auth, &msk);
 
        this->signer->set_key(this->signer, k_auth);
        this->crypter->set_key(this->crypter, k_encr);
 
-       charon->sim->key_hook(charon->sim, k_encr, k_auth);
+       call_hook(this, k_encr, k_auth);
 
        this->derived = TRUE;
        return chunk_clone(msk);
@@ -147,12 +175,12 @@ static void derive_keys_reauth(private_simaka_crypto_t *this, chunk_t mk)
        }
        k_encr = chunk_create(str.ptr, KENCR_LEN);
        k_auth = chunk_create(str.ptr + KENCR_LEN, KAUTH_LEN);
-       DBG3(DBG_IKE, "K_encr %B\nK_auth %B", &k_encr, &k_auth);
+       DBG3(DBG_LIB, "K_encr %B\nK_auth %B", &k_encr, &k_auth);
 
        this->signer->set_key(this->signer, k_auth);
        this->crypter->set_key(this->crypter, k_encr);
 
-       charon->sim->key_hook(charon->sim, k_encr, k_auth);
+       call_hook(this, k_encr, k_auth);
 
        this->derived = TRUE;
 }
@@ -181,7 +209,7 @@ static chunk_t derive_keys_reauth_msk(private_simaka_crypto_t *this,
                this->prf->get_bytes(this->prf, chunk_empty, str.ptr + str.len / 2 * i);
        }
        msk = chunk_create(str.ptr, MSK_LEN);
-       DBG3(DBG_IKE, "MSK %B", &msk);
+       DBG3(DBG_LIB, "MSK %B", &msk);
 
        return chunk_clone(msk);
 }
@@ -210,7 +238,7 @@ static void destroy(private_simaka_crypto_t *this)
 /**
  * See header
  */
-simaka_crypto_t *simaka_crypto_create()
+simaka_crypto_t *simaka_crypto_create(eap_type_t type)
 {
        private_simaka_crypto_t *this = malloc_thing(private_simaka_crypto_t);
 
@@ -223,6 +251,7 @@ simaka_crypto_t *simaka_crypto_create()
        this->public.clear_keys = (void(*)(simaka_crypto_t*))clear_keys;
        this->public.destroy = (void(*)(simaka_crypto_t*))destroy;
 
+       this->type = type;
        this->derived = FALSE;
        this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
        this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
@@ -232,7 +261,8 @@ simaka_crypto_t *simaka_crypto_create()
        if (!this->rng || !this->hasher || !this->prf ||
                !this->signer || !this->crypter)
        {
-               DBG1(DBG_IKE, "unable to use EAP-SIM, missing algorithms");
+               DBG1(DBG_LIB, "unable to use %N, missing algorithms",
+                        eap_type_names, type);
                destroy(this);
                return NULL;
        }
diff --git a/src/libsimaka/simaka_hooks.h b/src/libsimaka/simaka_hooks.h
new file mode 100644 (file)
index 0000000..ffe1c25
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2011 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 simaka_hooks simaka_hooks
+ * @{ @ingroup libsimaka
+ */
+
+#ifndef SIMAKA_HOOKS_H_
+#define SIMAKA_HOOKS_H_
+
+typedef struct simaka_hooks_t simaka_hooks_t;
+
+#include "simaka_message.h"
+
+/**
+ * Additional hooks invoked during EAP-SIM/AKA message processing.
+ */
+struct simaka_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)(simaka_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)(simaka_hooks_t *this, chunk_t k_encr, chunk_t k_auth);
+};
+
+#endif /** SIMAKA_HOOKS_H_ @}*/
diff --git a/src/libsimaka/simaka_manager.c b/src/libsimaka/simaka_manager.c
new file mode 100644 (file)
index 0000000..71daf6c
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * 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 "simaka_manager.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_simaka_manager_t private_simaka_manager_t;
+
+/**
+ * Private data of an simaka_manager_t object.
+ */
+struct private_simaka_manager_t {
+
+       /**
+        * Public simaka_manager_t interface.
+        */
+       simaka_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(simaka_manager_t, add_card, void,
+       private_simaka_manager_t *this, simaka_card_t *card)
+{
+       this->lock->write_lock(this->lock);
+       this->cards->insert_last(this->cards, card);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(simaka_manager_t, remove_card, void,
+       private_simaka_manager_t *this, simaka_card_t *card)
+{
+       this->lock->write_lock(this->lock);
+       this->cards->remove(this->cards, card, NULL);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(simaka_manager_t, card_get_triplet, bool,
+       private_simaka_manager_t *this, identification_t *id,
+       char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "tried %d SIM cards, but none has triplets for '%Y'",
+                tried, id);
+       return FALSE;
+}
+
+METHOD(simaka_manager_t, card_get_quintuplet, status_t,
+       private_simaka_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;
+       simaka_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_LIB, "tried %d SIM cards, but none has quintuplets for '%Y'",
+                tried, id);
+       return status;
+}
+
+METHOD(simaka_manager_t, card_resync, bool,
+       private_simaka_manager_t *this, identification_t *id,
+       char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
+{
+       enumerator_t *enumerator;
+       simaka_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(simaka_manager_t, card_set_pseudonym, void,
+       private_simaka_manager_t *this, identification_t *id,
+       identification_t *pseudonym)
+{
+       enumerator_t *enumerator;
+       simaka_card_t *card;
+
+       DBG1(DBG_LIB, "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(simaka_manager_t, card_get_pseudonym, identification_t*,
+       private_simaka_manager_t *this, identification_t *id)
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "using stored pseudonym identity '%Y' "
+                                "instead of '%Y'", pseudonym, id);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return pseudonym;
+}
+
+METHOD(simaka_manager_t, card_set_reauth, void,
+       private_simaka_manager_t *this, identification_t *id, identification_t *next,
+       char mk[HASH_SIZE_SHA1], u_int16_t counter)
+{
+       enumerator_t *enumerator;
+       simaka_card_t *card;
+
+       DBG1(DBG_LIB, "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(simaka_manager_t, card_get_reauth, identification_t*,
+       private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
+       u_int16_t *counter)
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "using stored reauthentication identity '%Y' "
+                                "instead of '%Y'", reauth, id);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return reauth;
+}
+
+METHOD(simaka_manager_t, add_provider, void,
+       private_simaka_manager_t *this, simaka_provider_t *provider)
+{
+       this->lock->write_lock(this->lock);
+       this->providers->insert_last(this->providers, provider);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(simaka_manager_t, remove_provider, void,
+       private_simaka_manager_t *this, simaka_provider_t *provider)
+{
+       this->lock->write_lock(this->lock);
+       this->providers->remove(this->providers, provider, NULL);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(simaka_manager_t, provider_get_triplet, bool,
+       private_simaka_manager_t *this, identification_t *id,
+       char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "tried %d SIM providers, but none had a triplet for '%Y'",
+                tried, id);
+       return FALSE;
+}
+
+METHOD(simaka_manager_t, provider_get_quintuplet, bool,
+       private_simaka_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;
+       simaka_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_LIB, "tried %d SIM providers, but none had a quintuplet for '%Y'",
+                tried, id);
+       return FALSE;
+}
+
+METHOD(simaka_manager_t, provider_resync, bool,
+       private_simaka_manager_t *this, identification_t *id,
+       char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
+{
+       enumerator_t *enumerator;
+       simaka_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(simaka_manager_t, provider_is_pseudonym, identification_t*,
+       private_simaka_manager_t *this, identification_t *id)
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "received pseudonym identity '%Y' "
+                                "mapping to '%Y'", id, permanent);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return permanent;
+}
+
+METHOD(simaka_manager_t, provider_gen_pseudonym, identification_t*,
+       private_simaka_manager_t *this, identification_t *id)
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "proposing new pseudonym '%Y'", pseudonym);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return pseudonym;
+}
+
+METHOD(simaka_manager_t, provider_is_reauth, identification_t*,
+       private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
+       u_int16_t *counter)
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "received reauthentication identity '%Y' "
+                                "mapping to '%Y'", id, permanent);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return permanent;
+}
+
+METHOD(simaka_manager_t, provider_gen_reauth, identification_t*,
+       private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1])
+{
+       enumerator_t *enumerator;
+       simaka_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_LIB, "proposing new reauthentication identity '%Y'", reauth);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return reauth;
+}
+
+METHOD(simaka_manager_t, add_hooks, void,
+       private_simaka_manager_t *this, simaka_hooks_t *hooks)
+{
+       this->lock->write_lock(this->lock);
+       this->hooks->insert_last(this->hooks, hooks);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(simaka_manager_t, remove_hooks, void,
+       private_simaka_manager_t *this, simaka_hooks_t *hooks)
+{
+       this->lock->write_lock(this->lock);
+       this->hooks->remove(this->hooks, hooks, NULL);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(simaka_manager_t, message_hook, void,
+       private_simaka_manager_t *this, simaka_message_t *message,
+       bool inbound, bool decrypted)
+{
+       enumerator_t *enumerator;
+       simaka_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(simaka_manager_t, key_hook, void,
+       private_simaka_manager_t *this, chunk_t k_encr, chunk_t k_auth)
+{
+       enumerator_t *enumerator;
+       simaka_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(simaka_manager_t, destroy, void,
+       private_simaka_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
+ */
+simaka_manager_t *simaka_manager_create()
+{
+       private_simaka_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;
+}
diff --git a/src/libsimaka/simaka_manager.h b/src/libsimaka/simaka_manager.h
new file mode 100644 (file)
index 0000000..403d10a
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2008-2011 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 simaka_manager simaka_manager
+ * @{ @ingroup libsimaka
+ */
+
+#ifndef SIMAKA_MANAGER_H_
+#define SIMAKA_MANAGER_H_
+
+#include <crypto/hashers/hasher.h>
+#include <utils/identification.h>
+#include <utils/enumerator.h>
+
+typedef struct simaka_manager_t simaka_manager_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 "simaka_card.h"
+#include "simaka_provider.h"
+#include "simaka_hooks.h"
+
+/**
+ * The SIM manager handles multiple (U)SIM cards/providers and hooks.
+ */
+struct simaka_manager_t {
+
+       /**
+        * Register a SIM card (client) at the manager.
+        *
+        * @param card          sim card to register
+        */
+       void (*add_card)(simaka_manager_t *this, simaka_card_t *card);
+
+       /**
+        * Unregister a previously registered card from the manager.
+        *
+        * @param card          sim card to unregister
+        */
+       void (*remove_card)(simaka_manager_t *this, simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_manager_t *this, simaka_provider_t *provider);
+
+       /**
+        * Unregister a previously registered provider from the manager.
+        *
+        * @param card          sim card to unregister
+        */
+       void (*remove_provider)(simaka_manager_t *this, simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_manager_t *this, simaka_hooks_t *hooks);
+
+       /**
+        * Unregister a set of hooks from the manager.
+        *
+        * @param hooks         hook interface implementation to unregister
+        */
+       void (*remove_hooks)(simaka_manager_t *this, simaka_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)(simaka_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)(simaka_manager_t *this, chunk_t k_encr, chunk_t k_auth);
+
+       /**
+        * Destroy a manager instance.
+        */
+       void (*destroy)(simaka_manager_t *this);
+};
+
+/**
+ * Create an SIM/AKA manager to handle multiple (U)SIM cards/providers.
+ *
+ * @return                     simaka_t object
+ */
+simaka_manager_t *simaka_manager_create();
+
+#endif /** SIMAKA_MANAGER_H_ @}*/
index 3a8f4be..adef5a9 100644 (file)
 
 #include "simaka_message.h"
 
+#include "simaka_manager.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+
 typedef struct private_simaka_message_t private_simaka_message_t;
 typedef struct hdr_t hdr_t;
 typedef struct attr_hdr_t attr_hdr_t;
@@ -136,7 +141,7 @@ bool simaka_attribute_skippable(simaka_attribute_t attribute)
 {
        bool skippable = !(attribute >= 0 && attribute <= 127);
 
-       DBG1(DBG_IKE, "%sskippable EAP-SIM/AKA attribute %N",
+       DBG1(DBG_LIB, "%sskippable EAP-SIM/AKA attribute %N",
                 skippable ? "ignoring " : "found non-",
                 simaka_attribute_names, attribute);
        return skippable;
@@ -269,7 +274,7 @@ static void add_attribute(private_simaka_message_t *this,
  */
 static bool not_encrypted(simaka_attribute_t type)
 {
-       DBG1(DBG_IKE, "received unencrypted %N", simaka_attribute_names, type);
+       DBG1(DBG_LIB, "received unencrypted %N", simaka_attribute_names, type);
        return FALSE;
 }
 
@@ -278,11 +283,33 @@ static bool not_encrypted(simaka_attribute_t type)
  */
 static bool invalid_length(simaka_attribute_t type)
 {
-       DBG1(DBG_IKE, "invalid length of %N", simaka_attribute_names, type);
+       DBG1(DBG_LIB, "invalid length of %N", simaka_attribute_names, type);
        return FALSE;
 }
 
 /**
+ * Call SIM/AKA message hooks
+ */
+static void call_hook(private_simaka_message_t *this,
+                                         bool inbound, bool decrypted)
+{
+       simaka_manager_t *mgr;
+
+       switch (this->hdr->type)
+       {
+               case EAP_SIM:
+                       mgr = lib->get(lib, "sim-manager");
+                       break;
+               case EAP_AKA:
+                       mgr = lib->get(lib, "aka-manager");
+                       break;
+               default:
+                       return;
+       }
+       mgr->message_hook(mgr, &this->public, inbound, decrypted);
+}
+
+/**
  * Parse attributes from a chunk of data
  */
 static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
@@ -294,7 +321,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
 
                if (in.len < sizeof(attr_hdr_t))
                {
-                       DBG1(DBG_IKE, "found short %N attribute header",
+                       DBG1(DBG_LIB, "found short %N attribute header",
                                 eap_type_names, this->hdr->type);
                        return FALSE;
                }
@@ -450,7 +477,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
                                }
                                else if (!this->encrypted)
                                {
-                                       DBG1(DBG_IKE, "found P-bit 0 notify in unencrypted message");
+                                       DBG1(DBG_LIB, "found P-bit 0 notify in unencrypted message");
                                        return FALSE;
                                }
                                /* FALL */
@@ -460,7 +487,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
                }
        }
 
-       charon->sim->message_hook(charon->sim, &this->public, TRUE, this->encrypted);
+       call_hook(this, TRUE, this->encrypted);
 
        return TRUE;
 }
@@ -481,7 +508,7 @@ static bool decrypt(private_simaka_message_t *this)
        }
        if (this->encr.len % crypter->get_block_size(crypter))
        {
-               DBG1(DBG_IKE, "%N ENCR_DATA not a multiple of block size",
+               DBG1(DBG_LIB, "%N ENCR_DATA not a multiple of block size",
                         eap_type_names, this->hdr->type);
                return FALSE;
        }
@@ -543,7 +570,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
                {
                        if (!this->mac.ptr || !signer)
                        {       /* require MAC, but not found */
-                               DBG1(DBG_IKE, "%N message requires a MAC, but none found",
+                               DBG1(DBG_LIB, "%N message requires a MAC, but none found",
                                         simaka_subtype_names, this->hdr->subtype);
                                return FALSE;
                        }
@@ -558,7 +585,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
                        }
                        if (!this->mac.ptr || !signer)
                        {
-                               DBG1(DBG_IKE, "%N message has a phase 0 notify, but "
+                               DBG1(DBG_LIB, "%N message has a phase 0 notify, but "
                                         "no MAC found", simaka_subtype_names, this->hdr->subtype);
                                return FALSE;
                        }
@@ -566,7 +593,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
                }
                default:
                        /* unknown message? */
-                       DBG1(DBG_IKE, "signature rule for %N messages missing",
+                       DBG1(DBG_LIB, "signature rule for %N messages missing",
                                 simaka_subtype_names, this->hdr->subtype);
                        return FALSE;
        }
@@ -582,7 +609,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
        }
        if (!signer->verify_signature(signer, data, backup))
        {
-               DBG1(DBG_IKE, "%N MAC verification failed",
+               DBG1(DBG_LIB, "%N MAC verification failed",
                         eap_type_names, this->hdr->type);
                return FALSE;
        }
@@ -592,7 +619,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
 /**
  * Implementation of simaka_message_t.generate
  */
-static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
+static chunk_t generate(private_simaka_message_t *this, chunk_t sigdata)
 {
        /* buffers large enough for messages we generate */
        char out_buf[1024], encr_buf[512];
@@ -603,7 +630,7 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
        u_int16_t len;
        signer_t *signer;
 
-       charon->sim->message_hook(charon->sim, &this->public, FALSE, TRUE);
+       call_hook(this, FALSE, TRUE);
 
        out = chunk_create(out_buf, sizeof(out_buf));
        encr = chunk_create(encr_buf, sizeof(encr_buf));
@@ -723,7 +750,7 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
                        }
                        default:
                        {
-                               DBG1(DBG_IKE, "no rule to encode %N, skipped",
+                               DBG1(DBG_LIB, "no rule to encode %N, skipped",
                                         simaka_attribute_names, type);
                                break;
                        }
@@ -817,9 +844,9 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
                signer->get_signature(signer, data, mac.ptr);
        }
 
-       charon->sim->message_hook(charon->sim, &this->public, FALSE, FALSE);
+       call_hook(this, FALSE, FALSE);
 
-       return eap_payload_create_data(out);
+       return chunk_clone(out);
 }
 
 /**
@@ -843,18 +870,18 @@ static simaka_message_t *simaka_message_create_data(chunk_t data,
 
        if (data.len < sizeof(hdr_t) || hdr->length != htons(data.len))
        {
-               DBG1(DBG_IKE, "EAP-SIM/AKA header has invalid length");
+               DBG1(DBG_LIB, "EAP-SIM/AKA header has invalid length");
                return NULL;
        }
        if (hdr->code != EAP_REQUEST && hdr->code != EAP_RESPONSE)
        {
-               DBG1(DBG_IKE, "invalid EAP code in EAP-SIM/AKA message",
+               DBG1(DBG_LIB, "invalid EAP code in EAP-SIM/AKA message",
                         eap_type_names, hdr->type);
                return NULL;
        }
        if (hdr->type != EAP_SIM && hdr->type != EAP_AKA)
        {
-               DBG1(DBG_IKE, "invalid EAP type in EAP-SIM/AKA message",
+               DBG1(DBG_LIB, "invalid EAP type in EAP-SIM/AKA message",
                         eap_type_names, hdr->type);
                return NULL;
        }
@@ -869,7 +896,7 @@ static simaka_message_t *simaka_message_create_data(chunk_t data,
        this->public.add_attribute = (void(*)(simaka_message_t*, simaka_attribute_t type, chunk_t data))add_attribute;
        this->public.parse = (bool(*)(simaka_message_t*))parse;
        this->public.verify = (bool(*)(simaka_message_t*, chunk_t sigdata))verify;
-       this->public.generate = (eap_payload_t*(*)(simaka_message_t*, chunk_t sigdata))generate;
+       this->public.generate = (chunk_t(*)(simaka_message_t*, chunk_t sigdata))generate;
        this->public.destroy = (void(*)(simaka_message_t*))destroy;
 
        this->attributes = linked_list_create();
@@ -888,10 +915,10 @@ static simaka_message_t *simaka_message_create_data(chunk_t data,
 /**
  * See header.
  */
-simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload,
+simaka_message_t *simaka_message_create_from_payload(chunk_t data,
                                                                                                         simaka_crypto_t *crypto)
 {
-       return simaka_message_create_data(payload->get_data(payload), crypto);
+       return simaka_message_create_data(data, crypto);
 }
 
 /**
index 341f729..28fe218 100644 (file)
@@ -27,7 +27,7 @@
 #define SIMAKA_MESSAGE_H_
 
 #include <enum.h>
-#include <daemon.h>
+#include <eap/eap.h>
 
 #include "simaka_crypto.h"
 
@@ -35,6 +35,7 @@ typedef enum simaka_attribute_t simaka_attribute_t;
 typedef enum simaka_subtype_t simaka_subtype_t;
 typedef enum simaka_notification_t simaka_notification_t;
 typedef enum simaka_client_error_t simaka_client_error_t;
+typedef struct simaka_message_t simaka_message_t;
 
 /**
  * Subtypes of EAP-SIM/AKA messages
@@ -235,9 +236,9 @@ struct simaka_message_t {
         * Generate a message, optionally encrypt attributes and create a MAC.
         *
         * @param sigdata       additional data to include in signature, if any
-        * @return                      generated eap payload, NULL if failed
+        * @return                      allocated data of generated message
         */
-       eap_payload_t* (*generate)(simaka_message_t *this, chunk_t sigdata);
+       chunk_t (*generate)(simaka_message_t *this, chunk_t sigdata);
 
        /**
         * Destroy a simaka_message_t.
@@ -262,11 +263,11 @@ simaka_message_t *simaka_message_create(bool request, u_int8_t identifier,
 /**
  * Create an simaka_message from a chunk of data.
  *
- * @param payload              payload to create message from
+ * @param data                 message data to parse
  * @param crypto               EAP-SIM/AKA crypto helper
  * @return                             EAP message, NULL on error
  */
-simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload,
+simaka_message_t *simaka_message_create_from_payload(chunk_t data,
                                                                                                         simaka_crypto_t *crypto);
 
 #endif /** SIMAKA_MESSAGE_H_ @}*/
diff --git a/src/libsimaka/simaka_provider.h b/src/libsimaka/simaka_provider.h
new file mode 100644 (file)
index 0000000..f1bf800
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008-2011 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 simaka_provider simaka_provider
+ * @{ @ingroup libsimaka
+ */
+
+#ifndef SIMAKA_PROVIDER_H_
+#define SIMAKA_PROVIDER_H_
+
+typedef struct simaka_provider_t simaka_provider_t;
+
+#include "simaka_manager.h"
+
+#include <utils/identification.h>
+
+/**
+ * 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 simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_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)(simaka_provider_t *this, identification_t *id,
+                                                                       char mk[HASH_SIZE_SHA1]);
+};
+
+#endif /** SIMAKA_CARD_H_ @}*/