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
This commit is contained in:
parent
8401c47490
commit
eb1df9aff0
|
@ -9,6 +9,9 @@
|
|||
<Author>Henryk Plötz</Author>
|
||||
<Email>henryk@ploetzli.ch</Email>
|
||||
<Sources>
|
||||
<Source>
|
||||
<Name>utils.py</Name>
|
||||
</Source>
|
||||
</Sources>
|
||||
<Forms>
|
||||
</Forms>
|
||||
|
|
137
utils.py
137
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])
|
||||
|
Loading…
Reference in New Issue