aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2007-02-10 21:52:06 +0000
committerhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2007-02-10 21:52:06 +0000
commit82cddea7e7bdd15a9c80a13e5c8a80259c8d4aa3 (patch)
tree08e15abe57234dc6b0e5dc77a91b6e8544e2b3d5
parenta4efadb3776691af55dfb25aae02bbc1b27dfa84 (diff)
Add support for aliases in application selection
Add skeleton for support of application specific commands that can be dynamically loaded Pending addition of commands to work with passports git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@173 f711b948-2313-0410-aaa9-d29f33439f0b
-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,
+ }