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

Annotation of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Tue Feb 23 19:18:59 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 8211 byte(s)


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     DWORD CreateContext(__in PCARD_DATA pCardData)
77     {
78     DWORD dwReturn;
79     PBYTE pbCapabilities = NULL, pbCardCapabilities;
80     PBYTE pbExtendedCapabilities = NULL;
81     PBYTE pbApplicationIdentifier = NULL;
82     DWORD dwCapabilitiesSize,
83     dwCardCapabilitiesSize,
84     dwApplicationIdentifierSize;
85     BYTE bCategoryIndicator, bStatusIndicator;
86     __try
87     {
88     POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
89     if (pContext)
90     {
91     Trace(WINEVENT_LEVEL_ERROR, L"pContext != NULL");
92     dwReturn = SCARD_E_UNEXPECTED;
93     __leave;
94     }
95     // not found => initialize context
96     pContext = pCardData->pfnCspAlloc(sizeof(OPENPGP_CONTEXT));
97     if (!pContext)
98     {
99     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
100     dwReturn = SCARD_E_NO_MEMORY;
101     __leave;
102     }
103     memset(pContext, 0, sizeof(OPENPGP_CONTEXT));
104     pCardData->pvVendorSpecific = pContext;
105    
106     dwReturn = SelectOpenPGPApplication(pCardData);
107     if (dwReturn)
108     {
109     Trace(WINEVENT_LEVEL_ERROR, L"No SelectOpenPGPApplication");
110     __leave;
111     }
112     dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPApplicationIdentifier, &pbApplicationIdentifier, &dwApplicationIdentifierSize);
113     if (dwReturn)
114     {
115     __leave;
116     }
117     if (dwApplicationIdentifierSize != sizeof(OPENPGP_AID))
118     {
119     Trace(WINEVENT_LEVEL_ERROR, L"dwApplicationIdentifierSize = %02X", dwApplicationIdentifierSize);
120     dwReturn = SCARD_E_UNEXPECTED;
121     __leave;
122     }
123     memcpy(&(pContext->Aid),pbApplicationIdentifier,sizeof(OPENPGP_AID));
124     dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPHistoricalBytes, &pbCapabilities, &dwCapabilitiesSize);
125     if (dwReturn)
126     {
127     __leave;
128     }
129     bCategoryIndicator = pbCapabilities[0];
130     if (bCategoryIndicator != 0)
131     {
132     Trace(WINEVENT_LEVEL_ERROR, L"bCategoryIndicator = %02X", bCategoryIndicator);
133     dwReturn = SCARD_E_UNEXPECTED;
134     __leave;
135     }
136     bStatusIndicator = pbCapabilities[dwCapabilitiesSize -3];
137     if (bStatusIndicator != 0 && bStatusIndicator != 03 && bStatusIndicator != 05)
138     {
139     Trace(WINEVENT_LEVEL_ERROR, L"bStatusIndicator = %02X", bStatusIndicator);
140     dwReturn = SCARD_E_UNEXPECTED;
141     __leave;
142     }
143     if (!find_compacttlv(pbCapabilities + 1, dwCapabilitiesSize - 1, 7, &pbCardCapabilities, &dwCardCapabilitiesSize))
144     {
145     Trace(WINEVENT_LEVEL_ERROR, L"tlv not found");
146     dwReturn = SCARD_E_UNEXPECTED;
147     __leave;
148     }
149     if (dwCardCapabilitiesSize != 3)
150     {
151     Trace(WINEVENT_LEVEL_ERROR, L"dwCardCapabilitiesSize = %02X", dwCardCapabilitiesSize);
152     dwReturn = SCARD_E_UNEXPECTED;
153     __leave;
154     }
155     //dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPExtendedCap, &pbExtendedCapabilities, &dwExtendedCapabilitiesSize);
156     if (dwReturn)
157     {
158     //__leave;
159     }
160     pContext->fExtentedLeLcFields = ((pbCardCapabilities[2] & 0x40)?TRUE:FALSE);
161     pContext->fSupportCommandChaining = ((pbCardCapabilities[2] & 0x80)?TRUE:FALSE);
162     pContext->dwMaxLength = 0x0800;// pbCapabilities[8] * 256 + pbCapabilities[9];
163     dwReturn = CCIDgetFeatures(pCardData);
164     if (dwReturn)
165     {
166     __leave;
167     }
168     dwReturn = 0;
169     }
170     __finally
171     {
172     if (pbApplicationIdentifier)
173     pCardData->pfnCspFree(pbApplicationIdentifier);
174     if (pbCapabilities)
175     pCardData->pfnCspFree(pbCapabilities);
176     if (pbExtendedCapabilities)
177     pCardData->pfnCspFree(pbExtendedCapabilities);
178     }
179     return dwReturn;
180     }
181    
182    
183     DWORD CheckContext(__in PCARD_DATA pCardData)
184     {
185     DWORD dwReturn;
186     DWORD dwI, dwJ;
187     BOOL fFound = FALSE;
188     BOOL fRightATRLenFound = FALSE;
189     __try
190     {
191     if ( pCardData == NULL )
192     {
193     Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL");
194     dwReturn = SCARD_E_INVALID_PARAMETER;
195     __leave;
196     }
197     if (pCardData->pbAtr == NULL)
198     {
199     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pbAtr == NULL");
200     dwReturn = SCARD_E_INVALID_PARAMETER;
201     __leave;
202     }
203    
204     if (pCardData->dwVersion < CARD_DATA_VERSION_SIX)
205     {
206     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->dwVersion(%d) < CARD_DATA_VERSION_SIX", pCardData->dwVersion);
207     dwReturn = ERROR_REVISION_MISMATCH;
208     __leave;
209     }
210     pCardData->dwVersion = min(pCardData->dwVersion, CARD_DATA_VERSION_SIX);
211     for (dwI = 0; dwI < dwSupportedATRCount; dwI++)
212     {
213     if (SupportedATR[dwI].cbAtr == pCardData->cbAtr)
214     {
215     BYTE pbAtr[36];
216     fRightATRLenFound = TRUE;
217     memcpy(pbAtr, pCardData->pbAtr, SupportedATR[dwI].cbAtr);
218     for( dwJ = 0; dwJ < SupportedATR[dwI].cbAtr; dwJ++)
219     {
220     pbAtr[dwJ] &= SupportedATR[dwI].rgbMask[dwJ];
221     }
222     if (memcmp(pbAtr, pCardData->pbAtr, SupportedATR[dwI].cbAtr) == 0)
223     {
224     fFound = TRUE;
225     //Trace(WINEVENT_LEVEL_VERBOSE, L"card match ATR %d", dwI);
226     break;
227     }
228    
229     }
230     }
231     if (!fRightATRLenFound)
232     {
233     Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR len %d",pCardData->cbAtr);
234     dwReturn = SCARD_E_INVALID_PARAMETER;
235     __leave;
236     }
237     if (!fFound)
238     {
239     Trace(WINEVENT_LEVEL_ERROR, L"card doesn't match ATR");
240     dwReturn = SCARD_E_UNKNOWN_CARD;
241     __leave;
242     }
243    
244     if ( pCardData->pwszCardName == NULL )
245     {
246     Trace(WINEVENT_LEVEL_ERROR, L"pCardData->pwszCardName");
247     dwReturn = SCARD_E_INVALID_PARAMETER;
248     __leave;
249     }
250     /* Memory management functions */
251     if ( ( pCardData->pfnCspAlloc == NULL ) ||
252     ( pCardData->pfnCspReAlloc == NULL ) ||
253     ( pCardData->pfnCspFree == NULL ) )
254     {
255     Trace(WINEVENT_LEVEL_ERROR, L"Memory functions null");
256     dwReturn = SCARD_E_INVALID_PARAMETER;
257     __leave;
258     }
259     if (!pCardData->pvVendorSpecific)
260     {
261     // not found =>
262     dwReturn = SCARD_E_UNEXPECTED;
263     __leave;
264     }
265     dwReturn = 0;
266     }
267     __finally
268     {
269     }
270     return dwReturn;
271     }
272    
273     DWORD CleanContext(__in PCARD_DATA pCardData)
274     {
275     DWORD dwReturn = 0;
276     __try
277     {
278     if (pCardData)
279     {
280     if ( pCardData->pvVendorSpecific)
281     {
282     pCardData->pfnCspFree( pCardData->pvVendorSpecific);
283     pCardData->pvVendorSpecific = NULL;
284     }
285     }
286     }
287     __finally
288     {
289     }
290     return dwReturn;
291     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26