fix decoding of multi-byte tags
move parse_tlv to generic card git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@69 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
parent
b3b052df7f
commit
ac08ac1ff8
23
TLV_utils.py
23
TLV_utils.py
|
@ -179,14 +179,26 @@ tags = {
|
|||
0x87: (binary, "Identifier of an EF containing an extension of the FCI"),
|
||||
0x88: (binary, "Short EF identifier"),
|
||||
0x8A: (binary, "Life cycle status byte"),
|
||||
|
||||
0xA5: (recurse, "Proprietary information", None),
|
||||
},
|
||||
}
|
||||
|
||||
BER_CLASSES = {
|
||||
0x0: "universal",
|
||||
0x1: "application",
|
||||
0x2: "context-specific",
|
||||
0x3: "private",
|
||||
}
|
||||
|
||||
def tlv_unpack(data):
|
||||
ber_class = (ord(data[0]) & 0xC0) >> 6
|
||||
constructed = (ord(data[0]) & 0x20) != 0 ## 0 = primitive, 0x20 = constructed
|
||||
tag = ord(data[0])
|
||||
data = data[1:]
|
||||
if (tag & 0x1F) == 0x1F:
|
||||
tag = (tag << 8) | ord(data[0])
|
||||
data = data[1:]
|
||||
while ord(data[0]) & 0x80 == 0x80:
|
||||
tag = tag << 8 + ord(data[0])
|
||||
data = data[1:]
|
||||
|
@ -206,7 +218,7 @@ def tlv_unpack(data):
|
|||
value = data[:length]
|
||||
rest = data[length:]
|
||||
|
||||
return constructed, tag, length, value, rest
|
||||
return ber_class, constructed, tag, length, value, rest
|
||||
|
||||
def decode(data, context = None, level = 0):
|
||||
result = []
|
||||
|
@ -215,12 +227,15 @@ def decode(data, context = None, level = 0):
|
|||
data = data[1:]
|
||||
continue
|
||||
|
||||
constructed, tag, length, value, data = tlv_unpack(data)
|
||||
ber_class, constructed, tag, length, value, data = tlv_unpack(data)
|
||||
|
||||
interpretation = tags.get(context, tags.get(None, {})).get(tag, None)
|
||||
if interpretation is None:
|
||||
if not constructed: interpretation = (binary, "Unknown field")
|
||||
else: interpretation = (recurse, "Unknown structure", context)
|
||||
if not constructed: interpretation = [binary, "Unknown field"]
|
||||
else: interpretation = [recurse, "Unknown structure", context]
|
||||
|
||||
interpretation[1] = "%s (%s class)" % (interpretation[1], BER_CLASSES[ber_class])
|
||||
interpretation = tuple(interpretation)
|
||||
|
||||
current = ["\t"*level]
|
||||
current.append("Tag 0x%02X, Len 0x%02X, '%s':" % (tag, length, interpretation[1]))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import crypto_utils, utils, pycsc, binascii, fnmatch, sre
|
||||
import TLV_utils, crypto_utils, utils, pycsc, binascii, fnmatch, sre
|
||||
from utils import C_APDU, R_APDU
|
||||
|
||||
DEBUG = True
|
||||
|
@ -58,9 +58,14 @@ class Card:
|
|||
"""Reset the card."""
|
||||
self.card.reconnect(init=pycsc.SCARD_RESET_CARD)
|
||||
|
||||
def cmd_parsetlv(self):
|
||||
"Decode the TLV data in the last response"
|
||||
print TLV_utils.decode(self.last_result.data)
|
||||
|
||||
COMMANDS = {
|
||||
"reset": cmd_reset,
|
||||
"verify": cmd_verify
|
||||
"verify": cmd_verify,
|
||||
"parse_tlv": cmd_parsetlv,
|
||||
}
|
||||
|
||||
def _real_send(self, apdu):
|
||||
|
|
|
@ -95,10 +95,6 @@ class ISO_7816_4_Card(Card):
|
|||
print utils.hexdump(result.data)
|
||||
print TLV_utils.decode(result.data)
|
||||
|
||||
def cmd_parsetlv(self):
|
||||
"Decode the TLV data in the last response"
|
||||
print TLV_utils.decode(self.last_result.data)
|
||||
|
||||
ATRS = list(Card.ATRS)
|
||||
ATRS.extend( [
|
||||
(".*", None), ## For now we accept any card
|
||||
|
@ -110,7 +106,6 @@ class ISO_7816_4_Card(Card):
|
|||
"cd": cmd_cd,
|
||||
"cat": cmd_cat,
|
||||
"open": cmd_open,
|
||||
"parse_tlv": cmd_parsetlv,
|
||||
} )
|
||||
|
||||
STATUS_WORDS = dict(Card.STATUS_WORDS)
|
||||
|
|
Loading…
Reference in New Issue