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

Annotation of /trunk/OpenPGPminidriver/PublicDataOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Tue Feb 23 19:18:59 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 14282 byte(s)


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26