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

Contents of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show 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 /* 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