diff --git a/TLV_utils.py b/TLV_utils.py index 7395bc5..475df4e 100644 --- a/TLV_utils.py +++ b/TLV_utils.py @@ -1,12 +1,28 @@ -import binascii, utils, sre +import binascii, utils, sre, sys -context_FCP = object() -context_FMD = object() -context_FCI = object() -recurse = object() -binary = object() -number = object() -ascii = object() +class identifier: + """An identifier, because I'm too lazy to use quotes all over the place. + Instantiating an object of this type registers a name in the current scope, essentially + making each instantiation of this class equal to + foo = identifier("foo") + even when you only write + identifier("foo") + """ + def __init__(self,name): + self.name = name + sys._getframe(1).f_locals[name] = self + def __str__(self): + return self.name + def __repr__(self): + return "identifier(%r)" % self.name + +identifier("context_FCP") +identifier("context_FMD") +identifier("context_FCI") +identifier("recurse") +identifier("binary") +identifier("number") +identifier("ascii") file_descriptor_byte_descriptions = [ #mask byte no match match @@ -241,7 +257,7 @@ def tlv_unpack(data): return ber_class, constructed, tag, length, value, rest -def decode(data, context = None, level = 0): +def decode(data, context = None, level = 0, tags=tags): result = [] while len(data) > 0: if ord(data[0]) in (0x00, 0xFF): @@ -263,7 +279,7 @@ def decode(data, context = None, level = 0): if interpretation[0] is recurse: current.append("\n") - current.append( decode(value, interpretation[2], level+1) ) + current.append( decode(value, interpretation[2], level+1, tags=tags) ) elif interpretation[0] is number: num = 0 for i in value: diff --git a/cards/__init__.py b/cards/__init__.py index 04aad81..001c60f 100644 --- a/cards/__init__.py +++ b/cards/__init__.py @@ -55,6 +55,7 @@ class Cardmultiplexer: of the participating classes instead of overriding them.""" MERGE_DICTS = ("APPLICATIONS", "COMMANDS", "STATUS_WORDS") + MERGE_DICTS_RECURSIVE = ("TLV_OBJECTS", ) MERGE_LISTS = () def __init__(self, classes, *args, **kwargs): @@ -143,12 +144,29 @@ class Cardmultiplexer: def _merge_attributes(self): """Update the local copy of merged attributes.""" - for attr in self.MERGE_DICTS: + for attr in self.MERGE_DICTS + self.MERGE_DICTS_RECURSIVE: tmpdict = {} have_one = False for cls in self._classes: if hasattr(cls, attr): - tmpdict.update( getattr(cls, attr) ) + if not attr in self.MERGE_DICTS_RECURSIVE: + tmpdict.update( getattr(cls, attr) ) + else: + def recurse(target, source): + for (key, value) in source.items(): + if target.has_key(key): + if isinstance(value, dict) and isinstance(target[key], dict): + recurse( target[key], value ) + elif isinstance(value, dict): + target[key] = dict(value) + else: + target[key] = value + else: + if isinstance(value, dict): + target[key] = dict(value) + else: + target[key] = value + recurse( tmpdict, getattr(cls, attr) ) have_one = True if have_one: setattr(self, attr, tmpdict) diff --git a/cards/generic_card.py b/cards/generic_card.py index 52e9d71..3b4d6ea 100644 --- a/cards/generic_card.py +++ b/cards/generic_card.py @@ -27,6 +27,8 @@ class Card: '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 = {} def __init__(self, card = None, reader = None): if card is None: @@ -61,7 +63,7 @@ class Card: def cmd_parsetlv(self): "Decode the TLV data in the last response" - print TLV_utils.decode(self.last_result.data) + print TLV_utils.decode(self.last_result.data, tags=self.TLV_OBJECTS) COMMANDS = { "reset": cmd_reset, diff --git a/cards/iso_7816_4_card.py b/cards/iso_7816_4_card.py index 4b5b854..ffeff3d 100644 --- a/cards/iso_7816_4_card.py +++ b/cards/iso_7816_4_card.py @@ -36,7 +36,7 @@ class ISO_7816_4_Card(Card): if len(result.data) > 0: print utils.hexdump(result.data) - print TLV_utils.decode(result.data) + print TLV_utils.decode(result.data,tags=self.TLV_OBJECTS) def open_file(self, fid): "Open an EF under the current DF" @@ -49,7 +49,7 @@ class ISO_7816_4_Card(Card): result = self.open_file(fid) if len(result.data) > 0: print utils.hexdump(result.data) - print TLV_utils.decode(result.data) + print TLV_utils.decode(result.data,tags=self.TLV_OBJECTS) def read_binary_file(self, offset = 0): """Read from the currently selected EF. @@ -93,7 +93,7 @@ class ISO_7816_4_Card(Card): result = self.select_file(p1, p2, fid) if len(result.data) > 0: print utils.hexdump(result.data) - print TLV_utils.decode(result.data) + print TLV_utils.decode(result.data,tags=self.TLV_OBJECTS) ATRS = list(Card.ATRS) ATRS.extend( [ @@ -162,3 +162,5 @@ class ISO_7816_4_Card(Card): "6A87": "Wrong parameter(s) P1-P2, Lc inconsistent with P1-P2", "6A88": "Wrong parameter(s) P1-P2, Referenced data not found", } ) + + TLV_OBJECTS = TLV_utils.tags