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

Annotation of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Wed Mar 31 08:58:46 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 11405 byte(s)
first msi Release
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 vletoux 9 #include "CryptoOperations.h"
25 vletoux 1
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 vletoux 8
78     DWORD CheckContextEx(__in PCARD_DATA pCardData, __in BOOL fOpenPGPContextShouldBeNotNull)
79 vletoux 1 {
80     DWORD dwReturn;
81 vletoux 8 DWORD dwI, dwJ;
82     BOOL fFound = FALSE;
83     BOOL fRightATRLenFound = FALSE;
84 vletoux 12 DWORD dwMinSupportedVersion;
85 vletoux 8 __try
86     {
87     if ( pCardData == NULL )
88     {
89     Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
90     dwReturn = SCARD_E_INVALID_PARAMETER;
91     __leave;
92     }
93     if (pCardData->pbAtr == NULL)
94     {
95     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pbAtr == NULL");
96     dwReturn = SCARD_E_INVALID_PARAMETER;
97     __leave;
98     }
99 vletoux 12 if (fRunOnVistaAndLater)
100 vletoux 8 {
101 vletoux 12 dwMinSupportedVersion = CARD_DATA_VERSION_SIX;
102     }
103     else
104     {
105     // only a subset of functions is supported
106     // so the project don't pass the ms test
107     // we do this so the driver can operate under XP
108     dwMinSupportedVersion = CARD_DATA_VERSION_FIVE;
109     }
110     if (pCardData->dwVersion < dwMinSupportedVersion)
111     {
112     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->dwVersion(%d) < dwMinSupportedVersion(%d)", pCardData->dwVersion, dwMinSupportedVersion);
113 vletoux 8 dwReturn = ERROR_REVISION_MISMATCH;
114     __leave;
115     }
116 vletoux 12 pCardData->dwVersion = min(pCardData->dwVersion, CARD_DATA_VERSION_SEVEN);
117 vletoux 8 for (dwI = 0; dwI < dwSupportedATRCount; dwI++)
118     {
119     if (SupportedATR[dwI].cbAtr == pCardData->cbAtr)
120     {
121     BYTE pbAtr[36];
122     fRightATRLenFound = TRUE;
123     memcpy(pbAtr, pCardData->pbAtr, SupportedATR[dwI].cbAtr);
124     for( dwJ = 0; dwJ < SupportedATR[dwI].cbAtr; dwJ++)
125     {
126     pbAtr[dwJ] &= SupportedATR[dwI].rgbMask[dwJ];
127     }
128     if (memcmp(pbAtr, SupportedATR[dwI].rgbAtr, SupportedATR[dwI].cbAtr) == 0)
129     {
130     fFound = TRUE;
131     //Trace(WINEVENT_LEVEL_VERBOSE, L"card match ATR %d", dwI);
132     break;
133     }
134    
135     }
136     }
137     if (!fRightATRLenFound)
138     {
139     Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR len %d",pCardData->cbAtr);
140     dwReturn = SCARD_E_INVALID_PARAMETER;
141     __leave;
142     }
143     if (!fFound)
144     {
145     Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR");
146     dwReturn = SCARD_E_UNKNOWN_CARD;
147     __leave;
148     }
149    
150     if ( pCardData->pwszCardName == NULL )
151     {
152     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pwszCardName");
153     dwReturn = SCARD_E_INVALID_PARAMETER;
154     __leave;
155     }
156     /* Memory management functions */
157     if ( ( pCardData->pfnCspAlloc == NULL ) ||
158     ( pCardData->pfnCspReAlloc == NULL ) ||
159     ( pCardData->pfnCspFree == NULL ) )
160     {
161     Trace(WINEVENT_LEVEL_ERROR, L"Memory functions null");
162     dwReturn = SCARD_E_INVALID_PARAMETER;
163     __leave;
164     }
165     if (fOpenPGPContextShouldBeNotNull)
166     {
167     if (!pCardData->pvVendorSpecific)
168     {
169     // not found =>
170     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pvVendorSpecific == NULL");
171     dwReturn = SCARD_E_UNEXPECTED;
172     __leave;
173     }
174     }
175     else
176     {
177 vletoux 11 pCardData->pvVendorSpecific = NULL;
178 vletoux 8 }
179     dwReturn = 0;
180     }
181     __finally
182     {
183     }
184     return dwReturn;
185     }
186    
187     DWORD CheckContext(__in PCARD_DATA pCardData)
188     {
189     return CheckContextEx(pCardData, TRUE);
190     }
191    
192     DWORD CleanContext(__in PCARD_DATA pCardData)
193     {
194 vletoux 10 DWORD dwReturn = 0, dwI;
195 vletoux 8 __try
196     {
197     if (pCardData)
198     {
199     if ( pCardData->pvVendorSpecific)
200     {
201 vletoux 10 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
202     for(dwI = 0; dwI < KeyMax; dwI++)
203     {
204     if (pContext->pbModulusInLittleEndian[dwI] != NULL)
205     {
206     pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwI]);
207     pContext->pbModulusInLittleEndian[dwI] = NULL;
208     }
209     }
210 vletoux 8 pCardData->pfnCspFree( pCardData->pvVendorSpecific);
211     pCardData->pvVendorSpecific = NULL;
212     }
213     else
214     {
215     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pvVendorSpecific == NULL");
216     }
217     }
218     else
219     {
220     Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
221     dwReturn = SCARD_E_INVALID_PARAMETER;
222     __leave;
223     }
224     }
225     __finally
226     {
227     }
228     return dwReturn;
229     }
230    
231    
232     DWORD CreateContext(__in PCARD_DATA pCardData, __in DWORD dwFlags)
233     {
234     DWORD dwReturn;
235 vletoux 1 PBYTE pbCapabilities = NULL, pbCardCapabilities;
236     PBYTE pbExtendedCapabilities = NULL;
237     PBYTE pbApplicationIdentifier = NULL;
238 vletoux 8 PBYTE pbFingerPrint = NULL;
239 vletoux 1 DWORD dwCapabilitiesSize,
240     dwCardCapabilitiesSize,
241 vletoux 6 dwApplicationIdentifierSize,
242 vletoux 8 dwExtendedCapabilitiesSize,
243     dwFingerPrintSize;
244 vletoux 9 DWORD dwI, dwJ;
245 vletoux 1 BYTE bCategoryIndicator, bStatusIndicator;
246 vletoux 8 POPENPGP_CONTEXT pContext;
247 vletoux 1 __try
248     {
249 vletoux 8 dwReturn = CheckContextEx(pCardData, FALSE);
250     if (dwReturn)
251 vletoux 1 {
252 vletoux 8 Trace(WINEVENT_LEVEL_ERROR, L"CheckContext");
253 vletoux 1 __leave;
254     }
255 vletoux 8 if (!(dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE))
256     {
257     if (pCardData->hSCardCtx == 0)
258     {
259     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hSCardCtx == NULL");
260     dwReturn = SCARD_E_INVALID_HANDLE;
261     __leave;
262     }
263     if (pCardData->hScard == 0)
264     {
265     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hScard == NULL");
266     dwReturn = SCARD_E_INVALID_HANDLE;
267     __leave;
268     }
269     }
270    
271 vletoux 1 // not found => initialize context
272     pContext = pCardData->pfnCspAlloc(sizeof(OPENPGP_CONTEXT));
273     if (!pContext)
274     {
275     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
276     dwReturn = SCARD_E_NO_MEMORY;
277     __leave;
278     }
279     memset(pContext, 0, sizeof(OPENPGP_CONTEXT));
280     pCardData->pvVendorSpecific = pContext;
281    
282     dwReturn = SelectOpenPGPApplication(pCardData);
283     if (dwReturn)
284     {
285     Trace(WINEVENT_LEVEL_ERROR, L"No SelectOpenPGPApplication");
286     __leave;
287     }
288 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPApplicationIdentifier, &pbApplicationIdentifier, &dwApplicationIdentifierSize);
289 vletoux 1 if (dwReturn)
290     {
291     __leave;
292     }
293     if (dwApplicationIdentifierSize != sizeof(OPENPGP_AID))
294     {
295     Trace(WINEVENT_LEVEL_ERROR, L"dwApplicationIdentifierSize = %02X", dwApplicationIdentifierSize);
296     dwReturn = SCARD_E_UNEXPECTED;
297     __leave;
298     }
299     memcpy(&(pContext->Aid),pbApplicationIdentifier,sizeof(OPENPGP_AID));
300 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPHistoricalBytes, &pbCapabilities, &dwCapabilitiesSize);
301 vletoux 1 if (dwReturn)
302     {
303     __leave;
304     }
305     bCategoryIndicator = pbCapabilities[0];
306     if (bCategoryIndicator != 0)
307     {
308     Trace(WINEVENT_LEVEL_ERROR, L"bCategoryIndicator = %02X", bCategoryIndicator);
309     dwReturn = SCARD_E_UNEXPECTED;
310     __leave;
311     }
312     bStatusIndicator = pbCapabilities[dwCapabilitiesSize -3];
313     if (bStatusIndicator != 0 && bStatusIndicator != 03 && bStatusIndicator != 05)
314     {
315     Trace(WINEVENT_LEVEL_ERROR, L"bStatusIndicator = %02X", bStatusIndicator);
316     dwReturn = SCARD_E_UNEXPECTED;
317     __leave;
318     }
319     if (!find_compacttlv(pbCapabilities + 1, dwCapabilitiesSize - 1, 7, &pbCardCapabilities, &dwCardCapabilitiesSize))
320     {
321     Trace(WINEVENT_LEVEL_ERROR, L"tlv not found");
322     dwReturn = SCARD_E_UNEXPECTED;
323     __leave;
324     }
325     if (dwCardCapabilitiesSize != 3)
326     {
327     Trace(WINEVENT_LEVEL_ERROR, L"dwCardCapabilitiesSize = %02X", dwCardCapabilitiesSize);
328     dwReturn = SCARD_E_UNEXPECTED;
329     __leave;
330     }
331 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPExtendedCap, &pbExtendedCapabilities, &dwExtendedCapabilitiesSize);
332 vletoux 1 if (dwReturn)
333     {
334 vletoux 6 __leave;
335 vletoux 1 }
336     pContext->fExtentedLeLcFields = ((pbCardCapabilities[2] & 0x40)?TRUE:FALSE);
337     pContext->fSupportCommandChaining = ((pbCardCapabilities[2] & 0x80)?TRUE:FALSE);
338 vletoux 12 if (pbExtendedCapabilities[0] & 0x80)
339     {
340     switch(pbExtendedCapabilities[1])
341     {
342     case 0:
343     pContext->aiSecureMessagingAlg = CALG_3DES;
344     break;
345     case 1:
346     pContext->aiSecureMessagingAlg = CALG_AES_128;
347     break;
348     }
349     Trace(WINEVENT_LEVEL_VERBOSE, L"secure messaging supported with aiAlg = %d", pContext->aiSecureMessagingAlg);
350     }
351 vletoux 6 pContext->dwMaxChallengeLength = pbExtendedCapabilities[2] * 0x100 + pbExtendedCapabilities[3];
352     pContext->dwMaxCertificateLength = pbExtendedCapabilities[4] * 0x100 + pbExtendedCapabilities[5];
353     pContext->dwMaxCommandDataLength = pbExtendedCapabilities[6] * 0x100 + pbExtendedCapabilities[7];
354     pContext->dwMaxResponseLength = pbExtendedCapabilities[8] * 0x100 + pbExtendedCapabilities[9];
355 vletoux 8 pContext->fIsReadOnly = TRUE;
356     dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPFingerprint, &pbFingerPrint, &dwFingerPrintSize);
357 vletoux 1 if (dwReturn)
358     {
359     __leave;
360     }
361 vletoux 8 if (dwFingerPrintSize != 60)
362 vletoux 1 {
363 vletoux 8 Trace(WINEVENT_LEVEL_ERROR, L"dwFingerPrintSize = %02X", dwFingerPrintSize);
364     dwReturn = SCARD_E_UNEXPECTED;
365 vletoux 1 __leave;
366     }
367 vletoux 9 memcpy(pContext->bFingerPrint, pbFingerPrint, 60);
368     for(dwJ = 0; dwJ < KeyMax; dwJ++)
369 vletoux 1 {
370 vletoux 9 pContext->fHasKey[dwJ] = FALSE;
371     for( dwI = dwJ * 20; dwI < dwJ * 20 + 20; dwI++)
372 vletoux 8 {
373 vletoux 9 if (pbFingerPrint[dwI] != 0)
374     {
375     pContext->fHasKey[dwJ] = TRUE;
376     break;
377     }
378 vletoux 8 }
379 vletoux 1 }
380 vletoux 10 /*dwReturn = CCIDgetFeatures(pCardData);
381 vletoux 8 if (dwReturn)
382 vletoux 1 {
383     __leave;
384 vletoux 10 }*/
385 vletoux 1 dwReturn = 0;
386     }
387     __finally
388     {
389 vletoux 8 if (pbFingerPrint)
390     pCardData->pfnCspFree(pbFingerPrint);
391     if (pbApplicationIdentifier)
392     pCardData->pfnCspFree(pbApplicationIdentifier);
393     if (pbCapabilities)
394     pCardData->pfnCspFree(pbCapabilities);
395     if (pbExtendedCapabilities)
396     pCardData->pfnCspFree(pbExtendedCapabilities);
397 vletoux 1 }
398     return dwReturn;
399     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26