From eb1df9aff073907d80928ecaf6d2a3b0f948a004 Mon Sep 17 00:00:00 2001 From: henryk Date: Wed, 28 Sep 2005 15:01:29 +0000 Subject: utils.py will contain general utility functions. hexdump and parse_status for now git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@7 f711b948-2313-0410-aaa9-d29f33439f0b --- utils.py | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) (limited to 'utils.py') diff --git a/utils.py b/utils.py index e69de29..0a87174 100644 --- a/utils.py +++ b/utils.py @@ -0,0 +1,137 @@ +import pycsc, string, binascii, sys + +def hexdump(data, offset = 0, short = False): + r"""Generates a nice hexdump of data and returns it. Consecutive lines will + be indented with offset spaces. When short is true, will instead generate + hexdump without adresses and on one line. + + Examples: + hexdump('\x00\x41') -> \ + '0000: 00 41 .A ' + hexdump('\x00\x41', short=True) -> '00 41 (.A)'""" + + def hexable(data): + return " ".join([binascii.b2a_hex(a) for a in data]) + + def printable(data): + return "".join([e in string.printable and e or "." for e in data]) + + if short: + return "%s (%s)" % (hexable(data), printable(data)) + + result = "" + (head, tail) = (data[:16], data[16:]) + pos = 0 + while len(head) > 0: + if pos > 0: + result = result + "\n%s" % ' ' * offset + result = result + "%04x: %-48s %-16s" % (pos, hexable(head), printable(head)) + pos = pos + len(head) + (head, tail) = (tail[:16], tail[16:]) + return result + +LIFE_CYCLES = {0x01: "Load file = loaded", + 0x03: "Applet instance / security domain = Installed", + 0x07: "Card manager = Initialized; Applet instance / security domain = Selectable", + 0x0F: "Card manager = Secured; Applet instance / security domain = Personalized", + 0x7F: "Card manager = Locked; Applet instance / security domain = Blocked", + 0xFF: "Applet instance = Locked"} + +def parse_status(data): + """Parses the Response APDU of a GetStatus command.""" + def parse_segment(segment): + def parse_privileges(privileges): + if privileges == 0x0: + return "N/A" + else: + privs = [] + if privileges & (1<<7): + privs.append("security domain") + if privileges & (1<<6): + privs.append("DAP DES verification") + if privileges & (1<<5): + privs.append("delegated management") + if privileges & (1<<4): + privs.append("card locking") + if privileges & (1<<3): + privs.append("card termination") + if privileges & (1<<2): + privs.append("default selected") + if privileges & (1<<1): + privs.append("global PIN modification") + if privileges & (1<<0): + privs.append("mandated DAP verification") + return ", ".join(privs) + + lgth = ord(segment[0]) + aid = segment[1:1+lgth] + lifecycle = ord(segment[1+lgth]) + privileges = ord(segment[1+lgth+1]) + + print "aid length: %i (%x)" % (lgth, lgth) + print "aid: %s" % hexdump(aid, offset = 18, short=True) + print "life cycle state: %x (%s)" % (lifecycle, LIFE_CYCLES.get(lifecycle, "unknown or invalid state")) + print "privileges: %x (%s)\n" % (privileges, parse_privileges(privileges)) + + pos = 0 + while pos < len(data): + lgth = ord(data[pos])+3 + segment = data[pos:pos+lgth] + parse_segment(segment) + pos = pos + lgth + +def _unformat_hexdump(dump): + hexdump = " ".join([line[7:54] for line in dump.splitlines()]) + return binascii.a2b_hex("".join([e != " " and e or "" for e in hexdump])) + +if __name__ == "__main__": + response = """ +0000: 07 A0 00 00 00 03 00 00 07 00 07 A0 00 00 00 62 ...............b +0010: 00 01 01 00 07 A0 00 00 00 62 01 01 01 00 07 A0 .........b...... +0020: 00 00 00 62 01 02 01 00 07 A0 00 00 00 62 02 01 ...b.........b.. +0030: 01 00 07 A0 00 00 00 03 00 00 01 00 0E A0 00 00 ................ +0040: 00 30 00 00 90 07 81 32 10 00 00 01 00 0E A0 00 .0.....2........ +0050: 00 00 30 00 00 90 07 81 42 10 00 00 01 00 0E A0 ..0.....B....... +0060: 00 00 00 30 00 00 90 07 81 41 10 00 00 07 00 0E ...0.....A...... +0070: A0 00 00 00 30 00 00 90 07 81 12 10 00 00 01 00 ....0........... +0080: 09 53 4C 42 43 52 59 50 54 4F 07 00 90 00 .SLBCRYPTO.... +""" # 64kv1 vorher + response = """ +0000: 07 A0 00 00 00 03 00 00 0F 00 07 A0 00 00 00 62 ...............b +0010: 00 01 01 00 07 A0 00 00 00 62 01 01 01 00 07 A0 .........b...... +0020: 00 00 00 62 01 02 01 00 07 A0 00 00 00 62 02 01 ...b.........b.. +0030: 01 00 07 A0 00 00 00 03 00 00 01 00 08 A0 00 00 ................ +0040: 00 30 00 CA 10 01 00 0E A0 00 00 00 30 00 00 90 .0..........0... +0050: 07 81 32 10 00 00 01 00 0E A0 00 00 00 30 00 00 ..2..........0.. +0060: 90 07 81 42 10 00 00 01 00 0E A0 00 00 00 30 00 ...B..........0. +0070: 00 90 07 81 41 10 00 00 07 00 0E A0 00 00 00 30 ....A..........0 +0080: 00 00 90 07 81 12 10 00 00 01 00 09 53 4C 42 43 ............SLBC +0090: 52 59 50 54 4F 07 00 90 00 RYPTO.... +""" # komische Karte + response = """ +0000: 07 A0 00 00 00 03 00 00 07 00 07 A0 00 00 00 62 ...............b +0010: 00 01 01 00 07 A0 00 00 00 62 01 01 01 00 07 A0 .........b...... +0020: 00 00 00 62 01 02 01 00 07 A0 00 00 00 62 02 01 ...b.........b.. +0030: 01 00 07 A0 00 00 00 03 00 00 01 00 0E A0 00 00 ................ +0040: 00 30 00 00 90 07 81 32 10 00 00 01 00 0E A0 00 .0.....2........ +0050: 00 00 30 00 00 90 07 81 42 10 00 00 01 00 0E A0 ..0.....B....... +0060: 00 00 00 30 00 00 90 07 81 41 10 00 00 07 00 0E ...0.....A...... +0070: A0 00 00 00 30 00 00 90 07 81 12 10 00 00 01 00 ....0........... +0080: 09 53 4C 42 43 52 59 50 54 4F 07 00 05 A0 00 00 .SLBCRYPTO...... +0090: 00 01 01 00 90 00 ...... +""" # 64kv1 nachher + response = """ +0000: 07 A0 00 00 00 03 00 00 07 00 07 A0 00 00 00 62 ...............b +0010: 00 01 01 00 07 A0 00 00 00 62 01 01 01 00 07 A0 .........b...... +0020: 00 00 00 62 01 02 01 00 07 A0 00 00 00 62 02 01 ...b.........b.. +0030: 01 00 07 A0 00 00 00 03 00 00 01 00 0E A0 00 00 ................ +0040: 00 30 00 00 90 07 81 32 10 00 00 01 00 0E A0 00 .0.....2........ +0050: 00 00 30 00 00 90 07 81 42 10 00 00 01 00 0E A0 ..0.....B....... +0060: 00 00 00 30 00 00 90 07 81 41 10 00 00 07 00 0E ...0.....A...... +0070: A0 00 00 00 30 00 00 90 07 81 12 10 00 00 01 00 ....0........... +0080: 09 53 4C 42 43 52 59 50 54 4F 07 00 05 A0 00 00 .SLBCRYPTO...... +0090: 00 01 01 00 06 A0 00 00 00 01 01 07 02 90 00 ............... +""" # 64k1 nach setup + response = sys.stdin.read() + parse_status(_unformat_hexdump(response)[:-2]) + -- cgit v1.2.3