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