Protect the communication with the SIM card during a transaction from access by a second application
This commit is contained in:
committed by
Andreas Steffen
parent
e8a512f800
commit
4b6ebf9995
@@ -98,6 +98,8 @@ METHOD(sim_card_t, get_triplet, bool,
|
|||||||
LPSTR mszReaders;
|
LPSTR mszReaders;
|
||||||
char *cur_reader;
|
char *cur_reader;
|
||||||
char full_nai[128];
|
char full_nai[128];
|
||||||
|
SCARDHANDLE hCard;
|
||||||
|
enum { DISCONNECTED, CONNECTED, TRANSACTION } hCard_status = DISCONNECTED;
|
||||||
|
|
||||||
snprintf(full_nai, sizeof(full_nai), "%Y", id);
|
snprintf(full_nai, sizeof(full_nai), "%Y", id);
|
||||||
|
|
||||||
@@ -131,7 +133,6 @@ METHOD(sim_card_t, get_triplet, bool,
|
|||||||
cur_reader += strlen(cur_reader) + 1)
|
cur_reader += strlen(cur_reader) + 1)
|
||||||
{
|
{
|
||||||
DWORD dwActiveProtocol = -1;
|
DWORD dwActiveProtocol = -1;
|
||||||
SCARDHANDLE hCard;
|
|
||||||
SCARD_IO_REQUEST *pioSendPci;
|
SCARD_IO_REQUEST *pioSendPci;
|
||||||
SCARD_IO_REQUEST pioRecvPci;
|
SCARD_IO_REQUEST pioRecvPci;
|
||||||
BYTE pbRecvBuffer[64];
|
BYTE pbRecvBuffer[64];
|
||||||
@@ -139,12 +140,26 @@ METHOD(sim_card_t, get_triplet, bool,
|
|||||||
char imsi[SIM_IMSI_MAX_LEN + 1];
|
char imsi[SIM_IMSI_MAX_LEN + 1];
|
||||||
|
|
||||||
/* See GSM 11.11 for SIM APDUs */
|
/* See GSM 11.11 for SIM APDUs */
|
||||||
BYTE pbSelectMF[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00 };
|
static const BYTE pbSelectMF[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00 };
|
||||||
BYTE pbSelectDFGSM[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x7f, 0x20 };
|
static const BYTE pbSelectDFGSM[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x7f, 0x20 };
|
||||||
BYTE pbSelectIMSI[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x6f, 0x07 };
|
static const BYTE pbSelectIMSI[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x6f, 0x07 };
|
||||||
BYTE pbReadBinary[] = { 0xa0, 0xb0, 0x00, 0x00, 0x09 };
|
static const BYTE pbReadBinary[] = { 0xa0, 0xb0, 0x00, 0x00, 0x09 };
|
||||||
BYTE pbRunGSMAlgorithm[5 + SIM_RAND_LEN] = { 0xa0, 0x88, 0x00, 0x00, 0x10 };
|
BYTE pbRunGSMAlgorithm[5 + SIM_RAND_LEN] = { 0xa0, 0x88, 0x00, 0x00, 0x10 };
|
||||||
BYTE pbGetResponse[] = { 0xa0, 0xc0, 0x00, 0x00, 0x0c };
|
static const BYTE pbGetResponse[] = { 0xa0, 0xc0, 0x00, 0x00, 0x0c };
|
||||||
|
|
||||||
|
/* If on 2nd or later reader, make sure we end the transaction
|
||||||
|
* and disconnect card in the previous reader */
|
||||||
|
switch (hCard_status)
|
||||||
|
{
|
||||||
|
case TRANSACTION:
|
||||||
|
SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
|
||||||
|
/* FALLTHRU */
|
||||||
|
case CONNECTED:
|
||||||
|
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||||
|
/* FALLTHRU */
|
||||||
|
case DISCONNECTED:
|
||||||
|
hCard_status = DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy RAND into APDU */
|
/* Copy RAND into APDU */
|
||||||
memcpy(pbRunGSMAlgorithm + 5, rand, SIM_RAND_LEN);
|
memcpy(pbRunGSMAlgorithm + 5, rand, SIM_RAND_LEN);
|
||||||
@@ -156,6 +171,7 @@ METHOD(sim_card_t, get_triplet, bool,
|
|||||||
DBG1(DBG_IKE, "SCardConnect: %s", pcsc_stringify_error(rv));
|
DBG1(DBG_IKE, "SCardConnect: %s", pcsc_stringify_error(rv));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
hCard_status = CONNECTED;
|
||||||
|
|
||||||
switch(dwActiveProtocol)
|
switch(dwActiveProtocol)
|
||||||
{
|
{
|
||||||
@@ -170,6 +186,15 @@ METHOD(sim_card_t, get_triplet, bool,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start transaction */
|
||||||
|
rv = SCardBeginTransaction(hCard);
|
||||||
|
if (rv != SCARD_S_SUCCESS)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "SCardBeginTransaction: %s", pcsc_stringify_error(rv));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
hCard_status = TRANSACTION;
|
||||||
|
|
||||||
/* APDU: Select MF */
|
/* APDU: Select MF */
|
||||||
dwRecvLength = sizeof(pbRecvBuffer);
|
dwRecvLength = sizeof(pbRecvBuffer);
|
||||||
rv = SCardTransmit(hCard, pioSendPci, pbSelectMF, sizeof(pbSelectMF),
|
rv = SCardTransmit(hCard, pioSendPci, pbSelectMF, sizeof(pbSelectMF),
|
||||||
@@ -299,12 +324,21 @@ METHOD(sim_card_t, get_triplet, bool,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
/* Transaction will be ended and card disconnected at the
|
||||||
if (rv != SCARD_S_SUCCESS)
|
* beginning of this loop or after this loop */
|
||||||
{
|
}
|
||||||
DBG1(DBG_IKE, "SCardDisconnect: %s", pcsc_stringify_error(rv));
|
|
||||||
continue;
|
/* Make sure we end any previous transaction and disconnect card */
|
||||||
}
|
switch (hCard_status)
|
||||||
|
{
|
||||||
|
case TRANSACTION:
|
||||||
|
SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
|
||||||
|
/* FALLTHRU */
|
||||||
|
case CONNECTED:
|
||||||
|
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
|
||||||
|
/* FALLTHRU */
|
||||||
|
case DISCONNECTED:
|
||||||
|
hCard_status = DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SCardReleaseContext(hContext);
|
rv = SCardReleaseContext(hContext);
|
||||||
|
|||||||
Reference in New Issue
Block a user