1
/******************************************************************
3
MUSCLE SmartCard Development ( http://www.linuxnet.com )
5
Author : David Corcoran
7
License: Copyright (C) 1999 David Corcoran
8
<corcoran@linuxnet.com>
9
Purpose: This keeps track of smartcard protocols,
10
timing issues, and atr handling.
12
********************************************************************/
2
* This keeps track of smartcard protocols, timing issues
5
* MUSCLE SmartCard Development ( http://www.linuxnet.com )
8
* David Corcoran <corcoran@linuxnet.com>
10
* $Id: atrhandler.c,v 1.6 2003/10/18 17:19:36 aet-guest Exp $
14
14
#include <syslog.h>
17
17
#include "wintypes.h"
18
18
#include "pcsclite.h"
19
19
#include "atrhandler.h"
21
/* Uncomment the following for ATR debugging */
22
/* #define ATR_DEBUG 1 */
24
short ATRDecodeAtr( PSMARTCARD_EXTENSION psExtension,
25
PUCHAR pucAtr, DWORD dwLength ) {
28
UCHAR K, TCK; /* MSN of T0/Check Sum */
29
UCHAR Y1i, T; /* MSN/LSN of TDi */
30
short TAi, TBi, TCi, TDi; /* Interface characters */
32
/* Zero out everything */
33
p = K = TCK = Y1i = T = TAi = TBi = TCi = TDi = 0;
36
return 0; /* Atr must have TS and T0 */
39
/* Zero out the bitmasks */
41
psExtension->CardCapabilities.AvailableProtocols = 0x00;
42
psExtension->CardCapabilities.CurrentProtocol = 0x00;
44
/* Decode the TS byte */
46
if ( pucAtr[0] == 0x3F ) { /* Inverse convention used */
47
psExtension->CardCapabilities.Convention = SCARD_CONVENTION_INVERSE;
48
} else if ( pucAtr[0] == 0x3B ) { /* Direct convention used */
49
psExtension->CardCapabilities.Convention = SCARD_CONVENTION_DIRECT;
51
memset( psExtension, 0x00, sizeof(SMARTCARD_EXTENSION) );
55
/* Here comes the platform dependant stuff */
57
/* Decode the T0 byte */
58
Y1i = pucAtr[1] >> 4; /* Get the MSN in Y1 */
59
K = pucAtr[1] & 0x0F; /* Get the LSN in K */
65
syslog( LOG_DEBUG, " Conv %02X, Y1 %02X, K %02X",
66
psExtension->CardCapabilities.Convention, Y1i, K );
68
printf(" Conv %02X, Y1 %02X, K %02X\n", psExtension->CardCapabilities.Convention,
77
TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
78
TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
79
TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
80
TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
84
syslog( LOG_DEBUG, " T's %02X %02X %02X %02X", TAi, TBi, TCi, TDi );
85
syslog( LOG_DEBUG, " P %02X", p );
87
printf(" T's %02X %02X %02X %02X\n", TAi, TBi, TCi, TDi );
88
printf(" P %02X\n", p);
92
/* Examine TDi to determine protocol and more */
94
Y1i = TDi >> 4; /* Get the MSN in Y1 */
95
T = TDi & 0x0F; /* Get the LSN in K */
97
/* Set the current protocol TD1 */
98
if ( psExtension->CardCapabilities.CurrentProtocol == 0x00 ) {
101
psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
104
psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T1;
114
syslog( LOG_DEBUG, "T=0 Protocol Found" );
116
printf("T=0 Protocol Found\n");
119
psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T0;
120
psExtension->CardCapabilities.T0.BGT = 0 ;
121
psExtension->CardCapabilities.T0.BWT = 0;
122
psExtension->CardCapabilities.T0.CWT = 0;
123
psExtension->CardCapabilities.T0.CGT = 0;
124
psExtension->CardCapabilities.T0.WT = 0;
125
} else if ( T == 1 ) {
128
syslog( LOG_DEBUG, "T=1 Protocol Found" );
130
printf("T=1 Protocol Found\n");
133
psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T1;
134
psExtension->CardCapabilities.T1.BGT = 0 ;
135
psExtension->CardCapabilities.T1.BWT = 0;
136
psExtension->CardCapabilities.T1.CWT = 0;
137
psExtension->CardCapabilities.T1.CGT = 0;
138
psExtension->CardCapabilities.T1.WT = 0;
140
psExtension->CardCapabilities.AvailableProtocols |= T;
141
/* Do nothing for now since other protocols
142
are not supported at this time */
149
if ( p > MAX_ATR_SIZE ) {
150
memset( psExtension, 0x00, sizeof(SMARTCARD_EXTENSION) );
154
} while ( Y1i != 0 );
156
/* If TDx is not set then the current must be T0 */
157
if ( psExtension->CardCapabilities.CurrentProtocol == 0x00 ) {
158
psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
159
psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T0;
162
/* Take care of the historical characters */
164
psExtension->ATR.HistoryLength = K;
165
memcpy( psExtension->ATR.HistoryValue, &pucAtr[p], K );
169
/* Check to see if TCK character is included It will
170
be included if more than T=0 is supported */
172
if ( psExtension->CardCapabilities.AvailableProtocols &
178
memcpy( psExtension->ATR.Value, pucAtr, p );
179
psExtension->ATR.Length = p; /* modified from p-1 */
22
* Uncomment the following for ATR debugging
28
short ATRDecodeAtr(PSMARTCARD_EXTENSION psExtension,
29
PUCHAR pucAtr, DWORD dwLength)
33
UCHAR K, TCK; /* MSN of T0/Check Sum */
34
UCHAR Y1i, T; /* MSN/LSN of TDi */
35
short TAi, TBi, TCi, TDi; /* Interface characters */
40
p = K = TCK = Y1i = T = TAi = TBi = TCi = TDi = 0;
44
return 0; /* Atr must have TS and T0 */
48
* Zero out the bitmasks
51
psExtension->CardCapabilities.AvailableProtocols = 0x00;
52
psExtension->CardCapabilities.CurrentProtocol = 0x00;
58
if (pucAtr[0] == 0x3F)
59
{ /* Inverse convention used */
60
psExtension->CardCapabilities.Convention =
61
SCARD_CONVENTION_INVERSE;
62
} else if (pucAtr[0] == 0x3B)
63
{ /* Direct convention used */
64
psExtension->CardCapabilities.Convention = SCARD_CONVENTION_DIRECT;
67
memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
72
* Here comes the platform dependant stuff
78
Y1i = pucAtr[1] >> 4; /* Get the MSN in Y1 */
79
K = pucAtr[1] & 0x0F; /* Get the LSN in K */
84
debug_msg("Conv %02X, Y1 %02X, K %02X",
85
psExtension->CardCapabilities.Convention, Y1i, K);
95
TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
96
TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
97
TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
98
TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
101
debug_msg("T's %02X %02X %02X %02X", TAi, TBi, TCi, TDi);
102
debug_msg("P %02X", p);
106
* Examine TDi to determine protocol and more
110
Y1i = TDi >> 4; /* Get the MSN in Y1 */
111
T = TDi & 0x0F; /* Get the LSN in K */
114
* Set the current protocol TD1
116
if (psExtension->CardCapabilities.CurrentProtocol == 0x00)
121
psExtension->CardCapabilities.CurrentProtocol =
125
psExtension->CardCapabilities.CurrentProtocol =
136
debug_msg("T=0 Protocol Found");
138
psExtension->CardCapabilities.AvailableProtocols |=
140
psExtension->CardCapabilities.T0.BGT = 0;
141
psExtension->CardCapabilities.T0.BWT = 0;
142
psExtension->CardCapabilities.T0.CWT = 0;
143
psExtension->CardCapabilities.T0.CGT = 0;
144
psExtension->CardCapabilities.T0.WT = 0;
148
debug_msg("T=1 Protocol Found");
150
psExtension->CardCapabilities.AvailableProtocols |=
152
psExtension->CardCapabilities.T1.BGT = 0;
153
psExtension->CardCapabilities.T1.BWT = 0;
154
psExtension->CardCapabilities.T1.CWT = 0;
155
psExtension->CardCapabilities.T1.CGT = 0;
156
psExtension->CardCapabilities.T1.WT = 0;
159
psExtension->CardCapabilities.AvailableProtocols |= T;
161
* Do nothing for now since other protocols are not
162
* supported at this time
171
if (p > MAX_ATR_SIZE)
173
memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
181
* If TDx is not set then the current must be T0
183
if (psExtension->CardCapabilities.CurrentProtocol == 0x00)
185
psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
186
psExtension->CardCapabilities.AvailableProtocols |=
191
* Take care of the historical characters
194
psExtension->ATR.HistoryLength = K;
195
memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
200
* Check to see if TCK character is included It will be included if
201
* more than T=0 is supported
204
if (psExtension->CardCapabilities.AvailableProtocols &
210
memcpy(psExtension->ATR.Value, pucAtr, p);
211
psExtension->ATR.Length = p; /* modified from p-1 */