pcsc-lite  1.8.20
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 
43 #include "config.h"
44 #include <string.h>
45 
46 #include "misc.h"
47 #include "pcsclite.h"
48 #include "debuglog.h"
49 #include "atrhandler.h"
50 
51 /*
52  * Uncomment the following for ATR debugging
53  * or use ./configure --enable-debugatr
54  */
55 /* #define ATR_DEBUG */
56 
66 short ATRDecodeAtr(int *availableProtocols, int *currentProtocol,
67  PUCHAR pucAtr, DWORD dwLength)
68 {
69  USHORT p;
70  UCHAR Y1i, T; /* MSN/LSN of TDi */
71  int i = 1; /* value of the index in TAi, TBi, etc. */
72 
73 #ifdef ATR_DEBUG
74  if (dwLength > 0)
75  LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
76 #endif
77 
78  if (dwLength < 2)
79  return 0;
81  /*
82  * Zero out the bitmasks
83  */
84  *availableProtocols = SCARD_PROTOCOL_UNDEFINED;
85  *currentProtocol = SCARD_PROTOCOL_UNDEFINED;
86 
87  /*
88  * Decode the TS byte
89  */
90  if ((pucAtr[0] != 0x3F) && (pucAtr[0] != 0x3B))
91  return 0;
93  /*
94  * Here comes the platform dependant stuff
95  */
96 
97  /*
98  * Decode the T0 byte
99  */
100  Y1i = pucAtr[1] >> 4; /* Get the MSN in Y1 */
101 
102  p = 2;
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  /* We don't use TBi and TCi but we must calculate them because
117  * of the p++ in the formulae */
118  (void)TBi;
119  (void)TCi;
120 
121 #ifdef ATR_DEBUG
122  Log9(PCSC_LOG_DEBUG,
123  "TA%d: %02X, TB%d: %02X, TC%d: %02X, TD%d: %02X",
124  i, TAi, i, TBi, i, TCi, i, TDi);
125 #endif
126 
127  /*
128  * Examine TDi to determine protocol and more
129  */
130  if (TDi >= 0)
131  {
132  Y1i = TDi >> 4; /* Get the MSN in Y1 */
133  T = TDi & 0x0F; /* Get the LSN in K */
134 
135  /*
136  * Set the current protocol TD1 (first TD only)
137  */
138  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
139  {
140  switch (T)
141  {
142  case 0:
143  *currentProtocol = SCARD_PROTOCOL_T0;
144  break;
145  case 1:
146  *currentProtocol = SCARD_PROTOCOL_T1;
147  break;
148  default:
149  return 0;
150  }
151  }
152 
153 #ifdef ATR_DEBUG
154  Log2(PCSC_LOG_DEBUG, "T=%d Protocol Found", T);
155 #endif
156  if (0 == T)
157  {
158  *availableProtocols |= SCARD_PROTOCOL_T0;
159  }
160  else
161  if (1 == T)
162  {
163  *availableProtocols |= SCARD_PROTOCOL_T1;
164  }
165  else
166  if (15 == T)
167  {
168  *availableProtocols |= SCARD_PROTOCOL_T15;
169  }
170  else
171  {
172  /*
173  * Do nothing for now since other protocols are not
174  * supported at this time
175  */
176  }
177  }
178  else
179  Y1i = 0;
180 
181  /* test presence of TA2 */
182  if ((2 == i) && (TAi >= 0))
183  {
184  T = TAi & 0x0F;
185 #ifdef ATR_DEBUG
186  Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
187 #endif
188  switch (T)
189  {
190  case 0:
191  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T0;
192  break;
193 
194  case 1:
195  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T1;
196  break;
197 
198  default:
199  return 0;
200  }
201  }
202 
203  if (p > MAX_ATR_SIZE)
204  return 0;
206  /* next interface characters index */
207  i++;
208  }
209  while (Y1i != 0);
210 
211  /*
212  * If TDx is not set then the current must be T0
213  */
214  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
215  {
216  *currentProtocol = SCARD_PROTOCOL_T0;
217  *availableProtocols |= SCARD_PROTOCOL_T0;
218  }
219 
220 #ifdef ATR_DEBUG
221  Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
222  *currentProtocol, *availableProtocols);
223 #endif
224 
225  return 1;
226 }
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition: pcsclite.h:242
#define SCARD_PROTOCOL_T15
T=15 protocol.
Definition: pcsclite.h:244
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:241
short ATRDecodeAtr(int *availableProtocols, int *currentProtocol, PUCHAR pucAtr, DWORD dwLength)
parse an ATR
Definition: atrhandler.c:66
This keeps a list of defines for pcsc-lite.
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
Definition: pcsclite.h:239
#define MAX_ATR_SIZE
Maximum ATR size.
Definition: pcsclite.h:59
This handles debugging.