~ubuntu-branches/ubuntu/jaunty/pcsc-lite/jaunty-security

« back to all changes in this revision

Viewing changes to src/atrhandler.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Rousseau
  • Date: 2005-11-27 18:04:59 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051127180459-qrex2gzpq9d8jexd
Tags: 1.2.9-beta9-1
* New upstream version
* debian/compat: change from 3 to 4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * MUSCLE SmartCard Development ( http://www.linuxnet.com )
 
3
 *
 
4
 * Copyright (C) 1999-2004
 
5
 *  David Corcoran <corcoran@linuxnet.com>
 
6
 *  Ludovic Rousseau <ludovic.rousseau@free.fr>
 
7
 *
 
8
 * $Id: atrhandler.c 1421 2005-04-12 12:09:21Z rousseau $
 
9
 */
 
10
 
 
11
/**
 
12
 * @file
 
13
 *
 
14
 * @brief This keeps track of smartcard protocols, timing issues
 
15
 * and ATR (Answer-to-Reset) handling.
 
16
 *
 
17
 * @note use ./configure --enable-debugatr to enable debug messages
 
18
 * to be logged.
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
#include <syslog.h>
 
23
#include <string.h>
 
24
 
 
25
#include "pcsclite.h"
 
26
#include "debuglog.h"
 
27
#include "atrhandler.h"
 
28
 
 
29
/**
 
30
 * Uncomment the following for ATR debugging
 
31
 * or use ./configure --enable-debugatr
 
32
 */
 
33
/* #define ATR_DEBUG */
 
34
 
 
35
/**
 
36
 * @brief
 
37
 * @param psExtension
 
38
 * @param pucAtr
 
39
 * @param dwLength
 
40
 * @return 
 
41
 */
 
42
short ATRDecodeAtr(PSMARTCARD_EXTENSION psExtension,
 
43
        PUCHAR pucAtr, DWORD dwLength)
 
44
{
 
45
        USHORT p;
 
46
        UCHAR K, TCK;                           /* MSN of T0/Check Sum */
 
47
        UCHAR Y1i, T;                           /* MSN/LSN of TDi */
 
48
        int i = 1;                                      /* value of the index in TAi, TBi, etc. */
 
49
 
 
50
        /*
 
51
         * Zero out everything 
 
52
         */
 
53
        p = K = TCK = Y1i = T = 0;
 
54
 
 
55
#ifdef ATR_DEBUG
 
56
        if (dwLength > 0)
 
57
                LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
 
58
#endif
 
59
 
 
60
        if (dwLength < 2)
 
61
                return 0;       /** @retval 0 Atr must have TS and T0 */
 
62
 
 
63
        /*
 
64
         * Zero out the bitmasks 
 
65
         */
 
66
        psExtension->CardCapabilities.AvailableProtocols = SCARD_PROTOCOL_UNSET;
 
67
        psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_UNSET;
 
68
 
 
69
        /*
 
70
         * Decode the TS byte 
 
71
         */
 
72
        if (pucAtr[0] == 0x3F)
 
73
        {       /* Inverse convention used */
 
74
                psExtension->CardCapabilities.Convention = SCARD_CONVENTION_INVERSE;
 
75
        }
 
76
        else
 
77
                if (pucAtr[0] == 0x3B)
 
78
                {       /* Direct convention used */
 
79
                        psExtension->CardCapabilities.Convention = SCARD_CONVENTION_DIRECT;
 
80
                }
 
81
                else
 
82
                {
 
83
                        memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
 
84
                        return 0;       /** @retval 0 Unable to decode TS byte */
 
85
                }
 
86
 
 
87
        /*
 
88
         * Here comes the platform dependant stuff 
 
89
         */
 
90
 
 
91
        /*
 
92
         * Decode the T0 byte 
 
93
         */
 
94
        Y1i = pucAtr[1] >> 4;   /* Get the MSN in Y1 */
 
95
        K = pucAtr[1] & 0x0F;   /* Get the LSN in K */
 
96
 
 
97
        p = 2;
 
98
 
 
99
#ifdef ATR_DEBUG
 
100
        Log4(PCSC_LOG_DEBUG, "Conv: %02X, Y1: %02X, K: %02X",
 
101
                psExtension->CardCapabilities.Convention, Y1i, K);
 
102
#endif
 
103
 
 
104
        /*
 
105
         * Examine Y1 
 
106
         */
 
107
        do
 
108
        {
 
109
                short TAi, TBi, TCi, TDi;       /* Interface characters */
 
110
 
 
111
                TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
 
112
                TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
 
113
                TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
 
114
                TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
 
115
 
 
116
#ifdef ATR_DEBUG
 
117
                Log9(PCSC_LOG_DEBUG,
 
118
                        "TA%d: %02X, TB%d: %02X, TC%d: %02X, TD%d: %02X",
 
119
                        i, TAi, i, TBi, i, TCi, i, TDi);
 
120
#endif
 
121
 
 
122
                /*
 
123
                 * Examine TDi to determine protocol and more 
 
124
                 */
 
125
                if (TDi >= 0)
 
126
                {
 
127
                        Y1i = TDi >> 4; /* Get the MSN in Y1 */
 
128
                        T = TDi & 0x0F; /* Get the LSN in K */
 
129
 
 
130
                        /*
 
131
                         * Set the current protocol TD1 (first TD only)
 
132
                         */
 
133
                        if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNSET)
 
134
                        {
 
135
                                switch (T)
 
136
                                {
 
137
                                        case 0:
 
138
                                                psExtension->CardCapabilities.CurrentProtocol =
 
139
                                                        SCARD_PROTOCOL_T0;
 
140
                                                break;
 
141
                                        case 1:
 
142
                                                psExtension->CardCapabilities.CurrentProtocol =
 
143
                                                        SCARD_PROTOCOL_T1;
 
144
                                                break;
 
145
                                        default:
 
146
                                                return 0; /** @retval 0 Unable to decode LNS */
 
147
                                }
 
148
                        }
 
149
 
 
150
#ifdef ATR_DEBUG
 
151
                        Log2(PCSC_LOG_DEBUG, "T=%d Protocol Found", T);
 
152
#endif
 
153
                        if (0 == T)
 
154
                        {
 
155
                                psExtension->CardCapabilities.AvailableProtocols |=
 
156
                                        SCARD_PROTOCOL_T0;
 
157
                                psExtension->CardCapabilities.T0.BGT = 0;
 
158
                                psExtension->CardCapabilities.T0.BWT = 0;
 
159
                                psExtension->CardCapabilities.T0.CWT = 0;
 
160
                                psExtension->CardCapabilities.T0.CGT = 0;
 
161
                                psExtension->CardCapabilities.T0.WT = 0;
 
162
                        }
 
163
                        else
 
164
                                if (1 == T)
 
165
                                {
 
166
                                        psExtension->CardCapabilities.AvailableProtocols |=
 
167
                                                SCARD_PROTOCOL_T1;
 
168
                                        psExtension->CardCapabilities.T1.BGT = 0;
 
169
                                        psExtension->CardCapabilities.T1.BWT = 0;
 
170
                                        psExtension->CardCapabilities.T1.CWT = 0;
 
171
                                        psExtension->CardCapabilities.T1.CGT = 0;
 
172
                                        psExtension->CardCapabilities.T1.WT = 0;
 
173
                                }
 
174
                                else
 
175
                                        if (15 == T)
 
176
                                        {
 
177
                                                psExtension->CardCapabilities.AvailableProtocols |=
 
178
                                                        SCARD_PROTOCOL_T15;
 
179
                                        }
 
180
                                        else
 
181
                                        {
 
182
                                                /*
 
183
                                                 * Do nothing for now since other protocols are not
 
184
                                                 * supported at this time 
 
185
                                                 */
 
186
                                        }
 
187
 
 
188
                        /* test presence of TA2 */
 
189
                        if ((2 == i) && (TAi >= 0))
 
190
                        {
 
191
                                T = TAi & 0x0F;
 
192
#ifdef ATR_DEBUG
 
193
                                Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
 
194
#endif
 
195
                                switch (T)
 
196
                                {
 
197
                                        case 0:
 
198
                                                psExtension->CardCapabilities.CurrentProtocol =
 
199
                                                        psExtension->CardCapabilities.AvailableProtocols =
 
200
                                                        SCARD_PROTOCOL_T0;
 
201
                                                break;
 
202
 
 
203
                                        case 1:
 
204
                                                psExtension->CardCapabilities.CurrentProtocol =
 
205
                                                        psExtension->CardCapabilities.AvailableProtocols =
 
206
                                                        SCARD_PROTOCOL_T1;
 
207
                                                break;
 
208
 
 
209
                                        default:
 
210
                                                return 0; /** @retval 0 Unable do decode T protocol */
 
211
                                }
 
212
                        }
 
213
                } else
 
214
                        Y1i = 0;
 
215
 
 
216
                if (p > MAX_ATR_SIZE)
 
217
                {
 
218
                        memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
 
219
                        return 0;       /** @retval 0 Maximum attribute size */
 
220
                }
 
221
 
 
222
                /* next interface characters index */
 
223
                i++;
 
224
        }
 
225
        while (Y1i != 0);
 
226
 
 
227
        /*
 
228
         * If TDx is not set then the current must be T0 
 
229
         */
 
230
        if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNSET)
 
231
        {
 
232
                psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
 
233
                psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T0;
 
234
        }
 
235
 
 
236
        /*
 
237
         * Take care of the historical characters 
 
238
         */
 
239
        psExtension->ATR.HistoryLength = K;
 
240
        memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
 
241
 
 
242
        p = p + K;
 
243
 
 
244
        /*
 
245
         * Check to see if TCK character is included It will be included if
 
246
         * more than T=0 is supported 
 
247
         */
 
248
        if (psExtension->CardCapabilities.AvailableProtocols & SCARD_PROTOCOL_T1)
 
249
                TCK = pucAtr[p++];
 
250
 
 
251
        memcpy(psExtension->ATR.Value, pucAtr, p);
 
252
        psExtension->ATR.Length = p;    /* modified from p-1 */
 
253
 
 
254
#ifdef ATR_DEBUG
 
255
        Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
 
256
                psExtension->CardCapabilities.CurrentProtocol,
 
257
                psExtension->CardCapabilities.AvailableProtocols);
 
258
#endif
 
259
 
 
260
        return 1; /** @retval 1 Success */
 
261
}
 
262