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