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

Annotation of /trunk/OpenPGPminidriver/PinOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide annotations)
Thu Feb 25 22:09:17 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 7890 byte(s)
fixed public key export (big endian - little endian issue)
signature works (sign & verify)
decrypt really decrypt but output not recognized yet by cryptoapi
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     DWORD dwMinPinSize = 0, dwMaxPinSize;
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     break;
45     case ROLE_ADMIN:
46     dwMinPinSize = 8;
47     break;
48     default:
49     dwReturn = SCARD_E_INVALID_PARAMETER;
50     __leave;
51     }
52     if (cbPin < dwMinPinSize)
53     {
54     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV ROLE = %d cbPin = %d minPinSize = %d",PinId, cbPin, dwMinPinSize);
55     dwReturn = SCARD_W_WRONG_CHV;
56     __leave;
57     }
58     // check in status DO
59     dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, NULL);
60     switch(PinId)
61     {
62     case ROLE_SIGNATURE:
63     case ROLE_AUTHENTICATION:
64     case ROLE_CONFIDENTIALITY:
65     dwMaxPinSize = pbResponse[1];
66     break;
67     case ROLE_PUK:
68     dwMaxPinSize = pbResponse[2];
69     break;
70     case ROLE_ADMIN:
71     dwMaxPinSize = pbResponse[3];
72     break;
73     default:
74     dwReturn = SCARD_E_INVALID_PARAMETER;
75     __leave;
76     }
77     if (cbPin > dwMaxPinSize)
78     {
79     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_WRONG_CHV ROLE = %d cbPin = %d dwMaxPinSize = %d", PinId, cbPin, dwMaxPinSize);
80     dwReturn = SCARD_W_WRONG_CHV;
81     __leave;
82     }
83     dwReturn = 0;
84     }
85     __finally
86     {
87     if (pbResponse)
88     pCardData->pfnCspFree(pbResponse);
89     }
90     return dwReturn;
91     }
92    
93     DWORD GetRemainingPin(__in PCARD_DATA pCardData, __in PIN_ID PinId, __out PDWORD pdwCounter)
94     {
95     DWORD dwReturn;
96     PBYTE pbResponse = NULL;
97     __try
98     {
99     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
100     dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPStatus, &pbResponse, NULL);
101     switch(PinId)
102     {
103     case ROLE_SIGNATURE:
104     case ROLE_AUTHENTICATION:
105     case ROLE_CONFIDENTIALITY:
106     *pdwCounter = pbResponse[4];
107     break;
108     case ROLE_PUK:
109     *pdwCounter = pbResponse[5];
110     break;
111     case ROLE_ADMIN:
112     *pdwCounter = pbResponse[6];
113     break;
114     default:
115     dwReturn = SCARD_E_INVALID_PARAMETER;
116     __leave;
117     }
118     }
119     __finally
120     {
121     if (pbResponse)
122     pCardData->pfnCspFree(pbResponse);
123     }
124     return dwReturn;
125     }
126    
127     DWORD VerifyPIN(__in PCARD_DATA pCardData,__in PIN_ID PinId,
128     __in_bcount(cbPin) PBYTE pbPin, __in DWORD cbPin)
129     {
130     DWORD dwReturn;
131     // 256 because the size of the PIN must fit in a Byte
132     BYTE pbCmd[256 + 5] = {0x00,
133     0x20,
134     0x00,
135     0x82,
136     0x00
137     };
138     __try
139     {
140     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
141     switch(PinId)
142     {
143     case ROLE_SIGNATURE:
144     pbCmd[3] = 0x81;
145     break;
146     case ROLE_AUTHENTICATION:
147     case ROLE_CONFIDENTIALITY:
148     pbCmd[3] = 0x82;
149     break;
150     case ROLE_ADMIN:
151     pbCmd[3] = 0x83;
152     break;
153     case ROLE_PUK:
154     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
155     __leave;
156     default:
157     dwReturn = SCARD_E_INVALID_PARAMETER;
158     __leave;
159     }
160     pbCmd[4] = (BYTE) cbPin;
161     memcpy(pbCmd + 5, pbPin, cbPin);
162     dwReturn = SCardSendCommand(pCardData, pbCmd, 5 + cbPin);
163     if (dwReturn)
164     {
165     __leave;
166     }
167 vletoux 3 /*switch(PinId)
168 vletoux 1 {
169     case ROLE_AUTHENTICATION:
170     case ROLE_CONFIDENTIALITY:
171     dwReturn = VerifyPIN(pCardData, ROLE_SIGNATURE, pbPin, cbPin);
172     break;
173 vletoux 3 }*/
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     dwReturn = CheckPinLength(pCardData, PinId, cbOldPin);
201     if (dwReturn)
202     {
203     __leave;
204     }
205     switch(PinId)
206     {
207     case ROLE_SIGNATURE:
208     case ROLE_AUTHENTICATION:
209     case ROLE_CONFIDENTIALITY:
210     pbCmd[3] = 0x81;
211     break;
212     case ROLE_ADMIN:
213     pbCmd[3] = 0x83;
214     break;
215     case ROLE_PUK:
216     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
217     __leave;
218     default:
219     dwReturn = SCARD_E_INVALID_PARAMETER;
220     __leave;
221     }
222     pbCmd[4] = (BYTE) (cbOldPin + cbNewPin);
223     memcpy(pbCmd + 5, pbOldPin, cbOldPin);
224     memcpy(pbCmd + 5 + cbOldPin, pbNewPin, cbNewPin);
225     dwReturn = SCardSendCommand(pCardData, pbCmd, 5 + cbOldPin + cbNewPin);
226     }
227     __finally
228     {
229     SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
230     }
231     return dwReturn;
232     }
233    
234     /** only the user PIN can be reseted => target is implicit*/
235     DWORD ResetUserPIN(__in PCARD_DATA pCardData, __in PIN_ID PinId,
236     __in_bcount(cbPin) PBYTE pbAuthenticator, __in DWORD cbAuthenticator,
237     __in_bcount(cbPin) PBYTE pbNewPin, __in DWORD cbNewPin
238     )
239     {
240     DWORD dwReturn;
241     BYTE pbCmd[256 + 5] = {0x00,
242     0x2C,
243     0x02,
244     0x81,
245     0x00
246     };
247     DWORD dwCmdSize;
248    
249     __try
250     {
251     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter PinId=%d",PinId);
252     switch(PinId)
253     {
254     case ROLE_ADMIN:
255     // authenticate the admin
256     dwReturn = VerifyPIN(pCardData, PinId, pbAuthenticator, cbAuthenticator);
257     if (!dwReturn)
258     {
259     return dwReturn;
260     }
261     pbCmd[4] = (BYTE) cbAuthenticator;
262     memcpy(pbCmd + 5, pbNewPin, cbNewPin);
263     dwCmdSize = 5 + cbNewPin;
264     break;
265     case ROLE_PUK:
266     dwReturn = CheckPinLength(pCardData, PinId, cbAuthenticator);
267     if (dwReturn)
268     {
269     __leave;
270     }
271     pbCmd[2] = 0x00;
272     pbCmd[4] = (BYTE) (cbAuthenticator + cbNewPin);
273     memcpy(pbCmd + 5, pbAuthenticator, cbAuthenticator);
274     memcpy(pbCmd + 5 + cbAuthenticator, pbNewPin, cbNewPin);
275     dwCmdSize = 5 + cbNewPin + cbAuthenticator;
276     break;
277     default:
278     dwReturn = SCARD_E_INVALID_PARAMETER;
279     __leave;
280     }
281     dwReturn = SCardSendCommand(pCardData, pbCmd, dwCmdSize);
282     }
283     __finally
284     {
285     SecureZeroMemory(pbCmd, ARRAYSIZE(pbCmd));
286     }
287     return dwReturn;
288     }
289    
290     DWORD Deauthenticate(__in PCARD_DATA pCardData)
291     {
292     DWORD dwAP;
293     DWORD dwReturn;
294     __try
295     {
296     // reset the card
297     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter");
298     dwReturn = SCardReconnect(pCardData->hScard,
299     SCARD_SHARE_SHARED,
300     SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
301     SCARD_LEAVE_CARD,
302     &dwAP );
303     if (dwReturn)
304     {
305     Trace(WINEVENT_LEVEL_ERROR, L"SCardControl 0x%08X", dwReturn);
306     __leave;
307     }
308     // regain the ownership of a transaction
309     dwReturn = SCardBeginTransaction(pCardData->hScard);
310     if (dwReturn)
311     {
312     Trace(WINEVENT_LEVEL_ERROR, L"SCardBeginTransaction 0x%08X", dwReturn);
313     __leave;
314     }
315     dwReturn = SelectOpenPGPApplication(pCardData);
316     }
317     __finally
318     {
319     }
320     return dwReturn;
321     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26