00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00021 #include "config.h"
00022 #include <syslog.h>
00023 #include <string.h>
00024
00025 #include "misc.h"
00026 #include "pcsclite.h"
00027 #include "debuglog.h"
00028 #include "atrhandler.h"
00029
00034
00035
00043 short ATRDecodeAtr(PSMARTCARD_EXTENSION psExtension,
00044 PUCHAR pucAtr, DWORD dwLength)
00045 {
00046 USHORT p;
00047 UCHAR K, TCK;
00048 UCHAR Y1i, T;
00049 int i = 1;
00050
00051
00052
00053
00054 p = K = TCK = Y1i = T = 0;
00055
00056 #ifdef ATR_DEBUG
00057 if (dwLength > 0)
00058 LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
00059 #endif
00060
00061 if (dwLength < 2)
00062 return 0;
00064
00065
00066
00067 psExtension->CardCapabilities.AvailableProtocols = SCARD_PROTOCOL_UNSET;
00068 psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_UNSET;
00069
00070
00071
00072
00073 if (pucAtr[0] == 0x3F)
00074 {
00075 psExtension->CardCapabilities.Convention = SCARD_CONVENTION_INVERSE;
00076 }
00077 else
00078 if (pucAtr[0] == 0x3B)
00079 {
00080 psExtension->CardCapabilities.Convention = SCARD_CONVENTION_DIRECT;
00081 }
00082 else
00083 {
00084 memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
00085 return 0;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095 Y1i = pucAtr[1] >> 4;
00096 K = pucAtr[1] & 0x0F;
00097
00098 p = 2;
00099
00100 #ifdef ATR_DEBUG
00101 Log4(PCSC_LOG_DEBUG, "Conv: %02X, Y1: %02X, K: %02X",
00102 psExtension->CardCapabilities.Convention, Y1i, K);
00103 #endif
00104
00105
00106
00107
00108 do
00109 {
00110 short TAi, TBi, TCi, TDi;
00111
00112 TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
00113 TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
00114 TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
00115 TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
00116
00117 #ifdef ATR_DEBUG
00118 Log9(PCSC_LOG_DEBUG,
00119 "TA%d: %02X, TB%d: %02X, TC%d: %02X, TD%d: %02X",
00120 i, TAi, i, TBi, i, TCi, i, TDi);
00121 #endif
00122
00123
00124
00125
00126 if (TDi >= 0)
00127 {
00128 Y1i = TDi >> 4;
00129 T = TDi & 0x0F;
00130
00131
00132
00133
00134 if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNSET)
00135 {
00136 switch (T)
00137 {
00138 case 0:
00139 psExtension->CardCapabilities.CurrentProtocol =
00140 SCARD_PROTOCOL_T0;
00141 break;
00142 case 1:
00143 psExtension->CardCapabilities.CurrentProtocol =
00144 SCARD_PROTOCOL_T1;
00145 break;
00146 default:
00147 return 0;
00148 }
00149 }
00150
00151 #ifdef ATR_DEBUG
00152 Log2(PCSC_LOG_DEBUG, "T=%d Protocol Found", T);
00153 #endif
00154 if (0 == T)
00155 {
00156 psExtension->CardCapabilities.AvailableProtocols |=
00157 SCARD_PROTOCOL_T0;
00158 psExtension->CardCapabilities.T0.BGT = 0;
00159 psExtension->CardCapabilities.T0.BWT = 0;
00160 psExtension->CardCapabilities.T0.CWT = 0;
00161 psExtension->CardCapabilities.T0.CGT = 0;
00162 psExtension->CardCapabilities.T0.WT = 0;
00163 }
00164 else
00165 if (1 == T)
00166 {
00167 psExtension->CardCapabilities.AvailableProtocols |=
00168 SCARD_PROTOCOL_T1;
00169 psExtension->CardCapabilities.T1.BGT = 0;
00170 psExtension->CardCapabilities.T1.BWT = 0;
00171 psExtension->CardCapabilities.T1.CWT = 0;
00172 psExtension->CardCapabilities.T1.CGT = 0;
00173 psExtension->CardCapabilities.T1.WT = 0;
00174 }
00175 else
00176 if (15 == T)
00177 {
00178 psExtension->CardCapabilities.AvailableProtocols |=
00179 SCARD_PROTOCOL_T15;
00180 }
00181 else
00182 {
00183
00184
00185
00186
00187 }
00188
00189
00190 if ((2 == i) && (TAi >= 0))
00191 {
00192 T = TAi & 0x0F;
00193 #ifdef ATR_DEBUG
00194 Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
00195 #endif
00196 switch (T)
00197 {
00198 case 0:
00199 psExtension->CardCapabilities.CurrentProtocol =
00200 psExtension->CardCapabilities.AvailableProtocols =
00201 SCARD_PROTOCOL_T0;
00202 break;
00203
00204 case 1:
00205 psExtension->CardCapabilities.CurrentProtocol =
00206 psExtension->CardCapabilities.AvailableProtocols =
00207 SCARD_PROTOCOL_T1;
00208 break;
00209
00210 default:
00211 return 0;
00212 }
00213 }
00214 } else
00215 Y1i = 0;
00216
00217 if (p > MAX_ATR_SIZE)
00218 {
00219 memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
00220 return 0;
00221 }
00222
00223
00224 i++;
00225 }
00226 while (Y1i != 0);
00227
00228
00229
00230
00231 if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNSET)
00232 {
00233 psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
00234 psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T0;
00235 }
00236
00237
00238
00239
00240 psExtension->ATR.HistoryLength = K;
00241 memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
00242
00243 p = p + K;
00244
00245
00246
00247
00248
00249 if (psExtension->CardCapabilities.AvailableProtocols & SCARD_PROTOCOL_T1)
00250 TCK = pucAtr[p++];
00251
00252 memcpy(psExtension->ATR.Value, pucAtr, p);
00253 psExtension->ATR.Length = p;
00254
00255 #ifdef ATR_DEBUG
00256 Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
00257 psExtension->CardCapabilities.CurrentProtocol,
00258 psExtension->CardCapabilities.AvailableProtocols);
00259 #endif
00260
00261 return 1;
00262 }
00263