summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/authenticators
diff options
context:
space:
mode:
authorRené Mayrhofer <rene@mayrhofer.eu.org>2011-05-19 13:37:29 +0200
committerRené Mayrhofer <rene@mayrhofer.eu.org>2011-05-19 13:37:29 +0200
commit0a9d51a49042a68daa15b0c74a2b7f152f52606b (patch)
tree451888dcb17d00e52114f734e846821373fbbd44 /src/libcharon/sa/authenticators
parent568905f488e63e28778f87ac0e38d845f45bae79 (diff)
downloadvyos-strongswan-0a9d51a49042a68daa15b0c74a2b7f152f52606b.tar.gz
vyos-strongswan-0a9d51a49042a68daa15b0c74a2b7f152f52606b.zip
Imported Upstream version 4.5.2
Diffstat (limited to 'src/libcharon/sa/authenticators')
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_method.h21
-rw-r--r--src/libcharon/sa/authenticators/eap/sim_card.h125
-rw-r--r--src/libcharon/sa/authenticators/eap/sim_hooks.h53
-rw-r--r--src/libcharon/sa/authenticators/eap/sim_manager.c298
-rw-r--r--src/libcharon/sa/authenticators/eap/sim_manager.h229
-rw-r--r--src/libcharon/sa/authenticators/eap/sim_provider.h124
-rw-r--r--src/libcharon/sa/authenticators/eap_authenticator.c16
7 files changed, 481 insertions, 385 deletions
diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h
index 9961039ff..0eab2b5ff 100644
--- a/src/libcharon/sa/authenticators/eap/eap_method.h
+++ b/src/libcharon/sa/authenticators/eap/eap_method.h
@@ -113,14 +113,29 @@ struct eap_method_t {
* Not all EAP methods establish a shared secret. For implementations of
* the EAP-Identity method, get_msk() returns the received identity.
*
- * @param msk chunk receiving internal stored MSK
+ * @param msk chunk receiving internal stored MSK
* @return
- * - SUCCESS, or
- * - FAILED, if MSK not established (yet)
+ * - SUCCESS, or
+ * - FAILED, if MSK not established (yet)
*/
status_t (*get_msk) (eap_method_t *this, chunk_t *msk);
/**
+ * Get the current EAP identifier.
+ *
+ * @return current EAP identifier
+ */
+ u_int8_t (*get_identifier) (eap_method_t *this);
+
+ /**
+ * Set the EAP identifier to a deterministic value, overwriting
+ * the randomly initialized default value.
+ *
+ * @param identifier current EAP identifier
+ */
+ void (*set_identifier) (eap_method_t *this, u_int8_t identifier);
+
+ /**
* Destroys a eap_method_t object.
*/
void (*destroy) (eap_method_t *this);
diff --git a/src/libcharon/sa/authenticators/eap/sim_card.h b/src/libcharon/sa/authenticators/eap/sim_card.h
new file mode 100644
index 000000000..5f5dc580b
--- /dev/null
+++ b/src/libcharon/sa/authenticators/eap/sim_card.h
@@ -0,0 +1,125 @@
+/*
+ * 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
new file mode 100644
index 000000000..0a675e4ab
--- /dev/null
+++ b/src/libcharon/sa/authenticators/eap/sim_hooks.h
@@ -0,0 +1,53 @@
+/*
+ * 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
index 157865083..9ccaf5298 100644
--- a/src/libcharon/sa/authenticators/eap/sim_manager.c
+++ b/src/libcharon/sa/authenticators/eap/sim_manager.c
@@ -17,6 +17,7 @@
#include <daemon.h>
#include <utils/linked_list.h>
+#include <threading/rwlock.h>
typedef struct private_sim_manager_t private_sim_manager_t;
@@ -44,65 +45,67 @@ struct private_sim_manager_t {
* list of added hooks
*/
linked_list_t *hooks;
+
+ /**
+ * lock for lists above
+ */
+ rwlock_t *lock;
};
-/**
- * Implementation of sim_manager_t.add_card
- */
-static void add_card(private_sim_manager_t *this, sim_card_t *card)
+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);
}
-/**
- * Implementation of sim_manager_t.remove_card
- */
-static void remove_card(private_sim_manager_t *this, sim_card_t *card)
+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);
}
-/**
- * Implementation of sim_manager_t.card_get_triplet
- */
-static bool card_get_triplet(private_sim_manager_t *this, identification_t *id,
- char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
- char kc[SIM_KC_LEN])
+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;
}
-/**
- * Implementation of sim_manager_t.card_get_quintuplet
- */
-static status_t card_get_quintuplet(private_sim_manager_t *this,
- identification_t *id, char rand[AKA_RAND_LEN],
- char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
- char ik[AKA_IK_LEN], char res[AKA_RES_MAX],
- int *res_len)
+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))
{
@@ -112,6 +115,7 @@ static status_t card_get_quintuplet(private_sim_manager_t *this,
case SUCCESS:
case INVALID_STATE:
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
return status;
case NOT_SUPPORTED:
case FAILED:
@@ -121,62 +125,62 @@ static status_t card_get_quintuplet(private_sim_manager_t *this,
}
}
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;
}
-/**
- * Implementation of sim_manager_t.card_resync
- */
-static bool card_resync(private_sim_manager_t *this, identification_t *id,
- char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
+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;
}
-/**
- * Implementation of sim_manager_t.card_set_pseudonym
- */
-static void card_set_pseudonym(private_sim_manager_t *this,
- identification_t *id, identification_t *pseudonym)
+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);
}
-/**
- * Implementation of sim_manager_t.card_get_pseudonym
- */
-static identification_t* card_get_pseudonym(private_sim_manager_t *this,
- identification_t *id)
+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))
{
@@ -189,15 +193,13 @@ static identification_t* card_get_pseudonym(private_sim_manager_t *this,
}
}
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
return pseudonym;
}
-/**
- * Implementation of sim_manager_t.card_set_reauth
- */
-static void card_set_reauth(private_sim_manager_t *this, identification_t *id,
- identification_t *next, char mk[HASH_SIZE_SHA1],
- u_int16_t counter)
+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;
@@ -205,25 +207,25 @@ static void card_set_reauth(private_sim_manager_t *this, identification_t *id,
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);
}
-/**
- * Implementation of sim_manager_t.card_get_reauth
- */
-static identification_t* card_get_reauth(private_sim_manager_t *this,
- identification_t *id, char mk[HASH_SIZE_SHA1],
- u_int16_t *counter)
+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))
{
@@ -236,66 +238,63 @@ static identification_t* card_get_reauth(private_sim_manager_t *this,
}
}
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
return reauth;
}
-/**
- * Implementation of sim_manager_t.add_provider
- */
-static void add_provider(private_sim_manager_t *this, sim_provider_t *provider)
+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);
}
-/**
- * Implementation of sim_manager_t.remove_provider
- */
-static void remove_provider(private_sim_manager_t *this,
- sim_provider_t *provider)
+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);
}
-/**
- * Implementation of sim_manager_t.provider_get_triplet
- */
-static bool provider_get_triplet(private_sim_manager_t *this,
- identification_t *id, char rand[SIM_RAND_LEN],
- char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
+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;
}
-/**
- * Implementation of sim_manager_t.provider_get_quintuplet
- */
-static bool provider_get_quintuplet(private_sim_manager_t *this,
- identification_t *id, char rand[AKA_RAND_LEN],
- char xres[AKA_RES_MAX], int *xres_len,
- char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
- char autn[AKA_AUTN_LEN])
+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))
{
@@ -303,47 +302,48 @@ static bool provider_get_quintuplet(private_sim_manager_t *this,
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;
}
-/**
- * Implementation of sim_manager_t.provider_resync
- */
-static bool provider_resync(private_sim_manager_t *this, identification_t *id,
- char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
+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;
}
-/**
- * Implementation of sim_manager_t.provider_is_pseudonym
- */
-static identification_t* provider_is_pseudonym(private_sim_manager_t *this,
- identification_t *id)
+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))
{
@@ -356,19 +356,18 @@ static identification_t* provider_is_pseudonym(private_sim_manager_t *this,
}
}
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
return permanent;
}
-/**
- * Implementation of sim_manager_t.provider_gen_pseudonym
- */
-static identification_t* provider_gen_pseudonym(private_sim_manager_t *this,
- identification_t *id)
+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))
{
@@ -380,20 +379,19 @@ static identification_t* provider_gen_pseudonym(private_sim_manager_t *this,
}
}
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
return pseudonym;
}
-/**
- * Implementation of sim_manager_t.provider_is_reauth
- */
-static identification_t* provider_is_reauth(private_sim_manager_t *this,
- identification_t *id, char mk[HASH_SIZE_SHA1],
- u_int16_t *counter)
+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))
{
@@ -406,19 +404,18 @@ static identification_t* provider_is_reauth(private_sim_manager_t *this,
}
}
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
return permanent;
}
-/**
- * Implementation of sim_manager_t.provider_gen_reauth
- */
-static identification_t* provider_gen_reauth(private_sim_manager_t *this,
- identification_t *id, char mk[HASH_SIZE_SHA1])
+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))
{
@@ -430,67 +427,66 @@ static identification_t* provider_gen_reauth(private_sim_manager_t *this,
}
}
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
return reauth;
}
-/**
- * Implementation of sim_manager_t.add_hooks
- */
-static void add_hooks(private_sim_manager_t *this, sim_hooks_t *hooks)
+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);
}
-/**
- * Implementation of sim_manager_t.remove_hooks
- */
-static void remove_hooks(private_sim_manager_t *this, sim_hooks_t *hooks)
+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);
}
-/**
- * Implementation of sim_manager_t.message_hook
- */
-static void message_hook(private_sim_manager_t *this,
- simaka_message_t *message, bool inbound, bool decrypted)
+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);
}
-/**
- * Implementation of sim_manager_t.key_hook
- */
-static void key_hook(private_sim_manager_t *this,
- chunk_t k_encr, chunk_t k_auth)
+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);
}
-/**
- * Implementation of sim_manager_t.destroy.
- */
-static void destroy(private_sim_manager_t *this)
+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);
}
@@ -499,35 +495,39 @@ static void destroy(private_sim_manager_t *this)
*/
sim_manager_t *sim_manager_create()
{
- private_sim_manager_t *this = malloc_thing(private_sim_manager_t);
-
- this->public.add_card = (void(*)(sim_manager_t*, sim_card_t *card))add_card;
- this->public.remove_card = (void(*)(sim_manager_t*, sim_card_t *card))remove_card;
- this->public.card_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))card_get_triplet;
- this->public.card_get_quintuplet = (status_t(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))card_get_quintuplet;
- this->public.card_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))card_resync;
- this->public.card_set_pseudonym = (void(*)(sim_manager_t*, identification_t *id, identification_t *pseudonym))card_set_pseudonym;
- this->public.card_get_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))card_get_pseudonym;
- this->public.card_set_reauth = (void(*)(sim_manager_t*, identification_t *id, identification_t *next, char mk[HASH_SIZE_SHA1], u_int16_t counter))card_set_reauth;
- this->public.card_get_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))card_get_reauth;
- this->public.add_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))add_provider;
- this->public.remove_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))remove_provider;
- this->public.provider_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))provider_get_triplet;
- this->public.provider_get_quintuplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))provider_get_quintuplet;
- this->public.provider_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))provider_resync;
- this->public.provider_is_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_is_pseudonym;
- this->public.provider_gen_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_gen_pseudonym;
- this->public.provider_is_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))provider_is_reauth;
- this->public.provider_gen_reauth = (identification_t*(*)(sim_manager_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))provider_gen_reauth;
- this->public.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.message_hook = (void(*)(sim_manager_t*, simaka_message_t *message, bool inbound, bool decrypted))message_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();
+ 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
index 9aa661ac8..db4a65011 100644
--- a/src/libcharon/sa/authenticators/eap/sim_manager.h
+++ b/src/libcharon/sa/authenticators/eap/sim_manager.h
@@ -27,9 +27,6 @@
#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;
/** implemented in libsimaka, but we need it for the message hook */
typedef struct simaka_message_t simaka_message_t;
@@ -45,229 +42,9 @@ typedef struct simaka_message_t simaka_message_t;
#define AKA_AUTN_LEN 16
#define AKA_AUTS_LEN 14
-/**
- * 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);
-};
-
-/**
- * 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]);
-};
-
-/**
- * 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);
-};
+#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.
diff --git a/src/libcharon/sa/authenticators/eap/sim_provider.h b/src/libcharon/sa/authenticators/eap/sim_provider.h
new file mode 100644
index 000000000..191e094db
--- /dev/null
+++ b/src/libcharon/sa/authenticators/eap/sim_provider.h
@@ -0,0 +1,124 @@
+/*
+ * 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_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c
index dea02755d..d442acb00 100644
--- a/src/libcharon/sa/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/authenticators/eap_authenticator.c
@@ -183,16 +183,18 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this,
if (this->method)
{
action = "initiating";
+ type = this->method->get_type(this->method, &vendor);
if (this->method->initiate(this->method, &out) == NEED_MORE)
{
if (vendor)
{
- DBG1(DBG_IKE, "initiating EAP vendor type %d-%d method",
- type, vendor);
+ DBG1(DBG_IKE, "initiating EAP vendor type %d-%d method (id 0x%02X)",
+ type, vendor, out->get_identifier(out));
}
else
{
- DBG1(DBG_IKE, "initiating %N method", eap_type_names, type);
+ DBG1(DBG_IKE, "initiating %N method (id 0x%02X)", eap_type_names,
+ type, out->get_identifier(out));
}
return out;
}
@@ -371,13 +373,13 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this,
{
if (vendor)
{
- DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d",
- type, vendor);
+ DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d ",
+ "(id 0x%02X)", type, vendor, in->get_identifier(in));
}
else
{
- DBG1(DBG_IKE, "server requested %N authentication",
- eap_type_names, type);
+ DBG1(DBG_IKE, "server requested %N authentication (id 0x%02X)",
+ eap_type_names, type, in->get_identifier(in));
}
this->method = load_method(this, type, vendor, EAP_PEER);
if (!this->method)