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

📄 pcsc_funcs.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		return -1;	}	os_memcpy(aid, efdir->rid, efdir->aid_len);	return efdir->aid_len;}/** * scard_init - Initialize SIM/USIM connection using PC/SC * @sim_type: Allowed SIM types (SIM, USIM, or both) * 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. */struct scard_data * scard_init(scard_sim_type sim_type){	long ret;	unsigned long len;	struct scard_data *scard;#ifdef CONFIG_NATIVE_WINDOWS	TCHAR *readers = NULL;#else /* CONFIG_NATIVE_WINDOWS */	char *readers = NULL;#endif /* CONFIG_NATIVE_WINDOWS */	unsigned char buf[100];	size_t blen;	int transaction = 0;	int pin_needed;	wpa_printf(MSG_DEBUG, "SCARD: initializing smart card interface");	if (mingw_load_symbols())		return NULL;	scard = os_zalloc(sizeof(*scard));	if (scard == NULL)		return NULL;	ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL,				    &scard->ctx);	if (ret != SCARD_S_SUCCESS) {		wpa_printf(MSG_DEBUG, "SCARD: Could not establish smart card "			   "context (err=%ld)", ret);		goto failed;	}	ret = SCardListReaders(scard->ctx, NULL, NULL, &len);	if (ret != SCARD_S_SUCCESS) {		wpa_printf(MSG_DEBUG, "SCARD: SCardListReaders failed "			   "(err=%ld)", ret);		goto failed;	}#ifdef UNICODE	len *= 2;#endif /* UNICODE */	readers = os_malloc(len);	if (readers == NULL) {		wpa_printf(MSG_INFO, "SCARD: malloc failed\n");		goto failed;	}	ret = SCardListReaders(scard->ctx, NULL, readers, &len);	if (ret != SCARD_S_SUCCESS) {		wpa_printf(MSG_DEBUG, "SCARD: SCardListReaders failed(2) "			   "(err=%ld)", ret);		goto failed;	}	if (len < 3) {		wpa_printf(MSG_WARNING, "SCARD: No smart card readers "			   "available.");		goto failed;	}	/* readers is a list of available reader. Last entry is terminated with	 * double NUL.	 * TODO: add support for selecting the reader; now just use the first	 * one.. */#ifdef UNICODE	wpa_printf(MSG_DEBUG, "SCARD: Selected reader='%S'", readers);#else /* UNICODE */	wpa_printf(MSG_DEBUG, "SCARD: Selected reader='%s'", readers);#endif /* UNICODE */	ret = SCardConnect(scard->ctx, readers, SCARD_SHARE_SHARED,			   SCARD_PROTOCOL_T0, &scard->card, &scard->protocol);	if (ret != SCARD_S_SUCCESS) {		if (ret == (long) SCARD_E_NO_SMARTCARD)			wpa_printf(MSG_INFO, "No smart card inserted.");		else			wpa_printf(MSG_WARNING, "SCardConnect err=%lx", ret);		goto failed;	}	os_free(readers);	readers = NULL;	wpa_printf(MSG_DEBUG, "SCARD: card=0x%x active_protocol=%lu (%s)",		   (unsigned int) scard->card, scard->protocol,		   scard->protocol == SCARD_PROTOCOL_T0 ? "T0" : "T1");	ret = SCardBeginTransaction(scard->card);	if (ret != SCARD_S_SUCCESS) {		wpa_printf(MSG_DEBUG, "SCARD: Could not begin transaction: "			   "0x%x", (unsigned int) ret);		goto failed;	}	transaction = 1;	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;		}	}	if (scard->sim_type == SCARD_GSM_SIM) {		blen = sizeof(buf);		if (scard_select_file(scard, SCARD_FILE_MF, buf, &blen)) {			wpa_printf(MSG_DEBUG, "SCARD: Failed to read MF");			goto failed;		}		blen = sizeof(buf);		if (scard_select_file(scard, SCARD_FILE_GSM_DF, buf, &blen)) {			wpa_printf(MSG_DEBUG, "SCARD: Failed to read GSM DF");			goto failed;		}	} else {		unsigned char aid[32];		int aid_len;		aid_len = scard_get_aid(scard, aid, sizeof(aid));		if (aid_len < 0) {			wpa_printf(MSG_DEBUG, "SCARD: Failed to find AID for "				   "3G USIM app - try to use standard 3G RID");			os_memcpy(aid, "\xa0\x00\x00\x00\x87", 5);			aid_len = 5;		}		wpa_hexdump(MSG_DEBUG, "SCARD: 3G USIM AID", aid, aid_len);		/* Select based on AID = 3G RID from EF_DIR. This is usually		 * starting with A0 00 00 00 87. */		blen = sizeof(buf);		if (_scard_select_file(scard, 0, buf, &blen, scard->sim_type,				       aid, aid_len)) {			wpa_printf(MSG_INFO, "SCARD: Failed to read 3G USIM "				   "app");			wpa_hexdump(MSG_INFO, "SCARD: 3G USIM AID",				    aid, aid_len);			goto failed;		}	}	/* Verify whether CHV1 (PIN1) is needed to access the card. */	pin_needed = scard_pin_needed(scard, buf, blen);	if (pin_needed < 0) {		wpa_printf(MSG_DEBUG, "SCARD: Failed to determine whether PIN "			   "is needed");		goto failed;	}	if (pin_needed) {		scard->pin1_required = 1;		wpa_printf(MSG_DEBUG, "PIN1 needed for SIM access");	}	ret = SCardEndTransaction(scard->card, SCARD_LEAVE_CARD);	if (ret != SCARD_S_SUCCESS) {		wpa_printf(MSG_DEBUG, "SCARD: Could not end transaction: "			   "0x%x", (unsigned int) ret);	}	return scard;failed:	if (transaction)		SCardEndTransaction(scard->card, SCARD_LEAVE_CARD);	os_free(readers);	scard_deinit(scard);	return NULL;}/** * scard_set_pin - Set PIN (CHV1/PIN1) code for accessing SIM/USIM commands * @scard: Pointer to private data from scard_init() * pin: PIN code as an ASCII string (e.g., "1234") * Returns: 0 on success, -1 on failure */int scard_set_pin(struct scard_data *scard, const char *pin){	if (scard == NULL)		return -1;	/* Verify whether CHV1 (PIN1) is needed to access the card. */	if (scard->pin1_required) {		if (pin == NULL) {			wpa_printf(MSG_DEBUG, "No PIN configured for SIM "				   "access");			return -1;		}		if (scard_verify_pin(scard, pin)) {			wpa_printf(MSG_INFO, "PIN verification failed for "				"SIM access");			return -1;		}	}	return 0;}/** * scard_deinit - Deinitialize SIM/USIM connection * @scard: Pointer to private data from scard_init() * * This function closes the SIM/USIM connect opened with scard_init(). */void scard_deinit(struct scard_data *scard){	long ret;	if (scard == NULL)		return;	wpa_printf(MSG_DEBUG, "SCARD: deinitializing smart card interface");	if (scard->card) {		ret = SCardDisconnect(scard->card, SCARD_UNPOWER_CARD);		if (ret != SCARD_S_SUCCESS) {			wpa_printf(MSG_DEBUG, "SCARD: Failed to disconnect "				   "smart card (err=%ld)", ret);		}	}	if (scard->ctx) {		ret = SCardReleaseContext(scard->ctx);		if (ret != SCARD_S_SUCCESS) {			wpa_printf(MSG_DEBUG, "Failed to release smart card "				   "context (err=%ld)", ret);		}	}	os_free(scard);	mingw_unload_symbols();}static long scard_transmit(struct scard_data *scard,			   unsigned char *_send, size_t send_len,			   unsigned char *_recv, size_t *recv_len){	long ret;	unsigned long rlen;	wpa_hexdump_key(MSG_DEBUG, "SCARD: scard_transmit: send",			_send, send_len);	rlen = *recv_len;	ret = SCardTransmit(scard->card,			    scard->protocol == SCARD_PROTOCOL_T1 ?			    SCARD_PCI_T1 : SCARD_PCI_T0,			    _send, (unsigned long) send_len,			    NULL, _recv, &rlen);	*recv_len = rlen;	if (ret == SCARD_S_SUCCESS) {		wpa_hexdump(MSG_DEBUG, "SCARD: scard_transmit: recv",			    _recv, rlen);	} else {		wpa_printf(MSG_WARNING, "SCARD: SCardTransmit failed "			   "(err=0x%lx)", ret);	}	return ret;}static int _scard_select_file(struct scard_data *scard, unsigned short file_id,			      unsigned char *buf, size_t *buf_len,			      sim_types sim_type, unsigned char *aid,			      size_t aidlen){	long ret;	unsigned char resp[3];	unsigned char cmd[50] = { SIM_CMD_SELECT };	int cmdlen;	unsigned char get_resp[5] = { SIM_CMD_GET_RESPONSE };	size_t len, rlen;	if (sim_type == SCARD_USIM) {		cmd[0] = USIM_CLA;		cmd[3] = 0x04;		get_resp[0] = USIM_CLA;	}	wpa_printf(MSG_DEBUG, "SCARD: select file %04x", file_id);	if (aid) {		wpa_hexdump(MSG_DEBUG, "SCARD: select file by AID",			    aid, aidlen);		if (5 + aidlen > sizeof(cmd))			return -1;		cmd[2] = 0x04; /* Select by AID */		cmd[4] = aidlen; /* len */		os_memcpy(cmd + 5, aid, aidlen);		cmdlen = 5 + aidlen;	} else {		cmd[5] = file_id >> 8;		cmd[6] = file_id & 0xff;		cmdlen = 7;	}	len = sizeof(resp);	ret = scard_transmit(scard, cmd, cmdlen, resp, &len);	if (ret != SCARD_S_SUCCESS) {		wpa_printf(MSG_WARNING, "SCARD: SCardTransmit failed "			   "(err=0x%lx)", ret);		return -1;	}	if (len != 2) {		wpa_printf(MSG_WARNING, "SCARD: unexpected resp len "			   "%d (expected 2)", (int) len);		return -1;	}	if (resp[0] == 0x98 && resp[1] == 0x04) {		/* Security status not satisfied (PIN_WLAN) */		wpa_printf(MSG_WARNING, "SCARD: Security status not satisfied "			   "(PIN_WLAN)");		return -1;	}	if (resp[0] == 0x6e) {		wpa_printf(MSG_DEBUG, "SCARD: used CLA not supported");		return -1;	}	if (resp[0] != 0x6c && resp[0] != 0x9f && resp[0] != 0x61) {		wpa_printf(MSG_WARNING, "SCARD: unexpected response 0x%02x "			   "(expected 0x61, 0x6c, or 0x9f)", resp[0]);		return -1;	}	/* Normal ending of command; resp[1] bytes available */	get_resp[4] = resp[1];	wpa_printf(MSG_DEBUG, "SCARD: trying to get response (%d bytes)",		   resp[1]);	rlen = *buf_len;	ret = scard_transmit(scard, get_resp, sizeof(get_resp), buf, &rlen);	if (ret == SCARD_S_SUCCESS) {		*buf_len = resp[1] < rlen ? resp[1] : rlen;		return 0;	}	wpa_printf(MSG_WARNING, "SCARD: SCardTransmit err=0x%lx\n", ret);	return -1;}static int scard_select_file(struct scard_data *scard, unsigned short file_id,			     unsigned char *buf, size_t *buf_len){	return _scard_select_file(scard, file_id, buf, buf_len,				  scard->sim_type, NULL, 0);}static int scard_get_record_len(struct scard_data *scard, unsigned char recnum,				unsigned char mode){	unsigned char buf[255];	unsigned char cmd[5] = { SIM_CMD_READ_RECORD /* , len */ };	size_t blen;	long ret;	if (scard->sim_type == SCARD_USIM)		cmd[0] = USIM_CLA;	cmd[2] = recnum;	cmd[3] = mode;	cmd[4] = sizeof(buf);	blen = sizeof(buf);	ret = scard_transmit(scard, cmd, sizeof(cmd), buf, &blen);	if (ret != SCARD_S_SUCCESS) {		wpa_printf(MSG_DEBUG, "SCARD: failed to determine file "			   "length for record %d", recnum);		return -1;	}	wpa_hexdump(MSG_DEBUG, "SCARD: file length determination response",		    buf, blen);	if (blen < 2 || buf[0] != 0x6c) {		wpa_printf(MSG_DEBUG, "SCARD: unexpected response to file "			   "length determination");		return -1;	}	return buf[1];}static int scard_read_record(struct scard_data *scard,			     unsigned char *data, size_t len,

⌨️ 快捷键说明

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