aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenryk Plötz <henryk@ploetzli.ch>2010-10-15 08:20:22 +0200
committerHenryk Plötz <henryk@ploetzli.ch>2010-10-15 17:07:55 +0200
commita8d72543e97fe96837cbbcdf14b5247fdf876203 (patch)
tree217521a9be14c3c108f7c428efca966c98807704
parent9d5528a470a5560e6cdb3bc0a56d8a9db2adcc99 (diff)
Separate out generic "Card" functionality from ISO specific functionality in preparation of DESfire native semantics
FIXME: send machinery in Card is still broken, need some generalisation on request/response, then specialisation in ISO_Card
-rw-r--r--cards/generic_card.py107
-rw-r--r--cards/gsm_card.py6
-rw-r--r--cards/iso_7816_4_card.py12
-rw-r--r--cards/iso_card.py107
-rw-r--r--cards/java_card.py7
-rw-r--r--cards/passport_application.py3
-rw-r--r--cards/pn532_card.py8
-rw-r--r--cards/rfid_card.py6
-rw-r--r--cards/starcos_card.py2
9 files changed, 148 insertions, 110 deletions
diff --git a/cards/generic_card.py b/cards/generic_card.py
index b45f56c..48f0a7f 100644
--- a/cards/generic_card.py
+++ b/cards/generic_card.py
@@ -5,26 +5,21 @@ from utils import C_APDU, R_APDU
DEBUG = True
#DEBUG = False
-## Constants for check_sw()
-PURPOSE_SUCCESS = 1 # Command executed successful
-PURPOSE_GET_RESPONSE = 2 # Command executed successful but needs GET RESPONSE with correct length
-PURPOSE_SM_OK = 3 # Command not executed successful or with warnings, but response still contains SM objects
-PURPOSE_RETRY = 4 # Command would be executed successful but needs retry with correct length
_GENERIC_NAME = "Generic"
class Card:
DRIVER_NAME = [_GENERIC_NAME]
- APDU_GET_RESPONSE = C_APDU(ins=0xc0)
- APDU_VERIFY_PIN = C_APDU(ins=0x20)
- PURPOSE_SUCCESS, PURPOSE_GET_RESPONSE, PURPOSE_SM_OK, PURPOSE_RETRY = PURPOSE_SUCCESS, PURPOSE_GET_RESPONSE, PURPOSE_SM_OK, PURPOSE_RETRY
+ APDU_GET_RESPONSE = None
+
+ ## Constants for check_sw()
+ PURPOSE_SUCCESS = 1 # Command executed successful
+ PURPOSE_GET_RESPONSE = 2 # Command executed successful but needs GET RESPONSE with correct length
+ PURPOSE_SM_OK = 3 # Command not executed successful or with warnings, but response still contains SM objects
+ PURPOSE_RETRY = 4 # Command would be executed successful but needs retry with correct length
+
## Map for check_sw()
- STATUS_MAP = {
- PURPOSE_SUCCESS: ("\x90\x00", ),
- PURPOSE_GET_RESPONSE: ("61??", ), ## If this is received then GET RESPONSE should be called with SW2
- PURPOSE_SM_OK: ("\x90\x00",),
- PURPOSE_RETRY: (), ## Theoretically this would contain "6C??", but I dare not automatically resending a command for _all_ card types
- ## Instead, card types for which this is safe should set it in their own STATUS_MAP
- }
+ STATUS_MAP = {}
+
## Note: an item in this list must be a tuple of (atr, mask) where atr is a binary
## string and mask a binary mask. Alternatively mask may be None, then ATR must be a regex
## to match on the ATRs hexlify representation
@@ -32,18 +27,15 @@ class Card:
## Note: A list of _not_ supported ATRs, overriding any possible match in ATRS. Matching
## is done as for ATRS.
STOP_ATRS = []
- ## Note: a key in this dictionary may either be a two-byte string containing
- ## a binary status word, or a four-byte string containing a hexadecimal
+
+ ## Note: a key in this dictionary may either be a one- or two-byte string containing
+ ## a binary status word, or a two or four-byte string containing a hexadecimal
## status word, possibly with ? characters marking variable nibbles.
- ## Hexadecimal characters MUST be in uppercase. The values that four-byte
+ ## Hexadecimal characters MUST be in uppercase. The values that two- or four-byte
## strings map to may be either format strings, that can make use of the
## keyword substitutions for SW1 and SW2 or a callable accepting two arguments
## (SW1, SW2) that returns a string.
STATUS_WORDS = {
- '\x90\x00': "Normal execution",
- '61??': "%(SW2)i (0x%(SW2)02x) bytes of response data can be retrieved with GetResponse.",
- '6C??': "Bad value for LE, 0x%(SW2)02x is the correct value.",
- '63C?': lambda SW1,SW2: "The counter has reached the value '%i'" % (SW2%16)
}
## For the format of this dictionary of dictionaries see TLV_utils.tags
TLV_OBJECTS = {}
@@ -51,44 +43,10 @@ class Card:
## Format: "AID (binary)": ("name", [optional: description, {more information}])
APPLICATIONS = {
- "\xa0\x00\x00\x01\x67\x45\x53\x49\x47\x4e": ("DF.ESIGN", ),
- "\xa0\x00\x00\x00\x63\x50\x4b\x43\x53\x2d\x31\x35": ("DF_PKCS15", ),
- "\xD2\x76\x00\x01\x24\x01": ("DF_OpenPGP", "OpenPGP card", {"significant_length": 6} ),
- "\xa0\x00\x00\x02\x47\x10\x01": ("DF_LDS", "Machine Readable Travel Document", {"alias": ("mrtd",)}),
- ## The following are from 0341a.pdf: BSI-DSZ-CC-0341-2006
- "\xD2\x76\x00\x00\x66\x01": ("DF_SIG", "Signature application", {"fid": "\xAB\x00"}),
- "\xD2\x76\x00\x00\x25\x5A\x41\x02\x00": ("ZA_MF_NEU", "Zusatzanwendungen", {"fid": "\xA7\x00"}),
- "\xD2\x76\x00\x00\x25\x45\x43\x02\x00": ("DF_EC_CASH_NEU", "ec-Cash", {"fid": "\xA1\x00"}),
- "\xD2\x76\x00\x00\x25\x45\x50\x02\x00": ("DF_BOERSE_NEU", "Geldkarte", {"fid": "\xA2\x00", "alias": ("geldkarte",)}),
- "\xD2\x76\x00\x00\x25\x47\x41\x01\x00": ("DF_GA_MAESTRO", "GA-Maestro", {"fid": "\xAC\x00"}),
- "\xD2\x76\x00\x00\x25\x54\x44\x01\x00": ("DF_TAN", "TAN-Anwendung", {"fid": "\xAC\x02"}),
- "\xD2\x76\x00\x00\x25\x4D\x01\x02\x00": ("DF_MARKTPLATZ_NEU", "Marktplatz", {"fid": "\xB0\x01"}),
- "\xD2\x76\x00\x00\x25\x46\x53\x02\x00": ("DF_FAHRSCHEIN_NEU", "Fahrschein", {"fid": "\xB0\x00"}),
- "\xD2\x76\x00\x00\x25\x48\x42\x02\x00": ("DF_BANKING_20" , "HBCI", {"fid": "\xA6\x00"}),
- "\xD2\x76\x00\x00\x25\x4E\x50\x01\x00": ("DF_NOTEPAD", "Notepad", {"fid": "\xA6\x10"}),
-
- "\xd2\x76\x00\x00\x85\x01\x00": ("NFC_TYPE_4", "NFC NDEF Application on tag type 4", {"alias": ("nfc",)}, ),
-
- # From TR-03110_v201_pdf.pdf
- "\xE8\x07\x04\x00\x7f\x00\x07\x03\x02": ("DF_eID", "eID application"),
-
- "\xd2\x76\x00\x00\x25\x4b\x41\x4e\x4d\x30\x31\x00": ("VRS_TICKET", "VRS Ticket", {"fid": "\xad\x00", "alias": ("vrs",)}, ),
- "\xd2\x76\x00\x01\x35\x4b\x41\x4e\x4d\x30\x31\x00": ("VRS_TICKET", "VRS Ticket", {"fid": "\xad\x00",}, ),
}
- # Alias for DF_BOERSE_NEU
- APPLICATIONS["\xA0\x00\x00\x00\x59\x50\x41\x43\x45\x01\x00"] = APPLICATIONS["\xD2\x76\x00\x00\x25\x45\x50\x02\x00"]
- # Alias for DF_GA_MAESTRO
- APPLICATIONS["\xA0\x00\x00\x00\x04\x30\x60"] = APPLICATIONS["\xD2\x76\x00\x00\x25\x47\x41\x01\x00"]
## Format: "RID (binary)": ("vendor name", [optional: {more information}])
VENDORS = {
- "\xD2\x76\x00\x01\x24": ("Free Software Foundation Europe", ),
- "\xD2\x76\x00\x00\x25": ("Bankenverlag", ),
- "\xD2\x76\x00\x00\x60": ("Wolfgang Rankl", ),
- "\xD2\x76\x00\x00\x05": ("Giesecke & Devrient", ),
- "\xD2\x76\x00\x00\x40": ("Zentralinstitut fuer die Kassenaerztliche Versorgung in der Bundesrepublik Deutschland", ), # hpc-use-cases-01.pdf
- "\xa0\x00\x00\x02\x47": ("ICAO", ),
- "\xa0\x00\x00\x03\x06": ("PC/SC Workgroup", ),
}
def _decode_df_name(self, value):
@@ -125,11 +83,6 @@ class Card:
# Static method for when there is no object reference
return Card._decode_df_name(value)
- TLV_OBJECTS[TLV_utils.context_FCP] = {
- 0x84: (decode_df_name, "DF name"),
- }
- TLV_OBJECTS[TLV_utils.context_FCI] = TLV_OBJECTS[TLV_utils.context_FCP]
-
def __init__(self, reader):
self.reader = reader
@@ -141,28 +94,6 @@ class Card:
self._last_start = None
self.last_delta = None
- def post_merge(self):
- ## Called after cards.__init__.Cardmultiplexer._merge_attributes
- self.TLV_OBJECTS[TLV_utils.context_FCP][0x84] = (self._decode_df_name, "DF name")
- self.TLV_OBJECTS[TLV_utils.context_FCI][0x84] = (self._decode_df_name, "DF name")
-
- def verify_pin(self, pin_number, pin_value):
- apdu = C_APDU(self.APDU_VERIFY_PIN, P2 = pin_number,
- data = pin_value)
- result = self.send_apdu(apdu)
- return self.check_sw(result.sw)
-
- def cmd_verify(self, pin_number, pin_value):
- """Verify a PIN."""
- pin_number = int(pin_number, 0)
- pin_value = binascii.a2b_hex("".join(pin_value.split()))
- self.verify_pin(pin_number, pin_value)
-
- def cmd_reset(self):
- """Reset the card."""
- # FIXME
- raise NotImplementedException
-
def cmd_parsetlv(self, start = None, end = None):
"Decode the TLV data in the last response, start and end are optional"
lastlen = len(self.last_result.data)
@@ -189,9 +120,13 @@ class Card:
"description": len(info) > 1 and info[1] or ""
}
+ def cmd_reset(self):
+ """Reset the card."""
+ # FIXME
+ raise NotImplementedException
+
COMMANDS = {
"reset": cmd_reset,
- "verify": cmd_verify,
"parse_tlv": cmd_parsetlv,
"show_applications": cmd_show_applications,
}
@@ -216,11 +151,11 @@ class Card:
def _send_with_retry(self, apdu):
result = self._real_send(apdu)
- if self.check_sw(result.sw, PURPOSE_GET_RESPONSE):
+ if self.check_sw(result.sw, self.PURPOSE_GET_RESPONSE):
## Need to call GetResponse
gr_apdu = C_APDU(self.APDU_GET_RESPONSE, le = result.sw2, cla=apdu.cla) # FIXME
result = R_APDU(self._real_send(gr_apdu))
- elif self.check_sw(result.sw, PURPOSE_RETRY) and apdu.Le == 0:
+ elif self.check_sw(result.sw, self.PURPOSE_RETRY) and apdu.Le == 0:
## Retry with correct Le
gr_apdu = C_APDU(apdu, le = result.sw2)
result = R_APDU(self._real_send(gr_apdu))
diff --git a/cards/gsm_card.py b/cards/gsm_card.py
index 815bdac..408dd46 100644
--- a/cards/gsm_card.py
+++ b/cards/gsm_card.py
@@ -1,11 +1,11 @@
import utils
-from generic_card import *
+from iso_card import *
-class GSM_Card(Card):
+class GSM_Card(ISO_Card):
DRIVER_NAME = ["GSM"]
APDU_GET_RESPONSE = C_APDU("\xa0\xC0\x00\x00")
STATUS_MAP = {
- PURPOSE_GET_RESPONSE: ("9F??", )
+ Card.PURPOSE_GET_RESPONSE: ("9F??", )
}
ATRS = [
diff --git a/cards/iso_7816_4_card.py b/cards/iso_7816_4_card.py
index c13c100..899dcb2 100644
--- a/cards/iso_7816_4_card.py
+++ b/cards/iso_7816_4_card.py
@@ -1,6 +1,6 @@
import sys;sys.path.append(".."); sys.path.append(".")
import TLV_utils
-from generic_card import *
+from iso_card import *
from generic_application import Application
import building_blocks
@@ -156,7 +156,7 @@ class iso_df(iso_node):
if node not in self._children:
self._children.append(node)
-class ISO_7816_4_Card(building_blocks.Card_with_read_binary,Card):
+class ISO_7816_4_Card(building_blocks.Card_with_read_binary,ISO_Card):
APDU_SELECT_APPLICATION = C_APDU(ins=0xa4,p1=0x04)
APDU_SELECT_FILE = C_APDU(ins=0xa4, le=0)
APDU_READ_BINARY = C_APDU(ins=0xb0,le=0)
@@ -284,18 +284,18 @@ class ISO_7816_4_Card(building_blocks.Card_with_read_binary,Card):
aid = self.resolve_symbolic_aid(application)
Application.load_applications(self, aid)
- ATRS = list(Card.ATRS)
+ ATRS = list(ISO_Card.ATRS)
ATRS.extend( [
(".*", None), ## For now we accept any card
] )
- STOP_ATRS = list(Card.STOP_ATRS)
+ STOP_ATRS = list(ISO_Card.STOP_ATRS)
STOP_ATRS.extend( [
("3b8f8001804f0ca000000306......00000000..", None), # Contactless storage cards (PC/SC spec part 3 section 3.1.3.2.3
("3b8180018080", None), # Mifare DESfire (special case of contactless smartcard, ibid.)
] )
- COMMANDS = dict(Card.COMMANDS)
+ COMMANDS = dict(ISO_Card.COMMANDS)
COMMANDS.update(building_blocks.Card_with_read_binary.COMMANDS)
COMMANDS.update( {
"select_application": cmd_selectapplication,
@@ -307,7 +307,7 @@ class ISO_7816_4_Card(building_blocks.Card_with_read_binary,Card):
"next_record": cmd_next_record,
} )
- STATUS_WORDS = dict(Card.STATUS_WORDS)
+ STATUS_WORDS = dict(ISO_Card.STATUS_WORDS)
STATUS_WORDS.update( {
"62??": "Warning, State of non-volatile memory unchanged",
"63??": "Warning, State of non-volatile memory changed",
diff --git a/cards/iso_card.py b/cards/iso_card.py
new file mode 100644
index 0000000..feda66d
--- /dev/null
+++ b/cards/iso_card.py
@@ -0,0 +1,107 @@
+import smartcard
+import TLV_utils, crypto_utils, utils, binascii, fnmatch, re, time
+from generic_card import Card
+from utils import C_APDU, R_APDU
+
+class ISO_Card(Card):
+ DRIVER_NAME = ["ISO"]
+ APDU_GET_RESPONSE = C_APDU(ins=0xc0)
+ APDU_VERIFY_PIN = C_APDU(ins=0x20)
+
+ ## Map for check_sw()
+ STATUS_MAP = {
+ Card.PURPOSE_SUCCESS: ("\x90\x00", ),
+ Card.PURPOSE_GET_RESPONSE: ("61??", ), ## If this is received then GET RESPONSE should be called with SW2
+ Card.PURPOSE_SM_OK: ("\x90\x00",),
+ Card.PURPOSE_RETRY: (), ## Theoretically this would contain "6C??", but I dare not automatically resending a command for _all_ card types
+ ## Instead, card types for which this is safe should set it in their own STATUS_MAP
+ }
+
+ ATRS = list(Card.ATRS)
+ STOP_ATRS = list(Card.STOP_ATRS)
+
+ ## Note: a key in this dictionary may either be a one- or two-byte string containing
+ ## a binary status word, or a two or four-byte string containing a hexadecimal
+ ## status word, possibly with ? characters marking variable nibbles.
+ ## Hexadecimal characters MUST be in uppercase. The values that two- or four-byte
+ ## strings map to may be either format strings, that can make use of the
+ ## keyword substitutions for SW1 and SW2 or a callable accepting two arguments
+ ## (SW1, SW2) that returns a string.
+ STATUS_WORDS = {
+ '\x90\x00': "Normal execution",
+ '61??': "%(SW2)i (0x%(SW2)02x) bytes of response data can be retrieved with GetResponse.",
+ '6C??': "Bad value for LE, 0x%(SW2)02x is the correct value.",
+ '63C?': lambda SW1,SW2: "The counter has reached the value '%i'" % (SW2%16)
+ }
+ ## For the format of this dictionary of dictionaries see TLV_utils.tags
+ TLV_OBJECTS = dict(Card.TLV_OBJECTS)
+ DEFAULT_CONTEXT = None
+
+ ## Format: "AID (binary)": ("name", [optional: description, {more information}])
+ APPLICATIONS = {
+ "\xa0\x00\x00\x01\x67\x45\x53\x49\x47\x4e": ("DF.ESIGN", ),
+ "\xa0\x00\x00\x00\x63\x50\x4b\x43\x53\x2d\x31\x35": ("DF_PKCS15", ),
+ "\xD2\x76\x00\x01\x24\x01": ("DF_OpenPGP", "OpenPGP card", {"significant_length": 6} ),
+ "\xa0\x00\x00\x02\x47\x10\x01": ("DF_LDS", "Machine Readable Travel Document", {"alias": ("mrtd",)}),
+ ## The following are from 0341a.pdf: BSI-DSZ-CC-0341-2006
+ "\xD2\x76\x00\x00\x66\x01": ("DF_SIG", "Signature application", {"fid": "\xAB\x00"}),
+ "\xD2\x76\x00\x00\x25\x5A\x41\x02\x00": ("ZA_MF_NEU", "Zusatzanwendungen", {"fid": "\xA7\x00"}),
+ "\xD2\x76\x00\x00\x25\x45\x43\x02\x00": ("DF_EC_CASH_NEU", "ec-Cash", {"fid": "\xA1\x00"}),
+ "\xD2\x76\x00\x00\x25\x45\x50\x02\x00": ("DF_BOERSE_NEU", "Geldkarte", {"fid": "\xA2\x00", "alias": ("geldkarte",)}),
+ "\xD2\x76\x00\x00\x25\x47\x41\x01\x00": ("DF_GA_MAESTRO", "GA-Maestro", {"fid": "\xAC\x00"}),
+ "\xD2\x76\x00\x00\x25\x54\x44\x01\x00": ("DF_TAN", "TAN-Anwendung", {"fid": "\xAC\x02"}),
+ "\xD2\x76\x00\x00\x25\x4D\x01\x02\x00": ("DF_MARKTPLATZ_NEU", "Marktplatz", {"fid": "\xB0\x01"}),
+ "\xD2\x76\x00\x00\x25\x46\x53\x02\x00": ("DF_FAHRSCHEIN_NEU", "Fahrschein", {"fid": "\xB0\x00"}),
+ "\xD2\x76\x00\x00\x25\x48\x42\x02\x00": ("DF_BANKING_20" , "HBCI", {"fid": "\xA6\x00"}),
+ "\xD2\x76\x00\x00\x25\x4E\x50\x01\x00": ("DF_NOTEPAD", "Notepad", {"fid": "\xA6\x10"}),
+
+ "\xd2\x76\x00\x00\x85\x01\x00": ("NFC_TYPE_4", "NFC NDEF Application on tag type 4", {"alias": ("nfc",)}, ),
+
+ # From TR-03110_v201_pdf.pdf
+ "\xE8\x07\x04\x00\x7f\x00\x07\x03\x02": ("DF_eID", "eID application"),
+
+ "\xd2\x76\x00\x00\x25\x4b\x41\x4e\x4d\x30\x31\x00": ("VRS_TICKET", "VRS Ticket", {"fid": "\xad\x00", "alias": ("vrs",)}, ),
+ "\xd2\x76\x00\x01\x35\x4b\x41\x4e\x4d\x30\x31\x00": ("VRS_TICKET", "VRS Ticket", {"fid": "\xad\x00",}, ),
+ }
+ # Alias for DF_BOERSE_NEU
+ APPLICATIONS["\xA0\x00\x00\x00\x59\x50\x41\x43\x45\x01\x00"] = APPLICATIONS["\xD2\x76\x00\x00\x25\x45\x50\x02\x00"]
+ # Alias for DF_GA_MAESTRO
+ APPLICATIONS["\xA0\x00\x00\x00\x04\x30\x60"] = APPLICATIONS["\xD2\x76\x00\x00\x25\x47\x41\x01\x00"]
+
+ ## Format: "RID (binary)": ("vendor name", [optional: {more information}])
+ VENDORS = {
+ "\xD2\x76\x00\x01\x24": ("Free Software Foundation Europe", ),
+ "\xD2\x76\x00\x00\x25": ("Bankenverlag", ),
+ "\xD2\x76\x00\x00\x60": ("Wolfgang Rankl", ),
+ "\xD2\x76\x00\x00\x05": ("Giesecke & Devrient", ),
+ "\xD2\x76\x00\x00\x40": ("Zentralinstitut fuer die Kassenaerztliche Versorgung in der Bundesrepublik Deutschland", ), # hpc-use-cases-01.pdf
+ "\xa0\x00\x00\x02\x47": ("ICAO", ),
+ "\xa0\x00\x00\x03\x06": ("PC/SC Workgroup", ),
+ }
+
+ TLV_OBJECTS[TLV_utils.context_FCP] = {
+ 0x84: (Card.decode_df_name, "DF name"),
+ }
+ TLV_OBJECTS[TLV_utils.context_FCI] = TLV_OBJECTS[TLV_utils.context_FCP]
+
+ def post_merge(self):
+ ## Called after cards.__init__.Cardmultiplexer._merge_attributes
+ self.TLV_OBJECTS[TLV_utils.context_FCP][0x84] = (self._decode_df_name, "DF name")
+ self.TLV_OBJECTS[TLV_utils.context_FCI][0x84] = (self._decode_df_name, "DF name")
+
+ def verify_pin(self, pin_number, pin_value):
+ apdu = C_APDU(self.APDU_VERIFY_PIN, P2 = pin_number,
+ data = pin_value)
+ result = self.send_apdu(apdu)
+ return self.check_sw(result.sw)
+
+ def cmd_verify(self, pin_number, pin_value):
+ """Verify a PIN."""
+ pin_number = int(pin_number, 0)
+ pin_value = binascii.a2b_hex("".join(pin_value.split()))
+ self.verify_pin(pin_number, pin_value)
+
+ COMMANDS = {
+ "verify": cmd_verify,
+ }
+
diff --git a/cards/java_card.py b/cards/java_card.py
index 1a3fb89..2353f4a 100644
--- a/cards/java_card.py
+++ b/cards/java_card.py
@@ -1,13 +1,10 @@
import utils, binascii
-from generic_card import *
+from iso_card import *
from utils import C_APDU
-class Java_Card(Card):
+class Java_Card(ISO_Card):
DRIVER_NAME = ["Generic Java"]
APPLICATIONS = {
"\xa0\x00\x00\x00\x01\x01": ("muscle", "MUSCLE applet")
}
-
- def __init__(self, card = None):
- Card.__init__(self, card = card)
diff --git a/cards/passport_application.py b/cards/passport_application.py
index 2aae9c1..943038f 100644
--- a/cards/passport_application.py
+++ b/cards/passport_application.py
@@ -3,8 +3,7 @@ import struct, binascii, os, datetime, sys
from hashlib import sha1
from utils import hexdump, C_APDU
from tcos_card import SE_Config, TCOS_Security_Environment
-from generic_card import Card
-from iso_7816_4_card import ISO_7816_4_Card
+from iso_7816_4_card import ISO_7816_4_Card, ISO_Card, Card
import crypto_utils, tcos_card, TLV_utils, generic_card
from TLV_utils import identifier
diff --git a/cards/pn532_card.py b/cards/pn532_card.py
index bc84002..4efd8b6 100644
--- a/cards/pn532_card.py
+++ b/cards/pn532_card.py
@@ -1,13 +1,13 @@
import utils, binascii
-from generic_card import *
+from iso_card import *
-class PN532_Virtual_Card(Card):
+class PN532_Virtual_Card(ISO_Card):
# This is a virtual card that is enabled for the ACS ACR reader that
# contains a PN532 module
DRIVER_NAME = ["PN532"]
- STATUS_WORDS = dict(Card.STATUS_WORDS)
- COMMANDS = dict(Card.COMMANDS)
+ STATUS_WORDS = dict(ISO_Card.STATUS_WORDS)
+ COMMANDS = dict(ISO_Card.COMMANDS)
APDU_TRANSCEIVE_PN532 = C_APDU(cla=0xff, ins=0, p1=0, p2=0)
diff --git a/cards/rfid_card.py b/cards/rfid_card.py
index 1793cfd..7e29dd7 100644
--- a/cards/rfid_card.py
+++ b/cards/rfid_card.py
@@ -1,8 +1,8 @@
import utils
-from generic_card import *
+from iso_card import *
import building_blocks
-class RFID_Card(Card):
+class RFID_Card(ISO_Card):
DRIVER_NAME = ["RFID"]
APDU_GET_UID = utils.C_APDU(CLA=0xff, INS=0xCA, p1=0, p2=0, Le=0)
@@ -32,7 +32,7 @@ class RFID_Card(Card):
"get_uid": cmd_get_uid,
}
- STATUS_WORDS = dict(Card.STATUS_WORDS)
+ STATUS_WORDS = dict(ISO_Card.STATUS_WORDS)
STATUS_WORDS.update( {
"\x62\x82": "End of file (or UID) reached before Le bytes",
"\x67\x00": "Wrong Length",
diff --git a/cards/starcos_card.py b/cards/starcos_card.py
index aacf65d..a8ad477 100644
--- a/cards/starcos_card.py
+++ b/cards/starcos_card.py
@@ -12,7 +12,7 @@ class Starcos_Card(ISO_7816_4_Card):
else:
return self.select_file(0x00, 0x0C, fid)
- ATRS = list(Card.ATRS)
+ ATRS = list(ISO_Card.ATRS)
ATRS.extend( [
("3bb794008131fe6553504b32339000d1", None),
] )