|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of the License "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 #!/bin/perl |
|
17 |
|
18 # Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
19 # All rights reserved. |
|
20 # This component and the accompanying materials are made available |
|
21 # under the terms of the License "Symbian Foundation License v1.0" |
|
22 # which accompanies this distribution, and is available |
|
23 # at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html". |
|
24 # |
|
25 # Initial Contributors: |
|
26 # Nokia Corporation - initial contribution. |
|
27 # |
|
28 # Contributors: |
|
29 # |
|
30 # Description: |
|
31 # Imports ASN.1 files into a format that may be used by dergen.pl by |
|
32 # de-compiing the data using dumpasn1. |
|
33 # |
|
34 # |
|
35 |
|
36 use strict; |
|
37 use Getopt::Long; |
|
38 |
|
39 my $DEBUG = 0; |
|
40 my $TABS = ""; |
|
41 my $OUTPUT_BUFFER = ""; |
|
42 |
|
43 main(); |
|
44 exit; |
|
45 |
|
46 sub main() { |
|
47 my $out; |
|
48 my $outFh; |
|
49 my $in; |
|
50 my @lines; |
|
51 |
|
52 GetOptions('debug=i' => \$DEBUG, |
|
53 'in=s' => \$in, |
|
54 'out=s' => \$out); |
|
55 |
|
56 if (! defined $in && defined $ARGV[0]) { |
|
57 $in = $ARGV[0]; |
|
58 } |
|
59 |
|
60 if (defined $in) { |
|
61 @lines = decompile($in); |
|
62 } |
|
63 else { |
|
64 die "No input file specified.\n"; |
|
65 } |
|
66 |
|
67 if (! defined $out && defined $ARGV[1]) { |
|
68 $out = $ARGV[1]; |
|
69 } |
|
70 if (defined $out) { |
|
71 open $outFh, ">$out" || die "Cannot open output file $out"; |
|
72 } |
|
73 else { |
|
74 $outFh = *STDOUT; |
|
75 } |
|
76 translate(\@lines); |
|
77 print $outFh $OUTPUT_BUFFER; |
|
78 } |
|
79 |
|
80 sub translate($) { |
|
81 my ($lines) = @_; |
|
82 my $lineCount = scalar(@$lines); |
|
83 |
|
84 for (my $i = 0; $i < $lineCount; ++$i) { |
|
85 $_ = @$lines[$i]; |
|
86 s/^\s*//g; |
|
87 s/\n//g; |
|
88 |
|
89 if ($DEBUG >= 3) { |
|
90 print "$_\n"; |
|
91 } |
|
92 |
|
93 if ( /^OBJECT\s+IDENTIFIER\s*$/ ) { |
|
94 if ($DEBUG >= 3) { |
|
95 print "reading OID value from next line\n"; |
|
96 } |
|
97 if (defined @$lines[$i+1]) { |
|
98 $_ .= @$lines[++$i]; |
|
99 } |
|
100 } |
|
101 |
|
102 if ( /BIT\s+STRING,\s+encapsulates/i ) { |
|
103 addToOutput("BITSTRING_WRAPPER"); |
|
104 nest(); |
|
105 } |
|
106 elsif ( /^\s*BIT\s+STRING/i ) { |
|
107 # bitstring defined in binary |
|
108 if ( $$lines[$i+1] =~ /\'([01]+)\'/ ) { |
|
109 $i++; |
|
110 addToOutput("BITSTRING=$1"); |
|
111 } |
|
112 # bit string defined in hex |
|
113 elsif ( /^\s*BIT\s+STRING\s+(([A-F0-9][A-F0-9]\s*)+)/i ) { |
|
114 my $bitStr = toBitString($1); |
|
115 addToOutput("BITSTRING=$bitStr"); |
|
116 } |
|
117 else { |
|
118 # bit string wrapper |
|
119 addToOutput("BITSTRING_WRAPPER"); |
|
120 nest(); |
|
121 addToOutput("RAW \{"); |
|
122 nest(); |
|
123 $i++; |
|
124 addToOutput(getRawHex($lines,\$i)); |
|
125 leaveNest(); |
|
126 addToOutput(" \}"); |
|
127 leaveNest(); |
|
128 addToOutput("END"); |
|
129 } |
|
130 } |
|
131 elsif ( /^(BMPSTRING\s+)\'(.*)\'/i ) { |
|
132 addToOutput("BMPSTRING=$2"); |
|
133 } |
|
134 elsif ( /^(BOOLEAN\s+)(.*)/i ) { |
|
135 addToOutput("BOOLEAN=$2"); |
|
136 } |
|
137 elsif ( /(^ENUMERATED\s+)(\d+)*$/i ) { |
|
138 # small integer - non hex incoded |
|
139 addToOutput("ENUMERATED=$2"); |
|
140 } |
|
141 elsif ( /^\[(\d+)\]\s*\'(.*)\'/ ) { |
|
142 addToOutput("IMPLICIT=$1"); |
|
143 nest(); |
|
144 addToOutput("PRINTABLESTRING=$2"); |
|
145 leaveNest(); |
|
146 addToOutput("END"); |
|
147 } |
|
148 elsif ( /^\[(\d+)\]/ ) { |
|
149 # general case for implicit & explicit tags |
|
150 my $tag=$1; |
|
151 if (defined @$lines[$i+1] && isRawData(@$lines[$i+1])) { |
|
152 # if there is only raw data assume implicit |
|
153 addToOutput("IMPLICIT=$tag"); |
|
154 nest(); |
|
155 addToOutput("OCTETSTRING"); |
|
156 nest(); |
|
157 addToOutput("RAW \{"); |
|
158 while (isRawData(@$lines[++$i])) { |
|
159 addToOutput("" . @$lines[$i] . ""); |
|
160 } |
|
161 --$i; |
|
162 addToOutput("\}"); |
|
163 leaveNest(); |
|
164 addToOutput("END"); |
|
165 leaveNest(); |
|
166 addToOutput("END"); |
|
167 leaveNest(); |
|
168 } |
|
169 else { |
|
170 # otherwise assume explicit |
|
171 addToOutput("EXPLICIT=$tag"); |
|
172 } |
|
173 nest(); |
|
174 } |
|
175 elsif ( /^(IA5STRING\s+)\'(.*)\'/i ) { |
|
176 addToOutput("IA5STRING=$2"); |
|
177 } |
|
178 elsif ( /(^INTEGER\s+)(\d+)*$/i ) { |
|
179 # small integer - non hex incoded |
|
180 addToOutput("INTEGER=$2"); |
|
181 } |
|
182 elsif (/^INTEGER/) { |
|
183 # big integer |
|
184 addToOutput("BIGINTEGER {"); |
|
185 my $tmp = $_; |
|
186 $tmp =~ s/.*INTEGER\s+//g; |
|
187 nest(); |
|
188 if (isRawData($tmp)) { |
|
189 addToOutput($tmp); |
|
190 } |
|
191 |
|
192 $i++; |
|
193 addToOutput(getRawHex($lines,\$i)); |
|
194 leaveNest(); |
|
195 addToOutput("\}"); |
|
196 } |
|
197 elsif ( /^NULL/i ) { |
|
198 addToOutput("NULL"); |
|
199 } |
|
200 elsif ( /^OCTET STRING\s*$/i ) { |
|
201 $i++; |
|
202 addToOutput("OCTETSTRING"); |
|
203 nest(); |
|
204 addToOutput("RAW \{"); |
|
205 nest(); |
|
206 addToOutput(getRawHex($lines,\$i)); |
|
207 leaveNest(); |
|
208 addToOutput("\}"); |
|
209 leaveNest(); |
|
210 addToOutput("END"); |
|
211 } |
|
212 elsif ( /^OCTET\s+STRING.*encapsulates/i ) { |
|
213 addToOutput("OCTETSTRING"); |
|
214 nest(); |
|
215 } |
|
216 elsif ( /^OCTET\s+STRING/i ) { |
|
217 addToOutput("OCTETSTRING"); |
|
218 nest(); |
|
219 my $hex = $_; |
|
220 $hex =~ s/OCTET\s+STRING\s+//g; |
|
221 addToOutput("RAW=$hex"); |
|
222 leaveNest(); |
|
223 addToOutput("END"); |
|
224 } |
|
225 elsif ( /^OBJECT\s+IDENTIFIER\s+\'([\d ]+)\'/i ) { |
|
226 # plain oid |
|
227 my $oid = $1; |
|
228 $oid =~ s/ /./g; |
|
229 addToOutput("OID=$oid"); |
|
230 } |
|
231 elsif ( /(^OBJECT\s+IDENTIFIER.*\()([\d ]+)/i ) { |
|
232 # extra information printed with oid |
|
233 my $oid = $2; |
|
234 $oid =~ s/ /./g; |
|
235 addToOutput("OID=$oid"); |
|
236 } |
|
237 elsif ( /(^PRINTABLESTRING\s*\')([^\']*)/i ) { |
|
238 addToOutput("PRINTABLESTRING=$2"); |
|
239 } |
|
240 elsif ( /^SEQUENCE/i ) { |
|
241 addToOutput("SEQUENCE"); |
|
242 nest(); |
|
243 } |
|
244 elsif ( /^SET/i ) { |
|
245 addToOutput("SET"); |
|
246 nest(); |
|
247 } |
|
248 elsif (/^(UTCTIME\s+\')([^\']+)/i) { |
|
249 addToOutput("UTCTIME=$2"); |
|
250 } |
|
251 elsif ( /^(UTF8STRING\s+)\'(.*)\'/i ) { |
|
252 addToOutput("UTF8STRING=$2"); |
|
253 } |
|
254 elsif ( /^\}/) { |
|
255 leaveNest(); |
|
256 addToOutput("END"); |
|
257 } |
|
258 elsif (isRawData($_)) { |
|
259 my $raw = s/\s+/ /g; |
|
260 addToOutput("RAW=$_"); |
|
261 } |
|
262 |
|
263 } |
|
264 } |
|
265 |
|
266 sub addToOutput($) { |
|
267 my ($text) = @_; |
|
268 |
|
269 if ($DEBUG >= 3) { |
|
270 print "+${TABS}$text\n"; |
|
271 } |
|
272 $OUTPUT_BUFFER .= "${TABS}$text\n"; |
|
273 } |
|
274 |
|
275 sub getRawHex($) { |
|
276 my ($lines,$index) = @_; |
|
277 my $translated = ''; |
|
278 |
|
279 my $end = 0; |
|
280 do { |
|
281 my $line = $$lines[$$index]; |
|
282 last if (!defined $line); |
|
283 chomp($line); |
|
284 |
|
285 if (isRawData($line)) { |
|
286 $line =~ s/^\s+//g; |
|
287 addToOutput("$line"); |
|
288 $$index++; |
|
289 } |
|
290 else { |
|
291 $$index--; |
|
292 $end = 1; |
|
293 } |
|
294 } while (! $end); |
|
295 return $translated; |
|
296 } |
|
297 |
|
298 sub isRawData() { |
|
299 my ($line) = @_; |
|
300 my $retVal = ($line =~ /^\s*([A-F0-9][A-F0-9]\s?)+$/i); |
|
301 if ($DEBUG >= 3 && $retVal) { |
|
302 print "RAW: "; |
|
303 } |
|
304 return $retVal; |
|
305 } |
|
306 |
|
307 sub toBitString() { |
|
308 my ($hex) = @_; |
|
309 my $bitStr = ""; |
|
310 $hex =~ s/\s//g; |
|
311 |
|
312 for (my $i=0; $i < length($hex); $i+=2) { |
|
313 my $num = hex(substr($hex, $i, 2)); |
|
314 print ".$num"; |
|
315 for (my $j=0; $j < 8; $j++) { |
|
316 $bitStr .= ($num & 0x80) ? '1' : '0'; |
|
317 $num <<= 1; |
|
318 } |
|
319 } |
|
320 if ($DEBUG >= 2) { |
|
321 print "\nbitStr: $hex = $bitStr\n"; |
|
322 } |
|
323 return $bitStr; |
|
324 } |
|
325 |
|
326 # increment debug tabbing level |
|
327 sub nest() { |
|
328 $TABS .= " "; |
|
329 } |
|
330 |
|
331 # decrement debug tabbing level |
|
332 sub leaveNest() { |
|
333 $TABS =~ s/^...//; |
|
334 } |
|
335 |
|
336 |
|
337 sub decompile($) { |
|
338 my ($inFile) = @_; |
|
339 |
|
340 |
|
341 my @command = ("cmd", |
|
342 "/C \"dumpasn1 -apruz $inFile > _dump.tmp\""); |
|
343 |
|
344 if ((my $err = system(@command)) != 0) { |
|
345 die "decode: " . join(" ", @command) . "\nreturned error $err"; |
|
346 } |
|
347 |
|
348 my $dumpFh; |
|
349 open $dumpFh, "_dump.tmp"; |
|
350 my @lines = <$dumpFh>; |
|
351 close $dumpFh; |
|
352 |
|
353 return @lines; |
|
354 } |