nicer TLV parsing, (more ugly code)

git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@59 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
hploetz 2006-05-19 02:24:48 +00:00
parent 80c19becfa
commit 60c80e35c7
3 changed files with 112 additions and 2 deletions

View File

@ -8,6 +8,77 @@ binary = object()
number = object()
ascii = object()
file_descriptor_byte_descriptions = [
#byte mask no match match
(0x80, 0x80, None, "RFU"),
(0xC0, 0x40, "non shareable", "shareable"),
(0xB8, 0x00, None, "working EF"),
(0xB8, 0x08, None, "internal EF"),
(0xB8, 0x10, None, "Reserved for proprietary uses"),
(0xB8, 0x18, None, "Reserved for proprietary uses"),
(0xB8, 0x20, None, "Reserved for proprietary uses"),
(0xB8, 0x28, None, "Reserved for proprietary uses"),
(0xB8, 0x30, None, "Reserved for proprietary uses"),
(0xB8, 0x38, None, "DF"),
##(0x87, 0x00, None, "No EF structure information given"),
(0x87, 0x01, None, "Transparent"),
(0x87, 0x02, None, "Linear fixed, no further info"),
(0x87, 0x03, None, "Linear fixed, SIMPLE-TLV"),
(0x87, 0x04, None, "Linear variable, no further info"),
(0x87, 0x05, None, "Linear variable, SIMPLE-TLV"),
(0x87, 0x06, None, "Cyclic, no further info"),
(0x87, 0x07, None, "Cyclic, SIMPLE-TLV"),
]
data_coding_byte_descriptions = [
(0x60, 0x00, None, "one-time write"),
(0x60, 0x20, None, "proprietary"),
(0x60, 0x40, None, "write OR"),
(0x60, 0x60, None, "write AND"),
]
def decode_file_descriptor_byte(value, verbose = True):
result = " %s" % utils.hexdump(value, short=True)
if not verbose:
attributes = utils.parse_binary(ord(value[0]), file_descriptor_byte_descriptions, False)
if len(value) > 1:
attributes.append(
"data coding byte, behavior of write functions: %s, data unit size in in nibbles: %i" % (
"".join( utils.parse_binary(ord(value[1]), data_coding_byte_descriptions) ),
2 ** (ord(value[1])&0x07)
)
)
if len(value) > 2:
i = 0
for j in value[2:]:
i = i * 256 + ord(j)
attributes.append(
"maximum record length: %s" % i
)
return result + " (%s)" % "; ".join(attributes)
else:
result = result + "\nFile descriptor byte:\n"
result = result + "\t" + "\n\t".join(
utils.parse_binary(ord(value[0]), file_descriptor_byte_descriptions, True)
)
if len(value) > 1:
result = result + "\nData coding byte (0x%02X):\n" % ord(value[1])
result = result + "\tBehavior of write functions: %s\n\tData unit size in in nibbles: %i" % (
"".join( utils.parse_binary(ord(value[1]), data_coding_byte_descriptions) ),
2 ** (ord(value[1])&0x07)
)
if len(value) > 2:
i = 0
for j in value[2:]:
i = i * 256 + ord(j)
result = result + "\nMaximum record length: %s" % i
return result
tags = {
None: {
0x62: (recurse, "File Control Parameters", context_FCP),
@ -15,7 +86,7 @@ tags = {
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"),
0x82: (decode_file_descriptor_byte, "File descriptor byte"),
0x83: (binary, "File identifier"),
0x84: (binary, "DF name"),
0x85: (binary, "Proprietary information"),
@ -54,6 +125,8 @@ def decode(data, context = None, level = 0):
current.append( " %s" % value)
elif interpretation[0] is binary:
current.append( " %s" % utils.hexdump(value, short=True))
elif callable(interpretation[0]):
current.append( ("\n"+"\t"*(level+1)).join(interpretation[0](value).splitlines()) )
result.append( "".join(current) )
@ -66,3 +139,4 @@ if __name__ == "__main__":
decoded = decode(test)
print decoded

View File

@ -30,7 +30,7 @@ class ISO_7816_4_Card(Card):
def cmd_parsetlv(self):
"Decode the TLV data in the last response"
print TLV_utils.decode(self.last_result)
print TLV_utils.decode(self.last_result.data)
ATRS = list(Card.ATRS)
ATRS.extend( [

View File

@ -1,5 +1,41 @@
import pycsc, string, binascii, sys
def represent_binary_fancy(len, value, mask = 0):
result = []
for i in range(len):
if i%4 == 0:
result.append( " " )
if i%8 == 0:
result.append( " " )
if mask & 0x01:
result.append( str(value & 0x01) )
else:
result.append( "." )
mask = mask >> 1
value = value >> 2
result.reverse()
return "".join(result).strip()
def parse_binary(value, bytemasks, verbose = False, value_len = 8):
## Parses a binary structure and gives information back
## bytemasks is a sequence of (mask, value, string_if_no_match, string_if_match) tuples
result = []
for mask, byte, nonmatch, match in bytemasks:
if verbose:
prefix = represent_binary_fancy(value_len, byte, mask) + ": "
else:
prefix = ""
if (value & mask) == (byte & mask):
if match is not None:
result.append(prefix + match)
else:
if nonmatch is not None:
result.append(prefix + nonmatch)
return result
_myprintable = " " + string.letters + string.digits + string.punctuation
def hexdump(data, indent = 0, short = False):
r"""Generates a nice hexdump of data and returns it. Consecutive lines will