/[pcsclite]/trunk/Drivers/ccid/src/ifdhandler.c
ViewVC logotype

Contents of /trunk/Drivers/ccid/src/ifdhandler.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1441 - (hide annotations) (download)
Tue Apr 26 12:16:26 2005 UTC (8 years ago) by rousseau
File MIME type: text/plain
File size: 28940 byte(s)
extra_egt(): reuse the same baud rate calculation formula
1 rousseau 269 /*
2     ifdhandler.c: IFDH API
3 rousseau 1408 Copyright (C) 2003-2005 Ludovic Rousseau
4 rousseau 269
5 rousseau 1399 This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 rousseau 269
10 rousseau 1399 This library is distributed in the hope that it will be useful,
11 rousseau 269 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 rousseau 1399 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     Lesser General Public License for more details.
14 rousseau 269
15 rousseau 1399 You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 rousseau 269 */
19    
20 rousseau 773 /* $Id$ */
21 rousseau 770
22 rousseau 269 #include <stdio.h>
23     #include <string.h>
24 rousseau 773 #include <stdlib.h>
25 rousseau 998 #include <PCSC/pcsclite.h>
26     #include <PCSC/ifdhandler.h>
27 rousseau 269
28 rousseau 880 #include "ccid.h"
29 rousseau 611 #include "defs.h"
30 rousseau 880 #include "ccid_ifdhandler.h"
31 rousseau 269 #include "config.h"
32     #include "debug.h"
33     #include "utils.h"
34     #include "commands.h"
35 rousseau 998 #include "towitoko/atr.h"
36     #include "towitoko/pps.h"
37 rousseau 773 #include "parser.h"
38 rousseau 269
39 rousseau 563 #ifdef HAVE_PTHREAD
40 rousseau 463 #include <pthread.h>
41     #endif
42    
43 rousseau 410 /* Array of structures to hold the ATR and other state value of each slot */
44 rousseau 1077 static CcidDesc CcidSlots[CCID_DRIVER_MAX_READERS];
45 rousseau 269
46 rousseau 463 /* global mutex */
47 rousseau 563 #ifdef HAVE_PTHREAD
48 rousseau 463 static pthread_mutex_t ifdh_context_mutex = PTHREAD_MUTEX_INITIALIZER;
49     #endif
50 rousseau 269
51 rousseau 880 int LogLevel = DEBUG_LEVEL_CRITICAL | DEBUG_LEVEL_INFO;
52     int DriverOptions = 0;
53 rousseau 773 static int DebugInitialized = FALSE;
54 rousseau 463
55 rousseau 880 /* local functions */
56     static void init_driver(void);
57 rousseau 1438 static void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol);
58 rousseau 773
59    
60 rousseau 998 RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPTSTR lpcDevice)
61 rousseau 649 {
62 rousseau 770 RESPONSECODE return_value = IFD_SUCCESS;
63 rousseau 1107 int reader_index;
64 rousseau 770
65 rousseau 773 if (! DebugInitialized)
66 rousseau 880 init_driver();
67 rousseau 773
68 rousseau 649 DEBUG_INFO3("lun: %X, device: %s", Lun, lpcDevice);
69    
70 rousseau 1107 if (-1 == (reader_index = GetNewReaderIndex(Lun)))
71 rousseau 649 return IFD_COMMUNICATION_ERROR;
72    
73 rousseau 892 /* Reset ATR buffer */
74 rousseau 1107 CcidSlots[reader_index].nATRLength = 0;
75     *CcidSlots[reader_index].pcATRBuffer = '\0';
76 rousseau 649
77 rousseau 892 /* Reset PowerFlags */
78 rousseau 1107 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
79 rousseau 649
80     #ifdef HAVE_PTHREAD
81     pthread_mutex_lock(&ifdh_context_mutex);
82     #endif
83    
84 rousseau 1107 if (OpenPortByName(reader_index, lpcDevice) != STATUS_SUCCESS)
85 rousseau 649 {
86 rousseau 663 DEBUG_CRITICAL("failed");
87 rousseau 770 return_value = IFD_COMMUNICATION_ERROR;
88 rousseau 1152
89     /* release the allocated reader_index */
90     ReleaseReaderIndex(reader_index);
91 rousseau 649 }
92 rousseau 1152 else
93     /* Maybe we have a special treatment for this reader */
94     ccid_open_hack(reader_index);
95 rousseau 649
96     #ifdef HAVE_PTHREAD
97     pthread_mutex_unlock(&ifdh_context_mutex);
98     #endif
99    
100 rousseau 770 return return_value;
101 rousseau 649 } /* IFDHCreateChannelByName */
102    
103    
104 rousseau 269 RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel)
105     {
106     /*
107     * Lun - Logical Unit Number, use this for multiple card slots or
108     * multiple readers. 0xXXXXYYYY - XXXX multiple readers, YYYY multiple
109     * slots. The resource manager will set these automatically. By
110     * default the resource manager loads a new instance of the driver so
111     * if your reader does not have more than one smartcard slot then
112     * ignore the Lun in all the functions. Future versions of PC/SC might
113     * support loading multiple readers through one instance of the driver
114     * in which XXXX would be important to implement if you want this.
115     */
116    
117     /*
118     * Channel - Channel ID. This is denoted by the following: 0x000001 -
119     * /dev/pcsc/1 0x000002 - /dev/pcsc/2 0x000003 - /dev/pcsc/3
120     *
121     * USB readers may choose to ignore this parameter and query the bus
122     * for the particular reader.
123     */
124    
125     /*
126     * This function is required to open a communications channel to the
127     * port listed by Channel. For example, the first serial reader on
128     * COM1 would link to /dev/pcsc/1 which would be a sym link to
129     * /dev/ttyS0 on some machines This is used to help with intermachine
130     * independance.
131     *
132     * Once the channel is opened the reader must be in a state in which
133     * it is possible to query IFDHICCPresence() for card status.
134     *
135     * returns:
136     *
137     * IFD_SUCCESS IFD_COMMUNICATION_ERROR
138     */
139     RESPONSECODE return_value = IFD_SUCCESS;
140 rousseau 1107 int reader_index;
141 rousseau 269
142 rousseau 773 if (! DebugInitialized)
143 rousseau 880 init_driver();
144 rousseau 773
145 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
146 rousseau 269
147 rousseau 1107 if (-1 == (reader_index = GetNewReaderIndex(Lun)))
148 rousseau 269 return IFD_COMMUNICATION_ERROR;
149    
150 rousseau 410 /* Reset ATR buffer */
151 rousseau 1107 CcidSlots[reader_index].nATRLength = 0;
152     *CcidSlots[reader_index].pcATRBuffer = '\0';
153 rousseau 269
154 rousseau 410 /* Reset PowerFlags */
155 rousseau 1107 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
156 rousseau 269
157 rousseau 563 #ifdef HAVE_PTHREAD
158 rousseau 463 pthread_mutex_lock(&ifdh_context_mutex);
159     #endif
160    
161 rousseau 1107 if (OpenPort(reader_index, Channel) != STATUS_SUCCESS)
162 rousseau 269 {
163 rousseau 663 DEBUG_CRITICAL("failed");
164 rousseau 269 return_value = IFD_COMMUNICATION_ERROR;
165 rousseau 1152
166     /* release the allocated reader_index */
167     ReleaseReaderIndex(reader_index);
168 rousseau 269 }
169 rousseau 1152 else
170     /* Maybe we have a special treatment for this reader */
171     ccid_open_hack(reader_index);
172 rousseau 269
173 rousseau 563 #ifdef HAVE_PTHREAD
174 rousseau 463 pthread_mutex_unlock(&ifdh_context_mutex);
175     #endif
176    
177 rousseau 269 return return_value;
178     } /* IFDHCreateChannel */
179    
180    
181     RESPONSECODE IFDHCloseChannel(DWORD Lun)
182     {
183     /*
184     * This function should close the reader communication channel for the
185     * particular reader. Prior to closing the communication channel the
186     * reader should make sure the card is powered down and the terminal
187     * is also powered down.
188     *
189     * returns:
190     *
191     * IFD_SUCCESS IFD_COMMUNICATION_ERROR
192     */
193 rousseau 1107 int reader_index;
194 rousseau 269
195 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
196 rousseau 269
197 rousseau 1107 if (-1 == (reader_index = LunToReaderIndex(Lun)))
198 rousseau 269 return IFD_COMMUNICATION_ERROR;
199    
200 rousseau 1107 (void)CmdPowerOff(reader_index);
201 rousseau 410 /* No reader status check, if it failed, what can you do ? :) */
202 rousseau 269
203 rousseau 563 #ifdef HAVE_PTHREAD
204 rousseau 463 pthread_mutex_lock(&ifdh_context_mutex);
205     #endif
206    
207 rousseau 1107 (void)ClosePort(reader_index);
208     ReleaseReaderIndex(reader_index);
209 rousseau 269
210 rousseau 563 #ifdef HAVE_PTHREAD
211 rousseau 463 pthread_mutex_unlock(&ifdh_context_mutex);
212     #endif
213    
214 rousseau 269 return IFD_SUCCESS;
215     } /* IFDHCloseChannel */
216    
217    
218     RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag,
219     PDWORD Length, PUCHAR Value)
220     {
221     /*
222     * This function should get the slot/card capabilities for a
223     * particular slot/card specified by Lun. Again, if you have only 1
224     * card slot and don't mind loading a new driver for each reader then
225     * ignore Lun.
226     *
227     * Tag - the tag for the information requested example: TAG_IFD_ATR -
228     * return the Atr and it's size (required). these tags are defined in
229     * ifdhandler.h
230     *
231     * Length - the length of the returned data Value - the value of the
232     * data
233     *
234     * returns:
235     *
236     * IFD_SUCCESS IFD_ERROR_TAG
237     */
238 rousseau 1107 int reader_index;
239 rousseau 269
240 rousseau 804 DEBUG_INFO3("lun: %X, tag: 0x%X", Lun, Tag);
241 rousseau 269
242 rousseau 1107 if (-1 == (reader_index = LunToReaderIndex(Lun)))
243 rousseau 269 return IFD_COMMUNICATION_ERROR;
244    
245     switch (Tag)
246     {
247     case TAG_IFD_ATR:
248 rousseau 804 case SCARD_ATTR_ATR_STRING:
249 rousseau 410 /* If Length is not zero, powerICC has been performed.
250     * Otherwise, return NULL pointer
251     * Buffer size is stored in *Length */
252 rousseau 1107 *Length = (*Length < CcidSlots[reader_index].nATRLength) ?
253     *Length : CcidSlots[reader_index].nATRLength;
254 rousseau 269
255     if (*Length)
256 rousseau 1437 memcpy(Value, CcidSlots[reader_index].pcATRBuffer, *Length);
257 rousseau 269 break;
258    
259 rousseau 563 #ifdef HAVE_PTHREAD
260 rousseau 269 case TAG_IFD_SIMULTANEOUS_ACCESS:
261     if (*Length >= 1)
262     {
263     *Length = 1;
264 rousseau 1077 *Value = CCID_DRIVER_MAX_READERS;
265 rousseau 269 }
266     break;
267    
268 rousseau 463 case TAG_IFD_THREAD_SAFE:
269     if (*Length >= 1)
270     {
271     *Length = 1;
272     *Value = 1; /* Can talk to multiple readers at the same time */
273     }
274     break;
275 rousseau 563 #endif
276 rousseau 463
277 rousseau 269 case TAG_IFD_SLOTS_NUMBER:
278     if (*Length >= 1)
279     {
280     *Length = 1;
281 rousseau 1107 *Value = 1 + get_ccid_descriptor(reader_index) -> bMaxSlotIndex;
282     DEBUG_COMM2("Reader supports %d slots", *Value);
283 rousseau 269 }
284     break;
285    
286 rousseau 1107 case TAG_IFD_SLOT_THREAD_SAFE:
287     if (*Length >= 1)
288     {
289     *Length = 1;
290 rousseau 1153 *Value = 0; /* Can NOT talk to multiple slots at the same time */
291 rousseau 1107 }
292     break;
293    
294 rousseau 900 case IOCTL_SMARTCARD_VENDOR_VERIFY_PIN:
295     if (*Length >= 1)
296     {
297     *Length = 1;
298 rousseau 1107 *Value = get_ccid_descriptor(reader_index) -> bPINSupport & CCID_CLASS_PIN_VERIFY;
299 rousseau 900 }
300     break;
301    
302 rousseau 269 default:
303     return IFD_ERROR_TAG;
304     }
305 rousseau 569
306 rousseau 269 return IFD_SUCCESS;
307     } /* IFDHGetCapabilities */
308    
309    
310     RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag,
311 rousseau 1053 /*@unused@*/ DWORD Length, /*@unused@*/ PUCHAR Value)
312 rousseau 269 {
313     /*
314     * This function should set the slot/card capabilities for a
315     * particular slot/card specified by Lun. Again, if you have only 1
316     * card slot and don't mind loading a new driver for each reader then
317     * ignore Lun.
318     *
319     * Tag - the tag for the information needing set
320     *
321     * Length - the length of the returned data Value - the value of the
322     * data
323     *
324     * returns:
325     *
326     * IFD_SUCCESS IFD_ERROR_TAG IFD_ERROR_SET_FAILURE
327     * IFD_ERROR_VALUE_READ_ONLY
328     */
329    
330 rousseau 410 /* By default, say it worked */
331 rousseau 269
332 rousseau 804 DEBUG_INFO3("lun: %X, tag: 0x%X", Lun, Tag);
333 rousseau 269
334     /* if (CheckLun(Lun))
335     return IFD_COMMUNICATION_ERROR; */
336    
337 rousseau 569 return IFD_NOT_SUPPORTED;
338 rousseau 269 } /* IFDHSetCapabilities */
339    
340    
341     RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
342     UCHAR Flags, UCHAR PTS1, UCHAR PTS2, UCHAR PTS3)
343     {
344     /*
345     * This function should set the PTS of a particular card/slot using
346     * the three PTS parameters sent
347     *
348 rousseau 998 * Protocol - 0 .... 14 T=0 .... T=14
349     * Flags - Logical OR of possible values:
350     * IFD_NEGOTIATE_PTS1
351     * IFD_NEGOTIATE_PTS2
352     * IFD_NEGOTIATE_PTS3
353     * to determine which PTS values to negotiate.
354     * PTS1,PTS2,PTS3 - PTS Values.
355 rousseau 269 *
356     * returns:
357 rousseau 998 * IFD_SUCCESS
358     * IFD_ERROR_PTS_FAILURE
359     * IFD_COMMUNICATION_ERROR
360     * IFD_PROTOCOL_NOT_SUPPORTED
361 rousseau 269 */
362    
363 rousseau 998 BYTE pps[PPS_MAX_LENGTH];
364 rousseau 1368 ATR_t atr;
365 rousseau 998 unsigned int len;
366     int convention;
367 rousseau 1107 int reader_index;
368 rousseau 269
369 rousseau 998 /* Set ccid desc params */
370     CcidDesc *ccid_slot;
371     _ccid_descriptor *ccid_desc;
372 rousseau 269
373 rousseau 998 DEBUG_INFO3("lun: %X, protocol T=%d", Lun, Protocol-1);
374    
375 rousseau 1107 if (-1 == (reader_index = LunToReaderIndex(Lun)))
376 rousseau 998 return IFD_COMMUNICATION_ERROR;
377    
378     /* Set to zero buffer */
379     memset(pps, 0, sizeof(pps));
380     memset(&atr, 0, sizeof(atr));
381    
382     /* Get ccid params */
383 rousseau 1107 ccid_slot = get_ccid_slot(reader_index);
384     ccid_desc = get_ccid_descriptor(reader_index);
385 rousseau 998
386 rousseau 1354 /* Do not send CCID command SetParameters or PPS to the CCID
387     * The CCID will do this himself */
388     if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
389     return IFD_SUCCESS;
390    
391 rousseau 998 /* Get ATR of the card */
392     ATR_InitFromArray(&atr, ccid_slot->pcATRBuffer, ccid_slot->nATRLength);
393    
394 rousseau 1438 /* Apply Extra EGT patch for bogus cards */
395     extra_egt(&atr, ccid_desc, Protocol);
396    
397 rousseau 998 if (SCARD_PROTOCOL_T0 == Protocol)
398     pps[1] |= ATR_PROTOCOL_TYPE_T0;
399     else
400     if (SCARD_PROTOCOL_T1 == Protocol)
401     pps[1] |= ATR_PROTOCOL_TYPE_T1;
402     else
403     return IFD_PROTOCOL_NOT_SUPPORTED;
404    
405     /* TA2 present -> specific mode */
406     if (atr.ib[1][ATR_INTERFACE_BYTE_TA].present)
407     {
408     if (pps[1] != (atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x0F))
409     {
410     /* wrong protocol */
411     DEBUG_COMM3("Specific mode in T=%d and T=%d requested",
412     atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x0F, pps[1]);
413    
414     return IFD_PROTOCOL_NOT_SUPPORTED;
415     }
416     }
417    
418     /* TCi (i>2) indicates CRC instead of LRC */
419     if (SCARD_PROTOCOL_T1 == Protocol)
420     {
421     t1_state_t *t1 = &(ccid_slot -> t1);
422     int i;
423    
424     /* TCi (i>2) present? */
425     for (i=2; i<ATR_MAX_PROTOCOLS; i++)
426     if (atr.ib[i][ATR_INTERFACE_BYTE_TC].present)
427     {
428     if (0 == atr.ib[i][ATR_INTERFACE_BYTE_TC].value)
429     {
430     DEBUG_COMM("Use LRC");
431     t1_set_param(t1, IFD_PROTOCOL_T1_CHECKSUM_LRC, 0);
432     }
433     else
434     if (1 == atr.ib[i][ATR_INTERFACE_BYTE_TC].value)
435     {
436     DEBUG_COMM("Use CRC");
437     t1_set_param(t1, IFD_PROTOCOL_T1_CHECKSUM_CRC, 0);
438     }
439     else
440     DEBUG_COMM2("Wrong value for TCi: %d",
441     atr.ib[i][ATR_INTERFACE_BYTE_TC].value);
442    
443     /* only the first TCi (i>2) must be used */
444     break;
445     }
446     }
447    
448     /* PTS1? */
449     if (Flags & IFD_NEGOTIATE_PTS1)
450     {
451     /* just use the value passed in argument */
452     pps[1] |= 0x10; /* PTS1 presence */
453     pps[2] = PTS1;
454     }
455     else
456     {
457 rousseau 1352 /* TA1 present */
458     if (atr.ib[0][ATR_INTERFACE_BYTE_TA].present)
459 rousseau 998 {
460     unsigned int card_baudrate;
461     unsigned int default_baudrate;
462     double f, d;
463    
464     ATR_GetParameter(&atr, ATR_PARAMETER_D, &d);
465     ATR_GetParameter(&atr, ATR_PARAMETER_F, &f);
466    
467     /* Baudrate = f x D/F */
468     card_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock
469     * d / f);
470    
471     default_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock
472     * ATR_DEFAULT_D / ATR_DEFAULT_F);
473    
474     /* if the reader is fast enough */
475 rousseau 1351 if ((card_baudrate <= ccid_desc->dwMaxDataRate)
476 rousseau 998 /* and the card does not try to lower the default speed */
477     && (card_baudrate > default_baudrate ))
478     {
479     pps[1] |= 0x10; /* PTS1 presence */
480     pps[2] = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;
481    
482     DEBUG_COMM2("Set speed to %d bauds", card_baudrate);
483     }
484     }
485     }
486    
487     /* PTS2? */
488     if (Flags & IFD_NEGOTIATE_PTS2)
489     {
490     pps[1] |= 0x20; /* PTS2 presence */
491     pps[3] = PTS2;
492     }
493    
494     /* PTS3? */
495     if (Flags & IFD_NEGOTIATE_PTS3)
496     {
497     pps[1] |= 0x40; /* PTS3 presence */
498     pps[4] = PTS3;
499     }
500    
501     /* Generate PPS */
502     pps[0] = 0xFF;
503    
504     /* Automatic PPS made by the ICC? */
505     if ((! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_CUR))
506     /* TA2 absent: negociable mode */
507     && (! atr.ib[1][ATR_INTERFACE_BYTE_TA].present))
508     {
509     int default_protocol;
510    
511     if (ATR_MALFORMED == ATR_GetDefaultProtocol(&atr, &default_protocol))
512     return IFD_PROTOCOL_NOT_SUPPORTED;
513    
514     /* if the requested protocol is not the default one
515     * or a TA1/PPS1 is present */
516     if (((pps[1] & 0x0F) != default_protocol) || (PPS_HAS_PPS1(pps)))
517 rousseau 1107 if (PPS_Exchange(reader_index, pps, &len, &pps[2]) != PPS_OK)
518 rousseau 998 {
519     DEBUG_INFO("PPS_Exchange Failed");
520    
521     return IFD_ERROR_PTS_FAILURE;
522     }
523     }
524    
525     /* Now we must set the reader parameters */
526     ATR_GetConvention(&atr, &convention);
527    
528     /* specific mode and implicit parameters? (b5 of TA2) */
529     if (atr.ib[1][ATR_INTERFACE_BYTE_TA].present
530     && (atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x10))
531     return IFD_COMMUNICATION_ERROR;
532    
533     /* T=1 */
534     if (SCARD_PROTOCOL_T1 == Protocol)
535     {
536     BYTE param[] = {
537     0x11, /* Fi/Di */
538     0x10, /* TCCKS */
539     0x00, /* GuardTime */
540 rousseau 1439 0x4D, /* BWI/CWI */
541 rousseau 998 0x00, /* ClockStop */
542     0x20, /* IFSC */
543     0x00 /* NADValue */
544     };
545     int i;
546 rousseau 1195 t1_state_t *t1 = &(ccid_slot -> t1);
547 rousseau 1213 RESPONSECODE ret;
548 rousseau 998
549     /* TA1 is not default */
550     if (PPS_HAS_PPS1(pps))
551     param[0] = pps[2];
552 rousseau 1437
553 rousseau 1195 /* CRC checksum? */
554     if (2 == t1->rc_bytes)
555 rousseau 1196 param[1] |= 0x01;
556 rousseau 998
557 rousseau 1195 /* the CCID should ignore this bit */
558 rousseau 998 if (ATR_CONVENTION_INVERSE == convention)
559 rousseau 1196 param[1] |= 0x02;
560 rousseau 998
561     /* get TC1 Extra guard time */
562     if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)
563     param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;
564    
565 rousseau 1439 /* TBi (i>2) present? BWI/CWI */
566 rousseau 998 for (i=2; i<ATR_MAX_PROTOCOLS; i++)
567     if (atr.ib[i][ATR_INTERFACE_BYTE_TB].present)
568     {
569 rousseau 1439 DEBUG_COMM3("BWI/CWI (TB%d) present: 0x%02X", i+1,
570 rousseau 998 atr.ib[i][ATR_INTERFACE_BYTE_TB].value);
571     param[3] = atr.ib[i][ATR_INTERFACE_BYTE_TB].value;
572    
573     /* only the first TBi (i>2) must be used */
574     break;
575     }
576    
577 rousseau 1213 ret = SetParameters(reader_index, 1, sizeof(param), param);
578     if (IFD_SUCCESS != ret)
579     return ret;
580 rousseau 998 }
581     else
582     /* T=0 */
583     {
584     BYTE param[] = {
585     0x11, /* Fi/Di */
586     0x00, /* TCCKS */
587     0x00, /* GuardTime */
588     0x0A, /* WaitingInteger */
589     0x00 /* ClockStop */
590     };
591 rousseau 1213 RESPONSECODE ret;
592 rousseau 998
593     /* TA1 is not default */
594     if (PPS_HAS_PPS1(pps))
595     param[0] = pps[2];
596    
597     if (ATR_CONVENTION_INVERSE == convention)
598 rousseau 1196 param[1] |= 0x02;
599 rousseau 998
600     /* get TC1 Extra guard time */
601     if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)
602     param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;
603    
604     /* TC2 WWT */
605     if (atr.ib[1][ATR_INTERFACE_BYTE_TC].present)
606     param[3] = atr.ib[1][ATR_INTERFACE_BYTE_TC].value;
607    
608 rousseau 1213 ret = SetParameters(reader_index, 0, sizeof(param), param);
609     if (IFD_SUCCESS != ret)
610     return ret;
611 rousseau 998 }
612    
613     /* set IFSC & IFSD in T=1 */
614     if (SCARD_PROTOCOL_T1 == Protocol)
615     {
616     t1_state_t *t1 = &(ccid_slot -> t1);
617     int i;
618    
619     /* TAi (i>2) present? */
620     for (i=2; i<ATR_MAX_PROTOCOLS; i++)
621     if (atr.ib[i][ATR_INTERFACE_BYTE_TA].present)
622     {
623     DEBUG_COMM3("IFSC (TA%d) present: %d", i+1,
624     atr.ib[i][ATR_INTERFACE_BYTE_TA].value);
625     t1_set_param(t1, IFD_PROTOCOL_T1_IFSC,
626     atr.ib[i][ATR_INTERFACE_BYTE_TA].value);
627    
628     /* only the first TAi (i>2) must be used */
629     break;
630     }
631    
632     /* IFSD not negociated by the reader? */
633     if (! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_IFSD))
634     {
635 rousseau 1437 DEBUG_COMM2("Negociate IFSD at %d", ccid_desc -> dwMaxIFSD);
636 rousseau 998 if (t1_negociate_ifsd(t1, 0, ccid_desc -> dwMaxIFSD) < 0)
637     return IFD_COMMUNICATION_ERROR;
638     }
639     t1_set_param(t1, IFD_PROTOCOL_T1_IFSD, ccid_desc -> dwMaxIFSD);
640    
641     DEBUG_COMM3("T=1: IFSC=%d, IFSD=%d", t1->ifsc, t1->ifsd);
642     }
643    
644     return IFD_SUCCESS;
645 rousseau 269 } /* IFDHSetProtocolParameters */
646    
647    
648     RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action,
649     PUCHAR Atr, PDWORD AtrLength)
650     {
651     /*
652     * This function controls the power and reset signals of the smartcard
653     * reader at the particular reader/slot specified by Lun.
654     *
655     * Action - Action to be taken on the card.
656     *
657     * IFD_POWER_UP - Power and reset the card if not done so (store the
658     * ATR and return it and it's length).
659     *
660     * IFD_POWER_DOWN - Power down the card if not done already
661     * (Atr/AtrLength should be zero'd)
662     *
663     * IFD_RESET - Perform a quick reset on the card. If the card is not
664     * powered power up the card. (Store and return the Atr/Length)
665     *
666     * Atr - Answer to Reset of the card. The driver is responsible for
667     * caching this value in case IFDHGetCapabilities is called requesting
668     * the ATR and it's length. This should not exceed MAX_ATR_SIZE.
669     *
670     * AtrLength - Length of the Atr. This should not exceed
671     * MAX_ATR_SIZE.
672     *
673     * Notes:
674     *
675     * Memory cards without an ATR should return IFD_SUCCESS on reset but
676     * the Atr should be zero'd and the length should be zero
677     *
678     * Reset errors should return zero for the AtrLength and return
679     * IFD_ERROR_POWER_ACTION.
680     *
681     * returns:
682     *
683     * IFD_SUCCESS IFD_ERROR_POWER_ACTION IFD_COMMUNICATION_ERROR
684     * IFD_NOT_SUPPORTED
685     */
686    
687 rousseau 892 unsigned int nlength;
688 rousseau 269 RESPONSECODE return_value = IFD_SUCCESS;
689     unsigned char pcbuffer[RESP_BUF_SIZE];
690 rousseau 1107 int reader_index;
691 rousseau 269
692 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
693 rousseau 269
694 rousseau 410 /* By default, assume it won't work :) */
695 rousseau 269 *AtrLength = 0;
696    
697 rousseau 1107 if (-1 == (reader_index = LunToReaderIndex(Lun)))
698 rousseau 269 return IFD_COMMUNICATION_ERROR;
699    
700 rousseau 766 switch (Action)
701 rousseau 269 {
702 rousseau 766 case IFD_POWER_DOWN:
703     /* Clear ATR buffer */
704 rousseau 1107 CcidSlots[reader_index].nATRLength = 0;
705     *CcidSlots[reader_index].pcATRBuffer = '\0';
706 rousseau 269
707 rousseau 766 /* Memorise the request */
708 rousseau 1437 CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PDWN;
709 rousseau 998
710 rousseau 766 /* send the command */
711 rousseau 1107 if (IFD_SUCCESS != CmdPowerOff(reader_index))
712 rousseau 766 {
713     DEBUG_CRITICAL("PowerDown failed");
714     return_value = IFD_ERROR_POWER_ACTION;
715     goto end;
716     }
717 rousseau 269
718 rousseau 998 /* clear T=1 context */
719 rousseau 1107 t1_release(&(get_ccid_slot(reader_index) -> t1));
720 rousseau 840 break;
721 rousseau 616
722 rousseau 766 case IFD_POWER_UP:
723     case IFD_RESET:
724     nlength = sizeof(pcbuffer);
725 rousseau 1107 if (CmdPowerOn(reader_index, &nlength, pcbuffer) != IFD_SUCCESS)
726 rousseau 766 {
727     DEBUG_CRITICAL("PowerUp failed");
728     return_value = IFD_ERROR_POWER_ACTION;
729     goto end;
730     }
731 rousseau 269
732 rousseau 766 /* Power up successful, set state variable to memorise it */
733 rousseau 1437 CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PUP;
734     CcidSlots[reader_index].bPowerFlags &= ~MASK_POWERFLAGS_PDWN;
735 rousseau 269
736 rousseau 766 /* Reset is returned, even if TCK is wrong */
737 rousseau 1107 CcidSlots[reader_index].nATRLength = *AtrLength =
738 rousseau 766 (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE;
739     memcpy(Atr, pcbuffer, *AtrLength);
740 rousseau 1437 memcpy(CcidSlots[reader_index].pcATRBuffer, pcbuffer, *AtrLength);
741 rousseau 616
742 rousseau 998 /* initialise T=1 context */
743 rousseau 1107 t1_init(&(get_ccid_slot(reader_index) -> t1), reader_index);
744 rousseau 766 break;
745    
746     default:
747     DEBUG_CRITICAL("Action not supported");
748     return_value = IFD_NOT_SUPPORTED;
749 rousseau 269 }
750     end:
751    
752     return return_value;
753     } /* IFDHPowerICC */
754    
755    
756     RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci,
757     PUCHAR TxBuffer, DWORD TxLength,
758 rousseau 1053 PUCHAR RxBuffer, PDWORD RxLength, /*@unused@*/ PSCARD_IO_HEADER RecvPci)
759 rousseau 269 {
760     /*
761     * This function performs an APDU exchange with the card/slot
762     * specified by Lun. The driver is responsible for performing any
763     * protocol specific exchanges such as T=0/1 ... differences. Calling
764     * this function will abstract all protocol differences.
765     *
766     * SendPci Protocol - 0, 1, .... 14 Length - Not used.
767     *
768     * TxBuffer - Transmit APDU example (0x00 0xA4 0x00 0x00 0x02 0x3F
769     * 0x00) TxLength - Length of this buffer. RxBuffer - Receive APDU
770     * example (0x61 0x14) RxLength - Length of the received APDU. This
771     * function will be passed the size of the buffer of RxBuffer and this
772     * function is responsible for setting this to the length of the
773     * received APDU. This should be ZERO on all errors. The resource
774     * manager will take responsibility of zeroing out any temporary APDU
775     * buffers for security reasons.
776     *
777     * RecvPci Protocol - 0, 1, .... 14 Length - Not used.
778     *
779     * Notes: The driver is responsible for knowing what type of card it
780     * has. If the current slot/card contains a memory card then this
781     * command should ignore the Protocol and use the MCT style commands
782     * for support for these style cards and transmit them appropriately.
783     * If your reader does not support memory cards or you don't want to
784     * then ignore this.
785     *
786     * RxLength should be set to zero on error.
787     *
788     * returns:
789     *
790     * IFD_SUCCESS IFD_COMMUNICATION_ERROR IFD_RESPONSE_TIMEOUT
791     * IFD_ICC_NOT_PRESENT IFD_PROTOCOL_NOT_SUPPORTED
792     */
793    
794 rousseau 611 RESPONSECODE return_value;
795 rousseau 892 unsigned int rx_length;
796 rousseau 1107 int reader_index;
797 rousseau 269
798 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
799 rousseau 269
800 rousseau 1107 if (-1 == (reader_index = LunToReaderIndex(Lun)))
801 rousseau 269 return IFD_COMMUNICATION_ERROR;
802    
803 rousseau 611 rx_length = *RxLength;
804 rousseau 1107 return_value = CmdXfrBlock(reader_index, TxLength, TxBuffer, &rx_length,
805     RxBuffer, SendPci.Protocol);
806 rousseau 611 *RxLength = rx_length;
807 rousseau 269
808     return return_value;
809     } /* IFDHTransmitToICC */
810    
811    
812 rousseau 1085 RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, PUCHAR TxBuffer,
813     DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, PDWORD pdwBytesReturned)
814 rousseau 269 {
815     /*
816     * This function performs a data exchange with the reader (not the
817     * card) specified by Lun. Here XXXX will only be used. It is
818     * responsible for abstracting functionality such as PIN pads,
819     * biometrics, LCD panels, etc. You should follow the MCT, CTBCS
820     * specifications for a list of accepted commands to implement.
821     *
822     * TxBuffer - Transmit data TxLength - Length of this buffer. RxBuffer
823     * - Receive data RxLength - Length of the received data. This
824     * function will be passed the length of the buffer RxBuffer and it
825     * must set this to the length of the received data.
826     *
827     * Notes: RxLength should be zero on error.
828     */
829 rousseau 880 RESPONSECODE return_value = IFD_COMMUNICATION_ERROR;
830 rousseau 1107 int reader_index;
831 rousseau 269
832 rousseau 795 DEBUG_INFO3("lun: %X, ControlCode: 0x%X", Lun, dwControlCode);
833 rousseau 269
834 rousseau 1107 reader_index = LunToReaderIndex(Lun);
835     if ((-1 == reader_index) || (NULL == pdwBytesReturned)
836     || (NULL == RxBuffer))
837 rousseau 880 return return_value;
838 rousseau 269
839 rousseau 568 /* Set the return length to 0 to avoid problems */
840 rousseau 880 *pdwBytesReturned = 0;
841 rousseau 568
842 rousseau 880 if (IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE == dwControlCode)
843     {
844     if (FALSE == (DriverOptions & DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED))
845 rousseau 891 {
846     DEBUG_INFO("ifd exchange (Escape command) not allowed");
847 rousseau 880 return_value = IFD_COMMUNICATION_ERROR;
848 rousseau 891 }
849 rousseau 880 else
850     {
851 rousseau 892 unsigned int iBytesReturned;
852 rousseau 891
853     iBytesReturned = RxLength;
854 rousseau 1107 return_value = CmdEscape(reader_index, TxBuffer, TxLength, RxBuffer,
855 rousseau 891 &iBytesReturned);
856     *pdwBytesReturned = iBytesReturned;
857 rousseau 880 }
858     }
859    
860 rousseau 891 if (IOCTL_SMARTCARD_VENDOR_VERIFY_PIN == dwControlCode)
861     {
862 rousseau 892 unsigned int iBytesReturned;
863 rousseau 891
864     iBytesReturned = RxLength;
865 rousseau 1107 return_value = SecurePIN(reader_index, TxBuffer, TxLength, RxBuffer,
866 rousseau 891 &iBytesReturned);
867     *pdwBytesReturned = iBytesReturned;
868     }
869    
870 rousseau 880 return return_value;
871 rousseau 269 } /* IFDHControl */
872    
873    
874     RESPONSECODE IFDHICCPresence(DWORD Lun)
875     {
876     /*
877     * This function returns the status of the card inserted in the
878     * reader/slot specified by Lun. It will return either:
879     *
880     * returns: IFD_ICC_PRESENT IFD_ICC_NOT_PRESENT
881     * IFD_COMMUNICATION_ERROR
882     */
883    
884     unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
885     RESPONSECODE return_value = IFD_COMMUNICATION_ERROR;
886 rousseau 999 int oldLogLevel;
887 rousseau 1107 int reader_index;
888 rousseau 1154 _ccid_descriptor *ccid_descriptor;
889 rousseau 269
890 rousseau 608 DEBUG_PERIODIC2("lun: %X", Lun);
891 rousseau 269
892 rousseau 1107 if (-1 == (reader_index = LunToReaderIndex(Lun)))
893 rousseau 269 return IFD_COMMUNICATION_ERROR;
894    
895 rousseau 1154 ccid_descriptor = get_ccid_descriptor(reader_index);
896    
897 rousseau 999 /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */
898     oldLogLevel = LogLevel;
899     if (! (LogLevel & DEBUG_LEVEL_PERIODIC))
900     LogLevel &= ~DEBUG_LEVEL_COMM;
901    
902 rousseau 1107 return_value = CmdGetSlotStatus(reader_index, pcbuffer);
903 rousseau 999
904     /* set back the old LogLevel */
905     LogLevel = oldLogLevel;
906    
907     if (return_value != IFD_SUCCESS)
908 rousseau 269 return IFD_COMMUNICATION_ERROR;
909    
910 rousseau 999 return_value = IFD_COMMUNICATION_ERROR;
911 rousseau 1261 switch (pcbuffer[7] & CCID_ICC_STATUS_MASK) /* bStatus */
912 rousseau 269 {
913 rousseau 1261 case CCID_ICC_PRESENT_ACTIVE:
914     case CCID_ICC_PRESENT_INACTIVE:
915 rousseau 269 return_value = IFD_ICC_PRESENT;
916 rousseau 1094 /* use default slot */
917 rousseau 269 break;
918    
919 rousseau 1261 case CCID_ICC_ABSENT:
920 rousseau 807 /* Reset ATR buffer */
921 rousseau 1107 CcidSlots[reader_index].nATRLength = 0;
922     *CcidSlots[reader_index].pcATRBuffer = '\0';
923 rousseau 807
924     /* Reset PowerFlags */
925 rousseau 1107 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
926 rousseau 807
927 rousseau 269 return_value = IFD_ICC_NOT_PRESENT;
928     break;
929     }
930    
931 rousseau 1094 /* SCR331-DI contactless reader */
932     if ((SCR331DI == ccid_descriptor->readerID)
933 rousseau 1155 && (ccid_descriptor->bCurrentSlotIndex > 0))
934 rousseau 1094 {
935     unsigned char cmd[] = { 0x11 };
936     /* command: 11 ??
937     * response: 00 11 01 ?? no card
938     * 01 04 00 ?? card present */
939    
940     unsigned char res[10];
941     unsigned int length_res = sizeof(res);
942    
943     /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */
944     oldLogLevel = LogLevel;
945     if (! (LogLevel & DEBUG_LEVEL_PERIODIC))
946     LogLevel &= ~DEBUG_LEVEL_COMM;
947    
948 rousseau 1107 CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res);
949 rousseau 1094
950     /* set back the old LogLevel */
951     LogLevel = oldLogLevel;
952    
953     if (0x01 == res[0])
954     return_value = IFD_ICC_PRESENT;
955 rousseau 1155 else
956     {
957     /* Reset ATR buffer */
958     CcidSlots[reader_index].nATRLength = 0;
959     *CcidSlots[reader_index].pcATRBuffer = '\0';
960 rousseau 1094
961 rousseau 1155 /* Reset PowerFlags */
962     CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
963 rousseau 1094
964 rousseau 1155 return_value = IFD_ICC_NOT_PRESENT;
965 rousseau 1094 }
966     }
967    
968 rousseau 1156 DEBUG_PERIODIC2("Card %s",
969     IFD_ICC_PRESENT == return_value ? "present" : "absent");
970    
971 rousseau 269 return return_value;
972     } /* IFDHICCPresence */
973    
974 rousseau 609
975 rousseau 1107 CcidDesc *get_ccid_slot(unsigned int reader_index)
976 rousseau 609 {
977 rousseau 1107 return &CcidSlots[reader_index];
978 rousseau 609 } /* get_ccid_slot */
979    
980 rousseau 673
981 rousseau 880 void init_driver(void)
982 rousseau 773 {
983     char keyValue[TOKEN_MAX_VALUE_SIZE];
984     char infofile[FILENAME_MAX];
985    
986     /* Info.plist full patch filename */
987     snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
988     PCSCLITE_HP_DROPDIR, BUNDLE);
989    
990 rousseau 880 /* Log level */
991     if (0 == LTPBundleFindValueWithKey(infofile, "ifdLogLevel", keyValue, 0))
992     {
993     /* convert from hex or dec or octal */
994 rousseau 1078 LogLevel = strtoul(keyValue, NULL, 0);
995 rousseau 773
996 rousseau 880 /* print the log level used */
997 rousseau 1408 DEBUG_INFO2("LogLevel: 0x%.4X", LogLevel);
998 rousseau 880 }
999 rousseau 773
1000 rousseau 880 /* Driver options */
1001     if (0 == LTPBundleFindValueWithKey(infofile, "ifdDriverOptions", keyValue, 0))
1002     {
1003     /* convert from hex or dec or octal */
1004 rousseau 1078 DriverOptions = strtoul(keyValue, NULL, 0);
1005 rousseau 773
1006 rousseau 880 /* print the log level used */
1007 rousseau 1408 DEBUG_INFO2("DriverOptions: 0x%.4X", DriverOptions);
1008 rousseau 880 }
1009    
1010 rousseau 1107 /* initialise the Lun to reader_index mapping */
1011     InitReaderIndex();
1012    
1013 rousseau 773 DebugInitialized = TRUE;
1014 rousseau 880 } /* init_driver */
1015 rousseau 773
1016 rousseau 1438
1017     void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol)
1018     {
1019     /*
1020     * This function apply an extra EGT value for card who comply
1021     * with followings criterias.
1022     * If the extra EGT are not apply to the reader, the communication
1023     * with the smart card will be impossible.
1024     * It is a smart card bug wich are not compatible with ISO 7816-3
1025     * standard.
1026     */
1027    
1028 rousseau 1441 unsigned int card_baudrate;
1029     unsigned int default_baudrate;
1030     double f, d;
1031 rousseau 1438 int i;
1032    
1033     /* if TA1 not present */
1034     if (! atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
1035     return;
1036    
1037     ATR_GetParameter(atr, ATR_PARAMETER_D, &d);
1038     ATR_GetParameter(atr, ATR_PARAMETER_F, &f);
1039    
1040     /* Baudrate = f x D/F */
1041 rousseau 1441 card_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock * d / f);
1042 rousseau 1438
1043 rousseau 1441 default_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock
1044     * ATR_DEFAULT_D / ATR_DEFAULT_F);
1045 rousseau 1438
1046     /* TA1 > 11? */
1047     if (card_baudrate <= default_baudrate)
1048     return;
1049    
1050     /* Current EGT = 0 or FF? */
1051     if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present &&
1052     ((0x00 == atr->ib[0][ATR_INTERFACE_BYTE_TC].value) ||
1053 rousseau 1440 (0xFF == atr->ib[0][ATR_INTERFACE_BYTE_TC].value)))
1054 rousseau 1438 {
1055     if (SCARD_PROTOCOL_T0 == Protocol)
1056     {
1057     /* Init TC1 */
1058     atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1059     atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1060 rousseau 1440 DEBUG_INFO("Extra EGT patch applied");
1061 rousseau 1438 }
1062    
1063     if (SCARD_PROTOCOL_T1 == Protocol)
1064     {
1065 rousseau 1439 /* TBi (i>2) present? BWI/CWI */
1066 rousseau 1438 for (i=2; i<ATR_MAX_PROTOCOLS; i++)
1067     {
1068 rousseau 1440 /* CWI >= 2 ? */
1069     if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present &&
1070     ((atr->ib[i][ATR_INTERFACE_BYTE_TB].value & 0x0F) >= 2))
1071 rousseau 1438 {
1072 rousseau 1440 /* Init TC1 */
1073     atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1074     atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1075     DEBUG_INFO("Extra EGT patch applied");
1076 rousseau 1438
1077     /* only the first TBi (i>2) must be used */
1078     break;
1079     }
1080     }
1081     }
1082     }
1083     } /* extra_egt */
1084    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5