pcsc-lite  1.8.14
atrhandler.c
Go to the documentation of this file.
1 /*
2  * MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
3  *
4  * Copyright (C) 1999-2002
5  * David Corcoran <corcoran@musclecard.com>
6  * Copyright (C) 2002-2011
7  * Ludovic Rousseau <ludovic.rousseau@free.fr>
8  *
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12 
13 1. Redistributions of source code must retain the above copyright
14  notice, this list of conditions and the following disclaimer.
15 2. Redistributions in binary form must reproduce the above copyright
16  notice, this list of conditions and the following disclaimer in the
17  documentation and/or other materials provided with the distribution.
18 3. The name of the author may not be used to endorse or promote products
19  derived from this software without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $Id$
33  */
34 
45 #include "config.h"
46 #include <string.h>
47 
48 #include "misc.h"
49 #include "pcsclite.h"
50 #include "debuglog.h"
51 #include "atrhandler.h"
52 
53 /*
54  * Uncomment the following for ATR debugging
55  * or use ./configure --enable-debugatr
56  */
57 /* #define ATR_DEBUG */
58 
68 short ATRDecodeAtr(int *availableProtocols, int *currentProtocol,
69  PUCHAR pucAtr, DWORD dwLength)
70 {
71  USHORT p;
72  UCHAR Y1i, T; /* MSN/LSN of TDi */
73  int i = 1; /* value of the index in TAi, TBi, etc. */
74 
75 #ifdef ATR_DEBUG
76  if (dwLength > 0)
77  LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
78 #endif
79 
80  if (dwLength < 2)
81  return 0;
83  /*
84  * Zero out the bitmasks
85  */
86  *availableProtocols = SCARD_PROTOCOL_UNDEFINED;
87  *currentProtocol = SCARD_PROTOCOL_UNDEFINED;
88 
89  /*
90  * Decode the TS byte
91  */
92  if ((pucAtr[0] != 0x3F) && (pucAtr[0] != 0x3B))
93  return 0;
95  /*
96  * Here comes the platform dependant stuff
97  */
98 
99  /*
100  * Decode the T0 byte
101  */
102  Y1i = pucAtr[1] >> 4; /* Get the MSN in Y1 */
103 
104  p = 2;
105 
106  /*
107  * Examine Y1
108  */
109  do
110  {
111  short TAi, TBi, TCi, TDi; /* Interface characters */
112 
113  TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
114  TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
115  TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
116  TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
117 
118  /* We don't use TBi and TCi but we must calculate them because
119  * of the p++ in the formulae */
120  (void)TBi;
121  (void)TCi;
122 
123 #ifdef ATR_DEBUG
124  Log9(PCSC_LOG_DEBUG,
125  "TA%d: %02X, TB%d: %02X, TC%d: %02X, TD%d: %02X",
126  i, TAi, i, TBi, i, TCi, i, TDi);
127 #endif
128 
129  /*
130  * Examine TDi to determine protocol and more
131  */
132  if (TDi >= 0)
133  {
134  Y1i = TDi >> 4; /* Get the MSN in Y1 */
135  T = TDi & 0x0F; /* Get the LSN in K */
136 
137  /*
138  * Set the current protocol TD1 (first TD only)
139  */
140  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
141  {
142  switch (T)
143  {
144  case 0:
145  *currentProtocol = SCARD_PROTOCOL_T0;
146  break;
147  case 1:
148  *currentProtocol = SCARD_PROTOCOL_T1;
149  break;
150  default:
151  return 0;
152  }
153  }
154 
155 #ifdef ATR_DEBUG
156  Log2(PCSC_LOG_DEBUG, "T=%d Protocol Found", T);
157 #endif
158  if (0 == T)
159  {
160  *availableProtocols |= SCARD_PROTOCOL_T0;
161  }
162  else
163  if (1 == T)
164  {
165  *availableProtocols |= SCARD_PROTOCOL_T1;
166  }
167  else
168  if (15 == T)
169  {
170  *availableProtocols |= SCARD_PROTOCOL_T15;
171  }
172  else
173  {
174  /*
175  * Do nothing for now since other protocols are not
176  * supported at this time
177  */
178  }
179  }
180  else
181  Y1i = 0;
182 
183  /* test presence of TA2 */
184  if ((2 == i) && (TAi >= 0))
185  {
186  T = TAi & 0x0F;
187 #ifdef ATR_DEBUG
188  Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
189 #endif
190  switch (T)
191  {
192  case 0:
193  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T0;
194  break;
195 
196  case 1:
197  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T1;
198  break;
199 
200  default:
201  return 0;
202  }
203  }
204 
205  if (p > MAX_ATR_SIZE)
206  return 0;
208  /* next interface characters index */
209  i++;
210  }
211  while (Y1i != 0);
212 
213  /*
214  * If TDx is not set then the current must be T0
215  */
216  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
217  {
218  *currentProtocol = SCARD_PROTOCOL_T0;
219  *availableProtocols |= SCARD_PROTOCOL_T0;
220  }
221 
222 #ifdef ATR_DEBUG
223  Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
224  *currentProtocol, *availableProtocols);
225 #endif
226 
227  return 1;
228 }
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition: pcsclite.h:176
#define SCARD_PROTOCOL_T15
T=15 protocol.
Definition: pcsclite.h:178
This keeps track of smart card protocols, timing issues and Answer to Reset ATR handling.
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition: pcsclite.h:175
short ATRDecodeAtr(int *availableProtocols, int *currentProtocol, PUCHAR pucAtr, DWORD dwLength)
parse an ATR
Definition: atrhandler.c:68
This keeps a list of defines for pcsc-lite.
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
Definition: pcsclite.h:173
#define MAX_ATR_SIZE
Maximum ATR size.
Definition: pcsclite.h:61
This handles debugging.