diff options
Diffstat (limited to 'src/utils/pcsc_funcs.c')
-rw-r--r-- | src/utils/pcsc_funcs.c | 117 |
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; } |