#!/usr/bin/perl -w use strict; ($#ARGV==0) or die "usage $0: logfile"; $|=1; sub apdu { my ($dir, $buf) = @_; my %h2n = ( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 'a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15 ); $buf =~ s/^ //g; $buf =~ s/ $//g; $buf =~ s/ / /g; $buf =~ /^([0-9a-f]{2}) ([0-9a-f]{2}) ([0-9a-f])([0-9a-f]) (.*)/; my ($nad, $pcb, $l1, $l2, $rest) = ($1, $2, $3, $4, $5); my $l = $h2n{$l1} * 16 + $h2n{$l2}; my $match = "[0-9a-f]{2} " x $l; $rest =~ /($match)([0-9a-f]{2})/; my ($data, $edc) = ($1,$2); # print "$dir nad: $nad, pcb: $pcb, len: $l, data: $data, edc: $edc\n"; # print "buf: $buf\n"; unless ($nad =~ /00/) { print "NAD: $nad\n"; } if ($pcb =~ /00/ or $pcb =~ /40/) { our ($apdu, $more); my $hint = ""; $apdu .= $data; if ($dir eq "S") { $hint = "(append record)" if ($apdu =~ /^0. e2/); $hint = "(change reference data)" if ($apdu =~ /^0. 24/); $hint = "(change key)" if ($apdu =~ /^84 24/); $hint = "(create file)" if ($apdu =~ /^0. e0/); $hint = "(deactivate file)" if ($apdu =~ /^00 04/); $hint = "(decrease)" if ($apdu =~ /^8, 30/); $hint = "(delete file)" if ($apdu =~ /^0. e4/); $hint = "(directory)" if ($apdu =~ /^80 16/); $hint = "(erase files)" if ($apdu =~ /^84 06/); $hint = "(external authenticate)" if ($apdu =~ /^0. 82/); $hint = "(format)" if ($apdu =~ /^84 40/); $hint = "(get challenge)" if ($apdu =~ /^00 84/); $hint = "(get data)" if ($apdu =~ /^00 ca/); $hint = "(give random)" if ($apdu =~ /^80 86/); $hint = "(increase)" if ($apdu =~ /^8. 20/); $hint = "(initialize eeprom)" if ($apdu =~ /^8[04] 02/); $hint = "(initialize end)" if ($apdu =~ /^84 00/); $hint = "(internal authenticate)" if ($apdu =~ /^0. 88/); $hint = "(load executable)" if ($apdu =~ /^80 20/); $hint = "(mse)" if ($apdu =~ /^00 22/); $hint = "(personalize)" if ($apdu =~ /^8[04] 08/); $hint = "(phase control)" if ($apdu =~ /^80 10/); $hint = "(perform security operation)" if ($apdu =~ /^[01]. 2a/); $hint = "(put data)" if ($apdu =~ /^0. da/); $hint = "(reactivate file)" if ($apdu =~ /^00 44/); $hint = "(read binary)" if ($apdu =~ /^0. b0/); $hint = "(read record)" if ($apdu =~ /^0. b2/); $hint = "(reset retry counter)" if ($apdu =~ /^0. 2c/); $hint = "(reset security state)" if ($apdu =~ /^80 ea/); $hint = "(select file)" if ($apdu =~ /^00 a4/); $hint = "(uninstall package)" if ($apdu =~ /^80 e4/); $hint = "(update binary)" if ($apdu =~ /^0. d6/); $hint = "(update record)" if ($apdu =~ /^0. dc/); $hint = "(verify)" if ($apdu =~ /^0. 20/); } if ($apdu =~ /00 a4 04 0c 03 41 4b 53 00/) { $apdu .= " (AKS)"; } if ($apdu =~ /00 a4 04 00 04 05 04 02 00/) { $apdu .= " (Eutron)"; } $apdu =~ s/ $//g; $apdu =~ s/ +/:/g; print "$dir: $hint $apdu\n"; $apdu =""; $more = 0; } if ($pcb =~ /20/ or $pcb =~ /60/) { our ($apdu, $more); $apdu .= $data . " "; $more = 1; } if ($pcb =~ /91/) { print "$dir: EDC error\n"; } if ($pcb =~ /92/) { print "$dir: other error\n"; } if ($pcb =~ /c0/) { print "$dir: resynch req\n"; } if ($pcb =~ /e0/) { print "$dir: resynch resp\n"; } if ($pcb =~ /c1/) { print "$dir: ifsc req ($data)\n"; } if ($pcb =~ /e1/) { print "$dir: ifsc resp ($data)\n"; } if ($pcb =~ /c2/) { print "$dir: abort req\n"; } if ($pcb =~ /e2/) { print "$dir: abort resp\n"; } if ($pcb =~ /c3/) { print "$dir: wtx req\n"; } if ($pcb =~ /e3/) { print "$dir: wtx resp\n"; } } sub collect { my ($dir, $buf) = @_; our $init; return if (not $init and $buf =~ /^ 3b/); my %h2n = ( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 'a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15 ); $buf =~ s/^ //g; $buf =~ s/ $//g; $buf =~ s/ / /g; return unless ($buf); our $part; $part .= $buf . " "; if (not $init and $part =~ /^ff 11 94 7a/) { $init = 1; $part = ""; } $part =~ /^([0-9a-f]{2}) ([0-9a-f]{2}) ([0-9a-f])([0-9a-f]) (.*)/ or return; my ($nad, $pcb, $l1, $l2, $rest) = ($1, $2, $3, $4, $5); my $l = $h2n{$l1} * 16 + $h2n{$l2}; my $match = "[0-9a-f]{2} " x $l; $rest =~ /($match)([0-9a-f]{2})/ or return; apdu($dir, $part); $part=""; } sub setup_eval { my ($setup, $buffer) = @_; if ($setup =~ /^c0 86 00 00 00 00 [0-9a-f]{2} 00/) { apdu("R",$buffer); # etoken } elsif ($setup =~ /^40 06 00 00 00 00 [0-9a-f]{2} 00/) { apdu("S",$buffer); # etoken } elsif ($setup =~ /^40 0[1-3] 00 00 00 00 [0-9a-f]{2} 00/ or $setup =~ /^c0 8[1-3] 00 00 00 00 [0-9a-f]{2} 00/) { print "etoken special $setup\n"; print "buffer: $buffer\n" if ($buffer); } elsif ($setup =~ /^c1 02 00 00 00 00 [0-9a-f]{2} 00/) { collect("R",$buffer) if ($buffer); # eutron } elsif ($setup =~ /^42 01 00 00 00 00 [0-9a-f]{2} 00/) { apdu("S",$buffer) if ($buffer); # eutron } elsif ($setup =~ /^42 a1 00 00 00 00 [0-9a-f]{2} 00/) { collect("S",$buffer); # eutron } elsif ($setup =~ /^41 17 ([0-9a-f]{2} [0-9a-f]{2} [0-9a-f]{2} [0-9a-f]{2}) [0-9a-f]{2} [0-9a-f]{2}/) { apdu("S","$1 $buffer"); # ikey 3000 } elsif ($setup =~ /^c1 01 00 00 00 00 [0-9a-f]{2} 00/) { if ($buffer eq "00") { # ikey 3000 init sequence print "unknown setup $setup\n"; print "buffer: $buffer\n" if ($buffer); } else { apdu("R",$buffer); # ikey 3000 } } else { print "unknown setup $setup\n"; print "buffer: $buffer\n" if ($buffer); } } open LOGFILE,"<$ARGV[0]" or die "can't open $ARGV[0]: $!"; my $buffer; my $setup; my $final=0; while (my $line = ) { # usbsniff $line=$1 if ($line =~ /^[0-9]{8} [0-9]+\.[0-9]{8} (.*)/); # syslog $line=$1 if ($line =~/^[A-Za-z]{3} [ 0-9]{2} [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [a-z]* usbtoken\[[0-9]+\]: (.*)/); if ($line =~ /^Sending: [0-9a-f]{4}:([0-9a-f ]*)/) { # syslog $buffer .= $1; } if ($line =~ /^Received: [0-9a-f]{4}:([0-9a-f ]*)/) { # syslog $buffer .= $1; } if ($line =~ /^ [0-9a-f]{4}:([0-9a-f ]*)/) { # usbsniff $buffer .= $1; } if ($line =~ /usb_control: recv ([0-9a-f ]*)/) { # openct $buffer = $1; } if ($line =~ /usb_control: send ([0-9a-f ]*)/) { # openct setup_eval($setup, $1); $buffer=""; $setup=""; } if ($line =~ /^ SetupPacket : ([0-9a-f ]*)/) { # usbsniff $setup = $1; setup_eval($1, $buffer); $buffer=""; } if ($line =~ /usb xmit ([0-9a-f ]*)/) { # syslog my $new_setup = $1; setup_eval($setup, $buffer) if ($setup); $buffer=""; $setup = $new_setup; $final = 1; } if ($line =~ /usb_control: usb req type=x([0-9a-f]*) req=x([0-9a-f]*) val=x([0-9a-f]{2})([0-9a-f]*) ind=x([0-9a-f]{2})([0-9a-f]*) len=([0-9]*)/) { # openct if ($setup) { setup_eval($setup, $buffer); $buffer=""; } $setup = sprintf "%s %s %s %s %s %s %02x %02x", $1, $2, $4, $3, $6, $5, ($7%256), ($7/256); if ($buffer) { setup_eval($setup, $buffer); $setup=""; $buffer=""; } $final=1; } } if ($final) { setup_eval($setup, $buffer) if ($setup); } close LOGFILE; 0;