/[openpgpmdrv]/trunk/OpenPGPminidriver/SmartCard.c
ViewVC logotype

Contents of /trunk/OpenPGPminidriver/SmartCard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Thu Mar 11 20:32:26 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 8847 byte(s)
improvement of the quality of the project.
More test for the qualification of the driver success but not all ...

1 /* OpenPGP Smart Card Mini Driver
2 Copyright (C) 2009 Vincent Le Toux
3
4 This library is Free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License version 2.1 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Lesser General Public License for more details.
12
13 You should have received a copy of the GNU Lesser General Public
14 License along with this library; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 #include <windows.h>
19 #include <cardmod.h>
20 #include <stdio.h>
21 #include "Tracing.h"
22 #include "Context.h"
23 #include "SmartCard.h"
24
25 #pragma comment(lib,"Winscard")
26
27 DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData);
28
29 DWORD OCardReconnect(__in PCARD_DATA pCardData)
30 {
31 DWORD dwAP;
32 DWORD dwReturn;
33 __try
34 {
35 // reset the card
36 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
37 dwReturn = SCardReconnect(pCardData->hScard,
38 SCARD_SHARE_SHARED,
39 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
40 SCARD_LEAVE_CARD,
41 &dwAP );
42 if (dwReturn)
43 {
44 Trace(WINEVENT_LEVEL_ERROR, L"SCardReconnect 0x%08X", dwReturn);
45 __leave;
46 }
47
48 dwReturn = SelectOpenPGPApplication(pCardData);
49 }
50 __finally
51 {
52 }
53 return dwReturn;
54 }
55
56 DWORD OCardSendCommand(__in PCARD_DATA pCardData, __in PBYTE pbCmd, __in DWORD dwCmdSize)
57 {
58 DWORD dwReturn = 0;
59
60 SCARD_IO_REQUEST ioSendPci = {1, sizeof(SCARD_IO_REQUEST)};
61 SCARD_IO_REQUEST ioRecvPci = {1, sizeof(SCARD_IO_REQUEST)};
62 BYTE recvbuf[256];
63 DWORD recvlen = sizeof(recvbuf);
64 BYTE SW1, SW2;
65 __try
66 {
67
68 dwReturn = SCardTransmit(pCardData->hScard,
69 SCARD_PCI_T1,
70 pbCmd,
71 dwCmdSize,
72 NULL,
73 recvbuf,
74 &recvlen);
75 if ( dwReturn != SCARD_S_SUCCESS )
76 {
77 if (dwReturn == SCARD_W_RESET_CARD)
78 {
79 dwReturn = OCardReconnect(pCardData);
80 if (dwReturn)
81 {
82 __leave;
83 }
84 dwReturn = OCardSendCommand(pCardData,pbCmd, dwCmdSize);
85 __leave;
86 }
87 Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
88 __leave;
89 }
90 SW1 = recvbuf[recvlen-2];
91 SW2 = recvbuf[recvlen-1];
92 if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
93 {
94
95 }
96 else if ( (SW1 == 0x69) && (SW2 == 0x82) )
97 {
98 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
99 dwReturn = SCARD_W_WRONG_CHV;
100 __leave;
101 }
102 else if ( (SW1 == 0x69) && (SW2 == 0x83) )
103 {
104 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
105 dwReturn = SCARD_W_CHV_BLOCKED;
106 __leave;
107 }
108 else
109 {
110 TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
111 Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
112 dwReturn = SCARD_F_UNKNOWN_ERROR;
113 __leave;
114 }
115 }
116 __finally
117 {
118 }
119 return dwReturn;
120 }
121
122 DWORD SelectOpenPGPApplication(__in PCARD_DATA pCardData)
123 {
124 BYTE pbCmd[] = {0x00,
125 0xA4,
126 0x04,
127 0x00,
128 0x06,
129 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01,
130 0x00
131 };
132
133 return OCardSendCommand(pCardData, pbCmd, sizeof(pbCmd));
134 }
135
136
137 DWORD OCardGetData(__in PCARD_DATA pCardData,
138 __in PBYTE pbCmd, __in DWORD dwCmdSize,
139 __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize)
140 {
141
142 DWORD dwReturn;
143 BYTE pbGetResponse[] = {0x00,
144 0xC0,
145 0x00,
146 0x00,
147 0x00
148 };
149 DWORD dwGetResponseSize = ARRAYSIZE(pbGetResponse);
150 BYTE recvbuf[0x800];
151 DWORD recvlen = sizeof(recvbuf);
152 BYTE SW1, SW2;
153 DWORD dwDataSize = 0;
154 __try
155 {
156
157 *pbResponse = NULL;
158 dwReturn = SCardTransmit(pCardData->hScard,
159 SCARD_PCI_T1,
160 pbCmd,
161 dwCmdSize,
162 NULL,
163 recvbuf,
164 &recvlen);
165
166 do
167 {
168 if ( dwReturn != SCARD_S_SUCCESS )
169 {
170 if (dwReturn == SCARD_W_RESET_CARD)
171 {
172 dwReturn = OCardReconnect(pCardData);
173 if (dwReturn)
174 {
175 __leave;
176 }
177 dwReturn = OCardGetData(pCardData,pbCmd, dwCmdSize,pbResponse, pdwResponseSize);
178 __leave;
179 }
180 Trace(WINEVENT_LEVEL_ERROR, L"SCardTransmit errorcode: [0x%02X]", dwReturn);
181 __leave;
182 }
183 SW1 = recvbuf[recvlen-2];
184 SW2 = recvbuf[recvlen-1];
185 if ( ( SW1 == 0x90 ) && ( SW2 == 0x00 ) )
186 {
187 dwDataSize = recvlen-2;
188 *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
189 if (! *pbResponse)
190 {
191 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
192 dwReturn = SCARD_E_NO_MEMORY;
193 __leave;
194 }
195 memcpy(*pbResponse, recvbuf, dwDataSize);
196 }
197 else if (SW1 == 0x61)
198 {
199 dwDataSize += SW2;
200 if (*pbResponse)
201 {
202 *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, dwDataSize);
203 }
204 else
205 {
206 *pbResponse = pCardData->pfnCspAlloc(dwDataSize);
207 }
208 dwGetResponseSize = ARRAYSIZE(pbGetResponse);
209 dwReturn = SCardTransmit(pCardData->hScard,
210 SCARD_PCI_T1,
211 pbGetResponse,
212 dwGetResponseSize,
213 NULL,
214 recvbuf,
215 &recvlen);
216 }
217 else if ( (SW1 == 0x69) && (SW2 == 0x82) )
218 {
219 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV");
220 dwReturn = SCARD_W_WRONG_CHV;
221 __leave;
222 }
223 else if ( (SW1 == 0x69) && (SW2 == 0x83) )
224 {
225 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_CHV_BLOCKED");
226 dwReturn = SCARD_W_CHV_BLOCKED;
227 __leave;
228 }
229 else if ( (SW1 == 0x6A) && (SW2 == 0x88) )
230 {
231 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND");
232 dwReturn = SCARD_E_FILE_NOT_FOUND;
233 __leave;
234 }
235 else
236 {
237 TraceDump(WINEVENT_LEVEL_ERROR, pbCmd,dwCmdSize);
238 Trace(WINEVENT_LEVEL_ERROR, L"SW1=0x%02X SW2=0x%02X", SW1, SW2);
239 dwReturn = SCARD_F_UNKNOWN_ERROR;
240 __leave;
241 }
242
243 } while (SW1 == 0x61);
244 if (pdwResponseSize)
245 {
246 *pdwResponseSize = dwDataSize;
247 }
248 }
249 __finally
250 {
251 }
252 return dwReturn;
253 }
254
255 DWORD CCIDfindFeature(BYTE featureTag, BYTE* features, DWORD featuresLength)
256 {
257 DWORD idx = 0;
258 int count;
259 while (idx < featuresLength) {
260 BYTE tag = features[idx];
261 idx++;
262 idx++;
263 if (featureTag == tag) {
264 DWORD feature = 0;
265 for (count = 0; count < 3; count++) {
266 feature |= features[idx] & 0xff;
267 idx++;
268 feature <<= 8;
269 }
270 feature |= features[idx] & 0xff;
271 return feature;
272 }
273 idx += 4;
274 }
275 return 0;
276 }
277
278 DWORD CCIDgetFeatures(__in PCARD_DATA pCardData)
279 {
280 BYTE pbRecvBuffer[200];
281 DWORD dwRecvLength, dwReturn;
282 __try
283 {
284 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
285
286 pContext->SmartCardReaderFeatures.VERIFY_PIN_START = 0;
287 pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = 0;
288 pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = 0;
289 pContext->SmartCardReaderFeatures.MODIFY_PIN_START = 0;
290 pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = 0;
291 pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = 0;
292 pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = 0;
293 pContext->SmartCardReaderFeatures.ABORT = 0;
294
295 dwReturn = SCardControl(pCardData->hScard,
296 SCARD_CTL_CODE(3400),
297 NULL,
298 0,
299 pbRecvBuffer,
300 sizeof(pbRecvBuffer),
301 &dwRecvLength);
302 if ( dwReturn )
303 {
304 Trace(WINEVENT_LEVEL_ERROR, L"SCardControl errorcode: [0x%02X]", dwReturn);
305 __leave;
306 }
307 pContext->SmartCardReaderFeatures.VERIFY_PIN_START = CCIDfindFeature(FEATURE_VERIFY_PIN_START, pbRecvBuffer, dwRecvLength);
308 pContext->SmartCardReaderFeatures.VERIFY_PIN_FINISH = CCIDfindFeature(FEATURE_VERIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
309 pContext->SmartCardReaderFeatures.VERIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_VERIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
310 pContext->SmartCardReaderFeatures.MODIFY_PIN_START = CCIDfindFeature(FEATURE_MODIFY_PIN_START, pbRecvBuffer, dwRecvLength);
311 pContext->SmartCardReaderFeatures.MODIFY_PIN_FINISH = CCIDfindFeature(FEATURE_MODIFY_PIN_FINISH, pbRecvBuffer, dwRecvLength);
312 pContext->SmartCardReaderFeatures.MODIFY_PIN_DIRECT = CCIDfindFeature(FEATURE_MODIFY_PIN_DIRECT, pbRecvBuffer, dwRecvLength);
313 pContext->SmartCardReaderFeatures.GET_KEY_PRESSED = CCIDfindFeature(FEATURE_GET_KEY_PRESSED, pbRecvBuffer, dwRecvLength);
314 pContext->SmartCardReaderFeatures.ABORT = CCIDfindFeature(FEATURE_ABORT, pbRecvBuffer, dwRecvLength);
315 }
316 __finally
317 {
318 }
319 return dwReturn;
320 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26