?? sm_handler.c
字號(hào):
for (i=strlen(pin); i<8; i++)
{
if (Strcat(buf2, sizeof(buf2), "FF") != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return NULL;
}
}
len = MAXBUFF;
if (cardio(card_hdl, buf2, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error sending PIN to smart card! "
"(%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
// XXX When we get a GUI going, this should be sent to it.
if ((len == 2) && (buf[0] = 0x98))
{
if (buf[1] == 0x04)
{
debug_printf(DEBUG_NORMAL, "Incorrect PIN, at least one attempt "
"remaining!\n");
return NULL;
}
else if (buf[1] == 0x40)
{
debug_printf(DEBUG_NORMAL, "Incorrect PIN, no attempts "
"remaining!\n");
return NULL;
}
}
}
len = MAXBUFF;
if (cardio(card_hdl, SELECT_EF_IMSI, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to select the IMSI on the"
" smart card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
len = MAXBUFF;
memset((char *)&buf, 0x00, 512);
if (cardio(card_hdl, GET_IMSI, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to get the IMSI from the "
"smart card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
return decode_imsi((unsigned char *)&buf[1]);
}
int sm_handler_do_2g_auth(SCARDHANDLE *card_hdl, char reader_mode,
unsigned char *challenge, unsigned char *response,
unsigned char *ckey)
{
unsigned char buf[MAXBUFF], buff2[MAXBUFF], buff3[MAXBUFF];
int i;
DWORD len;
if ((!challenge) || (!response) || (!ckey))
{
debug_printf(DEBUG_NORMAL, "Invalid data passed to "
"sm_handler_do_2g_auth!\n");
return -1;
}
strcpy(buff2, RUN_GSM);
memset(&buff3, 0x00, MAXBUFF);
for (i = 0; i < 16; i++)
{
sprintf(buff3,"%02X",challenge[i]);
if (Strcat(buff2, sizeof(buff2), buff3) != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return -1;
}
}
len = MAXBUFF;
if (cardio(card_hdl, buff2, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to run the GSM algorithm!\n");
return -1;
}
memcpy(response, &buf[0], 4);
memcpy(ckey, &buf[4], 8);
return XENONE;
}
char *sm_handler_3g_imsi(SCARDHANDLE *card_hdl, char reader_mode, char *pin)
{
DWORD len;
unsigned char buf[MAXBUFF], buf2[MAXBUFF], aid[MAXBUFF], temp[MAXBUFF], *p;
unsigned char cmd[MAXBUFF], buf3[MAXBUFF];
int i,l,q, foundaid=0, pinretries=0;
unsigned char threeG[2] = { 0x10, 0x02 };
struct t_efdir *t;
if (!card_hdl)
{
debug_printf(DEBUG_NORMAL, "Invalid card handle passed to "
"sm_handler_3g_imsi()!\n");
return NULL;
}
if (strlen(pin) > 8)
{
// XXX This should be returned to a GUI when we have one!
debug_printf(DEBUG_NORMAL, "PIN is too long!\n");
return NULL;
}
// Select the USIM master file.
if (cardio(card_hdl, SELECT_MF_USIM, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to select the master file "
"on the SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
if (buf[0] == 0x6e)
{
debug_printf(DEBUG_NORMAL, "3G mode not supported by this card!\n");
return NULL;
}
// Select the ICCID of the card.
if (cardio(card_hdl, SELECT_EF_ICCID, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to select the ICCID of "
"this SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
if (cardio(card_hdl, SELECT_FCP, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to select the FCP of this "
"SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
if (cardio(card_hdl, SELECT_EFDIR, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error selecting the EFDIR on this SIM card!"
" (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
if (cardio(card_hdl, EFDIR_READREC1, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to read record #1 from "
"this SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
l = buf[len-1];
i = 1;
// Loop over EFdir
do {
sprintf(buf, "00B2%2.2X04%2.2X",i,l);
if (cardio(card_hdl, buf, reader_mode, MODE3G, (LPBYTE)&buf2, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to read a record from "
"this SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
i++;
t = (struct t_efdir *)&buf2;
if (!memcmp(&t->app_code, &threeG, 2))
{
memset((unsigned char *)&aid, 0x00, MAXBUFF);
p = (unsigned char *)&t->rid;
for (q=0; q< 12; q++)
{
sprintf(temp, "%02X", *p++);
if (Strcat(aid, sizeof(aid), temp) != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return NULL;
}
}
foundaid = 1;
}
} while ((buf2[len-2] == 0x90) && (buf2[len-1] == 0));
// Select the USIM aid.
strcpy(cmd, "00A404040C");
if (Strcat(cmd, sizeof(cmd), aid) != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return NULL;
}
if (cardio(card_hdl, cmd, reader_mode, MODE3G, (LPBYTE)&buf2, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't select the USIM application ID! "
"(%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
// Determine remaining CHV retires.
if (cardio(card_hdl, CHV_RETRIES, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error requesting the remaining number of "
"PIN attempts from this SIM! (%s:%d)\n", __FUNCTION__,
__LINE__);
return NULL;
}
if (buf[0] == 0x63)
{
pinretries = buf[1] & 0x0f;
}
// if (!(buf2[13] & 0x80))
{
if (pinretries == 0)
{
debug_printf(DEBUG_NORMAL, "No PIN retries remaining!\n");
return NULL;
}
// Otherwise, enter the PIN.
strcpy(buf2, CHV_ATTEMPT);
for (i=0;i < strlen(pin); i++)
{
memset((char *)&buf3, 0x00, 8);
sprintf(buf3, "%02X", pin[i]);
if (Strcat(buf2, sizeof(buf2), buf3) != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return NULL;
}
}
for (i=strlen(pin); i<8; i++)
{
if (Strcat(buf2, sizeof(buf2), "FF") != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return NULL;
}
}
if (cardio(card_hdl, buf2, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Invalid PIN! (%d tries remain.)\n",
pinretries-1);
return NULL;
}
if (cardio(card_hdl, buf2, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Invalid PIN! (%d tries remain.)\n",
pinretries-1);
return NULL;
}
} //else {
// debug_printf(DEBUG_SMARTCARD, "PIN not needed!\n");
//}
// Now, get the IMSI
if (cardio(card_hdl, USELECT_EF_IMSI, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to select the IMSI for this"
" SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
// XXX For now, assume that IMSIs are 9 bytes.
if (cardio(card_hdl, READ_IMSI, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error reading the IMSI on this SIM card! "
"(%s:%d)\n", __FUNCTION__, __LINE__);
return NULL;
}
return decode_imsi((unsigned char *)&buf[1]);
}
/* tack on a sequence of hex command bytes to a string
* buffer is assumed to already contain a zero-terminated string
*/
int
addhex(u8 *buffer, unsigned int buflen, const u8 *bytes, int len)
{
u8 temp[5];
int i;
for (i = 0; i < len; i++) {
sprintf(temp,"%02X", *bytes++);
if (Strcat(buffer, buflen, temp) != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return -1;
}
}
return 0;
}
// return -2 on sync failure. -1 for all other errors.
int sm_handler_do_3g_auth(SCARDHANDLE *card_hdl, char reader_mode,
unsigned char *Rand, unsigned char *autn,
unsigned char *c_auts, char *res_len,
unsigned char *c_sres, unsigned char *c_ck,
unsigned char *c_ik, unsigned char *c_kc)
{
unsigned char cmd[MAXBUFF], buf[MAXBUFF], sw1, sw2, *s;
DWORD len;
if (Strcpy(cmd, sizeof(cmd), "008800812210") != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return -1;
}
if (addhex(cmd, sizeof(cmd), Rand, 16) != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return -1;
}
if (Strcat(cmd, sizeof(cmd), "10") != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return -1;
}
if (addhex(cmd, sizeof(cmd), autn, 16) != 0)
{
fprintf(stderr, "Refusing to overflow string!\n");
return -1;
}
debug_printf(DEBUG_SMARTCARD, "Sending in '%s'\n", cmd);
len = MAXBUFF;
if (cardio(card_hdl, cmd, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
{
debug_printf(DEBUG_NORMAL, "Error attempting to execute 3G "
"authentication! (%s:%d)\n", __FUNCTION__, __LINE__);
return -1;
}
sw1 = buf[len-2]; sw2 = buf[len-1];
if ((sw1 == 0x90) && (sw2 == 0x00) && (buf[0] == 0xdc))
{
debug_printf(DEBUG_NORMAL, "Sync failure! (Result length = %d)\n",
len);
memcpy(c_auts, buf+2, len);
return -2;
}
if ((sw1 == 0x90) && (sw2 == 0x00) && (buf[0] == 0xdb))
{
// Success.
s = buf+1;
*res_len = *s;
memcpy(c_sres, s+1, *s);
s += (*s+1); // Step over TLV vectors
memcpy(c_ck, s+1, *s);
s += (*s+1); // Ditto.
memcpy(c_ik, s+1, *s);
s += (*s+1);
memcpy(c_kc, s+1, *s); s += *s;
return 0;
}
// Otherwise, we failed.
return -1;
}
int sm_handler_card_disconnect(SCARDHANDLE *card_hdl)
{
long ret = 0;
if (card_hdl)
{
ret = SCardDisconnect(*card_hdl, SCARD_UNPOWER_CARD);
if (ret != SCARD_S_SUCCESS)
{
debug_printf(DEBUG_NORMAL, "Couldn't disconnect from Smart Card! ");
print_sc_error(ret);
} else {
card_hdl = NULL;
}
}
return ret;
}
int sm_handler_close_sc(SCARDHANDLE *card_hdl, SCARDCONTEXT *card_ctx)
{
long ret;
if (card_hdl)
{
ret = SCardDisconnect(*card_hdl, SCARD_UNPOWER_CARD);
if (ret != SCARD_S_SUCCESS)
{
debug_printf(DEBUG_NORMAL, "Couldn't disconnect from Smart Card! ");
print_sc_error(ret);
}
}
if (card_ctx)
{
ret = SCardReleaseContext(*card_ctx);
if (ret != SCARD_S_SUCCESS)
{
debug_printf(DEBUG_NORMAL, "Couldn't release Smart Card context! ");
print_sc_error(ret);
}
}
return 0;
}
#endif
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -