cryptoservices/certificateandkeymgmt/tder/importdumpasn1.pl
changeset 0 2c201484c85f
child 6 50f2ff6984be
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     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 }