46fd63f4fe6dedfbc4302a4c69bc6b9991e9d110
[hexio] / derdump
1 #!/usr/bin/python
2
3 import sys
4
5 if len (sys.argv) != 2:
6         print 'Usage:  ' + sys.argv [0] + 'file.der'
7         print 'Output: MEANING: TAG ###CONTLEN @TAGOFS ^NESTING, CLASS, PRIMCONSTR'
8         sys.exit (1)
9
10 der = open (sys.argv [1], 'r').read (65537)
11 ofs = 0
12
13 def eof ():
14         global ofs, der
15         return ofs >= len (der)
16
17 def read1 ():
18         global ofs, der
19         if eof ():
20                 print 'ATTEMPTED READ BEYOND EOF (RETURNING 0x00)'
21                 return 0
22         else:
23                 ofs = ofs + 1
24                 return ord (der [ofs-1])
25
26 nesting = []
27
28 class2str = {
29         0: 'Universal',
30         1: 'Application',
31         2: 'Contextual',
32         3: 'Private'
33 }
34
35 pc2str = {
36         0: 'Primitive',
37         1: 'Constructed'
38 }
39
40 universal2str = {
41         0: 'End-Of-Content',
42         1: 'BOOLEAN',
43         2: 'INTEGER',
44         3: 'BITSTRING',
45         4: 'OCTETSTRING',
46         5: 'NULL',
47         6: 'OID',
48         7: 'Object-Descriptor',
49         8: 'EXTERNAL',
50         9: 'REAL',
51         10: 'ENUMERATED',
52         11: 'EMBEDDED PDV',
53         12: 'UTF8String',
54         13: 'RELATIVE-OID',
55         14: '*****',
56         15: '*****',
57         16: 'SEQUENCE (OF)',
58         17: 'SET (OF)',
59         18: 'NumericString',
60         19: 'PrintableString',
61         20: 'T61String',
62         21: 'VideotexString',
63         22: 'IA5String',
64         23: 'UTCTime',
65         24: 'GeneralizedTime',
66         25: 'GraphicString',
67         26: 'VisibleString',
68         27: 'GeneralString',
69         28: 'UniversalString',
70         29: 'CHARACTER STRING',
71         30: 'BMPString',
72         31: '*****'
73 }
74
75 while not eof ():
76
77         while nesting != [] and ofs >= nesting [-1]:
78                 if ofs > nesting [-1]:
79                         print 'READ OFFSET %d EXCEEDS ENCAPSULATION %d (RETURNING)' % (ofs, nesting [-1])
80                 ofs = nesting.pop ()
81
82         tag = read1 ()
83         tag_class = (tag & 0xc0) >> 6
84         tag_pc = (tag & 0x20) != 0
85         tag_num = tag & 0x1f
86
87         lenlen = read1 ()
88         if lenlen & 0x80 == 0:
89                 leng = lenlen
90                 lenlen = 1
91         else:
92                 lenlen = lenlen - 0x80 + 1
93                 leng = 0
94                 i = 1
95                 while i < lenlen:
96                         leng <<= 8
97                         leng = leng + read1 ()
98                         i = i + 1
99
100         if tag_class == 0:
101                 meaning = universal2str [tag_num]
102         elif tag_class == 1:
103                 meaning = '[APPLICATION ' + str (tag_num) + ']'
104         elif tag_class == 2:
105                 meaning = '[' + str (tag_num) + ']'
106         else:
107                 meaning = '[PRIVATE ' + str (tag_num) + ']'
108
109         print '%s%s: tag 0x%02x %s%d @%d ^%d, %s, %s' % (
110                         '  ' * len (nesting),
111                         meaning, tag,
112                         '#' * lenlen, leng,
113                         ofs - lenlen - 1,
114                         len (nesting),
115                         class2str [tag_class],
116                         pc2str [tag_pc] )
117
118         if tag_pc == 0 and leng > 0:
119                 print '  ' * ( len (nesting) + 1 ),
120                 cstr = '"'
121                 ival = None
122                 ostr = ''
123                 oval = None
124                 while leng > 0:
125                         ch = read1 ()
126                         print '%02x' % ch,
127                         if 32 <= ch < 127:
128                                 cstr = cstr + chr (ch)
129                         else:
130                                 cstr = cstr + '.'
131                         if ival is None:
132                                 ival = -1 if ch >= 128 else 0
133                         else:
134                                 ival = (ival << 8) | ch
135                         if oval is None:
136                                 ostr = str (ch / 40) + '.' + str (ch % 40)
137                                 oval = 0
138                         else:
139                                 oval = (oval << 7) | (ch & 0x7f)
140                                 if ch & 0x80 == 0:
141                                         ostr = ostr + '.' + str (oval)
142                                         oval = 0
143                         leng = leng - 1
144                 cstr = cstr + '"'
145                 if tag == 0x06:
146                         cstr = ostr
147                 elif tag == 0x02:
148                         cstr = str (ival)
149                 print '==', cstr
150
151         if tag_pc != 0:
152                 # print 'Now at', ofs, 'adding', leng, 'pushing', ofs + leng
153                 nesting.append (ofs + leng)
154
155 while nesting != []:
156         if ofs != nesting [-1]:
157                 print 'NESTING NOT ENDED CORRECTLY, OFFSET IS %d INSTEAD OF %d (CONTINUING)' % (ofs, nesting [-1])
158         nesting.pop ()
159