linuxsmartcardapdupcscpyscard

Why a ACR38U-CCID always return 0x6e 0x00?


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)

Solution

  • 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.