aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--utils.py111
1 files changed, 109 insertions, 2 deletions
diff --git a/utils.py b/utils.py
index abd2827..84f3dfa 100644
--- a/utils.py
+++ b/utils.py
@@ -85,6 +85,110 @@ 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]))
+
+class APDU(list):
+ OFFSET_CLA = 0
+ OFFSET_INS = 1
+ OFFSET_P1 = 2
+ OFFSET_P2 = 3
+ OFFSET_P3 = 4
+ OFFSET_LC = 4
+ OFFSET_LE = 4
+ OFFSET_CONTENT = 5
+
+ """Class for an APDU that mostly behaves like a list."""
+ def __init__(self, *args, **kwargs):
+ """Creates a new APDU instance. Can be given positional parameters which
+ must be sequences of either strings (or strings themselves) or integers
+ specifying byte values that will be concatenated in order. Alternatively
+ you may give exactly one positional argument that is an APDU instance.
+ The keyword arguments can then be used to override those values.
+ Keywords recognized are: cla, ins, p1, p2, p3, lc, le, content.
+ Note: only set the le parameter if you don't send data."""
+
+ if len(args) == 1 and type(args[0]) == APDU:
+ self.extend(args)
+ else:
+ for arg in args:
+ if type(arg) == str:
+ self.extend(arg)
+ elif hasattr(arg, "__iter__"):
+ for elem in arg:
+ if hasattr(elem, "__iter__"):
+ self.extend(elem)
+ else:
+ self.append(elem)
+ else:
+ self.append(arg)
+
+ if len(self) < 4:
+ self.extend([0] * (4-len(self)))
+
+ print self
+ le = None
+ for (kw, arg) in kwargs.items():
+ if kw == "cla":
+ self[self.OFFSET_CLA] = arg
+ elif kw == "ins":
+ self[self.OFFSET_INS] = arg
+ elif kw == "p1":
+ self[self.OFFSET_P1] = arg
+ elif kw == "p2":
+ self[self.OFFSET_P2] = arg
+ elif kw == "p3":
+ self[self.OFFSET_P3:self.OFFSET_P3+1] = (arg,)
+ elif kw == "lc":
+ self[self.OFFSET_LC:self.OFFSET_LC+1] = (arg,)
+ elif kw == "le":
+ le = arg
+ elif kw == "content":
+ self[self.OFFSET_CONTENT:self.OFFSET_CONTENT+len(arg)] = arg
+ else:
+ raise TypeError, "Got an unexpected keyword argument '%s'" % kw
+
+ print self
+ if le is not None:
+ if len(self) > self.OFFSET_CONTENT:
+ raise TypeError, "le can't be set when there is data to send"
+ else:
+ self[self.OFFSET_LE:self.OFFSET_LE+1] = (le,)
+
+ for i in range(len(self)):
+ t = type(self[i])
+ if t == str:
+ self[i] = ord(self[i])
+ elif t != int:
+ raise TypeError, "APDU must consist of ints or one-byte strings, not %s (index %s)" % (t, i)
+
+ def __str__(self):
+ result = "APDU(CLA=0x%x, INS=0x%x, P1=0x%x, P2=0x%x" % (
+ self[self.OFFSET_CLA], self[self.OFFSET_INS],
+ self[self.OFFSET_P1], self[self.OFFSET_P2])
+ if len(self) == self.OFFSET_CONTENT:
+ result = result + ", LE=0x%x)" % self[self.OFFSET_LE]
+ elif len(self) > self.OFFSET_CONTENT:
+ result = result + ", LC=0x%x) with %i(0x%x) bytes of contents" % (
+ self[self.OFFSET_LC], len(self)-self.OFFSET_CONTENT, len(self)-self.OFFSET_CONTENT)
+ else:
+ result = result + ")"
+ return result + ":\n" + hexdump(self.get_string())
+
+ def __repr__(self):
+ result = "APDU(cla=0x%x, ins=0x%x, p1=0x%x, p2=0x%x" % (
+ self[self.OFFSET_CLA], self[self.OFFSET_INS],
+ self[self.OFFSET_P1], self[self.OFFSET_P2])
+ if len(self) == self.OFFSET_CONTENT:
+ result = result + ", le=0x%x)" % self[self.OFFSET_LE]
+ elif len(self) > self.OFFSET_CONTENT:
+ result = result + ", lc=0x%x, content=%s)" % (
+ self[self.OFFSET_LC], self[self.OFFSET_CONTENT:])
+ else:
+ result = result + ")"
+ return result
+
+ def get_string(self):
+ return [chr(i) for i in self]
+
if __name__ == "__main__":
response = """
0000: 07 A0 00 00 00 03 00 00 07 00 07 A0 00 00 00 62 ...............b
@@ -133,6 +237,9 @@ if __name__ == "__main__":
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])
+ #response = sys.stdin.read()
+ #parse_status(_unformat_hexdump(response)[:-2])
+
+ print APDU((1,2,3), lc=42, cla=0x23, le=4)
+