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

Contents of /trunk/OpenPGPminidriver/PublicDataOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26