aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorSimon Baatz <gmbnomis@gmail.com>2012-01-22 19:28:24 +0200
committerJouni Malinen <j@w1.fi>2012-01-22 19:28:24 +0200
commit8ab7a3708910c0f572084e7dabff10d7c8ee3734 (patch)
tree169daf5b08cf4acdbd669c7af2409b7e98183fbb /src/utils
parent8aebb0e471f2e89e146713ebf9f3e1cbb58e8f52 (diff)
downloadexternal_wpa_supplicant_8_ti-8ab7a3708910c0f572084e7dabff10d7c8ee3734.zip
external_wpa_supplicant_8_ti-8ab7a3708910c0f572084e7dabff10d7c8ee3734.tar.gz
external_wpa_supplicant_8_ti-8ab7a3708910c0f572084e7dabff10d7c8ee3734.tar.bz2
SIM/USIM: Add function to get the MNC length from the SIM/USIM
The EF-AD (administrative data) file may contain information about the length of the MNC (2 or 3 digits) in the IMSI. This can be used to construct the realm according to 3GPP TS 23.003 during EAP-SIM or EAP-AKA authentication. Signed-hostap: Simon Baatz <gmbnomis@gmail.com>
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/pcsc_funcs.c55
-rw-r--r--src/utils/pcsc_funcs.h2
2 files changed, 57 insertions, 0 deletions
diff --git a/src/utils/pcsc_funcs.c b/src/utils/pcsc_funcs.c
index c36193e..aecc6f7 100644
--- a/src/utils/pcsc_funcs.c
+++ b/src/utils/pcsc_funcs.c
@@ -1024,6 +1024,61 @@ int scard_get_imsi(struct scard_data *scard, char *imsi, size_t *len)
/**
+ * scard_get_mnc_len - Read length of MNC in the IMSI from SIM/USIM card
+ * @scard: Pointer to private data from scard_init()
+ * Returns: length (>0) on success, -1 if administrative data file cannot be
+ * selected, -2 if administrative data file selection returns invalid result
+ * code, -3 if parsing FSP template file fails (USIM only), -4 if length of
+ * the file is unexpected, -5 if reading file fails, -6 if MNC length is not
+ * in range (i.e. 2 or 3), -7 if MNC length is not available.
+ *
+ */
+int scard_get_mnc_len(struct scard_data *scard)
+{
+ unsigned char buf[100];
+ size_t blen;
+ int file_size;
+
+ wpa_printf(MSG_DEBUG, "SCARD: reading MNC len from (GSM) EF-AD");
+ blen = sizeof(buf);
+ if (scard_select_file(scard, SCARD_FILE_GSM_EF_AD, buf, &blen))
+ return -1;
+ if (blen < 4) {
+ wpa_printf(MSG_WARNING, "SCARD: too short (GSM) EF-AD "
+ "header (len=%ld)", (long) blen);
+ return -2;
+ }
+
+ if (scard->sim_type == SCARD_GSM_SIM) {
+ file_size = (buf[2] << 8) | buf[3];
+ } else {
+ if (scard_parse_fsp_templ(buf, blen, NULL, &file_size))
+ return -3;
+ }
+ if (file_size == 3) {
+ wpa_printf(MSG_DEBUG, "SCARD: MNC length not available");
+ return -7;
+ }
+ if (file_size < 4 || file_size > sizeof(buf)) {
+ wpa_printf(MSG_DEBUG, "SCARD: invalid file length=%ld",
+ (long) file_size);
+ return -4;
+ }
+
+ if (scard_read_file(scard, buf, file_size))
+ return -5;
+ buf[3] = buf[3] & 0x0f; /* upper nibble reserved for future use */
+ if (buf[3] < 2 || buf[3] > 3) {
+ wpa_printf(MSG_DEBUG, "SCARD: invalid MNC length=%ld",
+ (long) buf[3]);
+ return -6;
+ }
+ wpa_printf(MSG_DEBUG, "SCARD: MNC length=%ld", (long) buf[3]);
+ return buf[3];
+}
+
+
+/**
* scard_gsm_auth - Run GSM authentication command on SIM card
* @scard: Pointer to private data from scard_init()
* @_rand: 16-byte RAND value from HLR/AuC
diff --git a/src/utils/pcsc_funcs.h b/src/utils/pcsc_funcs.h
index 543f7c5..483247b 100644
--- a/src/utils/pcsc_funcs.h
+++ b/src/utils/pcsc_funcs.h
@@ -26,6 +26,7 @@
#define SCARD_FILE_GSM_DF 0x7F20
#define SCARD_FILE_UMTS_DF 0x7F50
#define SCARD_FILE_GSM_EF_IMSI 0x6F07
+#define SCARD_FILE_GSM_EF_AD 0x6FAD
#define SCARD_FILE_EF_DIR 0x2F00
#define SCARD_FILE_EF_ICCID 0x2FE2
#define SCARD_FILE_EF_CK 0x6FE1
@@ -47,6 +48,7 @@ void scard_deinit(struct scard_data *scard);
int scard_set_pin(struct scard_data *scard, const char *pin);
int scard_get_imsi(struct scard_data *scard, char *imsi, size_t *len);
+int scard_get_mnc_len(struct scard_data *scard);
int scard_gsm_auth(struct scard_data *scard, const unsigned char *_rand,
unsigned char *sres, unsigned char *kc);
int scard_umts_auth(struct scard_data *scard, const unsigned char *_rand,