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

Contents of /trunk/OpenPGPminidriver/ContextManagement.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show 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 /* 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 dwExtendedCapabilitiesSize;
86 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 dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szOpenPGPExtendedCap, &pbExtendedCapabilities, &dwExtendedCapabilitiesSize);
157 if (dwReturn)
158 {
159 __leave;
160 }
161 pContext->fExtentedLeLcFields = ((pbCardCapabilities[2] & 0x40)?TRUE:FALSE);
162 pContext->fSupportCommandChaining = ((pbCardCapabilities[2] & 0x80)?TRUE:FALSE);
163 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 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