⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcsc_funcs.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			     unsigned char recnum, unsigned char mode){	unsigned char cmd[5] = { SIM_CMD_READ_RECORD /* , len */ };	size_t blen = len + 3;	unsigned char *buf;	long ret;	if (scard->sim_type == SCARD_USIM)		cmd[0] = USIM_CLA;	cmd[2] = recnum;	cmd[3] = mode;	cmd[4] = len;	buf = os_malloc(blen);	if (buf == NULL)		return -1;	ret = scard_transmit(scard, cmd, sizeof(cmd), buf, &blen);	if (ret != SCARD_S_SUCCESS) {		os_free(buf);		return -2;	}	if (blen != len + 2) {		wpa_printf(MSG_DEBUG, "SCARD: record read returned unexpected "			   "length %ld (expected %ld)",			   (long) blen, (long) len + 2);		os_free(buf);		return -3;	}	if (buf[len] != 0x90 || buf[len + 1] != 0x00) {		wpa_printf(MSG_DEBUG, "SCARD: record read returned unexpected "			   "status %02x %02x (expected 90 00)",			   buf[len], buf[len + 1]);		os_free(buf);		return -4;	}	os_memcpy(data, buf, len);	os_free(buf);	return 0;}static int scard_read_file(struct scard_data *scard,			   unsigned char *data, size_t len){	unsigned char cmd[5] = { SIM_CMD_READ_BIN /* , len */ };	size_t blen = len + 3;	unsigned char *buf;	long ret;	cmd[4] = len;	buf = os_malloc(blen);	if (buf == NULL)		return -1;	if (scard->sim_type == SCARD_USIM)		cmd[0] = USIM_CLA;	ret = scard_transmit(scard, cmd, sizeof(cmd), buf, &blen);	if (ret != SCARD_S_SUCCESS) {		os_free(buf);		return -2;	}	if (blen != len + 2) {		wpa_printf(MSG_DEBUG, "SCARD: file read returned unexpected "			   "length %ld (expected %ld)",			   (long) blen, (long) len + 2);		os_free(buf);		return -3;	}	if (buf[len] != 0x90 || buf[len + 1] != 0x00) {		wpa_printf(MSG_DEBUG, "SCARD: file read returned unexpected "			   "status %02x %02x (expected 90 00)",			   buf[len], buf[len + 1]);		os_free(buf);		return -4;	}	os_memcpy(data, buf, len);	os_free(buf);	return 0;}static int scard_verify_pin(struct scard_data *scard, const char *pin){	long ret;	unsigned char resp[3];	unsigned char cmd[5 + 8] = { SIM_CMD_VERIFY_CHV1 };	size_t len;	wpa_printf(MSG_DEBUG, "SCARD: verifying PIN");	if (pin == NULL || os_strlen(pin) > 8)		return -1;	if (scard->sim_type == SCARD_USIM)		cmd[0] = USIM_CLA;	os_memcpy(cmd + 5, pin, os_strlen(pin));	os_memset(cmd + 5 + os_strlen(pin), 0xff, 8 - os_strlen(pin));	len = sizeof(resp);	ret = scard_transmit(scard, cmd, sizeof(cmd), resp, &len);	if (ret != SCARD_S_SUCCESS)		return -2;	if (len != 2 || resp[0] != 0x90 || resp[1] != 0x00) {		wpa_printf(MSG_WARNING, "SCARD: PIN verification failed");		return -1;	}	wpa_printf(MSG_DEBUG, "SCARD: PIN verified successfully");	return 0;}/** * scard_get_imsi - Read IMSI from SIM/USIM card * @scard: Pointer to private data from scard_init() * @imsi: Buffer for IMSI * @len: Length of imsi buffer; set to IMSI length on success * Returns: 0 on success, -1 if IMSI file cannot be selected, -2 if IMSI file * selection returns invalid result code, -3 if parsing FSP template file fails * (USIM only), -4 if IMSI does not fit in the provided imsi buffer (len is set * to needed length), -5 if reading IMSI file fails. * * This function can be used to read IMSI from the SIM/USIM card. If the IMSI * file is PIN protected, scard_set_pin() must have been used to set the * correct PIN code before calling scard_get_imsi(). */int scard_get_imsi(struct scard_data *scard, char *imsi, size_t *len){	unsigned char buf[100];	size_t blen, imsilen, i;	char *pos;	wpa_printf(MSG_DEBUG, "SCARD: reading IMSI from (GSM) EF-IMSI");	blen = sizeof(buf);	if (scard_select_file(scard, SCARD_FILE_GSM_EF_IMSI, buf, &blen))		return -1;	if (blen < 4) {		wpa_printf(MSG_WARNING, "SCARD: too short (GSM) EF-IMSI "			   "header (len=%ld)", (long) blen);		return -2;	}	if (scard->sim_type == SCARD_GSM_SIM) {		blen = (buf[2] << 8) | buf[3];	} else {		int file_size;		if (scard_parse_fsp_templ(buf, blen, NULL, &file_size))			return -3;		blen = file_size;	}	if (blen < 2 || blen > sizeof(buf)) {		wpa_printf(MSG_DEBUG, "SCARD: invalid IMSI file length=%ld",			   (long) blen);		return -3;	}	imsilen = (blen - 2) * 2 + 1;	wpa_printf(MSG_DEBUG, "SCARD: IMSI file length=%ld imsilen=%ld",		   (long) blen, (long) imsilen);	if (blen < 2 || imsilen > *len) {		*len = imsilen;		return -4;	}	if (scard_read_file(scard, buf, blen))		return -5;	pos = imsi;	*pos++ = '0' + (buf[1] >> 4 & 0x0f);	for (i = 2; i < blen; i++) {		unsigned char digit;		digit = buf[i] & 0x0f;		if (digit < 10)			*pos++ = '0' + digit;		else			imsilen--;		digit = buf[i] >> 4 & 0x0f;		if (digit < 10)			*pos++ = '0' + digit;		else			imsilen--;	}	*len = imsilen;	return 0;}/** * 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 * @sres: 4-byte buffer for SRES * @kc: 8-byte buffer for Kc * Returns: 0 on success, -1 if SIM/USIM connection has not been initialized, * -2 if authentication command execution fails, -3 if unknown response code * for authentication command is received, -4 if reading of response fails, * -5 if if response data is of unexpected length * * This function performs GSM authentication using SIM/USIM card and the * provided RAND value from HLR/AuC. If authentication command can be completed * successfully, SRES and Kc values will be written into sres and kc buffers. */int scard_gsm_auth(struct scard_data *scard, const unsigned char *_rand,		   unsigned char *sres, unsigned char *kc){	unsigned char cmd[5 + 1 + 16] = { SIM_CMD_RUN_GSM_ALG };	int cmdlen;	unsigned char get_resp[5] = { SIM_CMD_GET_RESPONSE };	unsigned char resp[3], buf[12 + 3 + 2];	size_t len;	long ret;	if (scard == NULL)		return -1;	wpa_hexdump(MSG_DEBUG, "SCARD: GSM auth - RAND", _rand, 16);	if (scard->sim_type == SCARD_GSM_SIM) {		cmdlen = 5 + 16;		os_memcpy(cmd + 5, _rand, 16);	} else {		cmdlen = 5 + 1 + 16;		cmd[0] = USIM_CLA;		cmd[3] = 0x80;		cmd[4] = 17;		cmd[5] = 16;		os_memcpy(cmd + 6, _rand, 16);	}	len = sizeof(resp);	ret = scard_transmit(scard, cmd, cmdlen, resp, &len);	if (ret != SCARD_S_SUCCESS)		return -2;	if ((scard->sim_type == SCARD_GSM_SIM &&	     (len != 2 || resp[0] != 0x9f || resp[1] != 0x0c)) ||	    (scard->sim_type == SCARD_USIM &&	     (len != 2 || resp[0] != 0x61 || resp[1] != 0x0e))) {		wpa_printf(MSG_WARNING, "SCARD: unexpected response for GSM "			   "auth request (len=%ld resp=%02x %02x)",			   (long) len, resp[0], resp[1]);		return -3;	}	get_resp[4] = resp[1];	len = sizeof(buf);	ret = scard_transmit(scard, get_resp, sizeof(get_resp), buf, &len);	if (ret != SCARD_S_SUCCESS)		return -4;	if (scard->sim_type == SCARD_GSM_SIM) {		if (len != 4 + 8 + 2) {			wpa_printf(MSG_WARNING, "SCARD: unexpected data "				   "length for GSM auth (len=%ld, expected 14)",				   (long) len);			return -5;		}		os_memcpy(sres, buf, 4);		os_memcpy(kc, buf + 4, 8);	} else {		if (len != 1 + 4 + 1 + 8 + 2) {			wpa_printf(MSG_WARNING, "SCARD: unexpected data "				   "length for USIM auth (len=%ld, "				   "expected 16)", (long) len);			return -5;		}		if (buf[0] != 4 || buf[5] != 8) {			wpa_printf(MSG_WARNING, "SCARD: unexpected SREC/Kc "				   "length (%d %d, expected 4 8)",				   buf[0], buf[5]);		}		os_memcpy(sres, buf + 1, 4);		os_memcpy(kc, buf + 6, 8);	}	wpa_hexdump(MSG_DEBUG, "SCARD: GSM auth - SRES", sres, 4);	wpa_hexdump(MSG_DEBUG, "SCARD: GSM auth - Kc", kc, 8);	return 0;}/** * scard_umts_auth - Run UMTS authentication command on USIM card * @scard: Pointer to private data from scard_init() * @_rand: 16-byte RAND value from HLR/AuC * @autn: 16-byte AUTN value from HLR/AuC * @res: 16-byte buffer for RES * @res_len: Variable that will be set to RES length * @ik: 16-byte buffer for IK * @ck: 16-byte buffer for CK * @auts: 14-byte buffer for AUTS * Returns: 0 on success, -1 on failure, or -2 if USIM reports synchronization * failure * * This function performs AKA authentication using USIM card and the provided * RAND and AUTN values from HLR/AuC. If authentication command can be * completed successfully, RES, IK, and CK values will be written into provided * buffers and res_len is set to length of received RES value. If USIM reports * synchronization failure, the received AUTS value will be written into auts * buffer. In this case, RES, IK, and CK are not valid. */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){	unsigned char cmd[5 + 1 + AKA_RAND_LEN + 1 + AKA_AUTN_LEN] =		{ USIM_CMD_RUN_UMTS_ALG };	unsigned char get_resp[5] = { USIM_CMD_GET_RESPONSE };	unsigned char resp[3], buf[64], *pos, *end;	size_t len;	long ret;	if (scard == NULL)		return -1;	if (scard->sim_type == SCARD_GSM_SIM) {		wpa_printf(MSG_ERROR, "SCARD: Non-USIM card - cannot do UMTS "			   "auth");		return -1;	}	wpa_hexdump(MSG_DEBUG, "SCARD: UMTS auth - RAND", _rand, AKA_RAND_LEN);	wpa_hexdump(MSG_DEBUG, "SCARD: UMTS auth - AUTN", autn, AKA_AUTN_LEN);	cmd[5] = AKA_RAND_LEN;	os_memcpy(cmd + 6, _rand, AKA_RAND_LEN);	cmd[6 + AKA_RAND_LEN] = AKA_AUTN_LEN;	os_memcpy(cmd + 6 + AKA_RAND_LEN + 1, autn, AKA_AUTN_LEN);	len = sizeof(resp);	ret = scard_transmit(scard, cmd, sizeof(cmd), resp, &len);	if (ret != SCARD_S_SUCCESS)		return -1;	if (len <= sizeof(resp))		wpa_hexdump(MSG_DEBUG, "SCARD: UMTS alg response", resp, len);	if (len == 2 && resp[0] == 0x98 && resp[1] == 0x62) {		wpa_printf(MSG_WARNING, "SCARD: UMTS auth failed - "			   "MAC != XMAC");		return -1;	} else if (len != 2 || resp[0] != 0x61) {		wpa_printf(MSG_WARNING, "SCARD: unexpected response for UMTS "			   "auth request (len=%ld resp=%02x %02x)",			   (long) len, resp[0], resp[1]);		return -1;	}	get_resp[4] = resp[1];	len = sizeof(buf);	ret = scard_transmit(scard, get_resp, sizeof(get_resp), buf, &len);	if (ret != SCARD_S_SUCCESS || len > sizeof(buf))		return -1;	wpa_hexdump(MSG_DEBUG, "SCARD: UMTS get response result", buf, len);	if (len >= 2 + AKA_AUTS_LEN && buf[0] == 0xdc &&	    buf[1] == AKA_AUTS_LEN) {		wpa_printf(MSG_DEBUG, "SCARD: UMTS Synchronization-Failure");		os_memcpy(auts, buf + 2, AKA_AUTS_LEN);		wpa_hexdump(MSG_DEBUG, "SCARD: AUTS", auts, AKA_AUTS_LEN);		return -2;	} else if (len >= 6 + IK_LEN + CK_LEN && buf[0] == 0xdb) {		pos = buf + 1;		end = buf + len;		/* RES */		if (pos[0] > RES_MAX_LEN || pos + pos[0] > end) {			wpa_printf(MSG_DEBUG, "SCARD: Invalid RES");			return -1;		}		*res_len = *pos++;		os_memcpy(res, pos, *res_len);		pos += *res_len;		wpa_hexdump(MSG_DEBUG, "SCARD: RES", res, *res_len);		/* CK */		if (pos[0] != CK_LEN || pos + CK_LEN > end) {			wpa_printf(MSG_DEBUG, "SCARD: Invalid CK");			return -1;		}		pos++;		os_memcpy(ck, pos, CK_LEN);		pos += CK_LEN;		wpa_hexdump(MSG_DEBUG, "SCARD: CK", ck, CK_LEN);		/* IK */		if (pos[0] != IK_LEN || pos + IK_LEN > end) {			wpa_printf(MSG_DEBUG, "SCARD: Invalid IK");			return -1;		}		pos++;		os_memcpy(ik, pos, IK_LEN);		pos += IK_LEN;		wpa_hexdump(MSG_DEBUG, "SCARD: IK", ik, IK_LEN);		return 0;	}	wpa_printf(MSG_DEBUG, "SCARD: Unrecognized response");	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -