📄 sm_handler.c
字号:
/********************************************************************* * * SIM Card Handler for PC/SC lite library * * This code was developed by Chris Hessing, using code written by : * * Michael Haberler mah@eunet.at * based on original work by marek@bmlv.gv.at 2000 * make it work with pcsclite-1.0.1: Vincent Guyot <vguyot@inf.enst.fr> 2002-07-12 * some parts Chris Hessing chris.hessing@utah.edu * * * This code is released under dual BSD/GPL license. * ********************************************************************** * --- BSD License --- * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * Maryland at College Park and its contributors. * - Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *//******************************************************************** EAPOL Function implementations for supplicant * * File: sm_handler.c * * Authors: Chris.Hessing@utah.edu * * $Id: sm_handler.c,v 1.19 2006/06/01 22:49:50 galimorerpg Exp $ * $Date: 2006/06/01 22:49:50 $ * $Log: sm_handler.c,v $ * Revision 1.19 2006/06/01 22:49:50 galimorerpg * Converted all instances of u_char to uint8_t * Fixed a bad #include in the generic frame handler. * * Revision 1.18 2006/05/29 04:17:58 chessing * Fixes for some memory leaks. * * Revision 1.17 2006/03/28 21:16:07 chessing * Fixes to EAP-AKA, and PEAP. PEAP now handles inner success messages, and works with Funk SBR. * * Revision 1.16 2006/03/21 18:22:10 chessing * Fixes to EAP-AKA code. Changed a few defaults to disable Xsupplicant based roaming, and passive scanning for this release. (It would currently cause more problems than it would solve. * * Revision 1.15 2006/03/08 00:16:04 chessing * Fixed EAP hints code to work correctly when the request ID packet is padded out with null bytes. (Observed in Aruba APs.) Some changes/fixes for the EAP-AKA module. * * Revision 1.14 2005/08/09 01:39:17 chessing * Cleaned out old commit notes from the released version. Added a few small features including the ability to disable the friendly warnings that are spit out. (Such as the warning that is displayed when keys aren't rotated after 10 minutes.) We should also be able to start when the interface is down. Last, but not least, we can handle empty network configs. (This may be useful for situations where there isn't a good reason to have a default network defined.) * * *******************************************************************//******************************************************************* * * The development of the EAP/SIM support was funded by Internet * Foundation Austria (http://www.nic.at/ipa) * *******************************************************************//* Interface to Smart Cards using PCSC with 802.1x. */#ifdef EAP_SIM_ENABLE#include <stdio.h>#include <winscard.h>#include <string.h>#include <ctype.h>#include <strings.h>#include <stdlib.h>#include <unistd.h>#include "xsup_debug.h"#include "xsup_err.h"#ifdef USE_EFENCE#include <efence.h>#endif// 2G bytecodes#define SELECT_MF "A0A40000023F00"#define SELECT_DF_GSM "A0A40000027F20"#define SELECT_EF_IMSI "A0A40000026F07"#define RUN_GSM "A088000010"#define GET_IMSI "A0B0000009"// 3G bytecodes#define SELECT_MF_USIM "00A4000C"#define SELECT_EF_ICCID "00A40004022FE2"#define SELECT_FCP "00A4000C"#define SELECT_EFDIR "00A40004022F00"#define EFDIR_READREC1 "00B20104FF"#define CHV_RETRIES "0020000100"#define CHV_UNBLOCK "002C000110"#define CHV_ATTEMPT "0020000108"#define USELECT_EF_IMSI "00A40904026F07"#define READ_IMSI "00B0000009"#define MODE2G 1#define MODE3G 0#define DO_DEBUG 1#define MAXBUFF 512typedef unsigned char u8;/* structure of the EFdir AID (application ID) */typedef struct t_efdir { u8 tag61; u8 length; u8 tag4f; u8 aid_len; /* application identifier value */ u8 rid[5]; u8 app_code[2]; /* 0x1002 for 3G USIM app */ u8 country_code[2]; u8 prov_code[3]; u8 prov_field[4]; u8 tag50; u8 al_len; u8 app_label[16]; /* like "Mobilkom Austria", 0xff padded */} t_efdir;typedef struct { u8 msk[2], rsp[2], *text; } t_response;const t_response response[]= { { { 0xff, 0xff }, { 0x90, 0x00 } , "Ok" }, { { 0xff, 0xff }, { 0x98, 0x02 } , "no CHV initialized" }, { { 0xff, 0xff }, { 0x98, 0x04 } , "access condition not fulfilled" }, { { 0xff, 0xff }, { 0x98, 0x08 } , "in contradiction with CHV status" }, { { 0xff, 0xff }, { 0x98, 0x10 } , "in contradiction with invalidation status" }, { { 0xff, 0xff }, { 0x98, 0x40 } , "unsuccessful CHV verification, no attempts left" }, { { 0xff, 0xff }, { 0x98, 0x50 } , "decrease cannot be performed, maximum value reached" }, { { 0xff, 0xff }, { 0x98, 0x62 } , "verify if MAC == XMAC" }, { { 0xff, 0xff }, { 0x98, 0x64 } , "Service not available" }, { { 0xff, 0x00 }, { 0x9f, 0x00 } , "%d response bytes available" }, { { 0xff, 0x00 }, { 0x61, 0x00 } , "%d response bytes available" }, { { 0xff, 0xff }, { 0x62, 0x00 } , "curent file is already activated" }, { { 0xff, 0xff }, { 0x62, 0x81 } , "returned data may be corrupt" }, { { 0xff, 0xff }, { 0x62, 0x82 } , "EOF reached prematurely" }, { { 0xff, 0xff }, { 0x62, 0x83 } , "selected file invalid" }, { { 0xff, 0xff }, { 0x62, 0x84 } , "FCI not formated" }, { { 0xff, 0x00 }, { 0x62, 0x00 } , "nvmem unchanged" }, { { 0xff, 0x00 }, { 0x63, 0x81 } , "file filled up by last write" }, { { 0xff, 0xf0 }, { 0x63, 0xc0 } , "Counter=%1.1X" }, { { 0xff, 0x00 }, { 0x63, 0x00 } , "nvmem changed1" }, { { 0xff, 0xff }, { 0x64, 0x00 } , "nvmem unchanged or no active application" }, { { 0xff, 0x00 }, { 0x64, 0x00 } , "nvmem unchanged - RFU" }, { { 0xff, 0xff }, { 0x65, 0x00 } , "nvmem changed2" }, { { 0xff, 0xff }, { 0x65, 0x81 } , "nvmem changed - memory failure" }, { { 0xff, 0x00 }, { 0x65, 0x00 } , "nvmem changed - unknown?" }, { { 0xff, 0x00 }, { 0x66, 0x00 } , "security related %d" }, { { 0xff, 0xff }, { 0x67, 0x00 } , "wrong length" }, { { 0xff, 0x00 }, { 0x67, 0x00 } , "wrong length - %d expected" }, { { 0xff, 0xff }, { 0x68, 0x81 } , "wrong cla - logical channel not supported" }, { { 0xff, 0xff }, { 0x68, 0x82 } , "wrong cla - secure messaging not supported" }, { { 0xff, 0x00 }, { 0x68, 0x00 } , "cla not supported" }, { { 0xff, 0xff }, { 0x69, 0x81 } , "command incompatible with file structure" }, { { 0xff, 0xff }, { 0x69, 0x82 } , "security status not satisfied (PIN1)" }, { { 0xff, 0xff }, { 0x69, 0x83 } , "authentication method blocked - no PIN attempts left" }, { { 0xff, 0xff }, { 0x69, 0x84 } , "referenced data invalid" }, { { 0xff, 0xff }, { 0x69, 0x85 } , "conditions of use not satisfied" }, { { 0xff, 0xff }, { 0x69, 0x86 } , "command not allowed - no current EF" }, { { 0xff, 0xff }, { 0x69, 0x87 } , "expected SM data objects missing" }, { { 0xff, 0xff }, { 0x69, 0x88 } , "SM data objects incorrect" }, { { 0xff, 0x00 }, { 0x69, 0x00 } , "command not allowed" }, { { 0xff, 0xff }, { 0x6a, 0x80 } , "P1-P2: incorrect parameters in data field" }, { { 0xff, 0xff }, { 0x6a, 0x81 } , "P1-P2: function not supported" }, { { 0xff, 0xff }, { 0x6a, 0x82 } , "P1-P2: file/search pattern not found" }, { { 0xff, 0xff }, { 0x6a, 0x83 } , "P1-P2: record not found" }, { { 0xff, 0xff }, { 0x6a, 0x84 } , "P1-P2: not enough memory space in file" }, { { 0xff, 0xff }, { 0x6a, 0x85 } , "P1-P2: Lc inconsistent with TLV" }, { { 0xff, 0xff }, { 0x6a, 0x86 } , "P1-P2 incorrect (out of range)" }, { { 0xff, 0xff }, { 0x6a, 0x87 } , "P1-P2 inconsistent with Lc" }, { { 0xff, 0xff }, { 0x6a, 0x88 } , "verify if EFkeyop exists attached to current file" }, { { 0xff, 0xff }, { 0x6a, 0x88 } , "Referenced data not found" }, { { 0xff, 0xff }, { 0x6a, 0x89 } , "File already exists in current DF" }, { { 0xff, 0x00 }, { 0x6a, 0x00 } , "P1-P2 invalid" }, { { 0xff, 0x00 }, { 0x6b, 0x00 } , "P1-P2 invalid" }, { { 0xff, 0x00 }, { 0x6c, 0x00 } , "wrong length - %d expected" }, { { 0xff, 0x00 }, { 0x6d, 0x00 } , "INS code not supported or invalid" }, { { 0xff, 0x00 }, { 0x6e, 0x00 } , "CLA %02X not supported" }, { { 0xff, 0xff }, { 0x6f, 0x01 } , "no active application" }, { { 0xff, 0xff }, { 0x6f, 0x06 } , "FCP formatting aborted" }, { { 0xff, 0xff }, { 0x6f, 0x19 } , "no valid key attached to current file" }, { { 0xff, 0xff }, { 0x6f, 0x00 } , "EF or DF integrity error" }, { { 0xff, 0xff }, { 0x6f, 0x03 } , "Decrements number of the unblock mechanism (if not 0xff)" }, { { 0xff, 0xff }, { 0x6f, 0x07 } , "incorrect child number" }, { { 0xff, 0xff }, { 0x6f, 0x0d } , "Reset PIN/ADM retry counter or disable EFpin or EFadm" }, { { 0xff, 0xff }, { 0x6f, 0x0e } , "Reset UNBLOCK PIN error counter to maximum value" }, { { 0xff, 0xff }, { 0x6f, 0x15 } , "PIN/ADM enable/disable not allowed" }, { { 0xff, 0xff }, { 0x6f, 0x16 } , "incorrect UNBLOCK pin" }, { { 0xff, 0xff }, { 0x6f, 0x17 } , "number of unblock mechanism is not equal to 0x00" }, { { 0xff, 0xff }, { 0x6f, 0x1e } , "no data waiting for GET RESPONSE" }, { { 0xff, 0xff }, { 0x6f, 0x1f } , "File deactivated" }, { { 0xff, 0xff }, { 0x6f, 0x22 } , "length of search pattern > 128 bytes" }, { { 0xff, 0x00 }, { 0x6f, 0x00 } , "no precise diagnosis" }, { { 0x00, 0x00 }, { 0x00, 0x00 } , "Unknown response" }};void print_sc_error(long err){ switch (err) { case SCARD_E_CANCELLED: debug_printf(DEBUG_NORMAL, "Error : Card Request Cancelled!\n"); break; case SCARD_E_CANT_DISPOSE: debug_printf(DEBUG_NORMAL, "Error : Can't dispose (!?)\n"); break; case SCARD_E_INSUFFICIENT_BUFFER: debug_printf(DEBUG_NORMAL, "Error : Insufficient Buffer\n"); break; case SCARD_E_INVALID_ATR: debug_printf(DEBUG_NORMAL, "Error : Invalid ATR\n"); break; case SCARD_E_INVALID_HANDLE: debug_printf(DEBUG_NORMAL, "Error : Invalid handle\n"); break; case SCARD_E_INVALID_PARAMETER: debug_printf(DEBUG_NORMAL, "Error : Invalid parameter\n"); break; case SCARD_E_INVALID_TARGET: debug_printf(DEBUG_NORMAL, "Error : Invalid target\n"); break; case SCARD_E_INVALID_VALUE: debug_printf(DEBUG_NORMAL, "Error : Invalid Value\n"); break; case SCARD_E_NO_MEMORY: debug_printf(DEBUG_NORMAL, "Error : No memory\n"); break; case SCARD_F_COMM_ERROR: debug_printf(DEBUG_NORMAL, "Error : Communication error \n"); break; case SCARD_F_INTERNAL_ERROR: debug_printf(DEBUG_NORMAL, "Error : Internal error\n"); break; case SCARD_F_WAITED_TOO_LONG: debug_printf(DEBUG_NORMAL, "Error : Waited too long\n"); break; case SCARD_E_UNKNOWN_READER: debug_printf(DEBUG_NORMAL, "Error : Unknown reader\n"); break; case SCARD_E_TIMEOUT: debug_printf(DEBUG_NORMAL, "Error : Timeout\n"); break; case SCARD_E_SHARING_VIOLATION: debug_printf(DEBUG_NORMAL, "Error : Sharing Violation\n"); break; case SCARD_E_NO_SMARTCARD: debug_printf(DEBUG_NORMAL, "Error : No smartcard!\n"); break; case SCARD_E_UNKNOWN_CARD: debug_printf(DEBUG_NORMAL, "Error : Unknown card!\n"); break; case SCARD_E_PROTO_MISMATCH: debug_printf(DEBUG_NORMAL, "Error : Protocol mismatch!\n"); break; case SCARD_E_NOT_READY: debug_printf(DEBUG_NORMAL, "Error : Not ready!\n"); break; case SCARD_E_SYSTEM_CANCELLED: debug_printf(DEBUG_NORMAL, "Error : System Cancelled\n"); break; case SCARD_E_NOT_TRANSACTED: debug_printf(DEBUG_NORMAL, "Error : Not Transacted\n"); break; case SCARD_E_READER_UNAVAILABLE: debug_printf(DEBUG_NORMAL, "Error : Reader unavailable\n"); break; case SCARD_F_UNKNOWN_ERROR: default: debug_printf(DEBUG_NORMAL, "Unknown error!\n"); break; }}int sm_handler_init_ctx(SCARDCONTEXT *card_ctx){ long ret; if (!card_ctx) { debug_printf(DEBUG_NORMAL, "Invalid memory location for card context!\n"); return -1; } *card_ctx = 0; ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, card_ctx); if (ret != SCARD_S_SUCCESS) { debug_printf(DEBUG_NORMAL, "Couldn't establish Smart Card context! " "(Is pcscd loaded?)\n"); print_sc_error(ret); return -1; } return 0;}char *sm_handler_get_readers(SCARDCONTEXT *card_ctx){ long readerstrlen; char *readername; int ret; ret = SCardListReaders(*card_ctx, NULL, NULL, &readerstrlen); if (ret != SCARD_S_SUCCESS) { debug_printf(DEBUG_NORMAL, "Error requesting list of smart card " "readers! "); print_sc_error(ret); return NULL; } readername = (char *)malloc(readerstrlen+1); if (readername == NULL) { debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for reader name! " "(%s:%d)\n", __FUNCTION__, __LINE__); return NULL; } ret = SCardListReaders(*card_ctx, NULL, readername, &readerstrlen); if (ret != SCARD_S_SUCCESS) { debug_printf(DEBUG_NORMAL, "Error requesting list of smart card " "readers! "); print_sc_error(ret); return NULL; } return readername;}long sm_handler_card_connect(SCARDCONTEXT *card_ctx, SCARDHANDLE *card_hdl, char *cardreader){ long ret, activeprotocol; debug_printf(DEBUG_NORMAL, "Using reader : %s\n", cardreader); while (1) { ret = SCardConnect(*card_ctx, cardreader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, card_hdl, &activeprotocol); if (ret == SCARD_S_SUCCESS) break; if (ret == SCARD_E_NO_SMARTCARD) { // XXX This should be changed when we attach a GUI to Xsupplicant. debug_printf(DEBUG_NORMAL, "Please insert a smart card!\n"); sleep(2); } else { debug_printf(DEBUG_NORMAL, "Error attempting to connect to the " "smart card! "); print_sc_error(ret); return -1; break; } } return 0;}int sm_handler_wait_card_ready(SCARDHANDLE *card_hdl, int waittime){ DWORD dwState, dwProtocol, dwAtrLen, size; BYTE pbAtr[MAX_ATR_SIZE]; int loopcnt, ret; LPSTR mszReaders;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -