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

Contents of /trunk/OpenPGPminidriver/PinOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show 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 /* 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 /*switch(PinId)
168 {
169 case ROLE_AUTHENTICATION:
170 case ROLE_CONFIDENTIALITY:
171 dwReturn = VerifyPIN(pCardData, ROLE_SIGNATURE, pbPin, cbPin);
172 break;
173 }*/
174
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