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

Contents of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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
25 SCARD_ATRMASK SupportedATR [] =
26 {
27 { // v2
28 21,
29 //3B DA 18 FF 81 B1 FE 75 1F 03 00 31 C5 73 C0 01 40 00 90 00 0C
30 {0x3B,0xDA,0x18,0xFF,0x81,0xB1,0xFE,0x75,0x1F,0x03,
31 0x00,0x31,0xC5,0x73,0xC0,0x01,0x40,0x00,0x90,0x00,0x0C},
32 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
33 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}
34 },
35 { // v1
36 20,
37 //3B FA 13 00 FF 81 31 80 45 00 31 C1 73 C0 01 00 00 90 00 B1
38 {0x3B,0xFA,0x13,0x00,0xFF,0x81,0x31,0x80,0x45,0x00,
39 0x31,0xC1,0x73,0xC0,0x01,0x00,0x00,0x90,0x00,0xB1},
40 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
41 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}
42 }
43 };
44 DWORD dwSupportedATRCount = ARRAYSIZE(SupportedATR);
45
46 BOOL find_compacttlv(__in PBYTE pbData, __in DWORD dwTotalSize, __in BYTE bCode, __out PBYTE *pbDataOut, __out_opt PDWORD pdwSize)
47 {
48 DWORD dwOffset = 0;
49 DWORD dwSize;
50 while (dwOffset < dwTotalSize)
51 {
52 if (bCode * 0x10 == (pbData[dwOffset] & 0xF0) )
53 {
54 dwSize = (pbData[dwOffset] & 0x0F);
55 if (pdwSize)
56 {
57 *pdwSize = dwSize;
58 }
59 dwOffset++;
60 // size sequence
61
62 *pbDataOut = pbData + dwOffset;
63 return TRUE;
64 }
65 else
66 {
67
68 dwSize = (pbData[dwOffset] & 0x0F);
69 dwOffset += dwSize + 1;
70 }
71 }
72 return FALSE;
73 }
74
75
76
77 DWORD CheckContextEx(__in PCARD_DATA pCardData, __in BOOL fOpenPGPContextShouldBeNotNull)
78 {
79 DWORD dwReturn;
80 DWORD dwI, dwJ;
81 BOOL fFound = FALSE;
82 BOOL fRightATRLenFound = FALSE;
83 __try
84 {
85 if ( pCardData == NULL )
86 {
87 Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
88 dwReturn = SCARD_E_INVALID_PARAMETER;
89 __leave;
90 }
91 if (pCardData->pbAtr == NULL)
92 {
93 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pbAtr == NULL");
94 dwReturn = SCARD_E_INVALID_PARAMETER;
95 __leave;
96 }
97
98 if (pCardData->dwVersion < CARD_DATA_VERSION_SIX)
99 {
100 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->dwVersion(%d) < CARD_DATA_VERSION_SIX", pCardData->dwVersion);
101 dwReturn = ERROR_REVISION_MISMATCH;
102 __leave;
103 }
104 pCardData->dwVersion = min(pCardData->dwVersion, CARD_DATA_VERSION_SIX);
105 for (dwI = 0; dwI < dwSupportedATRCount; dwI++)
106 {
107 if (SupportedATR[dwI].cbAtr == pCardData->cbAtr)
108 {
109 BYTE pbAtr[36];
110 fRightATRLenFound = TRUE;
111 memcpy(pbAtr, pCardData->pbAtr, SupportedATR[dwI].cbAtr);
112 for( dwJ = 0; dwJ < SupportedATR[dwI].cbAtr; dwJ++)
113 {
114 pbAtr[dwJ] &= SupportedATR[dwI].rgbMask[dwJ];
115 }
116 if (memcmp(pbAtr, SupportedATR[dwI].rgbAtr, SupportedATR[dwI].cbAtr) == 0)
117 {
118 fFound = TRUE;
119 //Trace(WINEVENT_LEVEL_VERBOSE, L"card match ATR %d", dwI);
120 break;
121 }
122
123 }
124 }
125 if (!fRightATRLenFound)
126 {
127 Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR len %d",pCardData->cbAtr);
128 dwReturn = SCARD_E_INVALID_PARAMETER;
129 __leave;
130 }
131 if (!fFound)
132 {
133 Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR");
134 dwReturn = SCARD_E_UNKNOWN_CARD;
135 __leave;
136 }
137
138 if ( pCardData->pwszCardName == NULL )
139 {
140 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pwszCardName");
141 dwReturn = SCARD_E_INVALID_PARAMETER;
142 __leave;
143 }
144 /* Memory management functions */
145 if ( ( pCardData->pfnCspAlloc == NULL ) ||
146 ( pCardData->pfnCspReAlloc == NULL ) ||
147 ( pCardData->pfnCspFree == NULL ) )
148 {
149 Trace(WINEVENT_LEVEL_ERROR, L"Memory functions null");
150 dwReturn = SCARD_E_INVALID_PARAMETER;
151 __leave;
152 }
153 if (fOpenPGPContextShouldBeNotNull)
154 {
155 if (!pCardData->pvVendorSpecific)
156 {
157 // not found =>
158 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pvVendorSpecific == NULL");
159 dwReturn = SCARD_E_UNEXPECTED;
160 __leave;
161 }
162 if (pCardData->hSCardCtx == 0)
163 {
164 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hSCardCtx == NULL");
165 dwReturn = SCARD_E_INVALID_PARAMETER;
166 __leave;
167 }
168 if (pCardData->hScard == 0)
169 {
170 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hScard == NULL");
171 dwReturn = SCARD_E_INVALID_PARAMETER;
172 __leave;
173 }
174 }
175 else
176 {
177 if (pCardData->pvVendorSpecific)
178 {
179 Trace(WINEVENT_LEVEL_ERROR, L"pContext != NULL");
180 dwReturn = SCARD_E_UNEXPECTED;
181 __leave;
182 }
183 }
184 dwReturn = 0;
185 }
186 __finally
187 {
188 }
189 return dwReturn;
190 }
191
192 DWORD CheckContext(__in PCARD_DATA pCardData)
193 {
194 return CheckContextEx(pCardData, TRUE);
195 }
196
197 DWORD CleanContext(__in PCARD_DATA pCardData)
198 {
199 DWORD dwReturn = 0;
200 __try
201 {
202 if (pCardData)
203 {
204 if ( pCardData->pvVendorSpecific)
205 {
206 pCardData->pfnCspFree( pCardData->pvVendorSpecific);
207 pCardData->pvVendorSpecific = NULL;
208 }
209 else
210 {
211 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pvVendorSpecific == NULL");
212 }
213 }
214 else
215 {
216 Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
217 dwReturn = SCARD_E_INVALID_PARAMETER;
218 __leave;
219 }
220 }
221 __finally
222 {
223 }
224 return dwReturn;
225 }
226
227
228 DWORD CreateContext(__in PCARD_DATA pCardData, __in DWORD dwFlags)
229 {
230 DWORD dwReturn;
231 PBYTE pbCapabilities = NULL, pbCardCapabilities;
232 PBYTE pbExtendedCapabilities = NULL;
233 PBYTE pbApplicationIdentifier = NULL;
234 PBYTE pbFingerPrint = NULL;
235 DWORD dwCapabilitiesSize,
236 dwCardCapabilitiesSize,
237 dwApplicationIdentifierSize,
238 dwExtendedCapabilitiesSize,
239 dwFingerPrintSize;
240 DWORD dwI;
241 BYTE bCategoryIndicator, bStatusIndicator;
242 POPENPGP_CONTEXT pContext;
243 __try
244 {
245 dwReturn = CheckContextEx(pCardData, FALSE);
246 if (dwReturn)
247 {
248 Trace(WINEVENT_LEVEL_ERROR, L"CheckContext");
249 __leave;
250 }
251 if (!(dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE))
252 {
253 if (pCardData->hSCardCtx == 0)
254 {
255 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hSCardCtx == NULL");
256 dwReturn = SCARD_E_INVALID_HANDLE;
257 __leave;
258 }
259 if (pCardData->hScard == 0)
260 {
261 Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hScard == NULL");
262 dwReturn = SCARD_E_INVALID_HANDLE;
263 __leave;
264 }
265 }
266
267 // not found => initialize context
268 pContext = pCardData->pfnCspAlloc(sizeof(OPENPGP_CONTEXT));
269 if (!pContext)
270 {
271 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
272 dwReturn = SCARD_E_NO_MEMORY;
273 __leave;
274 }
275 memset(pContext, 0, sizeof(OPENPGP_CONTEXT));
276 pCardData->pvVendorSpecific = pContext;
277
278 dwReturn = SelectOpenPGPApplication(pCardData);
279 if (dwReturn)
280 {
281 Trace(WINEVENT_LEVEL_ERROR, L"No SelectOpenPGPApplication");
282 __leave;
283 }
284 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPApplicationIdentifier, &pbApplicationIdentifier, &dwApplicationIdentifierSize);
285 if (dwReturn)
286 {
287 __leave;
288 }
289 if (dwApplicationIdentifierSize != sizeof(OPENPGP_AID))
290 {
291 Trace(WINEVENT_LEVEL_ERROR, L"dwApplicationIdentifierSize = %02X", dwApplicationIdentifierSize);
292 dwReturn = SCARD_E_UNEXPECTED;
293 __leave;
294 }
295 memcpy(&(pContext->Aid),pbApplicationIdentifier,sizeof(OPENPGP_AID));
296 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPHistoricalBytes, &pbCapabilities, &dwCapabilitiesSize);
297 if (dwReturn)
298 {
299 __leave;
300 }
301 bCategoryIndicator = pbCapabilities[0];
302 if (bCategoryIndicator != 0)
303 {
304 Trace(WINEVENT_LEVEL_ERROR, L"bCategoryIndicator = %02X", bCategoryIndicator);
305 dwReturn = SCARD_E_UNEXPECTED;
306 __leave;
307 }
308 bStatusIndicator = pbCapabilities[dwCapabilitiesSize -3];
309 if (bStatusIndicator != 0 && bStatusIndicator != 03 && bStatusIndicator != 05)
310 {
311 Trace(WINEVENT_LEVEL_ERROR, L"bStatusIndicator = %02X", bStatusIndicator);
312 dwReturn = SCARD_E_UNEXPECTED;
313 __leave;
314 }
315 if (!find_compacttlv(pbCapabilities + 1, dwCapabilitiesSize - 1, 7, &pbCardCapabilities, &dwCardCapabilitiesSize))
316 {
317 Trace(WINEVENT_LEVEL_ERROR, L"tlv not found");
318 dwReturn = SCARD_E_UNEXPECTED;
319 __leave;
320 }
321 if (dwCardCapabilitiesSize != 3)
322 {
323 Trace(WINEVENT_LEVEL_ERROR, L"dwCardCapabilitiesSize = %02X", dwCardCapabilitiesSize);
324 dwReturn = SCARD_E_UNEXPECTED;
325 __leave;
326 }
327 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPExtendedCap, &pbExtendedCapabilities, &dwExtendedCapabilitiesSize);
328 if (dwReturn)
329 {
330 __leave;
331 }
332 pContext->fExtentedLeLcFields = ((pbCardCapabilities[2] & 0x40)?TRUE:FALSE);
333 pContext->fSupportCommandChaining = ((pbCardCapabilities[2] & 0x80)?TRUE:FALSE);
334 pContext->bSecureMessagingAlgorithm = pbExtendedCapabilities[1];
335 pContext->dwMaxChallengeLength = pbExtendedCapabilities[2] * 0x100 + pbExtendedCapabilities[3];
336 pContext->dwMaxCertificateLength = pbExtendedCapabilities[4] * 0x100 + pbExtendedCapabilities[5];
337 pContext->dwMaxCommandDataLength = pbExtendedCapabilities[6] * 0x100 + pbExtendedCapabilities[7];
338 pContext->dwMaxResponseLength = pbExtendedCapabilities[8] * 0x100 + pbExtendedCapabilities[9];
339 pContext->fIsReadOnly = TRUE;
340 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPFingerprint, &pbFingerPrint, &dwFingerPrintSize);
341 if (dwReturn)
342 {
343 __leave;
344 }
345 if (dwFingerPrintSize != 60)
346 {
347 Trace(WINEVENT_LEVEL_ERROR, L"dwFingerPrintSize = %02X", dwFingerPrintSize);
348 dwReturn = SCARD_E_UNEXPECTED;
349 __leave;
350 }
351 pContext->fHasSignature = FALSE;
352 for( dwI = 0; dwI < 20; dwI++)
353 {
354 if (pbFingerPrint[dwI] != 0)
355 {
356 pContext->fHasSignature = TRUE;
357 break;
358 }
359 }
360 pContext->fHasDecryption = FALSE;
361 for( dwI = 20; dwI < 40; dwI++)
362 {
363 if (pbFingerPrint[dwI] != 0)
364 {
365 pContext->fHasDecryption = TRUE;
366 break;
367 }
368 }
369 pContext->fHasAuthentication = FALSE;
370 for( dwI = 40; dwI < 60; dwI++)
371 {
372 if (pbFingerPrint[dwI] != 0)
373 {
374 pContext->fHasAuthentication = TRUE;
375 break;
376 }
377 }
378 dwReturn = CCIDgetFeatures(pCardData);
379 if (dwReturn)
380 {
381 __leave;
382 }
383 dwReturn = 0;
384 }
385 __finally
386 {
387 if (pbFingerPrint)
388 pCardData->pfnCspFree(pbFingerPrint);
389 if (pbApplicationIdentifier)
390 pCardData->pfnCspFree(pbApplicationIdentifier);
391 if (pbCapabilities)
392 pCardData->pfnCspFree(pbCapabilities);
393 if (pbExtendedCapabilities)
394 pCardData->pfnCspFree(pbExtendedCapabilities);
395 }
396 return dwReturn;
397 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26