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

Annotation of /trunk/OpenPGPminidriver/PublicDataOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (hide 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 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     typedef struct _OPENPGP_FILE
35     {
36     PCHAR szDirectory;
37     PCHAR szFile;
38     OPENPGP_FILE_TYPE dwFileType;
39 vletoux 6 DWORD dwTag;
40     DWORD dwTlv;
41 vletoux 1 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 vletoux 6 {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 vletoux 8 {szOpenPGPDir, szOpenPGPPUK, StoredOnSmartCard, 0xD3, 0, UnknownAc },
64 vletoux 6 {NULL, szCARD_IDENTIFIER_FILE, StoredOnSmartCard, 0x4F, 0, EveryoneReadAdminWriteAc},
65 vletoux 1 {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 vletoux 6 {szBASE_CSP_DIR, "ksc1", StoredOnSmartCard, 0x7F21, 0, EveryoneReadAdminWriteAc},
69 vletoux 1
70     };
71    
72     DWORD dwFileCount = ARRAYSIZE(Files);
73    
74 vletoux 8 DWORD OCardDirectoryList(__in PCARD_DATA pCardData,
75 vletoux 1 __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 vletoux 8
89 vletoux 1 // read file
90 vletoux 8 DWORD OCardReadFile(__in PCARD_DATA pCardData,
91 vletoux 1 __in_opt PSTR szDirectory, __in PSTR szFile,
92 vletoux 6 __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize)
93 vletoux 1 {
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 vletoux 6 PBYTE pbData = NULL;
102 vletoux 1 __try
103     {
104 vletoux 6 *pdwResponseSize = 0;
105 vletoux 1 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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
115 vletoux 1 }
116     if (fMatch)
117     {
118     fDirectoryFound = TRUE;
119 vletoux 8 if (_stricmp(szFile, Files[dwI].szFile) == 0)
120 vletoux 1 {
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 vletoux 6 pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100);
143     pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100);
144 vletoux 8 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, pdwResponseSize);
145 vletoux 6 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 vletoux 1 }
176     else
177     {
178     if (szDirectory == NULL)
179     {
180 vletoux 8 if (_stricmp(szFile, szCARD_APPLICATION_FILE) == 0)
181 vletoux 1 {
182 vletoux 8 dwReturn = OCardDirectoryList(pCardData, ppbResponse, pdwResponseSize);
183 vletoux 1 }
184 vletoux 8 else if (_stricmp(szFile, szCACHE_FILE) == 0)
185 vletoux 1 {
186     *pdwResponseSize = sizeof(CARD_CACHE_FILE_FORMAT);
187 vletoux 6 *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
188     memset(*ppbResponse,0,*pdwResponseSize);
189 vletoux 1 }
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 vletoux 8 else if (_stricmp(szDirectory,szBASE_CSP_DIR) == 0)
197 vletoux 1 {
198 vletoux 8 if (_stricmp(szFile, szCONTAINER_MAP_FILE) == 0)
199 vletoux 1 {
200 vletoux 8 dwReturn = OCardReadContainerMapFile(pCardData, ppbResponse, pdwResponseSize);
201 vletoux 1 }
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 vletoux 6 if( pbData)
225     pCardData->pfnCspFree(pbData);
226 vletoux 1 }
227 vletoux 6 Trace(WINEVENT_LEVEL_VERBOSE, L"%S\\%S dwReturn = 0x%08X size = %d",szDirectory, szFile, dwReturn, *pdwResponseSize);
228 vletoux 1 return dwReturn;
229     }
230    
231 vletoux 8 DWORD OCardEnumFile(__in PCARD_DATA pCardData,
232 vletoux 1 __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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
253 vletoux 1 }
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 vletoux 8 dwNotExists = OCardReadFile(pCardData, szDirectory, Files[dwI].szFile, &pbData, &dwSize);
264 vletoux 1 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 vletoux 8 DWORD OCardGetFileInfo(__in PCARD_DATA pCardData,
309 vletoux 1 __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 vletoux 8 dwReturn = OCardReadFile(pCardData, szDirectory, szFile, &pbData, &dwSize);
318 vletoux 1 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 vletoux 8 BOOL fMatch = FALSE;
328     if (szDirectory == NULL)
329 vletoux 1 {
330 vletoux 8 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 vletoux 1 {
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 vletoux 8 DWORD OCardWriteFile(__in PCARD_DATA pCardData,
355 vletoux 1 __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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
384 vletoux 1 }
385     if (fMatch)
386     {
387     fDirectoryFound = TRUE;
388 vletoux 8 if (_stricmp(szFile, Files[dwI].szFile) == 0)
389 vletoux 1 {
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 vletoux 6 if (Files[dwI].dwTlv > 0)
412 vletoux 1 {
413 vletoux 6 pbCmd[2] = (BYTE) (Files[dwI].dwTlv / 0x100);
414     pbCmd[3] = (BYTE) (Files[dwI].dwTlv % 0x100);
415 vletoux 1 }
416 vletoux 6 else
417     {
418     pbCmd[2] = (BYTE) (Files[dwI].dwTag / 0x100);
419     pbCmd[3] = (BYTE) (Files[dwI].dwTag % 0x100);
420     }
421 vletoux 1 pbCmd[4] = (BYTE) dwSize;
422     if (dwSize)
423     {
424     memcpy(pbCmd + 5, pbData, dwSize);
425     }
426     dwCmdSize = dwSize + 5;
427 vletoux 8 dwReturn = OCardSendCommand(pCardData, pbCmd, dwCmdSize);
428 vletoux 1 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 vletoux 8 DWORD OCardDeleteFile(__in PCARD_DATA pCardData,
450 vletoux 1 __in_opt PSTR szDirectory, __in PSTR szFile)
451     {
452 vletoux 8 return OCardWriteFile(pCardData, szDirectory, szFile, NULL, 0);
453 vletoux 1 }
454    
455     // just change the flag in Files
456 vletoux 8 DWORD OCardCreateFile(__in PCARD_DATA pCardData,
457 vletoux 1 __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 vletoux 8 if (Files[dwI].szDirectory && _stricmp(szDirectory, Files[dwI].szDirectory) == 0) fMatch = TRUE;
475 vletoux 1 }
476     if (fMatch)
477     {
478     fDirectoryFound = TRUE;
479 vletoux 8 if (_stricmp(szFile, Files[dwI].szFile) == 0)
480 vletoux 1 {
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