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

Contents of /trunk/OpenPGPminidriver/PublicDataOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26