scriptor 4.71 KB
Newer Older
1
#!/usr/bin/env perl
Lionel Victor's avatar
Lionel Victor committed
2

3 4
#    scriptor.pl: text interface to send APDU commands to a smart card
#    Copyright (C) 2001  Lionel Victor
5
#             2002-2008  Ludovic Rousseau
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Lionel Victor's avatar
Lionel Victor committed
21
use Getopt::Std;
22 23
use Chipcard::PCSC;
use Chipcard::PCSC::Card;
Lionel Victor's avatar
Lionel Victor committed
24 25

use strict;
26
use warnings;
Lionel Victor's avatar
Lionel Victor committed
27 28 29

my %options;

30
my $hContext = new Chipcard::PCSC();
Lionel Victor's avatar
Lionel Victor committed
31 32 33
my $hCard;
my @out_buffer;
my $in_buffer;
34
my $echo;
Lionel Victor's avatar
Lionel Victor committed
35

36
die ("Could not create Chipcard::PCSC object: $Chipcard::PCSC::errno\n") unless defined $hContext;
Lionel Victor's avatar
Lionel Victor committed
37

38
getopt ("r:p:" , \%options);
Lionel Victor's avatar
Lionel Victor committed
39 40

if ($options{h}) {
41 42 43 44 45 46
	print "Usage: $0 [-h] [-r reader] [-p protocol] [file]\n";
	print "          -h: this help\n";
	print "   -r reader: specify to use the PCSC smart card reader named reader\n";
	print "              By defaults the first one found is used so you\n";
	print "              don't have to specify anything if you just have\n";
	print "              one reader\n";
47 48
	print " -p protocol: protocol to use among T=0 and T=1.\n";
	print "              Default is to let pcsc-lite choose the protocol\n";
49
	print "        file: file containing APDUs\n";
Lionel Victor's avatar
Lionel Victor committed
50 51 52
	exit (0);
}

53 54 55
# protocol option
if ($options{p}) {
	if ($options{p} =~ m/T=0/) {
56
		print STDERR "Trying T=0 protocol\n";
57 58 59
		$options{p} = $Chipcard::PCSC::SCARD_PROTOCOL_T0;
	} else {
		if ($options{p} =~ m/T=1/) {
60
			print STDERR "Trying T=1 protocol\n";
61 62 63 64 65 66
			$options{p} = $Chipcard::PCSC::SCARD_PROTOCOL_T1;
		} else {
			die "unknown protocol: $options{p}\n";
		}
	}
} else {
67
	$options{p} = $Chipcard::PCSC::SCARD_PROTOCOL_T0 | $Chipcard::PCSC::SCARD_PROTOCOL_T1;
68 69 70
}

# reader option
Lionel Victor's avatar
Lionel Victor committed
71
if ($options{r}) {
72
	print STDERR "Using given card reader: $options{r}\n";
Lionel Victor's avatar
Lionel Victor committed
73 74
} else {
	my @readers_list = $hContext->ListReaders ();
75
	die ("Can't get readers list\n") unless defined $readers_list[0];
76
	print STDERR "No reader given: using $readers_list[0]\n";
77
	$options{r} = $readers_list[0];
Lionel Victor's avatar
Lionel Victor committed
78 79
}

80
$hCard = new Chipcard::PCSC::Card ($hContext, $options{r}, $Chipcard::PCSC::SCARD_SHARE_SHARED, $options{p});
81 82
die ("Can't allocate Chipcard::PCSC::Card object: $Chipcard::PCSC::errno\n") unless defined $hCard;

83 84 85 86 87 88 89 90 91 92 93
if ($hCard->{dwProtocol} == $Chipcard::PCSC::SCARD_PROTOCOL_T0) {
	print "Using T=0 protocol\n";
} else {
	if ($hCard->{dwProtocol} == $Chipcard::PCSC::SCARD_PROTOCOL_T1) {
		print "Using T=1 protocol\n";
	}
	else {
		print "Using an unknown protocol (not T=0 or T=1)\n";
	}
}

94
# file option
Lionel Victor's avatar
Lionel Victor committed
95
if ($ARGV[0]) {
96 97
	open (IN_FILEHANDLE, "<$ARGV[0]") or die ("Can't open $ARGV[0]: $!\n");
	print STDERR "Using given file: $ARGV[0]\n";
98
	$echo=1;
Lionel Victor's avatar
Lionel Victor committed
99 100 101
} else {
	*IN_FILEHANDLE = *STDIN;
	print STDERR "Reading commands from STDIN\n";
102
	$echo=0;
Lionel Victor's avatar
Lionel Victor committed
103 104 105 106
}

*OUT_FILEHANDLE = *STDOUT;

107
my $cmd;
108
my $match = ".. " x 16;
Lionel Victor's avatar
Lionel Victor committed
109 110
while (<IN_FILEHANDLE>) {
	my $tmp_value;
111
	my ($SendData, $RecvData, $sw);
Lionel Victor's avatar
Lionel Victor committed
112

113
	print if ($echo);
114
	last if /exit/i;
Lionel Victor's avatar
Lionel Victor committed
115 116 117
	next if /^\s*$/;
	next if /^#/;

118
	if (/reset/i) {
119
		print OUT_FILEHANDLE "> RESET\n";
120
		if (defined $hCard->Reconnect ($Chipcard::PCSC::SCARD_SHARE_SHARED,
121
		                   $options{p},
122
						   $Chipcard::PCSC::SCARD_RESET_CARD)) {
123 124 125 126
			my @s = $hCard->Status();
			print OUT_FILEHANDLE "< OK: ";
			print map { sprintf ("%02X ", $_) } @{$s[3]};
			print OUT_FILEHANDLE "\n";
127
		} else {
128
			print OUT_FILEHANDLE "< KO: $Chipcard::PCSC::errno\n";
129 130 131
		}
		next;
	}
132
	chomp;
133 134 135

	# if the command does not contains spaces (00A4030000) we expand it
	s/(..)/$1 /g if (! m/ /);
136 137 138 139 140 141 142 143 144 145 146

	# continue if line ends in \
	if (m/\\$/)
	{
		chop;	# remove the \
		s/ *$/ /;	# replace any spaces by ONE space
		$cmd .= $_;
		next;	# read next line
	}

	$cmd .= $_;
147 148

	# convert in an array (internal format)
149
	$SendData = Chipcard::PCSC::ascii_to_array($cmd);
150 151 152

	print OUT_FILEHANDLE "> $cmd\n";
	$RecvData = $hCard->Transmit($SendData);
153
	die ("Can't get info: $Chipcard::PCSC::errno\n") unless defined $RecvData;
154
	my $res = Chipcard::PCSC::array_to_ascii($RecvData);
155 156
	$sw = Chipcard::PCSC::Card::ISO7816Error(substr($res, -5));
	$res =~ s/($match)/$1\n/g;
157
	print OUT_FILEHANDLE "< $res : $sw\n";
158 159 160

	# empty the command
	$cmd = "";
Lionel Victor's avatar
Lionel Victor committed
161 162 163
}

close (IN_FILEHANDLE);
164
$hCard->Disconnect($Chipcard::PCSC::SCARD_LEAVE_CARD);
Lionel Victor's avatar
Lionel Victor committed
165 166 167 168
$hCard = undef;
$hContext = undef;

# End of File
169