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

Annotation of /trunk/OpenPGPminidriver/PublicDataOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide 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 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 <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 vletoux 6 #include "tlv.h"
27 vletoux 1
28     typedef enum _OPENPGP_FILE_TYPE
29     {
30     StoredOnSmartCard,
31     Virtual,
32     } OPENPGP_FILE_TYPE;
33    
34 vletoux 9 #define OPENPGP_FILE_OPTIONAL 1
35     #define OPENPGP_FILE_WRITE_ONLY 2
36     #define OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING 4
37    
38 vletoux 1 typedef struct _OPENPGP_FILE
39     {
40     PCHAR szDirectory;
41     PCHAR szFile;
42     OPENPGP_FILE_TYPE dwFileType;
43 vletoux 6 DWORD dwTag;
44     DWORD dwTlv;
45 vletoux 1 CARD_FILE_ACCESS_CONDITION dwAccess;
46 vletoux 9 DWORD dwFlag;
47 vletoux 1 } OPENPGP_FILE, *POPENPGP_FILE;
48    
49    
50     #define szCARD_APPLICATION_FILE "cardapps"
51    
52     OPENPGP_FILE Files[] =
53     {
54 vletoux 6 {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 vletoux 9 {szOpenPGPDir, szOpenPGPCertificate, StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc, OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING},
64 vletoux 6 {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 vletoux 9 {szOpenPGPDir, szOpenPGPPUK, StoredOnSmartCard, 0xD3, 0, UnknownAc, OPENPGP_FILE_WRITE_ONLY },
69 vletoux 6 {NULL, szCARD_IDENTIFIER_FILE, StoredOnSmartCard, 0x4F, 0, EveryoneReadAdminWriteAc},
70 vletoux 1 {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 vletoux 9 {szBASE_CSP_DIR, "ksc1", StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc, OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING},
74 vletoux 1
75     };
76    
77     DWORD dwFileCount = ARRAYSIZE(Files);
78    
79 vletoux 8 DWORD OCardDirectoryList(__in PCARD_DATA pCardData,
80 vletoux 1 __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 vletoux 8
94 vletoux 1 // read file
95 vletoux 8 DWORD OCardReadFile(__in PCARD_DATA pCardData,
96 vletoux 1 __in_opt PSTR szDirectory, __in PSTR szFile,
97 vletoux 6 __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize)
98 vletoux 1 {
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 vletoux 6 PBYTE pbData = NULL;
107 vletoux 1 __try
108     {
109 vletoux 6 *pdwResponseSize = 0;
110 vletoux 1 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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
120 vletoux 1 }
121     if (fMatch)
122     {
123     fDirectoryFound = TRUE;
124 vletoux 8 if (_stricmp(szFile, Files[dwI].szFile) == 0)
125 vletoux 1 {
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 vletoux 6 pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100);
148     pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100);
149 vletoux 8 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, pdwResponseSize);
150 vletoux 6 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 vletoux 1 }
181     else
182     {
183     if (szDirectory == NULL)
184     {
185 vletoux 8 if (_stricmp(szFile, szCARD_APPLICATION_FILE) == 0)
186 vletoux 1 {
187 vletoux 8 dwReturn = OCardDirectoryList(pCardData, ppbResponse, pdwResponseSize);
188 vletoux 1 }
189 vletoux 8 else if (_stricmp(szFile, szCACHE_FILE) == 0)
190 vletoux 1 {
191     *pdwResponseSize = sizeof(CARD_CACHE_FILE_FORMAT);
192 vletoux 6 *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
193     memset(*ppbResponse,0,*pdwResponseSize);
194 vletoux 1 }
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 vletoux 8 else if (_stricmp(szDirectory,szBASE_CSP_DIR) == 0)
202 vletoux 1 {
203 vletoux 8 if (_stricmp(szFile, szCONTAINER_MAP_FILE) == 0)
204 vletoux 1 {
205 vletoux 8 dwReturn = OCardReadContainerMapFile(pCardData, ppbResponse, pdwResponseSize);
206 vletoux 1 }
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 vletoux 6 if( pbData)
230     pCardData->pfnCspFree(pbData);
231 vletoux 1 }
232 vletoux 6 Trace(WINEVENT_LEVEL_VERBOSE, L"%S\\%S dwReturn = 0x%08X size = %d",szDirectory, szFile, dwReturn, *pdwResponseSize);
233 vletoux 1 return dwReturn;
234     }
235    
236 vletoux 8 DWORD OCardEnumFile(__in PCARD_DATA pCardData,
237 vletoux 1 __in_opt PSTR szDirectory,
238     __in PBYTE* pbResponse, __in PDWORD pdwResponseSize)
239     {
240 vletoux 9 DWORD dwReturn = 0, dwReadFileReturn;
241 vletoux 1 DWORD dwI, dwSize;
242     BOOL fDirectoryFound = FALSE;
243 vletoux 9 BOOL fAddToOuput;
244 vletoux 1 __try
245     {
246     *pbResponse = NULL;
247     *pdwResponseSize = 0;
248 vletoux 9
249     // compute the max size of the buffer
250     dwSize = 0;
251 vletoux 1 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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
261 vletoux 1 }
262 vletoux 9 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 vletoux 1 if (fMatch)
286     {
287     fDirectoryFound = TRUE;
288 vletoux 9 fAddToOuput = TRUE;
289     if (Files[dwI].dwFlag & OPENPGP_FILE_WRITE_ONLY)
290 vletoux 1 {
291 vletoux 9 fAddToOuput = FALSE;
292     }
293     if (fAddToOuput && (Files[dwI].dwFlag & OPENPGP_FILE_NULL_LENGHT_EQUALS_MISSING))
294     {
295 vletoux 1 PBYTE pbData = NULL;
296     DWORD dwSize;
297 vletoux 9 fAddToOuput = FALSE;
298 vletoux 1 // check if the file exists and be read
299 vletoux 9 dwReadFileReturn = OCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize);
300     if (!dwReadFileReturn)
301 vletoux 1 {
302     pCardData->pfnCspFree(pbData);
303 vletoux 9 if (dwSize > 0)
304     {
305     fAddToOuput = TRUE;
306     }
307 vletoux 1 }
308     }
309 vletoux 9 if (fAddToOuput)
310 vletoux 1 {
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 vletoux 8 DWORD OCardGetFileInfo(__in PCARD_DATA pCardData,
335 vletoux 1 __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 vletoux 8 dwReturn = OCardReadFile(pCardData, szDirectory, szFile, &pbData, &dwSize);
344 vletoux 1 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 vletoux 8 BOOL fMatch = FALSE;
354     if (szDirectory == NULL)
355 vletoux 1 {
356 vletoux 8 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 vletoux 1 {
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 vletoux 8 DWORD OCardWriteFile(__in PCARD_DATA pCardData,
381 vletoux 1 __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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
410 vletoux 1 }
411     if (fMatch)
412     {
413     fDirectoryFound = TRUE;
414 vletoux 8 if (_stricmp(szFile, Files[dwI].szFile) == 0)
415 vletoux 1 {
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 vletoux 6 if (Files[dwI].dwTlv > 0)
438 vletoux 1 {
439 vletoux 6 pbCmd[2] = (BYTE) (Files[dwI].dwTlv / 0x100);
440     pbCmd[3] = (BYTE) (Files[dwI].dwTlv % 0x100);
441 vletoux 1 }
442 vletoux 6 else
443     {
444     pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100);
445     pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100);
446     }
447 vletoux 1 pbCmd[4] = (BYTE) dwSize;
448     if (dwSize)
449     {
450     memcpy(pbCmd + 5, pbData, dwSize);
451     }
452     dwCmdSize = dwSize + 5;
453 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, dwCmdSize);
454 vletoux 1 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 vletoux 8 DWORD OCardDeleteFile(__in PCARD_DATA pCardData,
476 vletoux 1 __in_opt PSTR szDirectory, __in PSTR szFile)
477     {
478 vletoux 8 return OCardWriteFile(pCardData, szDirectory, szFile, NULL, 0);
479 vletoux 1 }
480    
481     // just change the flag in Files
482 vletoux 8 DWORD OCardCreateFile(__in PCARD_DATA pCardData,
483 vletoux 1 __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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
501 vletoux 1 }
502     if (fMatch)
503     {
504     fDirectoryFound = TRUE;
505 vletoux 8 if (_stricmp(szFile, Files[dwI].szFile) == 0)
506 vletoux 1 {
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