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

Annotation of /trunk/OpenPGPminidriver/PinOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Mon Mar 15 09:47:30 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 12160 byte(s)
more test success
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     // 256 because the size of the PIN must fit in a Byte
137     BYTE pbCmd[256 + 5] = {0x00,
138     0x20,
139     0x00,
140     0x82,
141     0x00
142     };
143     __try
144     {
145     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
146     switch(PinId)
147     {
148     case ROLE_SIGNATURE:
149     pbCmd[3] = 0x81;
150     break;
151     case ROLE_AUTHENTICATION:
152     case ROLE_CONFIDENTIALITY:
153     pbCmd[3] = 0x82;
154     break;
155     case ROLE_ADMIN:
156     pbCmd[3] = 0x83;
157     break;
158     case ROLE_PUK:
159     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
160     __leave;
161     default:
162     dwReturn = SCARD_E_INVALID_PARAMETER;
163     __leave;
164     }
165     pbCmd[4] = (BYTE) cbPin;
166     memcpy(pbCmd + 5, pbPin, cbPin);
167 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, 5 + cbPin);
168 vletoux 1 if (dwReturn)
169     {
170 vletoux 8 Trace(WINEVENT_LEVEL_VERBOSE, L"Authentication failed");
171 vletoux 1 __leave;
172     }
173 vletoux 8 Trace(WINEVENT_LEVEL_VERBOSE, L"Authentication successfull");
174 vletoux 1
175     }
176     __finally
177     {
178     SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
179     }
180    
181     return dwReturn;
182     }
183    
184     DWORD ChangePIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
185     __in_bcount(cbPin) PBYTE pbOldPin, __in DWORD cbOldPin,
186     __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
187     )
188     {
189     DWORD dwReturn;
190     // 256 because the size of the PIN must fit in a Byte
191     BYTE pbCmd[256 + 256 + 6] = {0x00,
192     0x24,
193     0x00,
194     0x81,
195     0x00
196     };
197     __try
198     {
199     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
200 vletoux 8 dwReturn = CheckPinLength(pCardData, PinId, cbNewPin);
201     if (dwReturn)
202     {
203     Trace(WINEVENT_LEVEL_ERROR, L"Invalid len %d",cbNewPin);
204     dwReturn = SCARD_E_INVALID_PARAMETER;
205     __leave;
206     }
207 vletoux 1 dwReturn = CheckPinLength(pCardData, PinId, cbOldPin);
208     if (dwReturn)
209     {
210     __leave;
211     }
212     switch(PinId)
213     {
214     case ROLE_SIGNATURE:
215     case ROLE_AUTHENTICATION:
216     case ROLE_CONFIDENTIALITY:
217     pbCmd[3] = 0x81;
218     break;
219     case ROLE_ADMIN:
220     pbCmd[3] = 0x83;
221     break;
222     case ROLE_PUK:
223     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
224     __leave;
225     default:
226     dwReturn = SCARD_E_INVALID_PARAMETER;
227     __leave;
228     }
229     pbCmd[4] = (BYTE) (cbOldPin + cbNewPin);
230     memcpy(pbCmd + 5, pbOldPin, cbOldPin);
231     memcpy(pbCmd + 5 + cbOldPin, pbNewPin, cbNewPin);
232 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, 5 + cbOldPin + cbNewPin);
233 vletoux 1 }
234     __finally
235     {
236     SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
237     }
238     return dwReturn;
239     }
240    
241     /** only the user PIN can be reseted => target is implicit*/
242     DWORD ResetUserPIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
243     __in_bcount(cbPin) PBYTE pbAuthenticator, __in DWORD cbAuthenticator,
244     __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
245     )
246     {
247     DWORD dwReturn;
248     BYTE pbCmd[256 + 5] = {0x00,
249     0x2C,
250     0x02,
251     0x81,
252     0x00
253     };
254     DWORD dwCmdSize;
255    
256     __try
257     {
258     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
259 vletoux 8 dwReturn = CheckPinLength(pCardData, ROLE_USER, cbNewPin);
260     if (dwReturn)
261     {
262     Trace(WINEVENT_LEVEL_ERROR, L"Invalid len %d",cbNewPin);
263     dwReturn = SCARD_E_INVALID_PARAMETER;
264     __leave;
265     }
266 vletoux 1 switch(PinId)
267     {
268     case ROLE_ADMIN:
269     // authenticate the admin
270     dwReturn = VerifyPIN(pCardData, PinId, pbAuthenticator, cbAuthenticator);
271 vletoux 8 if (dwReturn)
272 vletoux 1 {
273 vletoux 8 __leave;
274 vletoux 1 }
275 vletoux 8 pbCmd[4] = (BYTE) cbNewPin;
276 vletoux 1 memcpy(pbCmd + 5, pbNewPin, cbNewPin);
277     dwCmdSize = 5 + cbNewPin;
278     break;
279     case ROLE_PUK:
280     dwReturn = CheckPinLength(pCardData, PinId, cbAuthenticator);
281     if (dwReturn)
282     {
283     __leave;
284 vletoux 8 }
285 vletoux 1 pbCmd[2] = 0x00;
286     pbCmd[4] = (BYTE) (cbAuthenticator + cbNewPin);
287     memcpy(pbCmd + 5, pbAuthenticator, cbAuthenticator);
288     memcpy(pbCmd + 5 + cbAuthenticator, pbNewPin, cbNewPin);
289     dwCmdSize = 5 + cbNewPin + cbAuthenticator;
290     break;
291     default:
292     dwReturn = SCARD_E_INVALID_PARAMETER;
293     __leave;
294     }
295 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, dwCmdSize);
296 vletoux 1 }
297     __finally
298     {
299     SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
300     }
301     return dwReturn;
302     }
303    
304 vletoux 8 DWORD SetPUK(__in PCARD_DATA pCardData,
305     __in_bcount(cbPin) PBYTE pbAdminPin, __in DWORD cbAdminPin,
306     __in_bcount(cbPin) PBYTE pbPuk, __in DWORD cbPuk
307     )
308     {
309     DWORD dwReturn;
310     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
311     __try
312     {
313     dwReturn = CheckPinLength(pCardData, ROLE_PUK, cbPuk);
314     if (dwReturn)
315     {
316     Trace(WINEVENT_LEVEL_ERROR, L"Invalid len %d",cbPuk);
317     dwReturn = SCARD_E_INVALID_PARAMETER;
318     __leave;
319     }
320     dwReturn = VerifyPIN(pCardData, ROLE_ADMIN, pbAdminPin, cbAdminPin);
321     if (dwReturn)
322     {
323     __leave;
324     }
325     dwReturn = OCardWriteFile(pCardData, szOpenPGPDir, szOpenPGPPUK, pbPuk, cbPuk);
326     }
327     __finally
328     {
329     }
330     return dwReturn;
331     }
332    
333 vletoux 1 DWORD Deauthenticate(__in PCARD_DATA pCardData)
334     {
335 vletoux 9 /*DWORD dwCode, dwSize;
336 vletoux 1 DWORD dwReturn;
337     __try
338     {
339     // reset the card
340     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
341 vletoux 9 dwCode = SCARD_COLD_RESET;
342     dwReturn = SCardControl(pCardData->hScard, IOCTL_SMARTCARD_POWER,&dwCode,4,NULL,0,&dwSize);
343     if (dwReturn && dwReturn != SCARD_W_RESET_CARD)
344 vletoux 1 {
345 vletoux 9 Trace(WINEVENT_LEVEL_ERROR, L"SCardControl 0x%08X", dwReturn);
346 vletoux 1 __leave;
347     }
348 vletoux 9 Sleep(200);
349 vletoux 1 dwReturn = SelectOpenPGPApplication(pCardData);
350     }
351     __finally
352     {
353     }
354 vletoux 9 return dwReturn;*/
355     return SCARD_E_UNSUPPORTED_FEATURE;
356 vletoux 8 }
357    
358    
359     DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
360     {
361     DWORD dwReturn=0, dwVersion;
362     __try
363     {
364     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
365     dwVersion = (pPinInfo->dwVersion == 0) ? PIN_INFO_CURRENT_VERSION : pPinInfo->dwVersion;
366     if ( dwVersion != PIN_INFO_CURRENT_VERSION )
367     {
368     Trace(WINEVENT_LEVEL_ERROR, L"dwVersion %d", dwVersion);
369     dwReturn = ERROR_REVISION_MISMATCH;
370     __leave;
371     }
372     pPinInfo->dwVersion = dwVersion;
373     switch(dwPinIndex)
374     {
375     case ROLE_SIGNATURE:
376     pPinInfo->PinType = AlphaNumericPinType;
377     pPinInfo->PinPurpose = DigitalSignaturePin;
378     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
379     SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
380     SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
381     pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
382     SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
383     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
384     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
385     pPinInfo->dwFlags = 0;
386     break;
387     case ROLE_AUTHENTICATION:
388     pPinInfo->PinType = AlphaNumericPinType;
389     pPinInfo->PinPurpose = AuthenticationPin;
390     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
391     SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
392     SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
393     pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
394     SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
395     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
396     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
397     pPinInfo->dwFlags = 0;
398     break;
399     case ROLE_CONFIDENTIALITY:
400     pPinInfo->PinType = AlphaNumericPinType;
401     pPinInfo->PinPurpose = EncryptionPin;
402     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
403     SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
404     SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
405     pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
406     SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
407     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
408     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
409     pPinInfo->dwFlags = 0;
410     break;
411     case ROLE_ADMIN:
412     pPinInfo->PinType = AlphaNumericPinType;
413     pPinInfo->PinPurpose = AdministratorPin;
414     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_ADMIN);
415     pPinInfo->dwUnblockPermission = 0;
416     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
417     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
418     pPinInfo->dwFlags = 0;
419     break;
420     case ROLE_PUK:
421     pPinInfo->PinType = AlphaNumericPinType;
422     pPinInfo->PinPurpose = UnblockOnlyPin;
423     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_ADMIN);
424     pPinInfo->dwUnblockPermission = 0;
425     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
426     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
427     pPinInfo->dwFlags = 0;
428     break;
429     default:
430     Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
431     dwReturn = SCARD_E_INVALID_PARAMETER ;
432     __leave;
433     }
434     }
435     __finally
436     {
437     }
438     Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
439     return dwReturn;
440 vletoux 1 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26