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

Annotation of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Mon Mar 15 09:47:30 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 10858 byte(s)
more test success
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     __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     }
185     dwReturn = 0;
186     }
187     __finally
188     {
189     }
190     return dwReturn;
191     }
192    
193     DWORD CheckContext(__in PCARD_DATA pCardData)
194     {
195     return CheckContextEx(pCardData, TRUE);
196     }
197    
198     DWORD CleanContext(__in PCARD_DATA pCardData)
199     {
200     DWORD dwReturn = 0;
201     __try
202     {
203     if (pCardData)
204     {
205     if ( pCardData->pvVendorSpecific)
206     {
207     pCardData->pfnCspFree( pCardData->pvVendorSpecific);
208     pCardData->pvVendorSpecific = NULL;
209     }
210     else
211     {
212     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pvVendorSpecific == NULL");
213     }
214     }
215     else
216     {
217     Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
218     dwReturn = SCARD_E_INVALID_PARAMETER;
219     __leave;
220     }
221     }
222     __finally
223     {
224     }
225     return dwReturn;
226     }
227    
228    
229     DWORD CreateContext(__in PCARD_DATA pCardData, __in DWORD dwFlags)
230     {
231     DWORD dwReturn;
232 vletoux 1 PBYTE pbCapabilities = NULL, pbCardCapabilities;
233     PBYTE pbExtendedCapabilities = NULL;
234     PBYTE pbApplicationIdentifier = NULL;
235 vletoux 8 PBYTE pbFingerPrint = NULL;
236 vletoux 1 DWORD dwCapabilitiesSize,
237     dwCardCapabilitiesSize,
238 vletoux 6 dwApplicationIdentifierSize,
239 vletoux 8 dwExtendedCapabilitiesSize,
240     dwFingerPrintSize;
241 vletoux 9 DWORD dwI, dwJ;
242 vletoux 1 BYTE bCategoryIndicator, bStatusIndicator;
243 vletoux 8 POPENPGP_CONTEXT pContext;
244 vletoux 1 __try
245     {
246 vletoux 8 dwReturn = CheckContextEx(pCardData, FALSE);
247     if (dwReturn)
248 vletoux 1 {
249 vletoux 8 Trace(WINEVENT_LEVEL_ERROR, L"CheckContext");
250 vletoux 1 __leave;
251     }
252 vletoux 8 if (!(dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE))
253     {
254     if (pCardData->hSCardCtx == 0)
255     {
256     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hSCardCtx == NULL");
257     dwReturn = SCARD_E_INVALID_HANDLE;
258     __leave;
259     }
260     if (pCardData->hScard == 0)
261     {
262     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->hScard == NULL");
263     dwReturn = SCARD_E_INVALID_HANDLE;
264     __leave;
265     }
266     }
267    
268 vletoux 1 // not found => initialize context
269     pContext = pCardData->pfnCspAlloc(sizeof(OPENPGP_CONTEXT));
270     if (!pContext)
271     {
272     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
273     dwReturn = SCARD_E_NO_MEMORY;
274     __leave;
275     }
276     memset(pContext, 0, sizeof(OPENPGP_CONTEXT));
277     pCardData->pvVendorSpecific = pContext;
278    
279     dwReturn = SelectOpenPGPApplication(pCardData);
280     if (dwReturn)
281     {
282     Trace(WINEVENT_LEVEL_ERROR, L"No SelectOpenPGPApplication");
283     __leave;
284     }
285 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPApplicationIdentifier, &pbApplicationIdentifier, &dwApplicationIdentifierSize);
286 vletoux 1 if (dwReturn)
287     {
288     __leave;
289     }
290     if (dwApplicationIdentifierSize != sizeof(OPENPGP_AID))
291     {
292     Trace(WINEVENT_LEVEL_ERROR, L"dwApplicationIdentifierSize = %02X", dwApplicationIdentifierSize);
293     dwReturn = SCARD_E_UNEXPECTED;
294     __leave;
295     }
296     memcpy(&(pContext->Aid),pbApplicationIdentifier,sizeof(OPENPGP_AID));
297 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPHistoricalBytes, &pbCapabilities, &dwCapabilitiesSize);
298 vletoux 1 if (dwReturn)
299     {
300     __leave;
301     }
302     bCategoryIndicator = pbCapabilities[0];
303     if (bCategoryIndicator != 0)
304     {
305     Trace(WINEVENT_LEVEL_ERROR, L"bCategoryIndicator = %02X", bCategoryIndicator);
306     dwReturn = SCARD_E_UNEXPECTED;
307     __leave;
308     }
309     bStatusIndicator = pbCapabilities[dwCapabilitiesSize -3];
310     if (bStatusIndicator != 0 && bStatusIndicator != 03 && bStatusIndicator != 05)
311     {
312     Trace(WINEVENT_LEVEL_ERROR, L"bStatusIndicator = %02X", bStatusIndicator);
313     dwReturn = SCARD_E_UNEXPECTED;
314     __leave;
315     }
316     if (!find_compacttlv(pbCapabilities + 1, dwCapabilitiesSize - 1, 7, &pbCardCapabilities, &dwCardCapabilitiesSize))
317     {
318     Trace(WINEVENT_LEVEL_ERROR, L"tlv not found");
319     dwReturn = SCARD_E_UNEXPECTED;
320     __leave;
321     }
322     if (dwCardCapabilitiesSize != 3)
323     {
324     Trace(WINEVENT_LEVEL_ERROR, L"dwCardCapabilitiesSize = %02X", dwCardCapabilitiesSize);
325     dwReturn = SCARD_E_UNEXPECTED;
326     __leave;
327     }
328 vletoux 8 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPExtendedCap, &pbExtendedCapabilities, &dwExtendedCapabilitiesSize);
329 vletoux 1 if (dwReturn)
330     {
331 vletoux 6 __leave;
332 vletoux 1 }
333     pContext->fExtentedLeLcFields = ((pbCardCapabilities[2] & 0x40)?TRUE:FALSE);
334     pContext->fSupportCommandChaining = ((pbCardCapabilities[2] & 0x80)?TRUE:FALSE);
335 vletoux 6 pContext->bSecureMessagingAlgorithm = pbExtendedCapabilities[1];
336     pContext->dwMaxChallengeLength = pbExtendedCapabilities[2] * 0x100 + pbExtendedCapabilities[3];
337     pContext->dwMaxCertificateLength = pbExtendedCapabilities[4] * 0x100 + pbExtendedCapabilities[5];
338     pContext->dwMaxCommandDataLength = pbExtendedCapabilities[6] * 0x100 + pbExtendedCapabilities[7];
339     pContext->dwMaxResponseLength = pbExtendedCapabilities[8] * 0x100 + pbExtendedCapabilities[9];
340 vletoux 8 pContext->fIsReadOnly = TRUE;
341     dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPFingerprint, &pbFingerPrint, &dwFingerPrintSize);
342 vletoux 1 if (dwReturn)
343     {
344     __leave;
345     }
346 vletoux 8 if (dwFingerPrintSize != 60)
347 vletoux 1 {
348 vletoux 8 Trace(WINEVENT_LEVEL_ERROR, L"dwFingerPrintSize = %02X", dwFingerPrintSize);
349     dwReturn = SCARD_E_UNEXPECTED;
350 vletoux 1 __leave;
351     }
352 vletoux 9 memcpy(pContext->bFingerPrint, pbFingerPrint, 60);
353     for(dwJ = 0; dwJ < KeyMax; dwJ++)
354 vletoux 1 {
355 vletoux 9 pContext->fHasKey[dwJ] = FALSE;
356     for( dwI = dwJ * 20; dwI < dwJ * 20 + 20; dwI++)
357 vletoux 8 {
358 vletoux 9 if (pbFingerPrint[dwI] != 0)
359     {
360     pContext->fHasKey[dwJ] = TRUE;
361     break;
362     }
363 vletoux 8 }
364 vletoux 1 }
365 vletoux 8 dwReturn = CCIDgetFeatures(pCardData);
366     if (dwReturn)
367 vletoux 1 {
368     __leave;
369     }
370     dwReturn = 0;
371     }
372     __finally
373     {
374 vletoux 8 if (pbFingerPrint)
375     pCardData->pfnCspFree(pbFingerPrint);
376     if (pbApplicationIdentifier)
377     pCardData->pfnCspFree(pbApplicationIdentifier);
378     if (pbCapabilities)
379     pCardData->pfnCspFree(pbCapabilities);
380     if (pbExtendedCapabilities)
381     pCardData->pfnCspFree(pbExtendedCapabilities);
382 vletoux 1 }
383     return dwReturn;
384     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26