From 25635cb025ecf710364ba689e06517ffbbe9b35c Mon Sep 17 00:00:00 2001 From: oepen Date: Tue, 26 Jul 2011 11:10:06 +0000 Subject: [PATCH] -Removed unused code from utils.py -Added a unit test for case 2 extended length APDUs git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@436 96b47cad-a561-4643-ad3b-153ac7d7599c --- .../src/vpicc/virtualsmartcard/utils.py | 230 ++---------------- 1 file changed, 16 insertions(+), 214 deletions(-) diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/utils.py b/virtualsmartcard/src/vpicc/virtualsmartcard/utils.py index 0041aa6..66fb053 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/utils.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/utils.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License along with # virtualsmartcard. If not, see . # -import string, binascii, sys, re, getopt +import string, binascii def stringtoint(str): # {{{ #i = len(str) - 1 @@ -51,42 +51,6 @@ def inttostring(i, length=None): # {{{ return str # }}} -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 >> 1 - 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, value, 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, linelen = 16, offset = 0): """Generates a nice hexdump of data and returns it. Consecutive lines will @@ -285,7 +249,7 @@ class C_APDU(APDU): def parse(self, apdu): "Parse a full command APDU and assign the values to our object, overwriting whatever there was." - + print apdu apdu = map( lambda a: (isinstance(a, str) and (ord(a),) or (a,))[0], apdu) apdu = apdu + [0] * max(4-len(apdu), 0) @@ -361,7 +325,12 @@ class C_APDU(APDU): buffer.append(self.data) if hasattr(self, "_Le"): - buffer.append(chr(self.Le)) + if self.__extended_length: + buffer.append(chr(0x00)) + buffer.append(chr(self.Le>>8)) + buffer.append(chr(self.Le - self.Le>>8)) + else: + buffer.append(chr(self.Le)) return "".join(buffer) @@ -377,132 +346,8 @@ class C_APDU(APDU): return 3 else: return 4 + - _apduregex = re.compile(r'^\s*([0-9a-f]{2}\s*){4,}$', re.I) - _fancyapduregex = re.compile(r'^\s*([0-9a-f]{2}\s*){4,}\s*((xx|yy)\s*)?(([0-9a-f]{2}|:|\)|\(|\[|\])\s*)*$', re.I) - @staticmethod - def parse_fancy_apdu(*args): - apdu_string = " ".join(args) - if not C_APDU._fancyapduregex.match(apdu_string): - raise ValueError - - apdu_string = apdu_string.lower() - have_le = False - pos = apdu_string.find("xx") - if pos == -1: - pos = apdu_string.find("yy") - have_le = True - - apdu_head = "" - apdu_tail = apdu_string - if pos != -1: - apdu_head = apdu_string[:pos] - apdu_tail = apdu_string[pos+2:] - - if apdu_head.strip() != "" and not C_APDU._apduregex.match(apdu_head): - raise ValueError - - class Node(list): - def __init__(self, parent = None, type = None): - list.__init__(self) - self.parent = parent - self.type = type - - def make_binary(self): - "Recursively transform hex strings to binary" - for index, child in enumerate(self): - if isinstance(child,str): - child = "".join( ("".join(child.split())).split(":") ) - assert len(child) % 2 == 0 - self[index] = binascii.a2b_hex(child) - else: - child.make_binary() - - def calculate_lengths(self): - "Recursively calculate lengths and insert length counts" - self.length = 0 - index = 0 - while index < len(self): ## Can't use enumerate() due to the insert() below - child = self[index] - - if isinstance(child,str): - self.length = self.length + len(child) - else: - child.calculate_lengths() - - formatted_len = binascii.a2b_hex("%02x" % child.length) ## FIXME len > 255? - self.length = self.length + len(formatted_len) + child.length - self.insert(index, formatted_len) - index = index + 1 - - index = index + 1 - - def flatten(self, offset = 0, ignore_types=["("]): - "Recursively flatten, gather list of marks" - string_result = [] - mark_result = [] - for child in self: - if isinstance(child,str): - string_result.append(child) - offset = offset + len(child) - else: - start = offset - child_string, child_mark = child.flatten(offset, ignore_types) - string_result.append(child_string) - offset = end = offset + len(child_string) - if not child.type in ignore_types: - mark_result.append( (child.type, start, end) ) - mark_result.extend(child_mark) - - return "".join(string_result), mark_result - - - tree = Node() - current = tree - allowed_parens = {"(": ")", "[":"]"} - - for pos,char in enumerate(apdu_tail): - if char in (" ", "a", "b", "c", "d", "e", "f",":") or char.isdigit(): - if len(current) > 0 and isinstance(current[-1],str): - current[-1] = current[-1] + char - else: - current.append(str(char)) - - elif char in allowed_parens.values(): - if current.parent is None: - raise ValueError - if allowed_parens[current.type] != char: - raise ValueError - - current = current.parent - - elif char in allowed_parens.keys(): - current.append( Node(current, char) ) - current = current[-1] - - else: - raise ValueError - - if current != tree: - raise ValueError - - tree.make_binary() - tree.calculate_lengths() - - apdu_head = apdu_head.strip() - if apdu_head != "": - l = tree.length - if have_le: - l = l - 1 ## FIXME Le > 255? - formatted_len = "%02x" % l ## FIXME len > 255? - apdu_head = binascii.a2b_hex("".join( (apdu_head + formatted_len).split() )) - - apdu_tail, marks = tree.flatten(offset=0) - - apdu = C_APDU(apdu_head + apdu_tail, marks = marks) - return apdu - - class R_APDU(APDU): "Class for a response APDU" @@ -534,56 +379,6 @@ class R_APDU(APDU): return self.data + self.sw 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]) - a = C_APDU(1,2,3,4) # case 1 b = C_APDU(1,2,3,4,5) # case 2 c = C_APDU((1,2,3), cla=0x23, data="hallo") # case 3 @@ -618,3 +413,10 @@ if __name__ == "__main__": print for i in e, f: print hexdump(i.render()) + + g = C_APDU(0x00, 0xb0, 0x9c, 0x00, 0x00, 0x00, 0x00) # case 2 extended length + + print + print g + print repr(g) + print hexdump(g.render())