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

Annotation of /trunk/OpenPGPminidriver/PinOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide 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 vletoux 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 vletoux 6 DWORD dwMinPinSize = 0, dwMaxPinSize, dwSize;
32 vletoux 1 __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 vletoux 8 dwMinPinSize = 1;
45 vletoux 1 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 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, &dwSize);
61     if (dwReturn)
62     {
63     __leave;
64     }
65 vletoux 1 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 vletoux 6 DWORD dwReturn, dwSize;
101 vletoux 1 PBYTE pbResponse = NULL;
102     __try
103     {
104     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
105 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, &dwSize);
106 vletoux 1 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 vletoux 10 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
137 vletoux 1 // 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 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, 5 + cbPin);
169 vletoux 1 if (dwReturn)
170     {
171 vletoux 8 Trace(WINEVENT_LEVEL_VERBOSE, L"Authentication failed");
172 vletoux 1 __leave;
173     }
174 vletoux 8 Trace(WINEVENT_LEVEL_VERBOSE, L"Authentication successfull");
175 vletoux 10 if (PinId == ROLE_ADMIN)
176     {
177     pContext->fDoesTheAdminHasBeenAuthenticatedAtLeastOnce = TRUE;
178     }
179 vletoux 1 }
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 vletoux 8 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 vletoux 1 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 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, 5 + cbOldPin + cbNewPin);
237 vletoux 1 }
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 vletoux 8 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 vletoux 1 switch(PinId)
271     {
272     case ROLE_ADMIN:
273     // authenticate the admin
274     dwReturn = VerifyPIN(pCardData, PinId, pbAuthenticator, cbAuthenticator);
275 vletoux 8 if (dwReturn)
276 vletoux 1 {
277 vletoux 8 __leave;
278 vletoux 1 }
279 vletoux 8 pbCmd[4] = (BYTE) cbNewPin;
280 vletoux 1 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 vletoux 8 }
289 vletoux 1 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 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, dwCmdSize);
300 vletoux 1 }
301     __finally
302     {
303     SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
304     }
305     return dwReturn;
306     }
307    
308 vletoux 8 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 vletoux 1 DWORD Deauthenticate(__in PCARD_DATA pCardData)
338     {
339 vletoux 9 /*DWORD dwCode, dwSize;
340 vletoux 1 DWORD dwReturn;
341     __try
342     {
343     // reset the card
344     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
345 vletoux 9 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 vletoux 1 {
349 vletoux 9 Trace(WINEVENT_LEVEL_ERROR, L"SCardControl 0x%08X", dwReturn);
350 vletoux 1 __leave;
351     }
352 vletoux 9 Sleep(200);
353 vletoux 1 dwReturn = SelectOpenPGPApplication(pCardData);
354     }
355     __finally
356     {
357     }
358 vletoux 9 return dwReturn;*/
359     return SCARD_E_UNSUPPORTED_FEATURE;
360 vletoux 8 }
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 vletoux 1 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26