aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cards/generic_application.py39
-rw-r--r--cards/generic_card.py6
-rw-r--r--cards/iso_7816_4_card.py8
-rw-r--r--cards/passport_application.py17
4 files changed, 66 insertions, 4 deletions
diff --git a/cards/generic_application.py b/cards/generic_application.py
new file mode 100644
index 0000000..5b663b4
--- /dev/null
+++ b/cards/generic_application.py
@@ -0,0 +1,39 @@
+import binascii, re, sys, cards
+
+class Application:
+
+ # This must be a sequence of regular expressions
+ # When an application is selected through a matching AID
+ # then all correponding classes are merged into the card
+ # object.
+ # The application classes themselves are responsible for
+ # unmerging, should their application become deselected.
+ # However, the default implementation in the generic
+ # Application class which triggers unmerging on a card reset
+ # and a successfull SELECT APPLICATION should be sufficient
+ # in most cases.
+ # (Still haven't thought this through, though...)
+ ## FIXME Unloading is not implemented yet
+ #
+ # NOTE: Implementing classes MUST derive from Application
+ AID_LIST = []
+
+ def load_applications(card, aid):
+ classes_to_load = []
+ for i in dir(cards):
+ possible_class = getattr(cards, i)
+ if not hasattr(possible_class, "DRIVER_NAME") or not issubclass(possible_class, Application):
+ continue
+ if possible_class.can_handle_aid(card, aid):
+ classes_to_load.append(possible_class)
+ print ".oO(Loading application '%s')" % possible_class.DRIVER_NAME
+
+ card.add_classes(classes_to_load)
+ load_applications = staticmethod(load_applications)
+
+ def can_handle_aid(cls, card, aid):
+ for i in cls.AID_LIST:
+ if re.match(i+"$", binascii.b2a_hex(aid), re.I):
+ return True
+ return False
+ can_handle_aid = classmethod(can_handle_aid)
diff --git a/cards/generic_card.py b/cards/generic_card.py
index 0ef53e5..a582815 100644
--- a/cards/generic_card.py
+++ b/cards/generic_card.py
@@ -34,8 +34,8 @@ class Card:
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": (None, "Machine Readable Travel Document"),
+ "\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"}),
@@ -59,7 +59,7 @@ class Card:
"\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 für die Kassenaerztliche Versorgung in der Bundesrepublik Deutschland", ), # hpc-use-cases-01.pdf
+ "\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", ),
}
diff --git a/cards/iso_7816_4_card.py b/cards/iso_7816_4_card.py
index ed61943..8df1304 100644
--- a/cards/iso_7816_4_card.py
+++ b/cards/iso_7816_4_card.py
@@ -1,5 +1,6 @@
import TLV_utils
from generic_card import *
+from generic_application import Application
class ISO_7816_4_Card(Card):
APDU_SELECT_APPLICATION = C_APDU(ins=0xa4,p1=0x04)
@@ -122,13 +123,18 @@ class ISO_7816_4_Card(Card):
result = self.send_apdu(
C_APDU(self.APDU_SELECT_APPLICATION,
data = aid, le = 0) ) ## FIXME With or without le
+ if result.sw == self.SW_OK:
+ Application.load_applications(self, aid)
return result
def cmd_selectapplication(self, application):
"""Select an application on the card.
application can be given either as hexadecimal aid or by symbolic name (if known)."""
- s = [a for a,b in self.APPLICATIONS.items() if b[0] is not None and b[0].lower() == application.lower()]
+ s = [a for a,b in self.APPLICATIONS.items()
+ if (b[0] is not None and b[0].lower() == application.lower())
+ or (len(b) > 2 and application.lower() in [c.lower() for c in b[2].get("alias", [])])
+ ]
if len(s) > 0:
aid = s[0]
else:
diff --git a/cards/passport_application.py b/cards/passport_application.py
new file mode 100644
index 0000000..2061c4a
--- /dev/null
+++ b/cards/passport_application.py
@@ -0,0 +1,17 @@
+from generic_application import Application
+
+class Passport_Application(Application):
+ DRIVER_NAME = "Passport"
+
+
+ AID_LIST = [
+ "a0000002471001"
+ ]
+
+ def hello_cmd(self):
+ "Print a friendly greeting. For test purposes."
+ print "Hello world"
+
+ COMMANDS = {
+ "hello": hello_cmd,
+ }