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

Contents of /trunk/OpenPGPminidriver/PublicDataOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Thu Mar 11 20:32:26 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 13450 byte(s)
improvement of the quality of the project.
More test for the qualification of the driver success but not all ...

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 <stdio.h>
20 #include <cardmod.h>
21 #include "Tracing.h"
22 #include "Context.h"
23 #include "SmartCard.h"
24 #include "PublicDataOperations.h"
25 #include "CryptoOperations.h"
26 #include "tlv.h"
27
28 typedef enum _OPENPGP_FILE_TYPE
29 {
30 StoredOnSmartCard,
31 Virtual,
32 } OPENPGP_FILE_TYPE;
33
34 typedef struct _OPENPGP_FILE
35 {
36 PCHAR szDirectory;
37 PCHAR szFile;
38 OPENPGP_FILE_TYPE dwFileType;
39 DWORD dwTag;
40 DWORD dwTlv;
41 CARD_FILE_ACCESS_CONDITION dwAccess;
42 } OPENPGP_FILE, *POPENPGP_FILE;
43
44
45 #define szCARD_APPLICATION_FILE "cardapps"
46
47 OPENPGP_FILE Files[] =
48 {
49 {szOpenPGPDir, szOpenPGPFingerprint, StoredOnSmartCard, 0x6E, 0xC5, EveryoneReadAdminWriteAc},
50 {szOpenPGPDir, szOpenPGPStatus, StoredOnSmartCard, 0xC4, 0, EveryoneReadAdminWriteAc},
51 {szOpenPGPDir, szOpenPGPApplicationIdentifier, StoredOnSmartCard, 0x4F, 0, UnknownAc},
52 {szOpenPGPDir, szOpenPGPLogin, StoredOnSmartCard, 0x5E, 0, EveryoneReadAdminWriteAc},
53 {szOpenPGPDir, szOpenPGPName, StoredOnSmartCard, 0x65, 0x5B, EveryoneReadAdminWriteAc},
54 {szOpenPGPDir, szOpenPGPLanguage, StoredOnSmartCard, 0x65, 0x5F2D, EveryoneReadAdminWriteAc},
55 {szOpenPGPDir, szOpenPGPSex, StoredOnSmartCard, 0x65, 0x5F35,EveryoneReadAdminWriteAc},
56 {szOpenPGPDir, szOpenPGPUrl, StoredOnSmartCard, 0x5F50, 0, EveryoneReadAdminWriteAc},
57 {szOpenPGPDir, szOpenPGPHistoricalBytes, StoredOnSmartCard, 0x5F52, 0, UnknownAc},
58 {szOpenPGPDir, szOpenPGPCertificate, StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc},
59 {szOpenPGPDir, szOpenPGPExtendedCap, StoredOnSmartCard, 0x6E, 0xC0, UnknownAc},
60 {szOpenPGPDir, szOpenPGPAlgoAttributesSignature, StoredOnSmartCard, 0x6E, 0xC1, UnknownAc},
61 {szOpenPGPDir, szOpenPGPAlgoAttributesDecryption, StoredOnSmartCard, 0x6E, 0xC2,UnknownAc},
62 {szOpenPGPDir, szOpenPGPAlgoAttributesAuthentication, StoredOnSmartCard, 0x6E, 0xC3, UnknownAc },
63 {szOpenPGPDir, szOpenPGPPUK, StoredOnSmartCard, 0xD3, 0, UnknownAc },
64 {NULL, szCARD_IDENTIFIER_FILE, StoredOnSmartCard, 0x4F, 0, EveryoneReadAdminWriteAc},
65 {NULL, szCARD_APPLICATION_FILE, Virtual, 0, 0, EveryoneReadAdminWriteAc},
66 {NULL, szCACHE_FILE, Virtual, 0, 0, EveryoneReadUserWriteAc},
67 {szBASE_CSP_DIR, szCONTAINER_MAP_FILE, Virtual, 0, 0, EveryoneReadUserWriteAc},
68 {szBASE_CSP_DIR, "ksc1", StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc},
69
70 };
71
72 DWORD dwFileCount = ARRAYSIZE(Files);
73
74 DWORD OCardDirectoryList(__in PCARD_DATA pCardData,
75 __in PBYTE* pbResponse, __in_opt PDWORD pdwResponseSize)
76 {
77 // hardcoded
78 *pdwResponseSize = 16;
79 *pbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
80 if (!*pbResponse)
81 {
82 return SCARD_E_NO_MEMORY;
83 }
84 memcpy(*pbResponse, "openpgp\0mscp\0\0\0\0", *pdwResponseSize);
85 return 0;
86 }
87
88
89 // read file
90 DWORD OCardReadFile(__in PCARD_DATA pCardData,
91 __in_opt PSTR szDirectory, __in PSTR szFile,
92 __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize)
93 {
94 DWORD dwI;
95 DWORD dwReturn = 0;
96 BOOL fDirectoryFound = FALSE;
97 BOOL fFileFound = FALSE;
98 BYTE pbCmd[] = {0x00, 0xCA, 0x00, 0x00, 0x00};
99 DWORD dwCmdSize = ARRAYSIZE(pbCmd);
100 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
101 PBYTE pbData = NULL;
102 __try
103 {
104 *pdwResponseSize = 0;
105 for(dwI = 0; dwI < dwFileCount; dwI++)
106 {
107 BOOL fMatch = FALSE;
108 if (szDirectory == NULL)
109 {
110 if (!Files[dwI].szDirectory) fMatch = TRUE;
111 }
112 else
113 {
114 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
115 }
116 if (fMatch)
117 {
118 fDirectoryFound = TRUE;
119 if (_stricmp(szFile, Files[dwI].szFile) == 0)
120 {
121 fFileFound = TRUE;
122 break;
123 }
124 }
125 }
126 if (!fFileFound)
127 {
128 if (fDirectoryFound)
129 {
130 dwReturn = SCARD_E_FILE_NOT_FOUND;
131 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
132 }
133 else
134 {
135 dwReturn = SCARD_E_DIR_NOT_FOUND;
136 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szDirectory);
137 }
138 __leave;
139 }
140 if (Files[dwI].dwFileType == StoredOnSmartCard)
141 {
142 pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100);
143 pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100);
144 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, pdwResponseSize);
145 if (dwReturn)
146 {
147 __leave;
148 }
149 if (Files[dwI].dwTlv)
150 {
151 PBYTE pbPointer;
152 //TraceDump(0,pbData,*pdwResponseSize);
153 if (find_tlv(pbData, Files[dwI].dwTlv, *pdwResponseSize, &pbPointer, pdwResponseSize))
154 {
155 *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
156 if (!*ppbResponse )
157 {
158 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
159 dwReturn = SCARD_E_NO_MEMORY;
160 }
161 memcpy(*ppbResponse, pbPointer, *pdwResponseSize);
162 }
163 else
164 {
165 dwReturn = SCARD_E_FILE_NOT_FOUND;
166 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
167 }
168 }
169 else
170 {
171 *ppbResponse = pbData;
172 // do not free the data !
173 pbData = NULL;
174 }
175 }
176 else
177 {
178 if (szDirectory == NULL)
179 {
180 if (_stricmp(szFile, szCARD_APPLICATION_FILE) == 0)
181 {
182 dwReturn = OCardDirectoryList(pCardData, ppbResponse, pdwResponseSize);
183 }
184 else if (_stricmp(szFile, szCACHE_FILE) == 0)
185 {
186 *pdwResponseSize = sizeof(CARD_CACHE_FILE_FORMAT);
187 *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
188 memset(*ppbResponse,0,*pdwResponseSize);
189 }
190 else
191 {
192 dwReturn = SCARD_E_FILE_NOT_FOUND;
193 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
194 }
195 }
196 else if (_stricmp(szDirectory,szBASE_CSP_DIR) == 0)
197 {
198 if (_stricmp(szFile, szCONTAINER_MAP_FILE) == 0)
199 {
200 dwReturn = OCardReadContainerMapFile(pCardData, ppbResponse, pdwResponseSize);
201 }
202 else
203 {
204 dwReturn = SCARD_E_FILE_NOT_FOUND;
205 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
206 }
207 }
208 else
209 {
210 dwReturn = SCARD_E_DIR_NOT_FOUND;
211 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szDirectory);
212 }
213 }
214 if (dwReturn)
215 {
216 __leave;
217 }
218 // add to the cache
219 dwReturn = 0;
220
221 }
222 __finally
223 {
224 if( pbData)
225 pCardData->pfnCspFree(pbData);
226 }
227 Trace(WINEVENT_LEVEL_VERBOSE, L"%S\\%S dwReturn = 0x%08X size = %d",szDirectory, szFile, dwReturn, *pdwResponseSize);
228 return dwReturn;
229 }
230
231 DWORD OCardEnumFile(__in PCARD_DATA pCardData,
232 __in_opt PSTR szDirectory,
233 __in PBYTE* pbResponse, __in PDWORD pdwResponseSize)
234 {
235 DWORD dwReturn = 0, dwNotExists;
236 DWORD dwI, dwSize;
237 BOOL fDirectoryFound = FALSE;
238
239 __try
240 {
241 *pbResponse = NULL;
242 *pdwResponseSize = 0;
243 for(dwI = 0; dwI < dwFileCount; dwI++)
244 {
245 BOOL fMatch = FALSE;
246 if (szDirectory == NULL)
247 {
248 if (!Files[dwI].szDirectory) fMatch = TRUE;
249 }
250 else
251 {
252 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
253 }
254 if (fMatch)
255 {
256 fDirectoryFound = TRUE;
257 dwNotExists = 0;
258 if (StoredOnSmartCard == Files[dwI].dwFileType)
259 {
260 PBYTE pbData = NULL;
261 DWORD dwSize;
262 // check if the file exists and be read
263 dwNotExists = OCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize);
264 if (!dwNotExists)
265 {
266 pCardData->pfnCspFree(pbData);
267 }
268 }
269 if (!dwNotExists)
270 {
271 dwSize = (DWORD) strlen( Files[dwI].szFile) + 1;
272 // + 1 to add the final \0
273 if (*pbResponse)
274 {
275 *pbResponse = pCardData->pfnCspReAlloc(*pbResponse, *pdwResponseSize + dwSize + 1);
276 }
277 else
278 {
279 *pbResponse = pCardData->pfnCspAlloc(*pdwResponseSize + dwSize + 1);
280 }
281 if (!*pbResponse)
282 {
283 dwReturn = SCARD_E_NO_MEMORY;
284 __leave;
285 }
286 memcpy(*pbResponse + *pdwResponseSize, Files[dwI].szFile, dwSize);
287 *pdwResponseSize += dwSize;
288 }
289 }
290 }
291 if (!fDirectoryFound)
292 {
293 dwReturn = SCARD_E_DIR_NOT_FOUND;
294 __leave;
295 }
296 (*pbResponse)[*pdwResponseSize] = '\0';
297 *pdwResponseSize += 1;
298 dwReturn = 0;
299 }
300 __finally
301 {
302 }
303 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
304 return dwReturn;
305 }
306
307 // read file
308 DWORD OCardGetFileInfo(__in PCARD_DATA pCardData,
309 __in_opt PSTR szDirectory, __in PSTR szFile,
310 __inout PCARD_FILE_INFO pCardFileInfo)
311 {
312 DWORD dwReturn = 0;
313 PBYTE pbData = NULL;
314 DWORD dwSize, dwI;
315 __try
316 {
317 dwReturn = OCardReadFile(pCardData, szDirectory, szFile, &pbData, &dwSize);
318 if (dwReturn)
319 {
320 __leave;
321 }
322 pCardData->pfnCspFree(pbData);
323 pCardFileInfo->cbFileSize = dwSize;
324 pCardFileInfo->AccessCondition = InvalidAc;
325 for(dwI = 0; dwI < dwFileCount; dwI++)
326 {
327 BOOL fMatch = FALSE;
328 if (szDirectory == NULL)
329 {
330 if (!Files[dwI].szDirectory) fMatch = TRUE;
331 }
332 else
333 {
334 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
335 }
336 if (fMatch)
337 {
338 if (_stricmp(szFile, Files[dwI].szFile) == 0)
339 {
340 pCardFileInfo->AccessCondition = Files[dwI].dwAccess;
341 break;
342 }
343 }
344 }
345 dwReturn = 0;
346 }
347 __finally
348 {
349 }
350 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
351 return dwReturn;
352 }
353
354 DWORD OCardWriteFile(__in PCARD_DATA pCardData,
355 __in_opt PSTR szDirectory, __in PSTR szFile,
356 __in PBYTE pbData, __in DWORD dwSize)
357 {
358 DWORD dwI;
359 DWORD dwReturn = 0;
360 BOOL fDirectoryFound = FALSE;
361 BOOL fFileFound = FALSE;
362 BYTE pbCmd[5 + 256] = {0x00, 0xDA, 0x00, 0x00, 0x00};
363 DWORD dwCmdSize = 0;
364 __try
365 {
366 if (dwSize > 255)
367 {
368 dwReturn = SCARD_E_INVALID_PARAMETER;
369 Trace(WINEVENT_LEVEL_ERROR, L"dwSize %d",dwSize);
370 __leave;
371 }
372
373
374 for(dwI = 0; dwI < dwFileCount; dwI++)
375 {
376 BOOL fMatch = FALSE;
377 if (szDirectory == NULL)
378 {
379 if (!Files[dwI].szDirectory) fMatch = TRUE;
380 }
381 else
382 {
383 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
384 }
385 if (fMatch)
386 {
387 fDirectoryFound = TRUE;
388 if (_stricmp(szFile, Files[dwI].szFile) == 0)
389 {
390 fFileFound = TRUE;
391 break;
392 }
393 }
394 }
395 if (!fFileFound)
396 {
397 if (fDirectoryFound)
398 {
399 dwReturn = SCARD_E_FILE_NOT_FOUND;
400 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_FILE_NOT_FOUND %S",szFile);
401 }
402 else
403 {
404 dwReturn = SCARD_E_DIR_NOT_FOUND;
405 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szDirectory);
406 }
407 __leave;
408 }
409 if (Files[dwI].dwFileType == StoredOnSmartCard)
410 {
411 if (Files[dwI].dwTlv > 0)
412 {
413 pbCmd[2] = (BYTE) (Files[dwI].dwTlv / 0x100);
414 pbCmd[3] = (BYTE) (Files[dwI].dwTlv % 0x100);
415 }
416 else
417 {
418 pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100);
419 pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100);
420 }
421 pbCmd[4] = (BYTE) dwSize;
422 if (dwSize)
423 {
424 memcpy(pbCmd + 5, pbData, dwSize);
425 }
426 dwCmdSize = dwSize + 5;
427 dwReturn = OCardSendCommand(pCardData, pbCmd, dwCmdSize);
428 if (dwReturn)
429 {
430 __leave;
431 }
432 }
433 else
434 {
435 dwReturn = SCARD_W_SECURITY_VIOLATION;
436 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_SECURITY_VIOLATION %S",szFile);
437 __leave;
438 }
439
440
441 }
442 __finally
443 {
444 }
445 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
446 return dwReturn;
447 }
448
449 DWORD OCardDeleteFile(__in PCARD_DATA pCardData,
450 __in_opt PSTR szDirectory, __in PSTR szFile)
451 {
452 return OCardWriteFile(pCardData, szDirectory, szFile, NULL, 0);
453 }
454
455 // just change the flag in Files
456 DWORD OCardCreateFile(__in PCARD_DATA pCardData,
457 __in_opt PSTR szDirectory, __in PSTR szFile)
458 {
459 DWORD dwI;
460 DWORD dwReturn = 0;
461 BOOL fDirectoryFound = FALSE;
462 BOOL fFileFound = FALSE;
463 __try
464 {
465 for(dwI = 0; dwI < dwFileCount; dwI++)
466 {
467 BOOL fMatch = FALSE;
468 if (szDirectory == NULL)
469 {
470 if (!Files[dwI].szDirectory) fMatch = TRUE;
471 }
472 else
473 {
474 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
475 }
476 if (fMatch)
477 {
478 fDirectoryFound = TRUE;
479 if (_stricmp(szFile, Files[dwI].szFile) == 0)
480 {
481 fFileFound = TRUE;
482 break;
483 }
484 }
485 }
486 if (!fDirectoryFound)
487 {
488 dwReturn = SCARD_E_DIR_NOT_FOUND;
489 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_DIR_NOT_FOUND %S",szFile);
490 __leave;
491 }
492 if (!fFileFound)
493 {
494 dwReturn = SCARD_W_SECURITY_VIOLATION;
495 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_W_SECURITY_VIOLATION %S",szFile);
496 __leave;
497 }
498
499 }
500 __finally
501 {
502 }
503 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
504 return dwReturn;
505 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26