/[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 900 - (show annotations) (download)
Tue May 25 14:46:02 2004 UTC (9 years ago) by rousseau
File MIME type: text/plain
File size: 7678 byte(s)
add support for SCardGetAttrib(.., IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, ..)
to know if the reader supports SCardControl(.., IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, ..)
1 /*
2 scardcontrol.c: sample code to use/test SCardControl() API
3 Copyright (C) 2004 Ludovic Rousseau
4
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 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 /*
21 * $Id$
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <wintypes.h>
30 #include <winscard.h>
31
32 #ifndef TRUE
33 #define TRUE 1
34 #define FALSE 0
35 #endif
36
37 #define SCARD_CTL_CODE(code) (0x42000000 + (code))
38
39 #define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE SCARD_CTL_CODE(1)
40 #define IOCTL_SMARTCARD_VENDOR_VERIFY_PIN SCARD_CTL_CODE(2)
41 #define IOCTL_SMARTCARD_VENDOR_MODIFY_PIN SCARD_CTL_CODE(3)
42 #define IOCTL_SMARTCARD_VENDOR_TRANSFER_PIN SCARD_CTL_CODE(4)
43
44 /* PCSC error message pretty print */
45 #define PCSC_ERROR_EXIT(rv, text) \
46 if (rv != SCARD_S_SUCCESS) \
47 { \
48 printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
49 goto end; \
50 } \
51 else \
52 printf(text ": OK\n\n");
53
54 #define PCSC_ERROR_CONT(rv, text) \
55 if (rv != SCARD_S_SUCCESS) \
56 printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
57 else \
58 printf(text ": OK\n\n");
59
60 int main(int argc, char *argv[])
61 {
62 LONG rv;
63 SCARDCONTEXT hContext;
64 DWORD dwReaders;
65 LPSTR mszReaders;
66 char *ptr, **readers = NULL;
67 int nbReaders;
68 SCARDHANDLE hCard;
69 DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen;
70 BYTE pbAtr[MAX_ATR_SIZE] = "";
71 char pbReader[MAX_READERNAME] = "";
72 int reader_nb;
73 int i, offset;
74 unsigned char bSendBuffer[MAX_BUFFER_SIZE];
75 unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
76 DWORD length;
77 char attribute[1];
78 int attribute_length;
79
80 printf("SCardControl sample code\n");
81 printf("V 1.0 2004, Ludovic Rousseau <ludovic.rousseau@free.fr>\n");
82
83 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
84 if (rv != SCARD_S_SUCCESS)
85 {
86 printf("SCardEstablishContext: Cannot Connect to Resource Manager %lX\n", rv);
87 return 1;
88 }
89
90 /* Retrieve the available readers list */
91 rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
92 if (rv != SCARD_S_SUCCESS)
93 {
94 printf("SCardListReader: %lX\n", rv);
95 }
96
97 mszReaders = malloc(sizeof(char)*dwReaders);
98 if (mszReaders == NULL)
99 {
100 printf("malloc: not enough memory\n");
101 goto end;
102 }
103
104 rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
105 if (rv != SCARD_S_SUCCESS)
106 printf("SCardListReader: %lX\n", rv);
107
108 /* Extract readers from the null separated string and get the total
109 * number of readers */
110 nbReaders = 0;
111 ptr = mszReaders;
112 while (*ptr != '\0')
113 {
114 ptr += strlen(ptr)+1;
115 nbReaders++;
116 }
117
118 if (nbReaders == 0)
119 {
120 printf("No reader found\n");
121 goto end;
122 }
123
124 /* allocate the readers table */
125 readers = calloc(nbReaders, sizeof(char *));
126 if (NULL == readers)
127 {
128 printf("Not enough memory for readers[]\n");
129 goto end;
130 }
131
132 /* fill the readers table */
133 nbReaders = 0;
134 ptr = mszReaders;
135 while (*ptr != '\0')
136 {
137 printf("%d: %s\n", nbReaders, ptr);
138 readers[nbReaders] = ptr;
139 ptr += strlen(ptr)+1;
140 nbReaders++;
141 }
142
143 if (argc > 1)
144 {
145 reader_nb = atoi(argv[1]);
146 if (reader_nb < 0 || reader_nb >= nbReaders)
147 {
148 printf("Wrong reader index: %d\n", reader_nb);
149 goto end;
150 }
151 }
152 else
153 reader_nb = 0;
154
155 /* connect to a reader (even without a card) */
156 dwActiveProtocol = -1;
157 rv = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_DIRECT,
158 SCARD_PROTOCOL_ANY, &hCard, &dwActiveProtocol);
159 printf(" Protocol: %ld\n", dwActiveProtocol);
160 PCSC_ERROR_EXIT(rv, "SCardConnect")
161
162 /* get firmware */
163 printf(" Get Firmware\n");
164
165 /* this is specific to Gemplus readers */
166 bSendBuffer[0] = 0x02;
167 rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, bSendBuffer,
168 1, bRecvBuffer, sizeof(bRecvBuffer), &length);
169
170 printf(" Firmware: ");
171 for (i=0; i<length; i++)
172 printf("%02X ", bRecvBuffer[i]);
173 printf("\n");
174
175 bRecvBuffer[length] = '\0';
176 printf(" Firmware: %s (length %ld bytes)\n", bRecvBuffer, length);
177
178 PCSC_ERROR_CONT(rv, "SCardControl")
179
180 /* get card status */
181 dwAtrLen = sizeof(pbAtr);
182 dwReaderLen = sizeof(pbReader);
183 rv = SCardStatus(hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
184 pbAtr, &dwAtrLen);
185 printf(" Reader: %s (length %ld bytes)\n", pbReader, dwReaderLen);
186 printf(" State: 0x%lX\n", dwState);
187 printf(" Prot: %ld\n", dwProt);
188 printf(" ATR (length %ld bytes):", dwAtrLen);
189 for (i=0; i<dwAtrLen; i++)
190 printf(" %02X", pbAtr[i]);
191 printf("\n");
192 PCSC_ERROR_CONT(rv, "SCardStatus")
193
194 /* does the reader support PIN verification? */
195 attribute_length = sizeof(attribute);
196 rv = SCardGetAttrib(hCard, IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, attribute,
197 &attribute_length);
198 PCSC_ERROR_CONT(rv, "SCardGetAttrib")
199 if (FALSE == attribute[0])
200 {
201 printf("Reader %s does not support PIN verification\n",
202 readers[reader_nb]);
203 goto end;
204 }
205
206 /* verify PIN */
207 printf(" Secure verify PIN\n");
208 offset = 0;
209 /* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
210 bSendBuffer[offset++] = 0x00; /* CLA */
211 bSendBuffer[offset++] = 0x20; /* INS: VERIFY */
212 bSendBuffer[offset++] = 0x00; /* P1 */
213 bSendBuffer[offset++] = 0x00; /* P2 */
214 bSendBuffer[offset++] = 0x08; /* Lc: 8 data bytes */
215 bSendBuffer[offset++] = 0x30; /* '0' */
216 bSendBuffer[offset++] = 0x30; /* '0' */
217 bSendBuffer[offset++] = 0x30; /* '0' */
218 bSendBuffer[offset++] = 0x30; /* '0' */
219 bSendBuffer[offset++] = 0x00; /* '\0' */
220 bSendBuffer[offset++] = 0x00; /* '\0' */
221 bSendBuffer[offset++] = 0x00; /* '\0' */
222 bSendBuffer[offset++] = 0x00; /* '\0' */
223
224 /* CCID PIN verification data structure */
225 bSendBuffer[offset++] = 0x00; /* bPINOperation */
226 bSendBuffer[offset++] = 0x00; /* bTimeOut */
227 bSendBuffer[offset++] = 0x82; /* bmFormatString */
228 bSendBuffer[offset++] = 0x04; /* bmPINBlockString (PIN length) */
229 bSendBuffer[offset++] = 0x00; /* bmPINLengthFormat */
230 bSendBuffer[offset++] = 0x04; /* wPINMaxExtraDigit: min */
231 bSendBuffer[offset++] = 0x04; /* wPINMaxExtraDigit: max */
232 bSendBuffer[offset++] = 0x02; /* bEntryValidationCondition */
233 bSendBuffer[offset++] = 0x00; /* bNumberMessage */
234 bSendBuffer[offset++] = 0x04; /* wLangId: english */
235 bSendBuffer[offset++] = 0x09; /* */
236 bSendBuffer[offset++] = 0x00; /* bMsgIndex */
237 bSendBuffer[offset++] = 0x00; /* bTeoPrologue */
238 bSendBuffer[offset++] = 0x00;
239 bSendBuffer[offset++] = 0x00;
240
241 printf(" command:");
242 for (i=0; i<offset; i++)
243 printf(" %02X", bSendBuffer[i]);
244 printf("\n");
245 printf("Enter your PIN:");
246 fflush(stdout);
247 rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, bSendBuffer,
248 offset, bRecvBuffer, sizeof(bRecvBuffer), &length);
249
250 printf(" card response:");
251 for (i=0; i<length; i++)
252 printf(" %02X", bRecvBuffer[i]);
253 printf("\n");
254 PCSC_ERROR_CONT(rv, "SCardControl")
255
256 /* card disconnect */
257 rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
258 PCSC_ERROR_CONT(rv, "SCardDisconnect")
259
260 end:
261 /* We try to leave things as clean as possible */
262 rv = SCardReleaseContext(hContext);
263 if (rv != SCARD_S_SUCCESS)
264 printf("SCardReleaseContext: %s (0x%lX)\n", pcsc_stringify_error(rv),
265 rv);
266
267 /* free allocated memory */
268 free(mszReaders);
269 free(readers);
270
271 return 0;
272 } /* main */
273

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5