LudovicRousseau / pyscard

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

I can not read more than 8 cards, I think it is the cache memory of the library #156

Closed joselopezbinoovo closed 1 year ago

joselopezbinoovo commented 1 year ago

Your system information

Tablet microsoft surface pro 3 bussiness

Please describe your issue in as much detail as possible:

The program should read and wait for the reading of an NFC card, that does it well

My problem is about reading tag from nfc card ISO 14443A. The problem comes when I read more than 8 cards.

The program is left in a loop without any data. I thought that the problem could be in the cache memory of the library or the connection but I do not know very well how to reset it.

Describe what you expected should happen. Read tag from my NFC Reader Device "ARC 1222U" or my Tablet microsoft surface pro 3 bussiness

Console of my program

block 4:        03 17 D1 01 13 54 02 65 6E 49 6E 69 74 50 65 70 | ♥↨Ñ☺‼T☻enInitPep
block 5:        65 2F 31 32 33 34 46 69 6E FE 5A 00 00 00 00 00 | e/1234FinþZ
block 6:        6F 6D 2E 77 61 6B 64 65 76 2E 6E 66 63 74 61 73 | om.wakdev.nfctas
block 7:        00 00 00 00 00 00 7F 07 88 40 00 00 00 00 00 00 | @
block 8:         |
block 9:         | 
listToStr: ♥↨Ñ☺‼T☻enInitPepe/1234FinþZom.wakdev.nfctas@
INIT
string[0]: Pepe
URIName: 1234

Describe what did happen.

When I read more than 8 cards the program stays in a loop without returning anything in the blocks

URIName: 1234
block 4:         | 
block 5:         | 
block 6:         | 
block 7:         | 
block 8:         | 
block 9:         | 
listToStr:
block 4:         | 
block 5:         | 
block 6:         | 
block 7:         | 
block 8:         | 
block 9:         | 
listToStr: 
block 4:         | 
block 5:         | 
block 6:         | 
block 7:         | 
block 8:         | 
block 9:         | 
listToStr: 
block 4:         | 
block 5:         | 
block 6:         | 
block 7:         | 
block 8:         | 
block 9:         | 

Steps for reproducing this issue:

  1. Run my program: python main.py

CODE

'''
Python3 ACS-ACR122U-Tool
'''
from smartcard.System import readers
from smartcard.Exceptions import NoCardException
from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver
import sys
import time
import requests
from smartcard.util import toHexString

r = readers()
reader = r[0]
print ("Using: ", reader)
error = 'a'
espera = 'a'
#disconnect =''

while espera != '':
     espera = ''
     while error != '':
          error = '' 
          try: 
               connection = reader.createConnection()
               connection.connect()
               #cardtype = AnyCardType()
               #cardrequest = CardRequest( timeout=10, cardType=cardtype )
               #cardservice = cardrequest.waitforcard()
#
               #observer=ConsoleCardConnectionObserver()
               #cardservice.connection.addObserver( observer )
          except NoCardException as e:
               #print('error while')
               error = e 
               time.sleep(1)

     COMMAND = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, 4, 0x60, 0x00]
     #SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]
     #DF_TELECOM = [0x7F, 0x10]
     #apdu = SELECT+DF_TELECOM
     data, sw1, sw2 = connection.transmit(COMMAND)  
     if (sw1, sw2) == (0x90, 0x0):
          print('ENTRA AL PRIMER IF (sw1,sw2) == (0x90, 0x0)')
          #print ("Status: Decryption sector "+ '1' +" using key #0 as Key A successful.")
     elif (sw1, sw2) == (0x63, 0x0):
          print('ENTRA AL ELSE (sw1,sw2) == (0x63, 0x0)')
          #print ("Status: Decryption sector "+ '1' +" failed. Trying as Key B")
          COMMAND = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00,4, 0x61, 0x00]
          data, sw1, sw2 = connection.transmit(COMMAND)
          print(data, sw1, sw2)
          if (sw1, sw2) == (0x69, 0x88) or (0x69, 0x88):
               print('ENTRA AL SEGUNDO IF')
               print ("Status: Decryption sector "+ '1' +" using key #0 as Key B successful.")
          elif (sw1, sw2) == (0x69, 0x88):
               print('error de datos')
               sys.exit()
     array = []
     for block in range(4, 8):
          print(COMMAND)
          COMMAND = [0xFF, 0xB0, 0x00]
          COMMAND.append(block)
          COMMAND.append(16)
          data, sw1, sw2 = connection.transmit(COMMAND)
          #print ("block "+ str(block) +":\t"+ toHexString(data) +" | "+''.join(chr(i) for i in data))
          array.append(' '.join(chr(i)for i in data))

     listToStr = ' '.join([str(elem) for elem in array])
     listToStr=listToStr.replace(' ','')
     print('listToStr:',listToStr)
     if ( listToStr != ''):
          if(listToStr.find('Init') != -1):
               print('INIT')
               sep = 'Init'
               stripped = listToStr.split(sep, 1)[1]
               fin = 'Fin'
               stripped = stripped.split(fin, 1)[0]
               #print(stripped)
               string =  stripped.split('/')
               print('string[0]:',string[0])
               URLString = string[0]
               URIName = string[1]
               print('URIName:',URIName)
               url = f'http://127.0.0.1:8086/getMyUrl/{URLString}/{URIName}' 
               response = requests.get(url)
               espera = 'relleno'
               error = 'error'
               time.sleep(1) #No se puede poner 1sg poruqe el NFCRedaer tiene un retardo de desconexion de 2sg
          elif listToStr.find('Form') != -1:
               print('FORM')
               sep = 'Form'
               stripped = listToStr.split(sep, 1)[1]
               fin = 'Fin'
               stripped = stripped.split(fin, 1)[0]
               URLString = stripped
               print('URLString:',URLString)
               url = f'http://127.0.0.1:8086/getMyForm/{URLString}' 
               response = requests.get(url)
               espera = 'relleno'
               error = 'error'
               time.sleep(1) #No se puede poner 1sg poruqe el NFCRedaer tiene un retardo de desconexion de 2sg
          else:
               espera = 'relleno'
               error = 'error'
               #connection.disconnect()
               time.sleep(2)
     else: 
          espera = 'relleno'
          error = 'error'
LudovicRousseau commented 1 year ago

The PySCard library does not use a cache. Have you tried on a real PC with a normal Windows?

joselopezbinoovo commented 1 year ago

I use windows 11

LudovicRousseau commented 1 year ago

I see you do not check or print the value of sw1 and sw2 in:

          data, sw1, sw2 = connection.transmit(COMMAND)

Maybe you should

joselopezbinoovo commented 1 year ago

[] 105 136 I get this all the time

LudovicRousseau commented 1 year ago

105 136 is "69 88" in hex. SW1=69h SW2=88h

According to https://cardwerk.com/smart-card-standard-iso7816-4-section-5-basic-organizations/ Table 17 – Coding of SW2 when SW1=’69’ the error is "SM data objects incorrect"

It is not a bug in PySCard.