/[pcsclite]/trunk/Drivers/ccid/examples/scardcontrol.c
ViewVC logotype

Contents of /trunk/Drivers/ccid/examples/scardcontrol.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4341 - (hide annotations) (download)
Tue Jul 21 17:54:47 2009 UTC (3 years, 10 months ago) by rousseau
File MIME type: text/plain
File size: 17886 byte(s)
send a "secoder info" command if the reader supports
FEATURE_MCT_READERDIRECT
1 rousseau 889 /*
2     scardcontrol.c: sample code to use/test SCardControl() API
3 rousseau 3356 Copyright (C) 2004-2009 Ludovic Rousseau
4 rousseau 889
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15 rousseau 2974 You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc., 51
17     Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 rousseau 889 */
19    
20     /*
21     * $Id$
22     */
23    
24     #include <stdio.h>
25     #include <stdlib.h>
26 rousseau 1346 #include <sys/time.h>
27 rousseau 889 #include <unistd.h>
28     #include <string.h>
29 rousseau 2116 #include <arpa/inet.h>
30 rousseau 2597 #ifdef __APPLE__
31     #include <PCSC/winscard.h>
32     #include <PCSC/wintypes.h>
33     #else
34 rousseau 1771 #include <winscard.h>
35 rousseau 2597 #endif
36 rousseau 1771 #include <reader.h>
37 rousseau 889
38 rousseau 2407 #undef VERIFY_PIN
39     #define MODIFY_PIN
40 rousseau 3193 #undef GET_GEMPC_FIRMWARE
41 rousseau 1676
42 rousseau 889 #ifndef TRUE
43     #define TRUE 1
44     #define FALSE 0
45     #endif
46    
47     #define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE SCARD_CTL_CODE(1)
48    
49     /* PCSC error message pretty print */
50     #define PCSC_ERROR_EXIT(rv, text) \
51     if (rv != SCARD_S_SUCCESS) \
52     { \
53     printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
54     goto end; \
55     } \
56     else \
57     printf(text ": OK\n\n");
58    
59     #define PCSC_ERROR_CONT(rv, text) \
60     if (rv != SCARD_S_SUCCESS) \
61     printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
62     else \
63     printf(text ": OK\n\n");
64    
65     int main(int argc, char *argv[])
66     {
67     LONG rv;
68     SCARDCONTEXT hContext;
69     DWORD dwReaders;
70 rousseau 2591 LPSTR mszReaders = NULL;
71 rousseau 889 char *ptr, **readers = NULL;
72     int nbReaders;
73     SCARDHANDLE hCard;
74     DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen;
75     BYTE pbAtr[MAX_ATR_SIZE] = "";
76 rousseau 892 char pbReader[MAX_READERNAME] = "";
77 rousseau 889 int reader_nb;
78 rousseau 2592 unsigned int i;
79 rousseau 889 unsigned char bSendBuffer[MAX_BUFFER_SIZE];
80     unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
81 rousseau 1676 DWORD send_length, length;
82 rousseau 1631 DWORD verify_ioctl = 0;
83     DWORD modify_ioctl = 0;
84 rousseau 4341 DWORD pin_properties_ioctl = 0;
85     DWORD mct_readerdirect_ioctl = 0;
86 rousseau 972 SCARD_IO_REQUEST pioRecvPci;
87 rousseau 1635 SCARD_IO_REQUEST pioSendPci;
88 rousseau 1631 PCSC_TLV_STRUCTURE *pcsc_tlv;
89 rousseau 1691 #if defined(VERIFY_PIN) | defined(MODIFY_PIN)
90     int offset;
91     #endif
92     #ifdef VERIFY_PIN
93 rousseau 1631 PIN_VERIFY_STRUCTURE *pin_verify;
94 rousseau 1691 #endif
95     #ifdef MODIFY_PIN
96 rousseau 1631 PIN_MODIFY_STRUCTURE *pin_modify;
97 rousseau 1691 #endif
98 rousseau 4341 char secoder_info[] = { 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
99 rousseau 889
100     printf("SCardControl sample code\n");
101 rousseau 4337 printf("V 1.3 © 2004-2009, Ludovic Rousseau <ludovic.rousseau@free.fr>\n");
102 rousseau 889
103 rousseau 1263 printf("\nTHIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL!\n");
104     printf("Do NOT use it unless you really know what you do.\n\n");
105    
106 rousseau 889 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
107     if (rv != SCARD_S_SUCCESS)
108     {
109     printf("SCardEstablishContext: Cannot Connect to Resource Manager %lX\n", rv);
110     return 1;
111     }
112    
113     /* Retrieve the available readers list */
114     rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
115 rousseau 2590 PCSC_ERROR_EXIT(rv, "SCardListReaders")
116 rousseau 889
117     mszReaders = malloc(sizeof(char)*dwReaders);
118     if (mszReaders == NULL)
119     {
120     printf("malloc: not enough memory\n");
121     goto end;
122     }
123    
124     rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
125     if (rv != SCARD_S_SUCCESS)
126     printf("SCardListReader: %lX\n", rv);
127    
128     /* Extract readers from the null separated string and get the total
129     * number of readers */
130     nbReaders = 0;
131     ptr = mszReaders;
132     while (*ptr != '\0')
133     {
134     ptr += strlen(ptr)+1;
135     nbReaders++;
136     }
137    
138     if (nbReaders == 0)
139     {
140     printf("No reader found\n");
141     goto end;
142     }
143    
144     /* allocate the readers table */
145     readers = calloc(nbReaders, sizeof(char *));
146     if (NULL == readers)
147     {
148     printf("Not enough memory for readers[]\n");
149     goto end;
150     }
151    
152     /* fill the readers table */
153     nbReaders = 0;
154     ptr = mszReaders;
155 rousseau 4336 printf("Available readers (use command line argument to select)\n");
156 rousseau 889 while (*ptr != '\0')
157     {
158     printf("%d: %s\n", nbReaders, ptr);
159     readers[nbReaders] = ptr;
160     ptr += strlen(ptr)+1;
161     nbReaders++;
162     }
163 rousseau 4336 printf("\n");
164 rousseau 889
165     if (argc > 1)
166     {
167     reader_nb = atoi(argv[1]);
168     if (reader_nb < 0 || reader_nb >= nbReaders)
169     {
170     printf("Wrong reader index: %d\n", reader_nb);
171     goto end;
172     }
173     }
174     else
175     reader_nb = 0;
176    
177 rousseau 900 /* connect to a reader (even without a card) */
178 rousseau 889 dwActiveProtocol = -1;
179 rousseau 4336 printf("Using reader: %s\n", readers[reader_nb]);
180 rousseau 889 rv = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_DIRECT,
181 rousseau 940 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
182 rousseau 889 printf(" Protocol: %ld\n", dwActiveProtocol);
183     PCSC_ERROR_EXIT(rv, "SCardConnect")
184    
185 rousseau 3193 #ifdef GET_GEMPC_FIRMWARE
186 rousseau 972 /* get GemPC firmware */
187     printf(" Get GemPC Firmware\n");
188 rousseau 889
189     /* this is specific to Gemplus readers */
190     bSendBuffer[0] = 0x02;
191     rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, bSendBuffer,
192     1, bRecvBuffer, sizeof(bRecvBuffer), &length);
193    
194     printf(" Firmware: ");
195     for (i=0; i<length; i++)
196     printf("%02X ", bRecvBuffer[i]);
197     printf("\n");
198    
199     bRecvBuffer[length] = '\0';
200     printf(" Firmware: %s (length %ld bytes)\n", bRecvBuffer, length);
201    
202     PCSC_ERROR_CONT(rv, "SCardControl")
203 rousseau 3193 #endif
204 rousseau 889
205 rousseau 900 /* does the reader support PIN verification? */
206 rousseau 1631 rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
207     bRecvBuffer, sizeof(bRecvBuffer), &length);
208 rousseau 4335 PCSC_ERROR_EXIT(rv, "SCardControl")
209 rousseau 1631
210     printf(" TLV (%ld): ", length);
211     for (i=0; i<length; i++)
212     printf("%02X ", bRecvBuffer[i]);
213     printf("\n");
214    
215     PCSC_ERROR_CONT(rv, "SCardControl(CM_IOCTL_GET_FEATURE_REQUEST)")
216    
217     if (length % sizeof(PCSC_TLV_STRUCTURE))
218 rousseau 900 {
219 rousseau 1631 printf("Inconsistent result! Bad TLV values!\n");
220     goto end;
221     }
222    
223     /* get the number of elements instead of the complete size */
224     length /= sizeof(PCSC_TLV_STRUCTURE);
225    
226     pcsc_tlv = (PCSC_TLV_STRUCTURE *)bRecvBuffer;
227     for (i = 0; i < length; i++)
228     {
229 rousseau 4339 switch (pcsc_tlv[i].tag)
230     {
231     case FEATURE_VERIFY_PIN_DIRECT:
232 rousseau 4340 printf("Reader supports FEATURE_VERIFY_PIN_DIRECT\n");
233 rousseau 4339 verify_ioctl = ntohl(pcsc_tlv[i].value);
234     break;
235     case FEATURE_MODIFY_PIN_DIRECT:
236 rousseau 4340 printf("Reader supports FEATURE_MODIFY_PIN_DIRECT\n");
237 rousseau 4339 modify_ioctl = ntohl(pcsc_tlv[i].value);
238     break;
239 rousseau 4340 case FEATURE_IFD_PIN_PROPERTIES:
240     printf("Reader supports FEATURE_IFD_PIN_PROPERTIES\n");
241 rousseau 4341 pin_properties_ioctl = ntohl(pcsc_tlv[i].value);
242 rousseau 4340 break;
243     case FEATURE_MCT_READERDIRECT:
244     printf("Reader supports FEATURE_MCT_READERDIRECT\n");
245 rousseau 4341 mct_readerdirect_ioctl = ntohl(pcsc_tlv[i].value);
246 rousseau 4340 break;
247     default:
248     printf("Can't parse tag: 0x%02X\n", pcsc_tlv[i].tag);
249 rousseau 4339 }
250 rousseau 1631 }
251 rousseau 4341 printf("\n");
252 rousseau 1631
253 rousseau 4341 if (mct_readerdirect_ioctl)
254     {
255     rv = SCardControl(hCard, mct_readerdirect_ioctl, secoder_info,
256     sizeof(secoder_info), bRecvBuffer, sizeof(bRecvBuffer), &length);
257     PCSC_ERROR_CONT(rv, "SCardControl(MCT_READERDIRECT)")
258    
259     printf("MCT_READERDIRECT (%ld): ", length);
260     for (i=0; i<length; i++)
261     printf("%02X ", bRecvBuffer[i]);
262     printf("\n");
263    
264     }
265    
266 rousseau 1631 if (0 == verify_ioctl)
267     {
268 rousseau 900 printf("Reader %s does not support PIN verification\n",
269     readers[reader_nb]);
270     goto end;
271     }
272    
273 rousseau 4338 /* get card status */
274     dwAtrLen = sizeof(pbAtr);
275     dwReaderLen = sizeof(pbReader);
276     rv = SCardStatus(hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
277     pbAtr, &dwAtrLen);
278     printf(" Reader: %s (length %ld bytes)\n", pbReader, dwReaderLen);
279     printf(" State: 0x%04lX\n", dwState);
280     printf(" Prot: %ld\n", dwProt);
281     printf(" ATR (length %ld bytes):", dwAtrLen);
282     for (i=0; i<dwAtrLen; i++)
283     printf(" %02X", pbAtr[i]);
284     printf("\n");
285     PCSC_ERROR_CONT(rv, "SCardStatus")
286    
287     if (dwState & SCARD_ABSENT)
288     {
289     printf("No card inserted\n");
290     goto end;
291     }
292    
293 rousseau 972 /* connect to a reader (even without a card) */
294     dwActiveProtocol = -1;
295     rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
296 rousseau 2653 SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD,
297 rousseau 1635 &dwActiveProtocol);
298 rousseau 972 printf(" Protocol: %ld\n", dwActiveProtocol);
299     PCSC_ERROR_EXIT(rv, "SCardReconnect")
300    
301 rousseau 1635 switch(dwActiveProtocol)
302     {
303     case SCARD_PROTOCOL_T0:
304     pioSendPci = *SCARD_PCI_T0;
305     break;
306     case SCARD_PROTOCOL_T1:
307     pioSendPci = *SCARD_PCI_T1;
308     break;
309     default:
310 rousseau 2585 printf("Unknown protocol. No card present?\n");
311 rousseau 1635 return -1;
312     }
313    
314 rousseau 1676 /* APDU select applet */
315     printf("Select applet: ");
316     send_length = 11;
317     memcpy(bSendBuffer, "\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\xFF",
318     send_length);
319     for (i=0; i<send_length; i++)
320     printf(" %02X", bSendBuffer[i]);
321 rousseau 972 printf("\n");
322     length = sizeof(bRecvBuffer);
323 rousseau 1676 rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
324 rousseau 972 &pioRecvPci, bRecvBuffer, &length);
325     printf(" card response:");
326     for (i=0; i<length; i++)
327     printf(" %02X", bRecvBuffer[i]);
328     printf("\n");
329     PCSC_ERROR_EXIT(rv, "SCardTransmit")
330 rousseau 1743 if ((bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
331 rousseau 1742 {
332     printf("Error: test applet not found!\n");
333     goto end;
334     }
335 rousseau 972
336 rousseau 1676 #ifdef VERIFY_PIN
337 rousseau 889 /* verify PIN */
338     printf(" Secure verify PIN\n");
339 rousseau 1631 pin_verify = (PIN_VERIFY_STRUCTURE *)bSendBuffer;
340    
341 rousseau 3356 /* PC/SC v2.02.05 Part 10 PIN verification data structure */
342 rousseau 1631 pin_verify -> bTimerOut = 0x00;
343     pin_verify -> bTimerOut2 = 0x00;
344     pin_verify -> bmFormatString = 0x82;
345     pin_verify -> bmPINBlockString = 0x04;
346     pin_verify -> bmPINLengthFormat = 0x00;
347 rousseau 1669 pin_verify -> wPINMaxExtraDigit = HOST_TO_CCID_16(0x0408); /* Min Max */
348 rousseau 1711 pin_verify -> bEntryValidationCondition = 0x02; /* validation key pressed */
349 rousseau 1712 pin_verify -> bNumberMessage = 0x01;
350 rousseau 1669 pin_verify -> wLangId = HOST_TO_CCID_16(0x0904);
351 rousseau 1631 pin_verify -> bMsgIndex = 0x00;
352     pin_verify -> bTeoPrologue[0] = 0x00;
353     pin_verify -> bTeoPrologue[1] = 0x00;
354     pin_verify -> bTeoPrologue[2] = 0x00;
355     /* pin_verify -> ulDataLength = 0x00; we don't know the size yet */
356    
357     /* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
358 rousseau 889 offset = 0;
359 rousseau 1631 pin_verify -> abData[offset++] = 0x00; /* CLA */
360     pin_verify -> abData[offset++] = 0x20; /* INS: VERIFY */
361     pin_verify -> abData[offset++] = 0x00; /* P1 */
362     pin_verify -> abData[offset++] = 0x00; /* P2 */
363     pin_verify -> abData[offset++] = 0x08; /* Lc: 8 data bytes */
364     pin_verify -> abData[offset++] = 0x30; /* '0' */
365     pin_verify -> abData[offset++] = 0x30; /* '0' */
366     pin_verify -> abData[offset++] = 0x30; /* '0' */
367     pin_verify -> abData[offset++] = 0x30; /* '0' */
368     pin_verify -> abData[offset++] = 0x00; /* '\0' */
369     pin_verify -> abData[offset++] = 0x00; /* '\0' */
370     pin_verify -> abData[offset++] = 0x00; /* '\0' */
371     pin_verify -> abData[offset++] = 0x00; /* '\0' */
372 rousseau 1669 pin_verify -> ulDataLength = HOST_TO_CCID_32(offset); /* APDU size */
373 rousseau 889
374 rousseau 1631 length = sizeof(PIN_VERIFY_STRUCTURE) + offset -1; /* -1 because PIN_VERIFY_STRUCTURE contains the first byte of abData[] */
375 rousseau 889
376 rousseau 1631 printf(" command:");
377     for (i=0; i<length; i++)
378     printf(" %02X", bSendBuffer[i]);
379     printf("\n");
380     printf("Enter your PIN: ");
381     fflush(stdout);
382     rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
383     length, bRecvBuffer, sizeof(bRecvBuffer), &length);
384    
385     {
386     #ifndef S_SPLINT_S
387     fd_set fd;
388     #endif
389     struct timeval timeout;
390    
391     FD_ZERO(&fd);
392     FD_SET(STDIN_FILENO, &fd); /* stdin */
393 rousseau 2039 timeout.tv_sec = 0; /* timeout = 0.1s */
394     timeout.tv_usec = 100000;
395 rousseau 1631
396     /* we only try to read stdin if the pinpad is on a keyboard
397     * we do not read stdin for a SPR 532 for example */
398     if (select(1, &fd, NULL, NULL, &timeout) > 0)
399     {
400     /* read the fake digits */
401 rousseau 1749 char in[40]; /* 4 digits + \n + \0 */
402 rousseau 1631 (void)fgets(in, sizeof(in), stdin);
403    
404     printf("keyboard sent: %s", in);
405     }
406 rousseau 1676 else
407     /* if it is not a keyboard */
408     printf("\n");
409 rousseau 1631 }
410    
411 rousseau 1676 printf(" card response:");
412     for (i=0; i<length; i++)
413     printf(" %02X", bRecvBuffer[i]);
414     printf("\n");
415     PCSC_ERROR_CONT(rv, "SCardControl")
416    
417     /* verify PIN dump */
418     printf("\nverify PIN dump: ");
419     send_length = 5;
420     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
421     send_length);
422     for (i=0; i<send_length; i++)
423     printf(" %02X", bSendBuffer[i]);
424     printf("\n");
425     length = sizeof(bRecvBuffer);
426     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
427     &pioRecvPci, bRecvBuffer, &length);
428     printf(" card response:");
429     for (i=0; i<length; i++)
430     printf(" %02X", bRecvBuffer[i]);
431     printf("\n");
432     PCSC_ERROR_EXIT(rv, "SCardTransmit")
433    
434     if ((2 == length) && (0x6C == bRecvBuffer[0]))
435     {
436     printf("\nverify PIN dump: ");
437     send_length = 5;
438     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
439     send_length);
440     bSendBuffer[4] = bRecvBuffer[1];
441     for (i=0; i<send_length; i++)
442     printf(" %02X", bSendBuffer[i]);
443     printf("\n");
444     length = sizeof(bRecvBuffer);
445     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
446     &pioRecvPci, bRecvBuffer, &length);
447     printf(" card response:");
448     for (i=0; i<length; i++)
449     printf(" %02X", bRecvBuffer[i]);
450     printf("\n");
451     PCSC_ERROR_EXIT(rv, "SCardTransmit")
452     }
453     #endif
454    
455     /* check if the reader supports Modify PIN */
456 rousseau 1631 if (0 == modify_ioctl)
457     {
458     printf("Reader %s does not support PIN modification\n",
459     readers[reader_nb]);
460     goto end;
461     }
462    
463 rousseau 1676 #ifdef MODIFY_PIN
464 rousseau 1631 /* Modify PIN */
465     printf(" Secure modify PIN\n");
466     pin_modify = (PIN_MODIFY_STRUCTURE *)bSendBuffer;
467    
468 rousseau 2407 /* Table for bConfirmPIN and bNumberMessage
469     * bConfirmPIN = 3, bNumberMessage = 3: "Enter Pin" "New Pin" "Confirm Pin"
470     * bConfirmPIN = 2, bNumberMessage = 2: "Enter Pin" "New Pin"
471     * bConfirmPIN = 1, bNumberMessage = 2: "New Pin" "Confirm Pin"
472     * bConfirmPIN = 0, bNumberMessage = 1: "New Pin"
473     */
474 rousseau 3356 /* PC/SC v2.02.05 Part 10 PIN modification data structure */
475 rousseau 1631 pin_modify -> bTimerOut = 0x00;
476     pin_modify -> bTimerOut2 = 0x00;
477     pin_modify -> bmFormatString = 0x82;
478     pin_modify -> bmPINBlockString = 0x04;
479     pin_modify -> bmPINLengthFormat = 0x00;
480 rousseau 1716 pin_modify -> bInsertionOffsetOld = 0x00; /* offset from APDU start */
481 rousseau 1717 pin_modify -> bInsertionOffsetNew = 0x04; /* offset from APDU start */
482 rousseau 2405 pin_modify -> wPINMaxExtraDigit = HOST_TO_CCID_16(0x0408); /* Min Max */
483 rousseau 1634 pin_modify -> bConfirmPIN = 0x03; /* b0 set = confirmation requested */
484     /* b1 set = current PIN entry requested */
485     pin_modify -> bEntryValidationCondition = 0x02; /* validation key pressed */
486 rousseau 2407 pin_modify -> bNumberMessage = 0x03; /* see table above */
487 rousseau 1669 pin_modify -> wLangId = HOST_TO_CCID_16(0x0904);
488 rousseau 1631 pin_modify -> bMsgIndex1 = 0x00;
489     pin_modify -> bMsgIndex2 = 0x00;
490     pin_modify -> bMsgIndex3 = 0x00;
491     pin_modify -> bTeoPrologue[0] = 0x00;
492     pin_modify -> bTeoPrologue[1] = 0x00;
493     pin_modify -> bTeoPrologue[2] = 0x00;
494 rousseau 1634 /* pin_modify -> ulDataLength = 0x00; we don't know the size yet */
495 rousseau 1631
496 rousseau 1300 /* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
497 rousseau 1631 offset = 0;
498     pin_modify -> abData[offset++] = 0x00; /* CLA */
499 rousseau 1634 pin_modify -> abData[offset++] = 0x24; /* INS: CHANGE/UNBLOCK */
500 rousseau 1631 pin_modify -> abData[offset++] = 0x00; /* P1 */
501     pin_modify -> abData[offset++] = 0x00; /* P2 */
502 rousseau 1717 pin_modify -> abData[offset++] = 0x08; /* Lc: 2x8 data bytes */
503 rousseau 1634 pin_modify -> abData[offset++] = 0x30; /* '0' old PIN */
504 rousseau 1631 pin_modify -> abData[offset++] = 0x30; /* '0' */
505     pin_modify -> abData[offset++] = 0x30; /* '0' */
506     pin_modify -> abData[offset++] = 0x30; /* '0' */
507 rousseau 1634 pin_modify -> abData[offset++] = 0x30; /* '0' new PIN */
508 rousseau 1631 pin_modify -> abData[offset++] = 0x30; /* '0' */
509 rousseau 1634 pin_modify -> abData[offset++] = 0x30; /* '0' */
510     pin_modify -> abData[offset++] = 0x30; /* '0' */
511 rousseau 1669 pin_modify -> ulDataLength = HOST_TO_CCID_32(offset); /* APDU size */
512 rousseau 1300
513 rousseau 1634 length = sizeof(PIN_MODIFY_STRUCTURE) + offset -1; /* -1 because PIN_MODIFY_STRUCTURE contains the first byte of abData[] */
514    
515 rousseau 889 printf(" command:");
516 rousseau 1631 for (i=0; i<length; i++)
517 rousseau 889 printf(" %02X", bSendBuffer[i]);
518     printf("\n");
519 rousseau 972 printf("Enter your PIN: ");
520 rousseau 900 fflush(stdout);
521 rousseau 1634 rv = SCardControl(hCard, modify_ioctl, bSendBuffer,
522 rousseau 1631 length, bRecvBuffer, sizeof(bRecvBuffer), &length);
523 rousseau 889
524     printf(" card response:");
525     for (i=0; i<length; i++)
526     printf(" %02X", bRecvBuffer[i]);
527     printf("\n");
528     PCSC_ERROR_CONT(rv, "SCardControl")
529    
530 rousseau 972 {
531 rousseau 1067 #ifndef S_SPLINT_S
532 rousseau 972 fd_set fd;
533 rousseau 1067 #endif
534 rousseau 972 struct timeval timeout;
535    
536 rousseau 1985 /* old PIN, new PIN, confirmation PIN */
537     /* if the command is aborted we will not read every "PIN" */
538     for (i=0; i<3; i++)
539 rousseau 972 {
540 rousseau 1985 FD_ZERO(&fd);
541     FD_SET(STDIN_FILENO, &fd); /* stdin */
542 rousseau 2039 timeout.tv_sec = 0; /* timeout = 0.1s */
543     timeout.tv_usec = 100000;
544 rousseau 1750
545 rousseau 1985 /* we only try to read stdin if the pinpad is on a keyboard
546     * we do not read stdin for a SPR 532 for example */
547     if (select(1, &fd, NULL, NULL, &timeout) > 0)
548     {
549     /* read the fake digits */
550     char in[40]; /* 4 digits + \n + \0 */
551 rousseau 972
552 rousseau 1985 (void)fgets(in, sizeof(in), stdin);
553     printf("keyboard sent: %s", in);
554     }
555 rousseau 972 }
556     }
557 rousseau 1715
558     /* modify PIN dump */
559     printf("\nmodify PIN dump: ");
560     send_length = 5;
561     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
562     send_length);
563     for (i=0; i<send_length; i++)
564     printf(" %02X", bSendBuffer[i]);
565     printf("\n");
566     length = sizeof(bRecvBuffer);
567     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
568     &pioRecvPci, bRecvBuffer, &length);
569     printf(" card response:");
570     for (i=0; i<length; i++)
571     printf(" %02X", bRecvBuffer[i]);
572     printf("\n");
573     PCSC_ERROR_EXIT(rv, "SCardTransmit")
574    
575     if ((2 == length) && (0x6C == bRecvBuffer[0]))
576     {
577     printf("\nverify PIN dump: ");
578     send_length = 5;
579     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
580     send_length);
581     bSendBuffer[4] = bRecvBuffer[1];
582     for (i=0; i<send_length; i++)
583     printf(" %02X", bSendBuffer[i]);
584     printf("\n");
585     length = sizeof(bRecvBuffer);
586     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
587     &pioRecvPci, bRecvBuffer, &length);
588     printf(" card response:");
589     for (i=0; i<length; i++)
590     printf(" %02X", bRecvBuffer[i]);
591     printf("\n");
592     PCSC_ERROR_EXIT(rv, "SCardTransmit")
593     }
594 rousseau 1676 #endif
595 rousseau 972
596 rousseau 889 /* card disconnect */
597     rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
598     PCSC_ERROR_CONT(rv, "SCardDisconnect")
599    
600     end:
601     /* We try to leave things as clean as possible */
602     rv = SCardReleaseContext(hContext);
603     if (rv != SCARD_S_SUCCESS)
604     printf("SCardReleaseContext: %s (0x%lX)\n", pcsc_stringify_error(rv),
605     rv);
606    
607     /* free allocated memory */
608 rousseau 2591 if (mszReaders)
609     free(mszReaders);
610     if (readers)
611     free(readers);
612 rousseau 889
613     return 0;
614     } /* main */
615    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5