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

Annotation of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26