1
votes

Am working on a project to read from and write data to smart cards. The Card Reader am using is ACR38U-H1 from ACS. Following their APDU commands, I have being able to get access to the card and read some data. But am suspecting that I still have not being able to read the exact data inside, because always I get a response to the command APDU 0x6e 0x00, 0x00 instead of0x90 0x00.

What am I doing wrong?
Maybe the problem is in the smart card?

Python code:

#! /usr/bin/env python
from smartcard.scard import *
import smartcard.util


SELECT = [
    #0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00
    0XFF, 0xA4, 0x00, 0x00, 0x01, 0x05
]

COMMAND = [
    0x00, 0xC0, 0x00, 0x00, 0x00, 0x0B
]

try:
    hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
    if hresult != SCARD_S_SUCCESS:
        raise Exception('Failed to establish context : ' +
            SCardGetErrorMessage(hresult))
    print 'Context established!'

    try:
        hresult, readers = SCardListReaders(hcontext, [])
        if hresult != SCARD_S_SUCCESS:
            raise Exception('Failed to list readers: ' +
                SCardGetErrorMessage(hresult))
        print 'PCSC Readers:', readers

        if len(readers) < 1:
            raise Exception('No smart card readers')

        reader = readers[0]
        print "Using reader:", reader

        try:
            hresult, hcard, dwActiveProtocol = SCardConnect(hcontext, reader,
                SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T1)
            if hresult != SCARD_S_SUCCESS:
                raise Exception('Unable to connect: ' +
                    SCardGetErrorMessage(hresult))
            print 'Connected with active protocol', dwActiveProtocol

            try:
                hresult, response = SCardTransmit(hcard, dwActiveProtocol,
                    SELECT)
                if hresult != SCARD_S_SUCCESS:
                    raise Exception('Failed to transmit: ' +
                        SCardGetErrorMessage(hresult))
                print 'Select: ' + smartcard.util.toHexString(response,
                    smartcard.util.HEX)
#==========================================================================
                hresult, response = SCardTransmit(hcard, dwActiveProtocol,
                    COMMAND)
                if hresult != SCARD_S_SUCCESS:
                    raise Exception('Failed to transmit: ' +
                        SCardGetErrorMessage(hresult))
                print 'Command: ' + smartcard.util.toHexString(response,
                    smartcard.util.HEX)
# =========================================================================
            finally:
                hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD)
                if hresult != SCARD_S_SUCCESS:
                    raise Exception('Failed to disconnect: ' +
                        SCardGetErrorMessage(hresult))
                print 'Disconnected'

        except Exception, message:
            print "Exception:", message

    finally:
        hresult = SCardReleaseContext(hcontext)
        if hresult != SCARD_S_SUCCESS:
            raise Exception('Failed to release context: ' +
                    SCardGetErrorMessage(hresult))
        print 'Released context.'

except Exception, message:
    print "Exception:", message

Result of this code:

Context established!
PCSC Readers: ['ACS ACR38U-CCID 00 00']
Using reader: ACS ACR38U-CCID 00 00
Connected with active protocol 2
Select: 0x6E 0x00
Command: 0x67 0x00
Disconnected
Released context.

Result of open-tool:

[17:06:00]:~$ opensc-tool -s ff:a4:00:00:01:05
Using reader with a card: ACS ACR38U-CCID 00 00
Sending: FF A4 00 00 01 05 
Received (SW1=0x6E, SW2=0x00)
2
What smartcard are you trying to read from?Michael Roland
@MichaelRoland, this is card of Health card of Russian Federation (Params: ISO 7816 T=0, T=1,EMV, CAC, 2/3 BUS I2C/Extended I2C memory cards)Ilya Soltanov
Are you sure this one is a memory card? Can you post output of opensc-tool -a. I guess it is a normal T=0 or T=1 card which does not require those 0xFF APDUs (which are actually meant for the reader and not for the card). Where did you get these params -- they seem to me as reader capabilities and not card ones.vlp
@vlp, ~$ opensc-tool -a Using reader with a card: ACS ACR38U-CCID 00 00 3b:f7:13:00:00:81:31:fe:45:46:4f:4d:53:4f:4d:53:a9.Ilya Soltanov
Does opensc-tool -s 00:a4:04:0c:09:66:6f:6d:73:5f:72:6f:6f:74 and opensc-tool -s 00:a4:04:0c:07:46:4f:4d:53:5f:49:44 return 9000?vlp

2 Answers

0
votes

You are using SELECT_CARD_TYPE APDU command (0xFF00000101) which is meant to be used with I2C memory cards (up to 16 kilobits specifically) -- see section 9.3.1.1 in the reader reference manual.

This SELECT_CARD_TYPE command (having CLA set to 0xFF) is not addressed to the card but to the reader (which refuses it as the card does not use I2C).

Your card is a microprocessor card speaking T=1 protocol so you need to use "normal" ISO 7816 APDUs -- which ones should be specified in your card documentation.

Nevertheless there is a script for Smart Card Shell 3 tool which seems to read (and in a limited way emulate) FOMS card (I have not tried).

Given the script source it seems that card supports standard ISO 7816-4 SELECT and READ_BINARY APDU commands which are used behind new CardFile() and CardFile.readBinary().

Good luck!

Disclaimer: I have worked neither with any FOMS card nor with the scsh3 tool.

0
votes
SELECT = [
    #0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00
    0XFF, 0xA4, 0x00, 0x00, 0x01, 0x05
]

Here it seems you are trying to select MF ( AID = 3F00 on commented # command) OR Command seems wrong because no AID is of 1 byte length , Please check your command

 0XFF, 0xA4, 0x00, 0x00, 0x01, 0x05 // check it.

and getting 6E 00 Class not supported

Your other command is C0 - GET RESPONSE,

COMMAND = [
    0x00, 0xC0, 0x00, 0x00, 0x00, 0x0B
]

This command is used to get the response from the card of length specified by previous command having return code like - 61 XX and APDU sequence should like CLASS, INS, P1, P2, Le //please check your Get Response command

Here Get Response giving 6700 , it seems correct because previous command is failed already and card does not have nothing to return to it so unable to return Le data ( 0x0B - Suppose it is your Le)

I suggest , understand your card well before firing any command, seems it is a proprietary card so you should know the file structure/CLASS byte USED before sending command, when you shoot with correct CLA value, hope you will not get - CLA not supported error.

Hope this information helps to identify the problem.