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

Contents of /trunk/OpenPGPminidriver/PublicDataOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show 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 /* 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