Extended SIM manager by hooks, currently featuring attribute and key hooks
authorMartin Willi <martin@strongswan.org>
Fri, 27 Nov 2009 10:14:40 +0000 (11:14 +0100)
committerMartin Willi <martin@strongswan.org>
Mon, 30 Nov 2009 08:27:26 +0000 (09:27 +0100)
src/charon/sa/authenticators/eap/sim_manager.c
src/charon/sa/authenticators/eap/sim_manager.h

index 940b25d..5060a31 100644 (file)
@@ -39,6 +39,11 @@ struct private_sim_manager_t {
         * list of added provider
         */
        linked_list_t *providers;
+
+       /**
+        * list of added hooks
+        */
+       linked_list_t *hooks;
 };
 
 /**
@@ -429,12 +434,70 @@ static identification_t* provider_gen_reauth(private_sim_manager_t *this,
 }
 
 /**
+ * Implementation of sim_manager_t.add_hooks
+ */
+static void add_hooks(private_sim_manager_t *this, sim_hooks_t *hooks)
+{
+       this->hooks->insert_last(this->hooks, hooks);
+}
+
+/**
+ * Implementation of sim_manager_t.remove_hooks
+ */
+static void remove_hooks(private_sim_manager_t *this, sim_hooks_t *hooks)
+{
+       this->hooks->remove(this->hooks, hooks, NULL);
+}
+
+/**
+ * Implementation of sim_manager_t.attribute_hook
+ */
+static bool attribute_hook(private_sim_manager_t *this, eap_code_t code,
+                                                  eap_type_t type, u_int8_t subtype,
+                                                  u_int8_t attribute, chunk_t data)
+{
+       enumerator_t *enumerator;
+       sim_hooks_t *hooks;
+       bool filter = FALSE;
+
+       enumerator = this->hooks->create_enumerator(this->hooks);
+       while (enumerator->enumerate(enumerator, &hooks))
+       {
+               if (hooks->attribute(hooks, code, type, subtype, attribute, data))
+               {
+                       filter = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return filter;
+}
+
+/**
+ * Implementation of sim_manager_t.key_hook
+ */
+static void key_hook(private_sim_manager_t *this,
+                                        chunk_t k_encr, chunk_t k_auth)
+{
+       enumerator_t *enumerator;
+       sim_hooks_t *hooks;
+
+       enumerator = this->hooks->create_enumerator(this->hooks);
+       while (enumerator->enumerate(enumerator, &hooks))
+       {
+               hooks->keys(hooks, k_encr, k_auth);
+       }
+       enumerator->destroy(enumerator);
+}
+
+/**
  * Implementation of sim_manager_t.destroy.
  */
 static void destroy(private_sim_manager_t *this)
 {
        this->cards->destroy(this->cards);
        this->providers->destroy(this->providers);
+       this->hooks->destroy(this->hooks);
        free(this);
 }
 
@@ -463,10 +526,15 @@ sim_manager_t *sim_manager_create()
        this->public.provider_gen_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_gen_pseudonym;
        this->public.provider_is_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))provider_is_reauth;
        this->public.provider_gen_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))provider_gen_reauth;
+       this->public.add_hooks = (void(*)(sim_manager_t*, sim_hooks_t *hooks))add_hooks;
+       this->public.remove_hooks = (void(*)(sim_manager_t*, sim_hooks_t *hooks))remove_hooks;
+       this->public.attribute_hook = (bool(*)(sim_manager_t*, eap_code_t code, eap_type_t type, u_int8_t subtype, u_int8_t attribute, chunk_t data))attribute_hook;
+       this->public.key_hook = (void(*)(sim_manager_t*, chunk_t k_encr, chunk_t k_auth))key_hook;
        this->public.destroy = (void(*)(sim_manager_t*))destroy;
 
        this->cards = linked_list_create();
        this->providers = linked_list_create();
+       this->hooks = linked_list_create();
 
        return &this->public;
 }
index 75f3ace..49d27cb 100644 (file)
 #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;
 typedef struct sim_card_t sim_card_t;
 typedef struct sim_provider_t sim_provider_t;
+typedef struct sim_hooks_t sim_hooks_t;
 
 #define SIM_RAND_LEN   16
 #define SIM_SRES_LEN    4
@@ -238,7 +240,34 @@ struct sim_provider_t {
 };
 
 /**
- * The SIM manager handles multiple (U)SIM cards and providers.
+ * Additional hooks invoked during EAP-SIM/AKA message processing.
+ */
+struct sim_hooks_t {
+
+       /**
+        * SIM/AKA attribute parsing hook.
+        *
+        * @param code          code of EAP message the attribute was parsed from
+        * @param type          EAP method, SIM or AKA
+        * @param subtye        method specific subtype
+        * @param attribute     parsed SIM/AKA attribute type
+        * @param data          attribute data
+        * @return                      TRUE to filter out attribute from further processing
+        */
+       bool (*attribute)(sim_hooks_t *this, eap_code_t code, eap_type_t type,
+                                         u_int8_t subtype, u_int8_t attribute, chunk_t data);
+
+       /**
+        * 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);
+};
+
+/**
+ * The SIM manager handles multiple (U)SIM cards/providers and hooks.
  */
 struct sim_manager_t {
 
@@ -435,6 +464,42 @@ struct sim_manager_t {
                                                                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 attribute hook.
+        *
+        * @param code          EAP message code (Request/response/success/failed)
+        * @param type          EAP method type, EAP-SIM or AKA
+        * @param subtype       method specific message subtype
+        * @param attribute     SIM/AKA attribute type
+        * @param data          attribute data
+        * @return                      TRUE to filter out attribute from further processing
+        */
+       bool (*attribute_hook)(sim_manager_t *this, eap_code_t code,
+                                                  eap_type_t type, u_int8_t subtype,
+                                                  u_int8_t attribute, chunk_t data);
+
+       /**
+        * 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);