LudovicRousseau / pyscard

pyscard smartcard library for python
http://pyscard.sourceforge.net/
GNU Lesser General Public License v2.1
383 stars 110 forks source link

APDU with ICODE DNA (ISO 15693) #36

Closed ChristopheBelpaire closed 7 years ago

ChristopheBelpaire commented 7 years ago

Hello, I'm trying to send APDU on an ICODE DNA iso 15693 tag with an Orcanthus reader (http://www.orcanthus.eu/fr/product_84/lecteur+sans+contact+de+bureau.htm) The tag is successfully detected, I can send the apdu to retrieve the serial number. But, when I try to execute another APDU, it fails with :

INFO:root:Waiting for tag (timeout=10.0s)
INFO:root:Connecting to tag
DEBUG:root:Sending APDU FF CA 00 00 00
DEBUG:root:Got response 90 00 1B 96 9D 00 18 01 04 E0
[27, 150, 157, 0, 24, 1, 4, 224]
DEBUG:root:Sending APDU 02 20 05
Traceback (most recent call last):
  File "minimalApp.py", line 31, in send_apdu
    data, sw1, sw2 = self.cardservice.connection.transmit(apdu)
  File "/usr/lib/python2.7/dist-packages/smartcard/CardConnectionDecorator.py", line 82, in transmit
    return self.component.transmit(bytes, protocol)
  File "/usr/lib/python2.7/dist-packages/smartcard/CardConnection.py", line 144, in transmit
    data, sw1, sw2 = self.doTransmit(bytes, protocol)
  File "/usr/lib/python2.7/dist-packages/smartcard/pcsc/PCSCCardConnection.py", line 198, in doTransmit
    SCardGetErrorMessage(hresult))
CardConnectionException: Failed to transmit with protocol T1. Transaction failed.

Unable to connect with protocol: T1. Card protocol mismatch.

Do you have any idea why it fails ? Or does your library not support iso 15693?

Thanks in advance!

Here is the following code that launch the exception :

import logging
import traceback

from smartcard.CardRequest import CardRequest
from smartcard.CardType import ATRCardType
from smartcard.sw.ErrorCheckingChain import ErrorCheckingChain
from smartcard.sw.ISO7816_4ErrorChecker import ISO7816_4ErrorChecker
from smartcard.sw.ISO7816_4_SW1ErrorChecker import ISO7816_4_SW1ErrorChecker
from smartcard.sw.SWExceptions import WarningProcessingException
from smartcard.util import toHexString, toBytes

logging.basicConfig(level=logging.DEBUG)

class Orcanthus:
    def __init__(self, timeout=10.0):
        logging.info('Waiting for tag (timeout={:.1f}s)'.format(timeout))
        cardtype = ATRCardType(toBytes('3B 80 80 01 01'))
        cardrequest = CardRequest(timeout=timeout, cardType=cardtype)
        self.cardservice = cardrequest.waitforcard()
        errorchain = []
        errorchain = [ErrorCheckingChain(errorchain, ISO7816_4ErrorChecker()),
                      ErrorCheckingChain(errorchain, ISO7816_4_SW1ErrorChecker())]
        errorchain[0].addFilterException(WarningProcessingException)
        self.cardservice.connection.setErrorCheckingChain(errorchain)
        logging.info('Connecting to tag')
        self.cardservice.connection.connect()

    def send_apdu(self, apdu):
        logging.debug('Sending APDU {}'.format(toHexString(apdu)))
        try:
            data, sw1, sw2 = self.cardservice.connection.transmit(apdu)
        except Exception, e:
            tb = traceback.format_exc()
            print tb
            self.cardservice.connection.connect()
            raise e
        logging.debug('Got response {}'.format(toHexString([sw1] + [sw2] + data)))
        return data

class IcodeDna:
    APDU_GET_UID = [0xFF, 0xCA, 0x00, 0x00, 0x00]
    APDU_READ_PAGE = [0x02, 0x20, 0x05]

    def __init__(self, reader):
        self.reader = reader

    def transceive(self, apdu):
        return self.reader.send_apdu(apdu)

    def get_uid(self):
        return self.transceive(self.APDU_GET_UID)

    def read_page(self):
        return self.transceive(self.APDU_READ_PAGE)

if __name__ == '__main__':
    try:
        reader = Orcanthus()
        icode_dna_tag = IcodeDna(reader)
        print icode_dna_tag.get_uid()
        print icode_dna_tag.read_page()
    except Exception as e:
        print "{}".format(e)
LudovicRousseau commented 7 years ago

02 20 05 does not look like a valid APDU. An APDU is, at least, 4 bytes. https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit