aboutsummaryrefslogtreecommitdiffstats
path: root/src/eap_peer/eap_sim.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2013-10-19 15:36:12 (GMT)
committerJouni Malinen <j@w1.fi>2013-10-20 10:12:04 (GMT)
commit569ccf719f794d5df243f86892668995ab6d3868 (patch)
treee2cd90e177321a3c7b226c6eda9c1c3abf731842 /src/eap_peer/eap_sim.c
parent84dc137056c054cdeb5030c4b9ef780ff040b57b (diff)
downloadhostap-569ccf719f794d5df243f86892668995ab6d3868.zip
hostap-569ccf719f794d5df243f86892668995ab6d3868.tar.gz
hostap-569ccf719f794d5df243f86892668995ab6d3868.tar.bz2
EAP-SIM peer: Allow external SIM processing to be used
This allows the new external_sim=1 case to be used to perform GSM authentication step in EAP-SIM peer process. Following control interface event is used to request the operation: CTRL-REQ-SIM-<network id>:GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>] needed for SSID <SSID> For example: <3>CTRL-REQ-SIM-0:GSM-AUTH:5e3496ce7d5863b3b09f97f565513bc3: 73f0f0bc5c47bcbed6f572d07ab74056:447b784f08de80bdc2b1e100fccbb534 needed for SSID test Response from external processing is returned with CTRL-RSP-SIM-<network id> GSM-AUTH:<Kc1>:<SRES1>:<Kc2>:<SRES2> [:<Kc3>:<SRES3>] For example: wpa_cli sim 0 GSM-AUTH:d41c76e0079247aa:2709ebfb:43baa77cfc8bcd6c: 0fa98dc1:a8ad1f6e30e Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src/eap_peer/eap_sim.c')
-rw-r--r--src/eap_peer/eap_sim.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 82ea18d..d856054 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -145,6 +145,80 @@ static void eap_sim_deinit(struct eap_sm *sm, void *priv)
}
+static int eap_sim_ext_sim_req(struct eap_sm *sm, struct eap_sim_data *data)
+{
+ char req[200], *pos, *end;
+ size_t i;
+
+ wpa_printf(MSG_DEBUG, "EAP-SIM: Use external SIM processing");
+ pos = req;
+ end = pos + sizeof(req);
+ pos += os_snprintf(pos, end - pos, "GSM-AUTH");
+ for (i = 0; i < data->num_chal; i++) {
+ pos += os_snprintf(pos, end - pos, ":");
+ pos += wpa_snprintf_hex(pos, end - pos, data->rand[i],
+ GSM_RAND_LEN);
+ }
+
+ eap_sm_request_sim(sm, req);
+ return 1;
+}
+
+
+static int eap_sim_ext_sim_result(struct eap_sm *sm, struct eap_sim_data *data,
+ struct eap_peer_config *conf)
+{
+ char *resp, *pos;
+ size_t i;
+
+ wpa_printf(MSG_DEBUG,
+ "EAP-SIM: Use result from external SIM processing");
+
+ resp = conf->external_sim_resp;
+ conf->external_sim_resp = NULL;
+
+ if (os_strncmp(resp, "GSM-AUTH:", 9) != 0) {
+ wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized external SIM processing response");
+ os_free(resp);
+ return -1;
+ }
+
+ pos = resp + 9;
+ for (i = 0; i < data->num_chal; i++) {
+ wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND",
+ data->rand[i], GSM_RAND_LEN);
+
+ if (hexstr2bin(pos, data->kc[i], EAP_SIM_KC_LEN) < 0)
+ goto invalid;
+ wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc",
+ data->kc[i], EAP_SIM_KC_LEN);
+ pos += EAP_SIM_KC_LEN * 2;
+ if (*pos != ':')
+ goto invalid;
+ pos++;
+
+ if (hexstr2bin(pos, data->sres[i], EAP_SIM_SRES_LEN) < 0)
+ goto invalid;
+ wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES",
+ data->sres[i], EAP_SIM_SRES_LEN);
+ pos += EAP_SIM_SRES_LEN * 2;
+ if (i + 1 < data->num_chal) {
+ if (*pos != ':')
+ goto invalid;
+ pos++;
+ }
+ }
+
+ os_free(resp);
+ return 0;
+
+invalid:
+ wpa_printf(MSG_DEBUG, "EAP-SIM: Invalid external SIM processing GSM-AUTH response");
+ os_free(resp);
+ return -1;
+}
+
+
static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data)
{
struct eap_peer_config *conf;
@@ -154,6 +228,14 @@ static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data)
conf = eap_get_config(sm);
if (conf == NULL)
return -1;
+
+ if (sm->external_sim) {
+ if (conf->external_sim_resp)
+ return eap_sim_ext_sim_result(sm, data, conf);
+ else
+ return eap_sim_ext_sim_req(sm, data);
+ }
+
if (conf->pcsc) {
if (scard_gsm_auth(sm->scard_ctx, data->rand[0],
data->sres[0], data->kc[0]) ||
@@ -605,6 +687,7 @@ static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
const u8 *identity;
size_t identity_len;
struct eap_sim_attrs eattr;
+ int res;
wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge");
data->reauth = 0;
@@ -648,8 +731,13 @@ static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
os_memcpy(data->rand, attr->rand, attr->num_chal * GSM_RAND_LEN);
data->num_chal = attr->num_chal;
-
- if (eap_sim_gsm_auth(sm, data)) {
+
+ res = eap_sim_gsm_auth(sm, data);
+ if (res > 0) {
+ wpa_printf(MSG_DEBUG, "EAP-SIM: Wait for external SIM processing");
+ return NULL;
+ }
+ if (res) {
wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed");
return eap_sim_client_error(data, id,
EAP_SIM_UNABLE_TO_PROCESS_PACKET);