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