TLV utilities
git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@55 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
parent
f2bb9004cb
commit
53742b2705
|
@ -0,0 +1,68 @@
|
||||||
|
import binascii, utils
|
||||||
|
|
||||||
|
context_FCP = object()
|
||||||
|
context_FMD = object()
|
||||||
|
context_FCI = object()
|
||||||
|
recurse = object()
|
||||||
|
binary = object()
|
||||||
|
number = object()
|
||||||
|
ascii = object()
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
None: {
|
||||||
|
0x62: (recurse, "File Control Parameters", context_FCP),
|
||||||
|
0x64: (recurse, "File Management Data", context_FMD),
|
||||||
|
0x6F: (recurse, "File Control Information", context_FCI),
|
||||||
|
0x80: (number, "Number of data bytes in the file, excluding structural information"),
|
||||||
|
0x81: (number, "Number of data bytes in the file, including structural information"),
|
||||||
|
0x82: (binary, "File descriptor byte"),
|
||||||
|
0x83: (binary, "File identifier"),
|
||||||
|
0x84: (binary, "DF name"),
|
||||||
|
0x85: (binary, "Proprietary information"),
|
||||||
|
0x86: (binary, "Security attributes"),
|
||||||
|
0x87: (binary, "Identifier of an EF containing an extension of the FCI"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def tvl_unpack(data):
|
||||||
|
tag = ord(data[0])
|
||||||
|
length = ord(data[1])
|
||||||
|
value = data[2:(2+length)]
|
||||||
|
rest = data[(2+length):]
|
||||||
|
|
||||||
|
return tag, length, value, rest
|
||||||
|
|
||||||
|
def decode(data, context = None, level = 0):
|
||||||
|
result = []
|
||||||
|
while len(data) > 0:
|
||||||
|
tag, length, value, data = tvl_unpack(data)
|
||||||
|
|
||||||
|
interpretation = tags.get(context, tags.get(None, {})).get(tag, (binary, "Unknown"))
|
||||||
|
current = ["\t"*level]
|
||||||
|
current.append("Tag 0x%02X, Len 0x%02X, '%s':" % (tag, length, interpretation[1]))
|
||||||
|
|
||||||
|
if interpretation[0] is recurse:
|
||||||
|
current.append("\n")
|
||||||
|
current.append( decode(value, interpretation[2], level+1) )
|
||||||
|
elif interpretation[0] is number:
|
||||||
|
num = 0
|
||||||
|
for i in value:
|
||||||
|
num = num * 256
|
||||||
|
num = num + ord(i)
|
||||||
|
current.append( " 0x%02x (%i)" % (num, num))
|
||||||
|
elif interpretation[0] is ascii:
|
||||||
|
current.append( " %s" % value)
|
||||||
|
elif interpretation[0] is binary:
|
||||||
|
current.append( " %s" % utils.hexdump(value, short=True))
|
||||||
|
|
||||||
|
result.append( "".join(current) )
|
||||||
|
|
||||||
|
return "\n".join(result)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test = binascii.unhexlify("".join(("6f 2b 83 02 2f 00 81 02 01 00 82 03 05 41 26 85" \
|
||||||
|
+"02 01 00 86 18 60 00 00 00 ff ff b2 00 00 00 ff" \
|
||||||
|
+"ff dc 00 00 00 ff ff e4 10 00 00 ff ff").split()))
|
||||||
|
|
||||||
|
decoded = decode(test)
|
||||||
|
print decoded
|
|
@ -20,7 +20,6 @@ class Card:
|
||||||
STATUS_WORDS = {
|
STATUS_WORDS = {
|
||||||
SW_OK: "Normal execution",
|
SW_OK: "Normal execution",
|
||||||
'61??': "%(SW2)i (0x%(SW2)02x) bytes of response data can be retrieved with GetResponse.",
|
'61??': "%(SW2)i (0x%(SW2)02x) bytes of response data can be retrieved with GetResponse.",
|
||||||
'6700': "Wrong length",
|
|
||||||
'6C??': "Bad value for LE, 0x%(SW2)02x is the correct value.",
|
'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)
|
'63C?': lambda SW1,SW2: "The counter has reached the value '%i'" % (SW2%16)
|
||||||
}
|
}
|
||||||
|
@ -37,6 +36,7 @@ class Card:
|
||||||
self._i = 0
|
self._i = 0
|
||||||
self.last_apdu = None
|
self.last_apdu = None
|
||||||
self.last_sw = None
|
self.last_sw = None
|
||||||
|
self.last_result = None
|
||||||
self.sw_changed = False
|
self.sw_changed = False
|
||||||
|
|
||||||
def verify_pin(self, pin_number, pin_value):
|
def verify_pin(self, pin_number, pin_value):
|
||||||
|
@ -95,6 +95,7 @@ class Card:
|
||||||
print "Ending transaction %i\n%s\n" % (self._i, '-'*80)
|
print "Ending transaction %i\n%s\n" % (self._i, '-'*80)
|
||||||
self._i = self._i + 1
|
self._i = self._i + 1
|
||||||
|
|
||||||
|
self.last_result = result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def can_handle(cls, card):
|
def can_handle(cls, card):
|
||||||
|
|
15
utils.py
15
utils.py
|
@ -292,21 +292,6 @@ class R_APDU(APDU):
|
||||||
"Return this APDU as a binary string"
|
"Return this APDU as a binary string"
|
||||||
return self.data + self.sw
|
return self.data + self.sw
|
||||||
|
|
||||||
|
|
||||||
class TPDU:
|
|
||||||
"Base class for TPDUs"
|
|
||||||
|
|
||||||
def __init__(self, apdu):
|
|
||||||
self.apdu = apdu
|
|
||||||
|
|
||||||
class TPDU_T0(TPDU):
|
|
||||||
"Class for a T=0 TPDU"
|
|
||||||
protocol = 0
|
|
||||||
|
|
||||||
class TPDU_T1(TPDU):
|
|
||||||
"Class for T=1 TPDU"
|
|
||||||
protocol = 1
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
response = """
|
response = """
|
||||||
0000: 07 A0 00 00 00 03 00 00 07 00 07 A0 00 00 00 62 ...............b
|
0000: 07 A0 00 00 00 03 00 00 07 00 07 A0 00 00 00 62 ...............b
|
||||||
|
|
Loading…
Reference in New Issue