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

📄 pcsc_funcs.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * WPA Supplicant / PC/SC smartcard interface for USIM, GSM SIM * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. * * This file implements wrapper functions for accessing GSM SIM and 3GPP USIM * cards through PC/SC smartcard library. These functions are used to implement * authentication routines for EAP-SIM and EAP-AKA. */#include "includes.h"#include <winscard.h>#include "common.h"#include "pcsc_funcs.h"/* See ETSI GSM 11.11 and ETSI TS 102 221 for details. * SIM commands: * Command APDU: CLA INS P1 P2 P3 Data *   CLA (class of instruction): A0 for GSM, 00 for USIM *   INS (instruction) *   P1 P2 P3 (parameters, P3 = length of Data) * Response APDU: Data SW1 SW2 *   SW1 SW2 (Status words) * Commands (INS P1 P2 P3): *   SELECT: A4 00 00 02 <file_id, 2 bytes> *   GET RESPONSE: C0 00 00 <len> *   RUN GSM ALG: 88 00 00 00 <RAND len = 10> *   RUN UMTS ALG: 88 00 81 <len=0x22> data: 0x10 | RAND | 0x10 | AUTN *	P1 = ID of alg in card *	P2 = ID of secret key *   READ BINARY: B0 <offset high> <offset low> <len> *   READ RECORD: B2 <record number> <mode> <len> *	P2 (mode) = '02' (next record), '03' (previous record), *		    '04' (absolute mode) *   VERIFY CHV: 20 00 <CHV number> 08 *   CHANGE CHV: 24 00 <CHV number> 10 *   DISABLE CHV: 26 00 01 08 *   ENABLE CHV: 28 00 01 08 *   UNBLOCK CHV: 2C 00 <00=CHV1, 02=CHV2> 10 *   SLEEP: FA 00 00 00 *//* GSM SIM commands */#define SIM_CMD_SELECT			0xa0, 0xa4, 0x00, 0x00, 0x02#define SIM_CMD_RUN_GSM_ALG		0xa0, 0x88, 0x00, 0x00, 0x10#define SIM_CMD_GET_RESPONSE		0xa0, 0xc0, 0x00, 0x00#define SIM_CMD_READ_BIN		0xa0, 0xb0, 0x00, 0x00#define SIM_CMD_READ_RECORD		0xa0, 0xb2, 0x00, 0x00#define SIM_CMD_VERIFY_CHV1		0xa0, 0x20, 0x00, 0x01, 0x08/* USIM commands */#define USIM_CLA			0x00#define USIM_CMD_RUN_UMTS_ALG		0x00, 0x88, 0x00, 0x81, 0x22#define USIM_CMD_GET_RESPONSE		0x00, 0xc0, 0x00, 0x00#define SIM_RECORD_MODE_ABSOLUTE 0x04#define USIM_FSP_TEMPL_TAG		0x62#define USIM_TLV_FILE_DESC		0x82#define USIM_TLV_FILE_ID		0x83#define USIM_TLV_DF_NAME		0x84#define USIM_TLV_PROPR_INFO		0xA5#define USIM_TLV_LIFE_CYCLE_STATUS	0x8A#define USIM_TLV_FILE_SIZE		0x80#define USIM_TLV_TOTAL_FILE_SIZE	0x81#define USIM_TLV_PIN_STATUS_TEMPLATE	0xC6#define USIM_TLV_SHORT_FILE_ID		0x88#define USIM_PS_DO_TAG			0x90#define AKA_RAND_LEN 16#define AKA_AUTN_LEN 16#define AKA_AUTS_LEN 14#define RES_MAX_LEN 16#define IK_LEN 16#define CK_LEN 16typedef enum { SCARD_GSM_SIM, SCARD_USIM } sim_types;struct scard_data {	SCARDCONTEXT ctx;	SCARDHANDLE card;	DWORD protocol;	sim_types sim_type;	int pin1_required;};#ifdef __MINGW32_VERSION/* MinGW does not yet support WinScard, so load the needed functions * dynamically from winscard.dll for now. */static HINSTANCE dll = NULL; /* winscard.dll */static const SCARD_IO_REQUEST *dll_g_rgSCardT0Pci, *dll_g_rgSCardT1Pci;#undef SCARD_PCI_T0#define SCARD_PCI_T0 (dll_g_rgSCardT0Pci)#undef SCARD_PCI_T1#define SCARD_PCI_T1 (dll_g_rgSCardT1Pci)static WINSCARDAPI LONG WINAPI(*dll_SCardEstablishContext)(IN DWORD dwScope,			     IN LPCVOID pvReserved1,			     IN LPCVOID pvReserved2,			     OUT LPSCARDCONTEXT phContext);#define SCardEstablishContext dll_SCardEstablishContextstatic long (*dll_SCardReleaseContext)(long hContext);#define SCardReleaseContext dll_SCardReleaseContextstatic WINSCARDAPI LONG WINAPI(*dll_SCardListReadersA)(IN SCARDCONTEXT hContext,			 IN LPCSTR mszGroups,			 OUT LPSTR mszReaders,			 IN OUT LPDWORD pcchReaders);#undef SCardListReaders#define SCardListReaders dll_SCardListReadersAstatic WINSCARDAPI LONG WINAPI(*dll_SCardConnectA)(IN SCARDCONTEXT hContext,		     IN LPCSTR szReader,		     IN DWORD dwShareMode,		     IN DWORD dwPreferredProtocols,		     OUT LPSCARDHANDLE phCard,		     OUT LPDWORD pdwActiveProtocol);#undef SCardConnect#define SCardConnect dll_SCardConnectAstatic WINSCARDAPI LONG WINAPI(*dll_SCardDisconnect)(IN SCARDHANDLE hCard,		       IN DWORD dwDisposition);#define SCardDisconnect dll_SCardDisconnectstatic WINSCARDAPI LONG WINAPI(*dll_SCardTransmit)(IN SCARDHANDLE hCard,		     IN LPCSCARD_IO_REQUEST pioSendPci,		     IN LPCBYTE pbSendBuffer,		     IN DWORD cbSendLength,		     IN OUT LPSCARD_IO_REQUEST pioRecvPci,		     OUT LPBYTE pbRecvBuffer,		     IN OUT LPDWORD pcbRecvLength);#define SCardTransmit dll_SCardTransmitstatic WINSCARDAPI LONG WINAPI(*dll_SCardBeginTransaction)(IN SCARDHANDLE hCard);#define SCardBeginTransaction dll_SCardBeginTransactionstatic WINSCARDAPI LONG WINAPI(*dll_SCardEndTransaction)(IN SCARDHANDLE hCard, IN DWORD dwDisposition);#define SCardEndTransaction dll_SCardEndTransactionstatic int mingw_load_symbols(void){	char *sym;	if (dll)		return 0;	dll = LoadLibrary("winscard");	if (dll == NULL) {		wpa_printf(MSG_DEBUG, "WinSCard: Could not load winscard.dll "			   "library");		return -1;	}#define LOADSYM(s) \	sym = #s; \	dll_ ## s = (void *) GetProcAddress(dll, sym); \	if (dll_ ## s == NULL) \		goto fail;	LOADSYM(SCardEstablishContext);	LOADSYM(SCardReleaseContext);	LOADSYM(SCardListReadersA);	LOADSYM(SCardConnectA);	LOADSYM(SCardDisconnect);	LOADSYM(SCardTransmit);	LOADSYM(SCardBeginTransaction);	LOADSYM(SCardEndTransaction);	LOADSYM(g_rgSCardT0Pci);	LOADSYM(g_rgSCardT1Pci);#undef LOADSYM	return 0;fail:	wpa_printf(MSG_DEBUG, "WinSCard: Could not get address for %s from "		   "winscard.dll", sym);	FreeLibrary(dll);	dll = NULL;	return -1;}static void mingw_unload_symbols(void){	if (dll == NULL)		return;	FreeLibrary(dll);	dll = NULL;}#else /* __MINGW32_VERSION */#define mingw_load_symbols() 0#define mingw_unload_symbols() do { } while (0)#endif /* __MINGW32_VERSION */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);static int scard_select_file(struct scard_data *scard, unsigned short file_id,			     unsigned char *buf, size_t *buf_len);static int scard_verify_pin(struct scard_data *scard, const char *pin);static int scard_get_record_len(struct scard_data *scard,				unsigned char recnum, unsigned char mode);static int scard_read_record(struct scard_data *scard,			     unsigned char *data, size_t len,			     unsigned char recnum, unsigned char mode);static int scard_parse_fsp_templ(unsigned char *buf, size_t buf_len,				 int *ps_do, int *file_len){		unsigned char *pos, *end;		if (ps_do)			*ps_do = -1;		if (file_len)			*file_len = -1;		pos = buf;		end = pos + buf_len;		if (*pos != USIM_FSP_TEMPL_TAG) {			wpa_printf(MSG_DEBUG, "SCARD: file header did not "				   "start with FSP template tag");			return -1;		}		pos++;		if (pos >= end)			return -1;		if ((pos + pos[0]) < end)			end = pos + 1 + pos[0];		pos++;		wpa_hexdump(MSG_DEBUG, "SCARD: file header FSP template",			    pos, end - pos);		while (pos + 1 < end) {			wpa_printf(MSG_MSGDUMP, "SCARD: file header TLV "				   "0x%02x len=%d", pos[0], pos[1]);			if (pos + 2 + pos[1] > end)				break;			if (pos[0] == USIM_TLV_FILE_SIZE &&			    (pos[1] == 1 || pos[1] == 2) && file_len) {				if (pos[1] == 1)					*file_len = (int) pos[2];				else					*file_len = ((int) pos[2] << 8) |						(int) pos[3];				wpa_printf(MSG_DEBUG, "SCARD: file_size=%d",					   *file_len);			}			if (pos[0] == USIM_TLV_PIN_STATUS_TEMPLATE &&			    pos[1] >= 2 && pos[2] == USIM_PS_DO_TAG &&			    pos[3] >= 1 && ps_do) {				wpa_printf(MSG_DEBUG, "SCARD: PS_DO=0x%02x",					   pos[4]);				*ps_do = (int) pos[4];			}			pos += 2 + pos[1];			if (pos == end)				return 0;		}		return -1;}static int scard_pin_needed(struct scard_data *scard,			    unsigned char *hdr, size_t hlen){	if (scard->sim_type == SCARD_GSM_SIM) {		if (hlen > SCARD_CHV1_OFFSET &&		    !(hdr[SCARD_CHV1_OFFSET] & SCARD_CHV1_FLAG))			return 1;		return 0;	}	if (scard->sim_type == SCARD_USIM) {		int ps_do;		if (scard_parse_fsp_templ(hdr, hlen, &ps_do, NULL))			return -1;		/* TODO: there could be more than one PS_DO entry because of		 * multiple PINs in key reference.. */		if (ps_do > 0 && (ps_do & 0x80))			return 1;		return 0;	}	return -1;}static int scard_get_aid(struct scard_data *scard, unsigned char *aid,			 size_t maxlen){	int rlen, rec;	struct efdir {		unsigned char appl_template_tag; /* 0x61 */		unsigned char appl_template_len;		unsigned char appl_id_tag; /* 0x4f */		unsigned char aid_len;		unsigned char rid[5];		unsigned char appl_code[2]; /* 0x1002 for 3G USIM */	} *efdir;	unsigned char buf[100];	size_t blen;	efdir = (struct efdir *) buf;	blen = sizeof(buf);	if (scard_select_file(scard, SCARD_FILE_EF_DIR, buf, &blen)) {		wpa_printf(MSG_DEBUG, "SCARD: Failed to read EF_DIR");		return -1;	}	wpa_hexdump(MSG_DEBUG, "SCARD: EF_DIR select", buf, blen);	for (rec = 1; rec < 10; rec++) {		rlen = scard_get_record_len(scard, rec,					    SIM_RECORD_MODE_ABSOLUTE);		if (rlen < 0) {			wpa_printf(MSG_DEBUG, "SCARD: Failed to get EF_DIR "				   "record length");			return -1;		}		blen = sizeof(buf);		if (rlen > (int) blen) {			wpa_printf(MSG_DEBUG, "SCARD: Too long EF_DIR record");			return -1;		}		if (scard_read_record(scard, buf, rlen, rec,				      SIM_RECORD_MODE_ABSOLUTE) < 0) {			wpa_printf(MSG_DEBUG, "SCARD: Failed to read "				   "EF_DIR record %d", rec);			return -1;		}		wpa_hexdump(MSG_DEBUG, "SCARD: EF_DIR record", buf, rlen);		if (efdir->appl_template_tag != 0x61) {			wpa_printf(MSG_DEBUG, "SCARD: Unexpected application "				   "template tag 0x%x",				   efdir->appl_template_tag);			continue;		}		if (efdir->appl_template_len > rlen - 2) {			wpa_printf(MSG_DEBUG, "SCARD: Too long application "				   "template (len=%d rlen=%d)",				   efdir->appl_template_len, rlen);			continue;		}		if (efdir->appl_id_tag != 0x4f) {			wpa_printf(MSG_DEBUG, "SCARD: Unexpected application "				   "identifier tag 0x%x", efdir->appl_id_tag);			continue;		}		if (efdir->aid_len < 1 || efdir->aid_len > 16) {			wpa_printf(MSG_DEBUG, "SCARD: Invalid AID length %d",				   efdir->aid_len);			continue;		}		wpa_hexdump(MSG_DEBUG, "SCARD: AID from EF_DIR record",			    efdir->rid, efdir->aid_len);		if (efdir->appl_code[0] == 0x10 &&		    efdir->appl_code[1] == 0x02) {			wpa_printf(MSG_DEBUG, "SCARD: 3G USIM app found from "				   "EF_DIR record %d", rec);			break;		}	}	if (rec >= 10) {		wpa_printf(MSG_DEBUG, "SCARD: 3G USIM app not found "			   "from EF_DIR records");		return -1;	}	if (efdir->aid_len > maxlen) {		wpa_printf(MSG_DEBUG, "SCARD: Too long AID");

⌨️ 快捷键说明

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