/[pcsclite]/trunk/pcsc-tools/trunk/ATR_analysis
ViewVC logotype

Contents of /trunk/pcsc-tools/trunk/ATR_analysis

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3653 - (show annotations) (download)
Wed Oct 22 16:51:13 2003 UTC (9 years, 7 months ago) by rousseau
File size: 8704 byte(s)
typo
1 #!/usr/bin/perl
2
3 # ATR_analysis
4 # Copyright (C) 2000, 2002 Ludovic Rousseau, Christophe Levantis
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 # $Id: ATR_analysis,v 1.9 2003-10-22 16:51:13 rousseau Exp $
21
22 # For more information about the ATR see ISO 7816-3 1997, pages 12 and up
23 #
24 # TS initial character
25 # T0 format character, Y1 | K
26 # interfaces characters
27 # TA(1) global, codes FI and DI
28 # TB(1) global, codes II and PI
29 # TC(1) global, codes N
30 # TD(1) codes Y(2) and T
31 # TA(2) global, codes specific mode
32 # TB(2) global, codes PI2
33 # TC(2) specific
34 # TD(2) codes Y(3) and T
35 # TA(3) TA(i), TB(i), TC(i) (i>2)
36 # - specific after T!=15
37 # - global after T=15
38 # TD(i) codes Y(i+1) and T
39 # T1 historical bytes
40 # max 15 characters
41 # TK
42 # TCK check character
43
44 use strict;
45 use warnings;
46 use Getopt::Std;
47
48 # file containing the smart card models
49 my $SMARTCARD_LIST = "smartcard_list.txt";
50 # where to look for $SMARTCARD_LIST
51 my @LIST_PATH = qw(. /usr/local/pcsc /usr/lib/pcsc);
52
53 our ($opt_v, $opt_h);
54 my ($atr, %TS, @Fi, @Di, @XI, @UI, $T, $value, $counter, $line);
55 my ($Y1, $K, @object, $nb_bytes, $mpcard);
56
57 # tables
58 %TS = (0x3B, "Direct Convention", 0x3F, "Inverse Convention");
59 @Fi = (372, 372, 558, 744, 1116, 1488, 1860, "RFU", "RFU", 512, 768, 1024,
60 1536, 2048, "RFU", "RFU");
61 @Di = ("RFU", 1, 2, 4, 8, 16, 32, "RFU", 12, 20, "RFU", "RFU", "RFU",
62 "RFU", "RFU", "RFU");
63
64 @XI = ("not supported", "state L", "state H", "no preference");
65 @UI = ("A only (5V)", "B only (3V)", "A and B", "RFU");
66
67 # prorotypes
68 sub analyse_TA();
69 sub analyse_TB();
70 sub analyse_TC();
71 sub analyse_TD();
72 sub find_card($$@);
73
74 # globals init
75 $T = 0;
76
77 $value = 0;
78 $counter = 1;
79
80 getopts("vh");
81
82 if ($opt_v)
83 {
84 print "Version: 1.2, (c) 2002, Ludovic Rousseau <ludovic.rousseau\@free.fr>\n";
85 exit;
86 }
87
88 # 1_ 1 argument then input = ATR else smart card
89 if (($#ARGV != 0) or $opt_h)
90 {
91 print "Usage: $0 ATR_string\n";
92 print " Ex: $0 '3B A7 00 40 18 80 65 A2 08 01 01 52'\n";
93 exit;
94 }
95
96 # 1_ get the ATR
97 $atr = $ARGV[0];
98 if (substr ($atr, 2, 1) ne " ")
99 {
100 # "3BA7004018" -> "3B A7 00 40 18"
101 $atr =~ s/(..)/$1 /g;
102 $atr =~ s/ *$//;
103 }
104
105 print "ATR: $atr\n";
106
107 # 2_ Split in bytes of the lines
108 @object = split(/\s/, $atr);
109 $nb_bytes=$#object+1;
110 #print $nb_bytes;
111
112 # 3_ Analysis
113
114 # Analysis of TS:
115 $value=hex(shift(@object));
116 if (defined $TS{$value})
117 {
118 printf "+ TS = %02X --> %s\n", $value, $TS{$value};
119 $mpcard = 1;
120 }
121 else
122 {
123 printf "+ TS = %02X --> UNDEFINED\n", $value;
124 # this is NOT a microprocessor card
125 $mpcard = 0;
126 }
127
128 exit if ($#object < 0);
129
130 # Analysis of T0:
131 $value = hex(shift(@object));
132 $Y1 = $value >> 4;
133 $K = $value % 16;
134 printf "+ T0 = %02X, Y(1): %04b, K: %d (historical bytes)\n", $value, $Y1, $K;
135
136 exit if ($#object < 0);
137 analyse_TA() if ($Y1 & 0x1);
138
139 exit if ($#object < 0);
140 analyse_TB() if ($Y1 & 0x2);
141
142 exit if ($#object < 0);
143 analyse_TC() if ($Y1 & 0x4);
144
145 exit if ($#object < 0);
146 analyse_TD() if ($Y1 & 0x8);
147
148 # the rest are historical byets
149 print "+ Historical bytes: @object\n";
150
151 if (! $mpcard)
152 {
153 print "Your card is not a microprocessor card. It seams to be memory card.\n";
154 exit;
155 }
156
157 # find the corresponding card type
158 find_card($atr, $SMARTCARD_LIST, @LIST_PATH);
159
160 ######## Sub functions
161
162 # _____ _
163 # |_ _|/ \
164 # | | / _ \
165 # | |/ ___ \
166 # |_/_/ \_\
167 #
168 sub analyse_TA()
169 {
170 $value = hex(shift(@object));
171 printf (" TA($counter) = %02X --> ", $value);
172
173 # TA1 Analysis
174 if ($counter == 1)
175 {
176 my $F = $value >> 4;
177 my $D = $value % 16;
178
179 $value=$Fi[$F]/$Di[$D] if ($Di[$D] ne "RFU");
180
181 printf "Fi=%s, Di=%s, %.3f cycles/ETU", $Fi[$F], $Di[$D], $value;
182 }
183
184 # TA2 Analysis - TA2 is the specific mode byte
185 if ($counter==2)
186 {
187 my $F=$value >> 4;
188 my $D=$value % 16;
189
190 printf ("Protocol to be used in spec mode: T=%s", $D);
191 if ($F & 0x8)
192 {
193 print " - Unable to change";
194 }
195 else
196 {
197 print " - Capable to change";
198 }
199
200 if ($F & 0x1)
201 {
202 print " - implicity defined";
203 }
204 else
205 {
206 print " - defined by interface bytes";
207 }
208 }
209
210 # TA3 Analysis
211 if ($counter>=3)
212 {
213 if ($T==1)
214 {
215 printf ("IFSC: %s", $value);
216 }
217 else
218 { #### T <> 1
219 my $F=$value >> 6;
220 my $D=$value % 64;
221 my $Class="(3G) ";
222
223 $Class=$Class."A 5V " if ($D & 0x1);
224 $Class=$Class."B 3V " if ($D & 0x2);
225 $Class=$Class."C 1.8V " if ($D & 0x4);
226 $Class=$Class."D RFU " if ($D & 0x8);
227 $Class=$Class."E RFU" if ($D & 0x10);
228
229 printf ("Clock stop: %s - Class accepted by the card: %s", $XI[$F],$Class);
230 }
231 }
232 print "\n";
233 } # analyse_TA()
234
235 # _____ ____
236 # |_ _| __ )
237 # | | | _ \
238 # | | | |_) |
239 # |_| |____/
240 #
241 sub analyse_TB()
242 {
243 $value=hex(shift(@object));
244 printf (" TB($counter) = %02X --> ", $value);
245
246 my $I = $value >> 5;
247 my $PI = $value % 32;
248
249 if ($counter == 1)
250 {
251 print "Programming Param P: $PI Volts, I: $I milli-Amp?res";
252 }
253
254 if ($counter == 2)
255 {
256 print "Programming param PI2 (PI1 sould be ignored): ";
257 if (($value>49)||($value<251))
258 {
259 print "$value (dV)";
260 }
261 else
262 {
263 print "$value is RFU";
264 }
265 }
266
267 if ($counter >= 3)
268 {
269 if ($T == 1)
270 {
271 my $BWI=$value >> 4;
272 my $CWI=$value % 16;
273
274 printf ("Block Waiting Integer: %s - Character Waiting Integer: %s", $BWI, $CWI);
275 }
276 }
277 print "\n";
278 } # analyse_TB()
279
280 # _____ ____
281 # |_ _/ ___|
282 # | || |
283 # | || |___
284 # |_| \____|
285 #
286 sub analyse_TC()
287 {
288 $value=hex(shift(@object));
289 printf (" TC($counter) = %02X --> ", $value);
290
291
292 if ($counter == 1)
293 {
294 print "Extra guard time: $value";
295 }
296
297 if ($counter == 2)
298 {
299 printf ("Work waiting time: 960 x %d x (Fi/F)", $value);
300 }
301
302 if ($counter >= 3)
303 {
304 if ($T==1)
305 {
306 printf ("Error detection code: ");
307 if ($value==1)
308 {
309 print "CRC";
310 }
311 elsif ($value==0)
312 {
313 print "LRC";
314 }
315 else
316 {
317 print "RFU";
318 }
319 }
320 }
321 print "\n";
322 } # analyse_TC()
323
324 # _____ ____
325 # |_ _| _ \
326 # | | | | | |
327 # | | | |_| |
328 # |_| |____/
329 #
330 sub analyse_TD()
331 {
332 my $str='';
333
334 $value = hex(shift(@object));
335
336 my $Y = $value >> 4;
337 $T=$value % 16;
338
339 if ($T == 15)
340 {
341 $str=" - Global interface bytes following";
342 }
343 printf (" TD($counter) = %02X --> Y(i+1) = %04b, Protocol T = $T$str\n", $value, $Y);
344
345 $counter++;
346 print "-----\n";
347
348 exit if ($#object < 0);
349 analyse_TA() if ($Y & 0x1);
350
351 exit if ($#object < 0);
352 analyse_TB() if ($Y & 0x2);
353
354 exit if ($#object < 0);
355 analyse_TC() if ($Y & 0x4);
356
357 exit if ($#object < 0);
358 analyse_TD() if ($Y & 0x8);
359 } # analyse_TD()
360
361 # _____ _ _ _
362 #| ___(_)_ __ __| | ___ __ _ _ __ __| |
363 #| |_ | | '_ \ / _` | / __/ _` | '__/ _` |
364 #| _| | | | | | (_| | | (_| (_| | | | (_| |
365 #|_| |_|_| |_|\__,_| \___\__,_|_| \__,_|
366 #
367 sub find_card($$@)
368 {
369 my $atr = shift;
370 my $file = shift;
371 my @path = @_;
372
373 my ($line, $found, $p);
374
375 foreach $p (@path)
376 {
377 if (-e "$p/$file")
378 {
379 $file = "$p/$file";
380 last;
381 }
382 }
383
384 $found = 0;
385 print "\nPossibly identified card:\n";
386 open FILE, "< $file" or die "Can't open $file: $!\n";
387 while ($line = <FILE>)
388 {
389 next if ($line =~ m/^#/); # comment
390 next if ($line =~ m/^$/); # empty line
391 next if ($line =~ m/^\t/); # description
392
393 chomp $line;
394
395 if ($atr =~ m/^$line$/i)
396 {
397 # print the card ATR if a regular expression was used
398 print "$atr\n" if (uc $line ne uc $atr);
399
400 print "$line\n"; # print the matching ATR
401
402 $found = 1;
403 # print until a line do not start by a tabulation
404 while (($line = <FILE>) =~ m/^\t/)
405 {
406 print $line; # print the card description
407 }
408 }
409 }
410 close FILE;
411
412 if ((! $found) && ($atr =~ m/^[3B|3F]/))
413 {
414 print "\tNONE\n\n";
415 print "Your card is not present in the database.\n";
416 print "You can get the latest version of the database from\n";
417 print " http://ludovic.rousseau.free.fr/softwares/pcsc-tools/smartcard_list.txt\n";
418 print "If your ATR is still not in the latest version then please send a mail\n";
419 print "to <ludovic.rousseau\@free.fr> containing:\n";
420 print "- your ATR\n";
421 print "- a card description\n";
422 }
423 } # find_card($$)
424

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.5