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

Annotation of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (hide 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 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    
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 vletoux 8
77     DWORD CheckContextEx(__in PCARD_DATA pCardData, __in BOOL fOpenPGPContextShouldBeNotNull)
78 vletoux 1 {
79     DWORD dwReturn;
80 vletoux 8 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 vletoux 1 PBYTE pbCapabilities = NULL, pbCardCapabilities;
232     PBYTE pbExtendedCapabilities = NULL;
233     PBYTE pbApplicationIdentifier = NULL;
234 vletoux 8 PBYTE pbFingerPrint = NULL;
235 vletoux 1 DWORD dwCapabilitiesSize,
236     dwCardCapabilitiesSize,
237 vletoux 6 dwApplicationIdentifierSize,
238 vletoux 8 dwExtendedCapabilitiesSize,
239     dwFingerPrintSize;
240     DWORD dwI;
241 vletoux 1 BYTE bCategoryIndicator, bStatusIndicator;
242 vletoux 8 POPENPGP_CONTEXT pContext;
243 vletoux 1 __try
244     {
245 vletoux 8 dwReturn = CheckContextEx(pCardData, FALSE);
246     if (dwReturn)
247 vletoux 1 {
248 vletoux 8 Trace(WINEVENT_LEVEL_ERROR, L"CheckContext");
249 vletoux 1 __leave;
250     }
251 vletoux 8 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 vletoux 1 // 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 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPApplicationIdentifier, &pbApplicationIdentifier, &dwApplicationIdentifierSize);
285 vletoux 1 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 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPHistoricalBytes, &pbCapabilities, &dwCapabilitiesSize);
297 vletoux 1 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 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPExtendedCap, &pbExtendedCapabilities, &dwExtendedCapabilitiesSize);
328 vletoux 1 if (dwReturn)
329     {
330 vletoux 6 __leave;
331 vletoux 1 }
332     pContext->fExtentedLeLcFields = ((pbCardCapabilities[2] & 0x40)?TRUE:FALSE);
333     pContext->fSupportCommandChaining = ((pbCardCapabilities[2] & 0x80)?TRUE:FALSE);
334 vletoux 6 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 vletoux 8 pContext->fIsReadOnly = TRUE;
340     dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPFingerprint, &pbFingerPrint, &dwFingerPrintSize);
341 vletoux 1 if (dwReturn)
342     {
343     __leave;
344     }
345 vletoux 8 if (dwFingerPrintSize != 60)
346 vletoux 1 {
347 vletoux 8 Trace(WINEVENT_LEVEL_ERROR, L"dwFingerPrintSize = %02X", dwFingerPrintSize);
348     dwReturn = SCARD_E_UNEXPECTED;
349 vletoux 1 __leave;
350     }
351 vletoux 8 pContext->fHasSignature = FALSE;
352     for( dwI = 0; dwI < 20; dwI++)
353 vletoux 1 {
354 vletoux 8 if (pbFingerPrint[dwI] != 0)
355     {
356     pContext->fHasSignature = TRUE;
357     break;
358     }
359 vletoux 1 }
360 vletoux 8 pContext->fHasDecryption = FALSE;
361     for( dwI = 20; dwI < 40; dwI++)
362 vletoux 1 {
363 vletoux 8 if (pbFingerPrint[dwI] != 0)
364     {
365     pContext->fHasDecryption = TRUE;
366     break;
367     }
368 vletoux 1 }
369 vletoux 8 pContext->fHasAuthentication = FALSE;
370     for( dwI = 40; dwI < 60; dwI++)
371 vletoux 1 {
372 vletoux 8 if (pbFingerPrint[dwI] != 0)
373 vletoux 1 {
374 vletoux 8 pContext->fHasAuthentication = TRUE;
375     break;
376 vletoux 1 }
377     }
378 vletoux 8 dwReturn = CCIDgetFeatures(pCardData);
379     if (dwReturn)
380 vletoux 1 {
381     __leave;
382     }
383     dwReturn = 0;
384     }
385     __finally
386     {
387 vletoux 8 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 vletoux 1 }
396     return dwReturn;
397     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26