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

Annotation of /trunk/OpenPGPminidriver/PinOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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     DWORD dwAP;
336     DWORD dwReturn;
337     __try
338     {
339     // reset the card
340     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
341     dwReturn = SCardReconnect(pCardData->hScard,
342     SCARD_SHARE_SHARED,
343     SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
344 vletoux 8 SCARD_RESET_CARD,
345 vletoux 1 &dwAP );
346     if (dwReturn)
347     {
348 vletoux 8 Trace(WINEVENT_LEVEL_ERROR, L"SCardReconnect 0x%08X", dwReturn);
349 vletoux 1 __leave;
350     }
351     dwReturn = SCardBeginTransaction(pCardData->hScard);
352     if (dwReturn)
353     {
354     Trace(WINEVENT_LEVEL_ERROR, L"SCardBeginTransaction 0x%08X", dwReturn);
355     __leave;
356     }
357     dwReturn = SelectOpenPGPApplication(pCardData);
358     }
359     __finally
360     {
361     }
362     return dwReturn;
363 vletoux 8 }
364    
365    
366     DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
367     {
368     DWORD dwReturn=0, dwVersion;
369     __try
370     {
371     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
372     dwVersion = (pPinInfo->dwVersion == 0) ? PIN_INFO_CURRENT_VERSION : pPinInfo->dwVersion;
373     if ( dwVersion != PIN_INFO_CURRENT_VERSION )
374     {
375     Trace(WINEVENT_LEVEL_ERROR, L"dwVersion %d", dwVersion);
376     dwReturn = ERROR_REVISION_MISMATCH;
377     __leave;
378     }
379     pPinInfo->dwVersion = dwVersion;
380     switch(dwPinIndex)
381     {
382     case ROLE_SIGNATURE:
383     pPinInfo->PinType = AlphaNumericPinType;
384     pPinInfo->PinPurpose = DigitalSignaturePin;
385     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
386     SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
387     SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
388     pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
389     SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
390     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
391     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
392     pPinInfo->dwFlags = 0;
393     break;
394     case ROLE_AUTHENTICATION:
395     pPinInfo->PinType = AlphaNumericPinType;
396     pPinInfo->PinPurpose = AuthenticationPin;
397     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
398     SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
399     SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
400     pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
401     SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
402     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
403     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
404     pPinInfo->dwFlags = 0;
405     break;
406     case ROLE_CONFIDENTIALITY:
407     pPinInfo->PinType = AlphaNumericPinType;
408     pPinInfo->PinPurpose = EncryptionPin;
409     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_SIGNATURE);
410     SET_PIN(pPinInfo->dwChangePermission, ROLE_AUTHENTICATION);
411     SET_PIN(pPinInfo->dwChangePermission, ROLE_CONFIDENTIALITY);
412     pPinInfo->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
413     SET_PIN(pPinInfo->dwUnblockPermission, ROLE_PUK);
414     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
415     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
416     pPinInfo->dwFlags = 0;
417     break;
418     case ROLE_ADMIN:
419     pPinInfo->PinType = AlphaNumericPinType;
420     pPinInfo->PinPurpose = AdministratorPin;
421     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_ADMIN);
422     pPinInfo->dwUnblockPermission = 0;
423     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
424     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
425     pPinInfo->dwFlags = 0;
426     break;
427     case ROLE_PUK:
428     pPinInfo->PinType = AlphaNumericPinType;
429     pPinInfo->PinPurpose = UnblockOnlyPin;
430     pPinInfo->dwChangePermission = CREATE_PIN_SET(ROLE_ADMIN);
431     pPinInfo->dwUnblockPermission = 0;
432     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
433     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
434     pPinInfo->dwFlags = 0;
435     break;
436     default:
437     Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
438     dwReturn = SCARD_E_INVALID_PARAMETER ;
439     __leave;
440     }
441     }
442     __finally
443     {
444     }
445     Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
446     return dwReturn;
447 vletoux 1 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26