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

Contents of /trunk/OpenPGPminidriver/PinOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (show annotations)
Mon Mar 15 18:23:17 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 12338 byte(s)
first beta version
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 "Tracing.h"
21 #include "Context.h"
22 #include "SmartCard.h"
23 #include "PublicDataOperations.h"
24 #include "PinOperations.h"
25
26
27 DWORD CheckPinLength(__in PCARD_DATA pCardData, __in PIN_ID PinId, __in DWORD cbPin)
28 {
29 DWORD dwReturn;
30 PBYTE pbResponse = NULL;
31 DWORD dwMinPinSize = 0, dwMaxPinSize, dwSize;
32 __try
33 {
34 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
35 // check min Pin length
36 // (hard coded in specication)
37 switch(PinId)
38 {
39 case ROLE_SIGNATURE:
40 case ROLE_AUTHENTICATION:
41 case ROLE_CONFIDENTIALITY:
42 dwMinPinSize = 6;
43 case ROLE_PUK:
44 dwMinPinSize = 1;
45 break;
46 case ROLE_ADMIN:
47 dwMinPinSize = 8;
48 break;
49 default:
50 dwReturn = SCARD_E_INVALID_PARAMETER;
51 __leave;
52 }
53 if (cbPin < dwMinPinSize)
54 {
55 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV ROLE = %d cbPin = %d minPinSize = %d",PinId, cbPin, dwMinPinSize);
56 dwReturn = SCARD_W_WRONG_CHV;
57 __leave;
58 }
59 // check in status DO
60 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, &dwSize);
61 if (dwReturn)
62 {
63 __leave;
64 }
65 switch(PinId)
66 {
67 case ROLE_SIGNATURE:
68 case ROLE_AUTHENTICATION:
69 case ROLE_CONFIDENTIALITY:
70 dwMaxPinSize = pbResponse[1];
71 break;
72 case ROLE_PUK:
73 dwMaxPinSize = pbResponse[2];
74 break;
75 case ROLE_ADMIN:
76 dwMaxPinSize = pbResponse[3];
77 break;
78 default:
79 dwReturn = SCARD_E_INVALID_PARAMETER;
80 __leave;
81 }
82 if (cbPin > dwMaxPinSize)
83 {
84 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV ROLE = %d cbPin = %d dwMaxPinSize = %d", PinId, cbPin, dwMaxPinSize);
85 dwReturn = SCARD_W_WRONG_CHV;
86 __leave;
87 }
88 dwReturn = 0;
89 }
90 __finally
91 {
92 if (pbResponse)
93 pCardData->pfnCspFree(pbResponse);
94 }
95 return dwReturn;
96 }
97
98 DWORD GetRemainingPin(__in PCARD_DATA pCardData, __in PIN_ID PinId, __out PDWORD pdwCounter)
99 {
100 DWORD dwReturn, dwSize;
101 PBYTE pbResponse = NULL;
102 __try
103 {
104 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
105 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, &dwSize);
106 switch(PinId)
107 {
108 case ROLE_SIGNATURE:
109 case ROLE_AUTHENTICATION:
110 case ROLE_CONFIDENTIALITY:
111 *pdwCounter = pbResponse[4];
112 break;
113 case ROLE_PUK:
114 *pdwCounter = pbResponse[5];
115 break;
116 case ROLE_ADMIN:
117 *pdwCounter = pbResponse[6];
118 break;
119 default:
120 dwReturn = SCARD_E_INVALID_PARAMETER;
121 __leave;
122 }
123 }
124 __finally
125 {
126 if (pbResponse)
127 pCardData->pfnCspFree(pbResponse);
128 }
129 return dwReturn;
130 }
131
132 DWORD VerifyPIN(__in PCARD_DATA pCardData,__in PIN_ID PinId,
133 __in_bcount(cbPin) PBYTE pbPin, __in DWORD cbPin)
134 {
135 DWORD dwReturn;
136 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
137 // 256 because the size of the PIN must fit in a Byte
138 BYTE pbCmd[256 + 5] = {0x00,
139 0x20,
140 0x00,
141 0x82,
142 0x00
143 };
144 __try
145 {
146 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
147 switch(PinId)
148 {
149 case ROLE_SIGNATURE:
150 pbCmd[3] = 0x81;
151 break;
152 case ROLE_AUTHENTICATION:
153 case ROLE_CONFIDENTIALITY:
154 pbCmd[3] = 0x82;
155 break;
156 case ROLE_ADMIN:
157 pbCmd[3] = 0x83;
158 break;
159 case ROLE_PUK:
160 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
161 __leave;
162 default:
163 dwReturn = SCARD_E_INVALID_PARAMETER;
164 __leave;
165 }
166 pbCmd[4] = (BYTE) cbPin;
167 memcpy(pbCmd + 5, pbPin, cbPin);
168 dwReturn = OCardSendCommand(pCardData, pbCmd, 5 + cbPin);
169 if (dwReturn)
170 {
171 Trace(WINEVENT_LEVEL_VERBOSE, L"Authentication failed");
172 __leave;
173 }
174 Trace(WINEVENT_LEVEL_VERBOSE, L"Authentication successfull");
175 if (PinId == ROLE_ADMIN)
176 {
177 pContext->fDoesTheAdminHasBeenAuthenticatedAtLeastOnce = TRUE;
178 }
179 }
180 __finally
181 {
182 SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
183 }
184
185 return dwReturn;
186 }
187
188 DWORD ChangePIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
189 __in_bcount(cbPin) PBYTE pbOldPin, __in DWORD cbOldPin,
190 __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
191 )
192 {
193 DWORD dwReturn;
194 // 256 because the size of the PIN must fit in a Byte
195 BYTE pbCmd[256 + 256 + 6] = {0x00,
196 0x24,
197 0x00,
198 0x81,
199 0x00
200 };
201 __try
202 {
203 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
204 dwReturn = CheckPinLength(pCardData, PinId, cbNewPin);
205 if (dwReturn)
206 {
207 Trace(WINEVENT_LEVEL_ERROR, L"Invalid len %d",cbNewPin);
208 dwReturn = SCARD_E_INVALID_PARAMETER;
209 __leave;
210 }
211 dwReturn = CheckPinLength(pCardData, PinId, cbOldPin);
212 if (dwReturn)
213 {
214 __leave;
215 }
216 switch(PinId)
217 {
218 case ROLE_SIGNATURE:
219 case ROLE_AUTHENTICATION:
220 case ROLE_CONFIDENTIALITY:
221 pbCmd[3] = 0x81;
222 break;
223 case ROLE_ADMIN:
224 pbCmd[3] = 0x83;
225 break;
226 case ROLE_PUK:
227 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
228 __leave;
229 default:
230 dwReturn = SCARD_E_INVALID_PARAMETER;
231 __leave;
232 }
233 pbCmd[4] = (BYTE) (cbOldPin + cbNewPin);
234 memcpy(pbCmd + 5, pbOldPin, cbOldPin);
235 memcpy(pbCmd + 5 + cbOldPin, pbNewPin, cbNewPin);
236 dwReturn = OCardSendCommand(pCardData, pbCmd, 5 + cbOldPin + cbNewPin);
237 }
238 __finally
239 {
240 SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
241 }
242 return dwReturn;
243 }
244
245 /** only the user PIN can be reseted => target is implicit*/
246 DWORD ResetUserPIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
247 __in_bcount(cbPin) PBYTE pbAuthenticator, __in DWORD cbAuthenticator,
248 __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
249 )
250 {
251 DWORD dwReturn;
252 BYTE pbCmd[256 + 5] = {0x00,
253 0x2C,
254 0x02,
255 0x81,
256 0x00
257 };
258 DWORD dwCmdSize;
259
260 __try
261 {
262 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
263 dwReturn = CheckPinLength(pCardData, ROLE_USER, cbNewPin);
264 if (dwReturn)
265 {
266 Trace(WINEVENT_LEVEL_ERROR, L"Invalid len %d",cbNewPin);
267 dwReturn = SCARD_E_INVALID_PARAMETER;
268 __leave;
269 }
270 switch(PinId)
271 {
272 case ROLE_ADMIN:
273 // authenticate the admin
274 dwReturn = VerifyPIN(pCardData, PinId, pbAuthenticator, cbAuthenticator);
275 if (dwReturn)
276 {
277 __leave;
278 }
279 pbCmd[4] = (BYTE) cbNewPin;
280 memcpy(pbCmd + 5, pbNewPin, cbNewPin);
281 dwCmdSize = 5 + cbNewPin;
282 break;
283 case ROLE_PUK:
284 dwReturn = CheckPinLength(pCardData, PinId, cbAuthenticator);
285 if (dwReturn)
286 {
287 __leave;
288 }
289 pbCmd[2] = 0x00;
290 pbCmd[4] = (BYTE) (cbAuthenticator + cbNewPin);
291 memcpy(pbCmd + 5, pbAuthenticator, cbAuthenticator);
292 memcpy(pbCmd + 5 + cbAuthenticator, pbNewPin, cbNewPin);
293 dwCmdSize = 5 + cbNewPin + cbAuthenticator;
294 break;
295 default:
296 dwReturn = SCARD_E_INVALID_PARAMETER;
297 __leave;
298 }
299 dwReturn = OCardSendCommand(pCardData, pbCmd, dwCmdSize);
300 }
301 __finally
302 {
303 SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
304 }
305 return dwReturn;
306 }
307
308 DWORD SetPUK(__in PCARD_DATA pCardData,
309 __in_bcount(cbPin) PBYTE pbAdminPin, __in DWORD cbAdminPin,
310 __in_bcount(cbPin) PBYTE pbPuk, __in DWORD cbPuk
311 )
312 {
313 DWORD dwReturn;
314 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
315 __try
316 {
317 dwReturn = CheckPinLength(pCardData, ROLE_PUK, cbPuk);
318 if (dwReturn)
319 {
320 Trace(WINEVENT_LEVEL_ERROR, L"Invalid len %d",cbPuk);
321 dwReturn = SCARD_E_INVALID_PARAMETER;
322 __leave;
323 }
324 dwReturn = VerifyPIN(pCardData, ROLE_ADMIN, pbAdminPin, cbAdminPin);
325 if (dwReturn)
326 {
327 __leave;
328 }
329 dwReturn = OCardWriteFile(pCardData, szOpenPGPDir, szOpenPGPPUK, pbPuk, cbPuk);
330 }
331 __finally
332 {
333 }
334 return dwReturn;
335 }
336
337 DWORD Deauthenticate(__in PCARD_DATA pCardData)
338 {
339 /*DWORD dwCode, dwSize;
340 DWORD dwReturn;
341 __try
342 {
343 // reset the card
344 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
345 dwCode = SCARD_COLD_RESET;
346 dwReturn = SCardControl(pCardData->hScard, IOCTL_SMARTCARD_POWER,&dwCode,4,NULL,0,&dwSize);
347 if (dwReturn && dwReturn != SCARD_W_RESET_CARD)
348 {
349 Trace(WINEVENT_LEVEL_ERROR, L"SCardControl 0x%08X", dwReturn);
350 __leave;
351 }
352 Sleep(200);
353 dwReturn = SelectOpenPGPApplication(pCardData);
354 }
355 __finally
356 {
357 }
358 return dwReturn;*/
359 return SCARD_E_UNSUPPORTED_FEATURE;
360 }
361
362
363 DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
364 {
365 DWORD dwReturn=0, dwVersion;
366 __try
367 {
368 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
369 dwVersion = (pPinInfo->dwVersion == 0) ? PIN_INFO_CURRENT_VERSION : pPinInfo->dwVersion;
370 if ( dwVersion != PIN_INFO_CURRENT_VERSION )
371 {
372 Trace(WINEVENT_LEVEL_ERROR, L"dwVersion %d", dwVersion);
373 dwReturn = ERROR_REVISION_MISMATCH;
374 __leave;
375 }
376 pPinInfo->dwVersion = dwVersion;
377 switch(dwPinIndex)
378 {
379 case ROLE_SIGNATURE:
380 pPinInfo->PinType = AlphaNumericPinType;
381 pPinInfo->PinPurpose = DigitalSignaturePin;
382 pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
383 SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
384 SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
385 pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
386 SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
387 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
388 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
389 pPinInfo->dwFlags = 0;
390 break;
391 case ROLE_AUTHENTICATION:
392 pPinInfo->PinType = AlphaNumericPinType;
393 pPinInfo->PinPurpose = AuthenticationPin;
394 pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
395 SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
396 SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
397 pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
398 SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
399 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
400 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
401 pPinInfo->dwFlags = 0;
402 break;
403 case ROLE_CONFIDENTIALITY:
404 pPinInfo->PinType = AlphaNumericPinType;
405 pPinInfo->PinPurpose = EncryptionPin;
406 pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
407 SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
408 SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
409 pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
410 SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
411 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
412 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
413 pPinInfo->dwFlags = 0;
414 break;
415 case ROLE_ADMIN:
416 pPinInfo->PinType = AlphaNumericPinType;
417 pPinInfo->PinPurpose = AdministratorPin;
418 pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_ADMIN);
419 pPinInfo->dwUnblockPermission = 0;
420 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
421 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
422 pPinInfo->dwFlags = 0;
423 break;
424 case ROLE_PUK:
425 pPinInfo->PinType = AlphaNumericPinType;
426 pPinInfo->PinPurpose = UnblockOnlyPin;
427 pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_ADMIN);
428 pPinInfo->dwUnblockPermission = 0;
429 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
430 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
431 pPinInfo->dwFlags = 0;
432 break;
433 default:
434 Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
435 dwReturn = SCARD_E_INVALID_PARAMETER ;
436 __leave;
437 }
438 }
439 __finally
440 {
441 }
442 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
443 return dwReturn;
444 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26