diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2012-07-19 12:16:46 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2012-07-19 16:03:19 -0700 |
commit | 04949598a23f501be6eec21697465fd46a28840a (patch) | |
tree | 6eb315b8d139b0690cb644dc914c53bacb42df42 /src/eap_server | |
parent | ce1e0634ed741293de60d5ba3476b26ccbd58ce2 (diff) | |
download | external_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.zip external_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.tar.gz external_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.tar.bz2 |
wpa_supplicant: Update to 07-Jul-2012 TOT
commit a5ed45586c63ffd8f9d2b44e27c251d7bacbeaf4
Author: Jouni Malinen <j@w1.fi>
Date: Sat Jul 7 13:01:45 2012 +0300
WPS SSDP: Fix socket leaks on error paths
Change-Id: I0864aac7fc88fa2a60f5cca7d524b94363410c85
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/eap_server')
-rw-r--r-- | src/eap_server/eap_server_aka.c | 45 | ||||
-rw-r--r-- | src/eap_server/eap_server_pwd.c | 65 | ||||
-rw-r--r-- | src/eap_server/eap_server_sim.c | 31 | ||||
-rw-r--r-- | src/eap_server/eap_sim_db.c | 75 | ||||
-rw-r--r-- | src/eap_server/eap_sim_db.h | 17 |
5 files changed, 155 insertions, 78 deletions
diff --git a/src/eap_server/eap_server_aka.c b/src/eap_server/eap_server_aka.c index 135c02b..9cd5509 100644 --- a/src/eap_server/eap_server_aka.c +++ b/src/eap_server/eap_server_aka.c @@ -1,6 +1,6 @@ /* - * hostapd / EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf) - * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi> + * hostapd / EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448) + * Copyright (c) 2005-2012, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -266,8 +266,18 @@ static struct wpabuf * eap_aka_build_identity(struct eap_sm *sm, EAP_AKA_SUBTYPE_IDENTITY); if (eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity, sm->identity_len)) { - wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ"); - eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0); + if (sm->identity_len > 0 && + (sm->identity[0] == EAP_AKA_REAUTH_ID_PREFIX || + sm->identity[0] == EAP_AKA_PRIME_REAUTH_ID_PREFIX)) { + /* Reauth id may have expired - try fullauth */ + wpa_printf(MSG_DEBUG, " AT_FULLAUTH_ID_REQ"); + eap_sim_msg_add(msg, EAP_SIM_AT_FULLAUTH_ID_REQ, 0, + NULL, 0); + } else { + wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ"); + eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, + NULL, 0); + } } else { /* * RFC 4187, Chap. 4.1.4 recommends that identity from EAP is @@ -292,12 +302,23 @@ static int eap_aka_build_encr(struct eap_sm *sm, struct eap_aka_data *data, const u8 *nonce_s) { os_free(data->next_pseudonym); - data->next_pseudonym = - eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 1); + if (nonce_s == NULL) { + data->next_pseudonym = + eap_sim_db_get_next_pseudonym( + sm->eap_sim_db_priv, + data->eap_method == EAP_TYPE_AKA_PRIME ? + EAP_SIM_DB_AKA_PRIME : EAP_SIM_DB_AKA); + } else { + /* Do not update pseudonym during re-authentication */ + data->next_pseudonym = NULL; + } os_free(data->next_reauth_id); if (data->counter <= EAP_AKA_MAX_FAST_REAUTHS) { data->next_reauth_id = - eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 1); + eap_sim_db_get_next_reauth_id( + sm->eap_sim_db_priv, + data->eap_method == EAP_TYPE_AKA_PRIME ? + EAP_SIM_DB_AKA_PRIME : EAP_SIM_DB_AKA); } else { wpa_printf(MSG_DEBUG, "EAP-AKA: Max fast re-authentication " "count exceeded - force full authentication"); @@ -615,7 +636,8 @@ static void eap_aka_determine_identity(struct eap_sm *sm, identity = data->reauth->identity; identity_len = data->reauth->identity_len; } else if (sm->identity && sm->identity_len > 0 && - sm->identity[0] == EAP_AKA_PERMANENT_PREFIX) { + (sm->identity[0] == EAP_AKA_PERMANENT_PREFIX || + sm->identity[0] == EAP_AKA_PRIME_PERMANENT_PREFIX)) { identity = sm->identity; identity_len = sm->identity_len; } else { @@ -731,7 +753,7 @@ static void eap_aka_determine_identity(struct eap_sm *sm, sm->identity, identity_len); if (data->eap_method == EAP_TYPE_AKA_PRIME) { - eap_aka_prime_derive_keys(identity, identity_len, data->ik, + eap_aka_prime_derive_keys(sm->identity, identity_len, data->ik, data->ck, data->k_encr, data->k_aut, data->k_re, data->msk, data->emsk); } else { @@ -1017,11 +1039,6 @@ static void eap_aka_process_reauth(struct eap_sm *sm, identity_len = id2_len; } - if (data->next_pseudonym) { - eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity, - identity_len, data->next_pseudonym); - data->next_pseudonym = NULL; - } if (data->next_reauth_id) { if (data->eap_method == EAP_TYPE_AKA_PRIME) { #ifdef EAP_SERVER_AKA_PRIME diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c index 6c47dee..b61061b 100644 --- a/src/eap_server/eap_server_pwd.c +++ b/src/eap_server/eap_server_pwd.c @@ -9,6 +9,7 @@ #include "includes.h" #include "common.h" +#include "crypto/sha256.h" #include "eap_server/eap_i.h" #include "eap_common/eap_pwd_common.h" @@ -40,7 +41,7 @@ struct eap_pwd_data { EC_POINT *my_element; EC_POINT *peer_element; - u8 my_confirm[SHA256_DIGEST_LENGTH]; + u8 my_confirm[SHA256_MAC_LEN]; u8 msk[EAP_MSK_LEN]; u8 emsk[EAP_EMSK_LEN]; @@ -288,8 +289,8 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm, struct eap_pwd_data *data, u8 id) { BIGNUM *x = NULL, *y = NULL; - HMAC_CTX ctx; - u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr; + struct crypto_hash *hash; + u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr; u16 grp; int offset; @@ -313,7 +314,9 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm, * commit is H(k | server_element | server_scalar | peer_element | * peer_scalar | ciphersuite) */ - H_Init(&ctx); + hash = eap_pwd_h_init(); + if (hash == NULL) + goto fin; /* * Zero the memory each time because this is mod prime math and some @@ -324,7 +327,7 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm, os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k); BN_bn2bin(data->k, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); /* server element: x, y */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, @@ -338,18 +341,18 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm, os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x); BN_bn2bin(x, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y); BN_bn2bin(y, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); /* server scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->order) - BN_num_bytes(data->my_scalar); BN_bn2bin(data->my_scalar, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order)); /* peer element: x, y */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, @@ -363,18 +366,18 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm, os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x); BN_bn2bin(x, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y); BN_bn2bin(y, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); /* peer scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->order) - BN_num_bytes(data->peer_scalar); BN_bn2bin(data->peer_scalar, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order)); /* ciphersuite */ grp = htons(data->group_num); @@ -386,17 +389,17 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm, ptr += sizeof(u8); *ptr = EAP_PWD_DEFAULT_PRF; ptr += sizeof(u8); - H_Update(&ctx, cruft, ptr-cruft); + eap_pwd_h_update(hash, cruft, ptr - cruft); /* all done with the random function */ - H_Final(&ctx, conf); - os_memcpy(data->my_confirm, conf, SHA256_DIGEST_LENGTH); + eap_pwd_h_final(hash, conf); + os_memcpy(data->my_confirm, conf, SHA256_MAC_LEN); - data->outbuf = wpabuf_alloc(SHA256_DIGEST_LENGTH); + data->outbuf = wpabuf_alloc(SHA256_MAC_LEN); if (data->outbuf == NULL) goto fin; - wpabuf_put_data(data->outbuf, conf, SHA256_DIGEST_LENGTH); + wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN); fin: os_free(cruft); @@ -404,8 +407,6 @@ fin: BN_free(y); if (data->outbuf == NULL) eap_pwd_state(data, FAILURE); - - return; } @@ -735,10 +736,10 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data, const u8 *payload, size_t payload_len) { BIGNUM *x = NULL, *y = NULL; - HMAC_CTX ctx; + struct crypto_hash *hash; u32 cs; u16 grp; - u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr; + u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr; int offset; /* build up the ciphersuite: group | random_function | prf */ @@ -761,13 +762,15 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data, * commit is H(k | peer_element | peer_scalar | server_element | * server_scalar | ciphersuite) */ - H_Init(&ctx); + hash = eap_pwd_h_init(); + if (hash == NULL) + goto fin; /* k */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k); BN_bn2bin(data->k, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); /* peer element: x, y */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, @@ -780,18 +783,18 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data, os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x); BN_bn2bin(x, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y); BN_bn2bin(y, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); /* peer scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->order) - BN_num_bytes(data->peer_scalar); BN_bn2bin(data->peer_scalar, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order)); /* server element: x, y */ if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group, @@ -805,28 +808,28 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data, os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x); BN_bn2bin(x, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y); BN_bn2bin(y, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime)); /* server scalar */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); offset = BN_num_bytes(data->grp->order) - BN_num_bytes(data->my_scalar); BN_bn2bin(data->my_scalar, cruft + offset); - H_Update(&ctx, cruft, BN_num_bytes(data->grp->order)); + eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order)); /* ciphersuite */ os_memset(cruft, 0, BN_num_bytes(data->grp->prime)); - H_Update(&ctx, (u8 *)&cs, sizeof(u32)); + eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32)); /* all done */ - H_Final(&ctx, conf); + eap_pwd_h_final(hash, conf); ptr = (u8 *) payload; - if (os_memcmp(conf, ptr, SHA256_DIGEST_LENGTH)) { + if (os_memcmp(conf, ptr, SHA256_MAC_LEN)) { wpa_printf(MSG_INFO, "EAP-PWD (server): confirm did not " "verify"); goto fin; diff --git a/src/eap_server/eap_server_sim.c b/src/eap_server/eap_server_sim.c index f49f70e..6658d9c 100644 --- a/src/eap_server/eap_server_sim.c +++ b/src/eap_server/eap_server_sim.c @@ -107,8 +107,17 @@ static struct wpabuf * eap_sim_build_start(struct eap_sm *sm, EAP_SIM_SUBTYPE_START); if (eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity, sm->identity_len)) { - wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ"); - eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0); + if (sm->identity_len > 0 && + sm->identity[0] == EAP_SIM_REAUTH_ID_PREFIX) { + /* Reauth id may have expired - try fullauth */ + wpa_printf(MSG_DEBUG, " AT_FULLAUTH_ID_REQ"); + eap_sim_msg_add(msg, EAP_SIM_AT_FULLAUTH_ID_REQ, 0, + NULL, 0); + } else { + wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ"); + eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, + NULL, 0); + } } else { /* * RFC 4186, Chap. 4.2.4 recommends that identity from EAP is @@ -131,12 +140,19 @@ static int eap_sim_build_encr(struct eap_sm *sm, struct eap_sim_data *data, const u8 *nonce_s) { os_free(data->next_pseudonym); - data->next_pseudonym = - eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 0); + if (nonce_s == NULL) { + data->next_pseudonym = + eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, + EAP_SIM_DB_SIM); + } else { + /* Do not update pseudonym during re-authentication */ + data->next_pseudonym = NULL; + } os_free(data->next_reauth_id); if (data->counter <= EAP_SIM_MAX_FAST_REAUTHS) { data->next_reauth_id = - eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 0); + eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, + EAP_SIM_DB_SIM); } else { wpa_printf(MSG_DEBUG, "EAP-SIM: Max fast re-authentication " "count exceeded - force full authentication"); @@ -616,11 +632,6 @@ static void eap_sim_process_reauth(struct eap_sm *sm, identity_len = id2_len; } - if (data->next_pseudonym) { - eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity, - identity_len, data->next_pseudonym); - data->next_pseudonym = NULL; - } if (data->next_reauth_id) { eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity, identity_len, data->next_reauth_id, diff --git a/src/eap_server/eap_sim_db.c b/src/eap_server/eap_sim_db.c index 9db26dc..ce3238c 100644 --- a/src/eap_server/eap_sim_db.c +++ b/src/eap_server/eap_sim_db.c @@ -1,6 +1,6 @@ /* * hostapd / EAP-SIM database/authenticator gateway - * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2005-2010, 2012, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -647,7 +647,8 @@ eap_sim_db_get_pseudonym(struct eap_sim_db_data *data, const u8 *identity, if (identity_len == 0 || (identity[0] != EAP_SIM_PSEUDONYM_PREFIX && - identity[0] != EAP_AKA_PSEUDONYM_PREFIX)) + identity[0] != EAP_AKA_PSEUDONYM_PREFIX && + identity[0] != EAP_AKA_PRIME_PSEUDONYM_PREFIX)) return NULL; /* Remove possible realm from identity */ @@ -685,7 +686,8 @@ eap_sim_db_get_pseudonym_id(struct eap_sim_db_data *data, const u8 *identity, if (identity_len == 0 || (identity[0] != EAP_SIM_PERMANENT_PREFIX && - identity[0] != EAP_AKA_PERMANENT_PREFIX)) + identity[0] != EAP_AKA_PERMANENT_PREFIX && + identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX)) return NULL; p = data->pseudonyms; @@ -710,7 +712,8 @@ eap_sim_db_get_reauth(struct eap_sim_db_data *data, const u8 *identity, if (identity_len == 0 || (identity[0] != EAP_SIM_REAUTH_ID_PREFIX && - identity[0] != EAP_AKA_REAUTH_ID_PREFIX)) + identity[0] != EAP_AKA_REAUTH_ID_PREFIX && + identity[0] != EAP_AKA_PRIME_REAUTH_ID_PREFIX)) return NULL; /* Remove possible realm from identity */ @@ -777,8 +780,9 @@ eap_sim_db_get_reauth_id(struct eap_sim_db_data *data, const u8 *identity, * @identity_len: Length of identity in bytes * Returns: 0 if the user is found or -1 on failure * - * In most cases, the user name is ['0','1'] | IMSI, i.e., 1 followed by the - * IMSI in ASCII format, ['2','3'] | pseudonym, or ['4','5'] | reauth_id. + * In most cases, the user name is ['0','1','6'] | IMSI, i.e., 1 followed by + * the IMSI in ASCII format for EAP-SIM, ['2','3','7'] | pseudonym, or + * ['4','5','7'] | reauth_id. */ int eap_sim_db_identity_known(void *priv, const u8 *identity, size_t identity_len) @@ -789,21 +793,24 @@ int eap_sim_db_identity_known(void *priv, const u8 *identity, return -1; if (identity[0] == EAP_SIM_PSEUDONYM_PREFIX || - identity[0] == EAP_AKA_PSEUDONYM_PREFIX) { + identity[0] == EAP_AKA_PSEUDONYM_PREFIX || + identity[0] == EAP_AKA_PRIME_PSEUDONYM_PREFIX) { struct eap_sim_pseudonym *p = eap_sim_db_get_pseudonym(data, identity, identity_len); return p ? 0 : -1; } if (identity[0] == EAP_SIM_REAUTH_ID_PREFIX || - identity[0] == EAP_AKA_REAUTH_ID_PREFIX) { + identity[0] == EAP_AKA_REAUTH_ID_PREFIX || + identity[0] == EAP_AKA_PRIME_REAUTH_ID_PREFIX) { struct eap_sim_reauth *r = eap_sim_db_get_reauth(data, identity, identity_len); return r ? 0 : -1; } if (identity[0] != EAP_SIM_PERMANENT_PREFIX && - identity[0] != EAP_AKA_PERMANENT_PREFIX) { + identity[0] != EAP_AKA_PERMANENT_PREFIX && + identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) { /* Unknown identity prefix */ return -1; } @@ -843,7 +850,7 @@ static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix) /** * eap_sim_db_get_next_pseudonym - EAP-SIM DB: Get next pseudonym * @priv: Private data pointer from eap_sim_db_init() - * @aka: Using EAP-AKA instead of EAP-SIM + * @method: EAP method (SIM/AKA/AKA') * Returns: Next pseudonym (allocated string) or %NULL on failure * * This function is used to generate a pseudonym for EAP-SIM. The returned @@ -851,18 +858,31 @@ static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix) * with eap_sim_db_add_pseudonym() once the authentication has been completed * successfully. Caller is responsible for freeing the returned buffer. */ -char * eap_sim_db_get_next_pseudonym(void *priv, int aka) +char * eap_sim_db_get_next_pseudonym(void *priv, enum eap_sim_db_method method) { struct eap_sim_db_data *data = priv; - return eap_sim_db_get_next(data, aka ? EAP_AKA_PSEUDONYM_PREFIX : - EAP_SIM_PSEUDONYM_PREFIX); + char prefix = EAP_SIM_REAUTH_ID_PREFIX; + + switch (method) { + case EAP_SIM_DB_SIM: + prefix = EAP_SIM_PSEUDONYM_PREFIX; + break; + case EAP_SIM_DB_AKA: + prefix = EAP_AKA_PSEUDONYM_PREFIX; + break; + case EAP_SIM_DB_AKA_PRIME: + prefix = EAP_AKA_PRIME_PSEUDONYM_PREFIX; + break; + } + + return eap_sim_db_get_next(data, prefix); } /** * eap_sim_db_get_next_reauth_id - EAP-SIM DB: Get next reauth_id * @priv: Private data pointer from eap_sim_db_init() - * @aka: Using EAP-AKA instead of EAP-SIM + * @method: EAP method (SIM/AKA/AKA') * Returns: Next reauth_id (allocated string) or %NULL on failure * * This function is used to generate a fast re-authentication identity for @@ -871,11 +891,24 @@ char * eap_sim_db_get_next_pseudonym(void *priv, int aka) * has been completed successfully. Caller is responsible for freeing the * returned buffer. */ -char * eap_sim_db_get_next_reauth_id(void *priv, int aka) +char * eap_sim_db_get_next_reauth_id(void *priv, enum eap_sim_db_method method) { struct eap_sim_db_data *data = priv; - return eap_sim_db_get_next(data, aka ? EAP_AKA_REAUTH_ID_PREFIX : - EAP_SIM_REAUTH_ID_PREFIX); + char prefix = EAP_SIM_REAUTH_ID_PREFIX; + + switch (method) { + case EAP_SIM_DB_SIM: + prefix = EAP_SIM_REAUTH_ID_PREFIX; + break; + case EAP_SIM_DB_AKA: + prefix = EAP_AKA_REAUTH_ID_PREFIX; + break; + case EAP_SIM_DB_AKA_PRIME: + prefix = EAP_AKA_PRIME_REAUTH_ID_PREFIX; + break; + } + + return eap_sim_db_get_next(data, prefix); } @@ -1156,7 +1189,7 @@ void eap_sim_db_remove_reauth(void *priv, struct eap_sim_reauth *reauth) * called once the results become available. * * In most cases, the user name is '0' | IMSI, i.e., 0 followed by the IMSI in - * ASCII format. + * ASCII format for EAP-AKA and '6' | IMSI for EAP-AKA'. * * When using an external server for AKA authentication, this function can * always start a request and return EAP_SIM_DB_PENDING immediately if @@ -1178,7 +1211,8 @@ int eap_sim_db_get_aka_auth(void *priv, const u8 *identity, char msg[40]; if (identity_len < 2 || identity == NULL || - identity[0] != EAP_AKA_PERMANENT_PREFIX) { + (identity[0] != EAP_AKA_PERMANENT_PREFIX && + identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX)) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity", identity, identity_len); return EAP_SIM_DB_FAILURE; @@ -1281,7 +1315,8 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity, size_t i; if (identity_len < 2 || identity == NULL || - identity[0] != EAP_AKA_PERMANENT_PREFIX) { + (identity[0] != EAP_AKA_PERMANENT_PREFIX && + identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX)) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity", identity, identity_len); return -1; diff --git a/src/eap_server/eap_sim_db.h b/src/eap_server/eap_sim_db.h index abe185e..1f6375a 100644 --- a/src/eap_server/eap_sim_db.h +++ b/src/eap_server/eap_sim_db.h @@ -1,6 +1,6 @@ /* * hostapd / EAP-SIM database/authenticator gateway - * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> + * Copyright (c) 2005-2008, 2012, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -18,6 +18,15 @@ #define EAP_AKA_PERMANENT_PREFIX '0' #define EAP_AKA_PSEUDONYM_PREFIX '2' #define EAP_AKA_REAUTH_ID_PREFIX '4' +#define EAP_AKA_PRIME_PERMANENT_PREFIX '6' +#define EAP_AKA_PRIME_PSEUDONYM_PREFIX '7' +#define EAP_AKA_PRIME_REAUTH_ID_PREFIX '8' + +enum eap_sim_db_method { + EAP_SIM_DB_SIM, + EAP_SIM_DB_AKA, + EAP_SIM_DB_AKA_PRIME +}; void * eap_sim_db_init(const char *config, void (*get_complete_cb)(void *ctx, void *session_ctx), @@ -36,9 +45,11 @@ int eap_sim_db_get_gsm_triplets(void *priv, const u8 *identity, int eap_sim_db_identity_known(void *priv, const u8 *identity, size_t identity_len); -char * eap_sim_db_get_next_pseudonym(void *priv, int aka); +char * eap_sim_db_get_next_pseudonym(void *priv, + enum eap_sim_db_method method); -char * eap_sim_db_get_next_reauth_id(void *priv, int aka); +char * eap_sim_db_get_next_reauth_id(void *priv, + enum eap_sim_db_method method); int eap_sim_db_add_pseudonym(void *priv, const u8 *identity, size_t identity_len, char *pseudonym); |