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

Annotation of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26