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

Contents of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26