def testcase_Card_Eq_NotEq(self): """Test == and != for Cards.""" for reader in readers(): card = Card(str(reader), expectedATRinReader[str(reader)]) cardcopy = Card(str(reader), expectedATRinReader[str(reader)]) self.assertEqual(True, card == cardcopy) self.assertEqual(True, not card != cardcopy) for reader in readers(): card = Card(str(reader), expectedATRinReader[str(reader)]) cardcopy = Card(str(reader), [0, 0]) self.assertEqual(True, card != cardcopy) self.assertEqual(True, not card == cardcopy)
def testcase_Card_FromReaderStrings(self): """Create a Card from reader strings and test that the response to SELECT DF_TELECOM has two bytes.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): card = Card(str(reader), expectedATRinReader[str(reader)]) cc = card.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect() response, sw1, sw2 = cc.transmit(SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "9f 20": 2, "6e 0": 3} self.assertEquals([], response) self.assert_(expectedSWs.has_key("%x %x" % (sw1, sw2)) or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect)
def testcase_Card_FromReaderStrings(self): """Create a Card from reader strings and test that the response to SELECT DF_TELECOM has two bytes.""" SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02] DF_TELECOM = [0x7F, 0x10] for reader in readers(): card = Card(str(reader), expectedATRinReader[str(reader)]) cc = card.createConnection() if [] != expectedATRinReader[str(reader)]: cc.connect() response, sw1, sw2 = cc.transmit(SELECT + DF_TELECOM) expectedSWs = {"9f 1a": 1, "9f 20": 2, "6e 0": 3} self.assertEqual([], response) self.assertTrue("%x %x" % (sw1, sw2) in expectedSWs or "9f" == "%x" % sw1) else: self.assertRaises(NoCardException, cc.connect)
def testcase_CardDictionary(self): """Create a dictionnary with Card keys""" mydict = {} for reader in readers(): card = Card(reader, expectedATRinReader[str(reader)]) mydict[card] = reader for card in list(mydict.keys()): self.assertTrue(str(card.reader) in expectedReaders)
def _process_add_card(self, card: Card) -> None: """ Reads card's PAN and ATR and saves in a cache Supports only several Mastercard cards """ connection = card.createConnection() connection.connect() syslog.syslog( syslog.LOG_INFO, "Card connected. ATR: {}, protocol: {}".format( toHexString(card.atr), connection.getProtocol())) # Initialize card. Select Payment System Environment - 2PAY.SYS.DDF01 self._send_apdu_T0(connection, [ 0x00, 0xA4, 0x04, 0x00, 0x0E, 0x32, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00 ]) # Select AID - Mastercard International (A0 00 00 00 04 10 10) self._send_apdu_T0(connection, [ 0x00, 0xA4, 0x04, 0x00, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10 ]) # I had to comment this obscure magic straight away after playing with it. # Because now I can't remember what it means self._send_apdu_T0(connection, [0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00]) # Read file which contains card info (I need only PAN) resp = self._send_apdu_T0(connection, [0x00, 0xB2, 0x01, 0x2C, 0x00]) if resp is None: self._holder.set((None, None)) syslog.syslog(syslog.LOG_INFO, "Reading PAN failed") else: pan = self._parse_pan(toHexString(resp)) self._holder.set((pan, toHexString(card.atr))) syslog.syslog(syslog.LOG_INFO, "Reading PAN successful") connection.disconnect()
def run(self): """Runs until stopEvent is notified, and notify observers of all card insertion/removal. """ logging.debug("thread running: %d", self.observable.countObservers()) while not self.stopEvent.isSet(): try: added_cards = [] removed_cards = [] # Update the readers state list to add potentially new found readers and delete removed ones self.observable.updateReadersStateList() logging.debug("listening for changes...") hresult, new_readers_state = SCardGetStatusChange( self.observable.hcontext, self.polling_timeout, self.observable.getReadersStateList()) logging.debug("changes acquired!") logging.debug("states: %s", new_readers_state) # Listen only to others result errors if hresult != SCARD_S_SUCCESS and hresult != SCARD_E_UNKNOWN_READER and hresult != SCARD_E_TIMEOUT: if hresult == SCARD_E_CANCELLED: break else: raise CardConnectionException( 'Unable to get status change: ' + SCardGetErrorMessage(hresult)) # Update observable readers state list and search for added or removed cards self.observable.setReadersStateList(new_readers_state) for state in self.observable.getReadersStateList(): reader, event, atr = state if event & SCARD_STATE_CHANGED: # Check if we have a card present and an atr (is mute + atr a thing ?) if (event & SCARD_STATE_PRESENT or event & SCARD_STATE_MUTE) and len(atr) != 0: # If the event is telling that a card is present/mute add it to the cards list card = Card(reader, atr) logging.debug( "card added with atr: %s on reader %s", card.atr, card.reader) added_cards.append(card) self.observable.addCard(reader, atr) # Check if we have a card empty slot and if the card is in the list (change+empty can happen after SCARD_STATE_UNAWARE fo ex.) elif event & SCARD_STATE_EMPTY and reader in self.observable.getCardsList( ).keys(): # If the event is telling that reader is empty remove it from the cards list atr = self.observable.getCardsList().get(reader) card = Card(reader, atr) logging.debug( "card removed with atr: %s on reader %s", card.atr, card.reader) removed_cards.append(card) self.observable.removeCard(reader) elif event & SCARD_STATE_UNKNOWN or event & SCARD_STATE_IGNORE or event & SCARD_STATE_UNAVAILABLE: # If the event is telling that a reader is not available/existing remove the card on it from the cards list if reader in self.observable.cards_list.keys(): logging.debug( "reader removed, card removed with atr: %s on reader %s", card.atr, card.reader) removed_cards.append(card) self.observable.removeCard(reader) # Update observers if we have added or removed cards if added_cards != [] or removed_cards != []: self.observable.setChanged() self.observable.notifyObservers( (added_cards, removed_cards)) except Exception: # FIXME Tighten the exceptions caught by this block traceback.print_exc() self.stopEvent.set()