summaryrefslogtreecommitdiff
path: root/src/utils/pcsc_funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/pcsc_funcs.c')
-rw-r--r--src/utils/pcsc_funcs.c117
1 files changed, 62 insertions, 55 deletions
diff --git a/src/utils/pcsc_funcs.c b/src/utils/pcsc_funcs.c
index 08510d015d9df..6f5ea93962131 100644
--- a/src/utils/pcsc_funcs.c
+++ b/src/utils/pcsc_funcs.c
@@ -281,77 +281,82 @@ static int scard_parse_fsp_templ(unsigned char *buf, size_t buf_len,
wpa_hexdump(MSG_DEBUG, "SCARD: file header FSP template",
pos, end - pos);
- while (pos + 1 < end) {
+ while (end - pos >= 2) {
+ unsigned char type, len;
+
+ type = pos[0];
+ len = pos[1];
wpa_printf(MSG_MSGDUMP, "SCARD: file header TLV 0x%02x len=%d",
- pos[0], pos[1]);
- if (pos + 2 + pos[1] > end)
+ type, len);
+ pos += 2;
+
+ if (len > (unsigned int) (end - pos))
break;
- switch (pos[0]) {
+ switch (type) {
case USIM_TLV_FILE_DESC:
wpa_hexdump(MSG_MSGDUMP, "SCARD: File Descriptor TLV",
- pos + 2, pos[1]);
+ pos, len);
break;
case USIM_TLV_FILE_ID:
wpa_hexdump(MSG_MSGDUMP, "SCARD: File Identifier TLV",
- pos + 2, pos[1]);
+ pos, len);
break;
case USIM_TLV_DF_NAME:
wpa_hexdump(MSG_MSGDUMP, "SCARD: DF name (AID) TLV",
- pos + 2, pos[1]);
+ pos, len);
break;
case USIM_TLV_PROPR_INFO:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Proprietary "
- "information TLV", pos + 2, pos[1]);
+ "information TLV", pos, len);
break;
case USIM_TLV_LIFE_CYCLE_STATUS:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Life Cycle Status "
- "Integer TLV", pos + 2, pos[1]);
+ "Integer TLV", pos, len);
break;
case USIM_TLV_FILE_SIZE:
wpa_hexdump(MSG_MSGDUMP, "SCARD: File size TLV",
- pos + 2, pos[1]);
- if ((pos[1] == 1 || pos[1] == 2) && file_len) {
- if (pos[1] == 1)
- *file_len = (int) pos[2];
+ pos, len);
+ if ((len == 1 || len == 2) && file_len) {
+ if (len == 1)
+ *file_len = (int) pos[0];
else
- *file_len = ((int) pos[2] << 8) |
- (int) pos[3];
+ *file_len = WPA_GET_BE16(pos);
wpa_printf(MSG_DEBUG, "SCARD: file_size=%d",
*file_len);
}
break;
case USIM_TLV_TOTAL_FILE_SIZE:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Total file size TLV",
- pos + 2, pos[1]);
+ pos, len);
break;
case USIM_TLV_PIN_STATUS_TEMPLATE:
wpa_hexdump(MSG_MSGDUMP, "SCARD: PIN Status Template "
- "DO TLV", pos + 2, pos[1]);
- if (pos[1] >= 2 && pos[2] == USIM_PS_DO_TAG &&
- pos[3] >= 1 && ps_do) {
+ "DO TLV", pos, len);
+ if (len >= 2 && pos[0] == USIM_PS_DO_TAG &&
+ pos[1] >= 1 && ps_do) {
wpa_printf(MSG_DEBUG, "SCARD: PS_DO=0x%02x",
- pos[4]);
- *ps_do = (int) pos[4];
+ pos[2]);
+ *ps_do = (int) pos[2];
}
break;
case USIM_TLV_SHORT_FILE_ID:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Short File "
- "Identifier (SFI) TLV", pos + 2, pos[1]);
+ "Identifier (SFI) TLV", pos, len);
break;
case USIM_TLV_SECURITY_ATTR_8B:
case USIM_TLV_SECURITY_ATTR_8C:
case USIM_TLV_SECURITY_ATTR_AB:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Security attribute "
- "TLV", pos + 2, pos[1]);
+ "TLV", pos, len);
break;
default:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Unrecognized TLV",
- pos, 2 + pos[1]);
+ pos, len);
break;
}
- pos += 2 + pos[1];
+ pos += len;
if (pos == end)
return 0;
@@ -397,10 +402,12 @@ static int scard_get_aid(struct scard_data *scard, unsigned char *aid,
unsigned char rid[5];
unsigned char appl_code[2]; /* 0x1002 for 3G USIM */
} *efdir;
- unsigned char buf[127];
+ unsigned char buf[127], *aid_pos;
size_t blen;
+ unsigned int aid_len = 0;
efdir = (struct efdir *) buf;
+ aid_pos = &buf[4];
blen = sizeof(buf);
if (scard_select_file(scard, SCARD_FILE_EF_DIR, buf, &blen)) {
wpa_printf(MSG_DEBUG, "SCARD: Failed to read EF_DIR");
@@ -449,14 +456,15 @@ static int scard_get_aid(struct scard_data *scard, unsigned char *aid,
continue;
}
- if (efdir->aid_len < 1 || efdir->aid_len > 16) {
- wpa_printf(MSG_DEBUG, "SCARD: Invalid AID length %d",
- efdir->aid_len);
+ aid_len = efdir->aid_len;
+ if (aid_len < 1 || aid_len > 16) {
+ wpa_printf(MSG_DEBUG, "SCARD: Invalid AID length %u",
+ aid_len);
continue;
}
wpa_hexdump(MSG_DEBUG, "SCARD: AID from EF_DIR record",
- efdir->rid, efdir->aid_len);
+ aid_pos, aid_len);
if (efdir->appl_code[0] == 0x10 &&
efdir->appl_code[1] == 0x02) {
@@ -472,30 +480,28 @@ static int scard_get_aid(struct scard_data *scard, unsigned char *aid,
return -1;
}
- if (efdir->aid_len > maxlen) {
+ if (aid_len > maxlen) {
wpa_printf(MSG_DEBUG, "SCARD: Too long AID");
return -1;
}
- os_memcpy(aid, efdir->rid, efdir->aid_len);
+ os_memcpy(aid, aid_pos, aid_len);
- return efdir->aid_len;
+ return aid_len;
}
/**
* scard_init - Initialize SIM/USIM connection using PC/SC
- * @sim_type: Allowed SIM types (SIM, USIM, or both)
* @reader: Reader name prefix to search for
* Returns: Pointer to private data structure, or %NULL on failure
*
* This function is used to initialize SIM/USIM connection. PC/SC is used to
- * open connection to the SIM/USIM card and the card is verified to support the
- * selected sim_type. In addition, local flag is set if a PIN is needed to
- * access some of the card functions. Once the connection is not needed
- * anymore, scard_deinit() can be used to close it.
+ * open connection to the SIM/USIM card. In addition, local flag is set if a
+ * PIN is needed to access some of the card functions. Once the connection is
+ * not needed anymore, scard_deinit() can be used to close it.
*/
-struct scard_data * scard_init(scard_sim_type sim_type, const char *reader)
+struct scard_data * scard_init(const char *reader)
{
long ret;
unsigned long len, pos;
@@ -612,20 +618,14 @@ struct scard_data * scard_init(scard_sim_type sim_type, const char *reader)
blen = sizeof(buf);
- scard->sim_type = SCARD_GSM_SIM;
- if (sim_type == SCARD_USIM_ONLY || sim_type == SCARD_TRY_BOTH) {
- wpa_printf(MSG_DEBUG, "SCARD: verifying USIM support");
- if (_scard_select_file(scard, SCARD_FILE_MF, buf, &blen,
- SCARD_USIM, NULL, 0)) {
- wpa_printf(MSG_DEBUG, "SCARD: USIM is not supported");
- if (sim_type == SCARD_USIM_ONLY)
- goto failed;
- wpa_printf(MSG_DEBUG, "SCARD: Trying to use GSM SIM");
- scard->sim_type = SCARD_GSM_SIM;
- } else {
- wpa_printf(MSG_DEBUG, "SCARD: USIM is supported");
- scard->sim_type = SCARD_USIM;
- }
+ wpa_printf(MSG_DEBUG, "SCARD: verifying USIM support");
+ if (_scard_select_file(scard, SCARD_FILE_MF, buf, &blen,
+ SCARD_USIM, NULL, 0)) {
+ wpa_printf(MSG_DEBUG, "SCARD: USIM is not supported. Trying to use GSM SIM");
+ scard->sim_type = SCARD_GSM_SIM;
+ } else {
+ wpa_printf(MSG_DEBUG, "SCARD: USIM is supported");
+ scard->sim_type = SCARD_USIM;
}
if (scard->sim_type == SCARD_GSM_SIM) {
@@ -1104,7 +1104,7 @@ int scard_get_imsi(struct scard_data *scard, char *imsi, size_t *len)
}
if (scard->sim_type == SCARD_GSM_SIM) {
- blen = (buf[2] << 8) | buf[3];
+ blen = WPA_GET_BE16(&buf[2]);
} else {
int file_size;
if (scard_parse_fsp_templ(buf, blen, NULL, &file_size))
@@ -1178,7 +1178,7 @@ int scard_get_mnc_len(struct scard_data *scard)
}
if (scard->sim_type == SCARD_GSM_SIM) {
- file_size = (buf[2] << 8) | buf[3];
+ file_size = WPA_GET_BE16(&buf[2]);
} else {
if (scard_parse_fsp_templ(buf, blen, NULL, &file_size))
return -3;
@@ -1245,6 +1245,7 @@ int scard_gsm_auth(struct scard_data *scard, const unsigned char *_rand,
cmd[4] = 17;
cmd[5] = 16;
os_memcpy(cmd + 6, _rand, 16);
+ get_resp[0] = USIM_CLA;
}
len = sizeof(resp);
ret = scard_transmit(scard, cmd, cmdlen, resp, &len);
@@ -1413,6 +1414,12 @@ int scard_umts_auth(struct scard_data *scard, const unsigned char *_rand,
pos += IK_LEN;
wpa_hexdump(MSG_DEBUG, "SCARD: IK", ik, IK_LEN);
+ if (end > pos) {
+ wpa_hexdump(MSG_DEBUG,
+ "SCARD: Ignore extra data in end",
+ pos, end - pos);
+ }
+
return 0;
}