aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-03-03 13:51:34 +0200
committerJouni Malinen <j@w1.fi>2012-03-03 13:51:34 +0200
commit67303a5479249141d0fa63b92ca34d560ffcfbe4 (patch)
tree13bce6db6957010edbaf2e852850ed7a56cc47cd /src/utils
parenta8f3bfc421d66fbef466ee8ef6dae8ed396cc647 (diff)
downloadexternal_wpa_supplicant_8_ti-67303a5479249141d0fa63b92ca34d560ffcfbe4.zip
external_wpa_supplicant_8_ti-67303a5479249141d0fa63b92ca34d560ffcfbe4.tar.gz
external_wpa_supplicant_8_ti-67303a5479249141d0fa63b92ca34d560ffcfbe4.tar.bz2
SCARD: Add function for fetching PIN retry counter
Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/pcsc_funcs.c43
-rw-r--r--src/utils/pcsc_funcs.h4
2 files changed, 45 insertions, 2 deletions
diff --git a/src/utils/pcsc_funcs.c b/src/utils/pcsc_funcs.c
index daf8f23..eed521d 100644
--- a/src/utils/pcsc_funcs.c
+++ b/src/utils/pcsc_funcs.c
@@ -654,7 +654,8 @@ struct scard_data * scard_init(scard_sim_type sim_type, const char *reader)
}
if (pin_needed) {
scard->pin1_required = 1;
- wpa_printf(MSG_DEBUG, "PIN1 needed for SIM access");
+ wpa_printf(MSG_DEBUG, "PIN1 needed for SIM access (retry "
+ "counter=%d)", scard_get_pin_retry_counter(scard));
}
ret = SCardEndTransaction(scard->card, SCARD_LEAVE_CARD);
@@ -1011,6 +1012,46 @@ static int scard_verify_pin(struct scard_data *scard, const char *pin)
}
+int scard_get_pin_retry_counter(struct scard_data *scard)
+{
+ long ret;
+ unsigned char resp[3];
+ unsigned char cmd[5] = { SIM_CMD_VERIFY_CHV1 };
+ size_t len;
+ u16 val;
+
+ wpa_printf(MSG_DEBUG, "SCARD: fetching PIN retry counter");
+
+ if (scard->sim_type == SCARD_USIM)
+ cmd[0] = USIM_CLA;
+ cmd[4] = 0; /* Empty data */
+
+ len = sizeof(resp);
+ ret = scard_transmit(scard, cmd, sizeof(cmd), resp, &len);
+ if (ret != SCARD_S_SUCCESS)
+ return -2;
+
+ if (len != 2) {
+ wpa_printf(MSG_WARNING, "SCARD: failed to fetch PIN retry "
+ "counter");
+ return -1;
+ }
+
+ val = WPA_GET_BE16(resp);
+ if (val == 0x63c0 || val == 0x6983) {
+ wpa_printf(MSG_DEBUG, "SCARD: PIN has been blocked");
+ return 0;
+ }
+
+ if (val >= 0x63c0 && val <= 0x63cf)
+ return val & 0x000f;
+
+ wpa_printf(MSG_DEBUG, "SCARD: Unexpected PIN retry counter response "
+ "value 0x%x", val);
+ return 0;
+}
+
+
/**
* scard_get_imsi - Read IMSI from SIM/USIM card
* @scard: Pointer to private data from scard_init()
diff --git a/src/utils/pcsc_funcs.h b/src/utils/pcsc_funcs.h
index 507dab3..3699214 100644
--- a/src/utils/pcsc_funcs.h
+++ b/src/utils/pcsc_funcs.h
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / PC/SC smartcard interface for USIM, GSM SIM
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2006, 2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -49,6 +49,7 @@ int scard_umts_auth(struct scard_data *scard, const unsigned char *_rand,
const unsigned char *autn,
unsigned char *res, size_t *res_len,
unsigned char *ik, unsigned char *ck, unsigned char *auts);
+int scard_get_pin_retry_counter(struct scard_data *scard);
#else /* PCSC_FUNCS */
@@ -58,6 +59,7 @@ int scard_umts_auth(struct scard_data *scard, const unsigned char *_rand,
#define scard_get_imsi(s, i, l) -1
#define scard_gsm_auth(s, r, s2, k) -1
#define scard_umts_auth(s, r, a, r2, rl, i, c, a2) -1
+#define scard_get_pin_retry_counter(s) -1
#endif /* PCSC_FUNCS */