Click here to Skip to main content
15,867,308 members
Articles / Containers / Virtual Machine

How to access SmartCards simply and effectively

Rate me:
Please Sign up or sign in to vote.
4.52/5 (16 votes)
12 Apr 2008CPOL4 min read 233.8K   28.8K   72   33
Using a set of classes to access SmartCard readers, to test SmartCards via scripts - even to transmit APDUs one by one.

Image 1

Image 2

Introduction

This article has two demo projects to show you how to access SmartCards in Windows simply and effectively. If you are not familiar with this field, this is an opportunity to learn something about it.

The basic demo is very simple, it can show you how to list the readers in the system, connect/disconnect it, get the card's ATR, and transmit one APDU with a card.

Note: The basic demo only accepts one APDU without any non-number chars, such as: "0084000008" (get an 8-bytes challenge from the card).

The advanced demo demonstrates how to use SmartCards effectively over the basic layer:

  • There is an APDU processor: it can process the user input
    • One APDU with spaces separating: "0084 0000 08"
    • Multi-APDUs: "0084 0000 08; 00A4 0000 02 3F;"
    • Even an APDU's script file: "c:\myapdu.txt"
  • ATR analyzing, we demonstrate the protocol: T=0, or T=1.
  • Multi-APDU console: This consols is useful for these kinds of tests:
    • You can prompt the user for a 'Press any key to continue' if there is something wrong
    • You can select the console texts by holding the left-button and dragging a rectangle, releasing the left-button - the text is just in your clipboard - just like the Windows cmd.exe does, but this works on Win9x too ;-)

And if you want to know how they are running, you should prepare a SmartCard reader or install a virtual SmartCard reader, and at least one SmartCard.

But if not, there is also the multi-APDU console for you to run scripts in a console during certain occasions in your project, I think.

Background

I have used SmartCards in many projects since 2004, but I really could not find useful classes to access them here in CodeProject or anywhere else on the internet. So I decided to write several classes to show you the process we usually do.

For the SmartCard subsystem in Windows, we should know: the SmartCard reader should be connected to the system, the vender should present us a PC/SC driver, and there is a so called 'SmartCard Resource Manager' for Win32 programs to access all kinds of readers via a set of APIs.

For using these APIs, we should call:

  • SCardEstablishContext(): establishes the SmartCard's context;
  • SCardListReaders(): gets a reader's list from the resource manager;
  • SCardConnect(): connects a reader by giving the reader name;
  • SCardStatus(): gets the ATR from the selected card which is in the 'connected reader';
  • SCardTransmit(): transmits the APDU between the card and our program;
  • SCardDisconnect(): disconnects the connected reader;
  • SCardReleaseContext(): releases the context.

Among these, 4 is optional.

Using the code

As we can see, the basic demo has the core class CSCardmgr. And, its interface is very simple:

C++
// Get the readers' list
BOOL SCardGetPcscList();

// open the reader using the index
BOOL SCardOpen(int nInx);

// Get ATR from the card.
BOOL SCardReset(LPCTSTR strResp);

// Transmit APDU
BOOL SCardTransmit(LPCTSTR strApdu, LPCTSTR strResp, UINT *nSW);

// Close the connected reader
BOOL SCardClose();

Here are two very useful functions to do the string <-> hex, from Mr. Yu, one of my best leaders.

C++
///////////////////////////////////////////////////////////////////////////////
// hex to asc: 0x22 -> "22"
int Hex2Asc(char *Dest,char *Src,int SrcLen)
{
    int i;
    for ( i = 0; i < SrcLen; i ++ )
    {
        sprintf(Dest + i * 2,"%02X",(unsigned char)Src[i]);
    }
    Dest[i * 2] = 0;
    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// asc to hex: "22" -> 0x22
int Asc2Hex(char *Dest,char *Src,int SrcLen)
{
    int i;
    for ( i = 0; i < SrcLen / 2; i ++ )
    {
        sscanf(Src + i * 2,"%02X",(unsigned char *)&Dest[i]);
    }
    return TRUE;
}

For the advanced demo, we improve the ATR processing and the APDU processing - these are useful in the SmartCard application. First, the ATR processing: we extract the SmartCard supported protocol only, and displays its protocol at the end of the ATR string.

C++
///////////////////////////////////////////////////////////////////////////////
// Get the ATR information of the open Reader
void CSCardDemoDlg::OnReset() 
{
    CHAR        szATR[ATR_MAX_SIZE * 2 +1] = {0};
    BYTE        byATR[ATR_MAX_SIZE] = {0};
    CHAR        szFullAtr[MAX_RESPONSE] = {0};

    UINT        np = 0;                // Prot.
    BYTE        protocol = ATR_PROTOCOL_TYPE_T0;
    
    ZeroMemory(szATR, sizeof(szATR));

    if(m_SCard.SCardReset(szATR))
    // Do Reset it
    {
        int nLenAtr = strlen(szATR);

        // Convert ATR to Hex format
        Asc2Hex((char*)byATR, szATR, nLenAtr);                

        CAtr            objATR(byATR, nLenAtr/2);

        // get prots supported.
        objATR.ATR_GetNumberOfProtocols(&np);        
        INT nType = objATR.ATR_GetProtocolType(np, &protocol);

        sprintf(szFullAtr, "%s (T=%d).", szATR, protocol);

        // Display the ATR Information
        SetDlgItemText(IDS_MSG, szFullAtr);            
    }
}

Second, we provide the CApduProcesser and CConsoleWindow to improve the APDU transmission experience: the user input is more flexible as described, and we use CApduProcesser for this. We use this code block to eat the non-number chars:

C++
// Eat the non-numeric chars.
for(int i=0, j=0; i < strlen(szSLBuf); i++)
{
    if(szSLBuf[i] >='0' && szSLBuf[i] <= '9')
    {
        szString[j] = szSLBuf[i];
        j ++;
    }
    else if(szSLBuf[i] >='A' && szSLBuf[i] <= 'F')
    {
        szString[j] = szSLBuf[i];
        j ++;
    }
    else if(szSLBuf[i] >='a' && szSLBuf[i] <= 'f')
    {
        szString[j] = szSLBuf[i];
        j ++;
    }
    else
        continue;
}

CConsoleWindow is used for the Console output. Its highlight is 'Any key to continue', and mouse selection:

C++
void CConsoleWindow::WaitForAnyKeyEx()
{
    ... ...

    for(;;)
    {
        /* get an input event */
        bSuccess = ReadConsoleInput(hStdIn, &inputBuffer, 1, &dwInputEvents);
        PERR(bSuccess, "ReadConsoleInput");
        switch (inputBuffer.EventType)
        {
            case KEY_EVENT:
                 ... ...
                break;
            case MOUSE_EVENT:
                 ... ...
                break;
        }
    }

    ... ...
}

The 'KEY_EVENT' is for 'any key to continue', and 'MOUSE_EVENT', yes, for the mouse selection.

Points of Interest

What's a SmartCard? I have no idea, but what I'm sure is my iPhone has a SIM card and it is just a SmartCard. ^_^

If I had a SmartCard reader, I can read the contacts-list from my SIM card by using this demo.

Furthermore, the SmartCard is not just used in reading the SIM card, the PKI also needs it: the CSP and PKCS#11 all need it - (but not must ^_^ ). As I know, many vendors have combined the reader and card, that's the USB token; and the token has a finger scanner or OTP embedded. So, this field is very wonderful.

BTW, SmartCard is a contact card (restricted by ISO7816). There are the so called contactless card (restricted by ISO14443), such as Mifare S50/S70/DES/UL etc. Some venders also provide the so called two-module cards - these cards have two interfaces, and supports both ISO7816 and ISO14443.

History

  • 2008-01-19: First version.
  • 2008-04-12: Virtual PC/SC driver (virtual-pcsc_drv.zip) added for using/testing these demos.

For the driver's license, please refer to the readme.txt. :: It is recommend using this driver in a Virtual Machine. ::

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer emware
China China
software development is so nice and we can make our world better than ever, even the real world.
vc++6 is enough for me, althought i tried to upgrade to higher version, each time, i down-grade to vc6. ^_^

Comments and Discussions

 
QuestionSmartCard Virtual Driver Source Pin
GregTCubeDev17-Oct-17 21:25
GregTCubeDev17-Oct-17 21:25 
QuestionAuthenticate ntag213 with ACR122u and APDU Commands Pin
Member 132380203-Jun-17 22:43
Member 132380203-Jun-17 22:43 
Questionaccess the reader without the card presence? Pin
F.moghaddampoor19-Jul-16 21:44
F.moghaddampoor19-Jul-16 21:44 
QuestionCan i access Smartcard functions through web? Pin
sandeep nagabhairava6-May-15 2:38
sandeep nagabhairava6-May-15 2:38 
GeneralIt is a great demo Pin
gknows29-Sep-14 17:51
gknows29-Sep-14 17:51 
QuestionInstall VCardRdr using .INF File Pin
elaheshekuhi6-Jul-14 21:48
elaheshekuhi6-Jul-14 21:48 
QuestionHey! can we chat my mail? :-) Pin
Member 1068151020-Apr-14 7:19
Member 1068151020-Apr-14 7:19 
QuestionC# Pin
rejectkosta26-Nov-12 6:35
rejectkosta26-Nov-12 6:35 
QuestionAccess data protected by pin Pin
Andyh16-Jul-12 5:16
Andyh16-Jul-12 5:16 
QuestionMonitor your USB device as the smart card Pin
hereiam020810-Dec-11 5:36
hereiam020810-Dec-11 5:36 
Questionjava smartcardio Pin
fresh2g62-Apr-09 0:43
fresh2g62-Apr-09 0:43 
QuestionHow to used Non PC/SC Card Reader to read sim card contacts like SD/MMC Card Reader?? Pin
Kingle Zhuang12-Jan-09 22:50
Kingle Zhuang12-Jan-09 22:50 
GeneralHelp,How to get contacts from sim card and write contacts to sim card,Please help me!! Pin
Kingle Zhuang31-May-08 5:44
Kingle Zhuang31-May-08 5:44 
GeneralRe: Help,How to get contacts from sim card and write contacts to sim card,Please help me!! Pin
dotnfc31-May-08 19:45
dotnfc31-May-08 19:45 
GeneralRe: Help,How to get contacts from sim card and write contacts to sim card,Please help me!! Pin
dotnfc31-May-08 19:49
dotnfc31-May-08 19:49 
GeneralNice Article Pin
Gene OK12-Apr-08 6:03
Gene OK12-Apr-08 6:03 
GeneralRe: Nice Article Pin
ThatsAlok15-Apr-08 2:20
ThatsAlok15-Apr-08 2:20 
GeneralVirtual Smart Card Reader Pin
EdwaM4-Apr-08 14:34
EdwaM4-Apr-08 14:34 
You mention installing a virtual smart card reader. I have so far been unable to find a good one. Is there any that any of you know of?

Please let me know.
GeneralRe: Virtual Smart Card Reader Pin
dotnfc10-Apr-08 3:00
dotnfc10-Apr-08 3:00 
GeneralRe: Virtual Smart Card Reader Pin
EdwaM11-Apr-08 6:15
EdwaM11-Apr-08 6:15 
GeneralRe: Virtual Smart Card Reader Pin
dotnfc11-Apr-08 15:53
dotnfc11-Apr-08 15:53 
GeneralRe: Virtual Smart Card Reader Pin
dotnfc12-Apr-08 5:24
dotnfc12-Apr-08 5:24 
GeneralRe: Virtual Smart Card Reader Pin
EdwaM14-Apr-08 17:34
EdwaM14-Apr-08 17:34 
GeneralRe: Virtual Smart Card Reader Pin
ThatsAlok15-Apr-08 2:21
ThatsAlok15-Apr-08 2:21 
GeneralRe: Virtual Smart Card Reader Pin
susrik22-Apr-08 4:07
susrik22-Apr-08 4:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.