-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathtlv.py
132 lines (114 loc) · 3.02 KB
/
tlv.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/python
#
# Python TLV (as part of EMV Framework)
# Copyrigh 2012 Albert Puigsech Galicia <[email protected]>
#
# This code is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
TAG_CLASS_UNIVERSAL = 0x0
TAG_CLASS_APLICATION = 0x1
TAG_CLASS_CONTEXT_SPECIFIC= 0x2
TAG_CLASS_PRIVATE = 0x3
TAG_TYPE_PRIMITIVE = 0x0
TAG_TYPE_CONSTRUCTED = 0x1
TAG_SIZE_BIG_1 = 0x81
TAG_SIZE_BIG_2 = 0x82
class TAG:
def __init__(self, data=None, tags_db=None, content=True):
self.childs = []
self.root = False
self.code = None
self.name = None
self.type = None
self._class = None
self.extended = None
self.size = None
self.total_size = None
self.data = None
self.parsed_data = None
self.human_data = None
self.parse(data, tags_db, content)
def parse(self, data, tags_db, content):
if data == None:
return
size = len(data)
i = 0
if data[i]&0b00011111 == 0b00011111:
self.extended = True
else:
self.extended = False
self._class = (data[i]&0b11000000)>>6
self.type = (data[i]&0b00100000)>>5
if self.extended:
self.code = 256 * data[i] + data[i+1]
i += 2
else:
self.code = data[i]
i += 1
# Recursive extended size
if data[i] == TAG_SIZE_BIG_1:
self.size = data[i+1]
i += 2
elif data[i] == TAG_SIZE_BIG_2:
self.size = 256 * data[i+1] + data[i+2]
i += 3
else:
self.size = data[i]
i += 1
if content == True:
self.data = data[i:i+self.size]
i += self.size
if self.type == TAG_TYPE_CONSTRUCTED:
j = 0
while j < self.size:
tag = TAG(self.data[j:], tags_db)
self.childs.append(tag)
j += tag.total_size
key = '%x' % self.code
if tags_db != None and tags_db.has_key(key):
self.name = tags_db[key]['name']
if tags_db[key].has_key('parser') and tags_db[key]['parser'] != None:
d = tags_db[key]['parser'].split('.')
m = __import__ (d[0])
func = getattr(m,d[1])
func(self)
self.total_size = i
def list_childs(self, code=None):
if code == None:
return self.childs
ret = []
for c in self.childs:
if c.code == code:
ret.append(c)
return ret
def show(self, deep=0):
if self.root:
for c in self.childs:
c.show(deep)
else:
deep_str = deep*' '
print '%s%.2x [%.2x] - %s' % (deep_str, self.code, self.size, self.name)
if self.type == TAG_TYPE_PRIMITIVE and self.data != None:
print '%s ' % (deep_str),
for i in self.data:
print '%.2x' % (i),
print
if self.human_data != None:
print '%s ' % (deep_str),
print '( {0:s} )'.format(self.human_data)
deep += 1
for tag in self.childs:
tag.show(deep)
class TLV(TAG):
def parse(self, data, tags_db=None, content=True):
size = len(data)
self.root = True
self.type = TAG_TYPE_CONSTRUCTED
i = 0
while i < size:
tag = TAG(data[i:], tags_db, content)
self.childs.append(tag)
i += tag.total_size