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

Contents of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Wed Mar 31 08:58:46 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 50880 byte(s)
first msi Release
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 "CryptoOperations.h"
25 #include "PinOperations.h"
26 #include "PublicDataOperations.h"
27 #include "tlv.h"
28
29 OPENPGP_KEY_INFO Keys[] =
30 {
31 {0xB6, 0xCE, 0xC7, CALG_RSA_SIGN}, // signature
32 {0xB8, 0xCF, 0xC8, CALG_RSA_KEYX}, // confidentiality
33 {0xA4, 0xD0, 0xC9, CALG_RSA_SIGN} // authentication
34 };
35
36 OPENPGP_CONTAINER_INFO Containers[] =
37 {
38 {ROLE_SIGNATURE, AT_SIGNATURE},
39 {ROLE_AUTHENTICATION, AT_KEYEXCHANGE},
40 {ROLE_AUTHENTICATION, AT_SIGNATURE}
41 };
42 typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM
43 {
44 ALG_ID aiHashAlg;
45 DWORD dwHashSize;
46 PBYTE pbEncodedOid;
47 DWORD dwEncodedOidSize;
48 PWSTR szAlgId;
49 } OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM, *POPENPGP_SUPPORTED_SIGNATURE_ALGORITHM;
50
51 BYTE dwSHA1EncodedOid[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
52 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
53 BYTE dwSHA256EncodedOid[] = {0x30, 0x31, 0x30, 0x0D,0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
54 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
55 BYTE dwSHA384EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
56 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
57 BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
58 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
59
60 #define OPENPGP_NO_OID 0xFFFFFFFF
61 OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =
62 {
63 {CALG_SHA1,20,
64 dwSHA1EncodedOid,
65 ARRAYSIZE(dwSHA1EncodedOid), BCRYPT_SHA1_ALGORITHM},
66 {CALG_SHA-256,32,
67 dwSHA256EncodedOid,
68 ARRAYSIZE(dwSHA256EncodedOid), BCRYPT_SHA256_ALGORITHM},
69 {CALG_SHA-384,48,
70 dwSHA384EncodedOid,
71 ARRAYSIZE(dwSHA384EncodedOid), BCRYPT_SHA384_ALGORITHM},
72 {CALG_SHA-512,64,
73 dwSHA512EncodedOid,
74 ARRAYSIZE(dwSHA512EncodedOid), BCRYPT_SHA512_ALGORITHM},
75 };
76
77 DWORD dwSignatureAlgorithmCount = ARRAYSIZE(SignatureAlgorithm);
78
79
80
81 typedef struct _RSAPUBLICKEYBLOB
82 {
83 BLOBHEADER blobheader;
84 RSAPUBKEY rsapubkey;
85 BYTE modulus[sizeof(DWORD)];
86 } RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB;
87
88
89 DWORD OCardGetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
90 __in OPENPGP_KEY dwKey,
91 __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
92 {
93 DWORD dwReturn;
94 PSTR szAlgorithmAttributes = NULL;
95 PBYTE pbData = NULL;
96 DWORD dwResponseSize;
97 WORD wTemp;
98 __try
99 {
100 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwKey);
101 switch(dwKey)
102 {
103 case KeySignature:
104 szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
105 break;
106 case KeyAuthentication:
107 szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
108 break;
109 case KeyConfidentiality:
110 szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
111 break;
112 default:
113 dwReturn = SCARD_E_NO_KEY_CONTAINER;
114 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
115 __leave;
116 }
117 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, &pbData, &dwResponseSize);
118 if (dwReturn)
119 {
120 __leave;
121 }
122 if (dwResponseSize != sizeof(OPENPGP_ALGORITHM_ATTRIBUTE))
123 {
124 dwReturn = SCARD_E_UNEXPECTED;
125 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED");
126 __leave;
127 }
128 memcpy(pAttributes, pbData, dwResponseSize);
129 // big endian, little endian ...
130 wTemp = pAttributes->wExponentLengthInBit;
131 pAttributes->wExponentLengthInBit = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
132 wTemp = pAttributes->wModulusLengthInBit;
133 pAttributes->wModulusLengthInBit = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
134
135 dwReturn = 0;
136 }
137 __finally
138 {
139 if (pbData)
140 pCardData->pfnCspFree(pbData);
141 }
142 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
143 return dwReturn;
144 }
145
146 DWORD OCardSetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
147 __in OPENPGP_KEY dwKey,
148 __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
149 {
150 DWORD dwReturn;
151 PSTR szAlgorithmAttributes = NULL;
152 OPENPGP_ALGORITHM_ATTRIBUTE TempAttributes;
153 WORD wTemp;
154 __try
155 {
156 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwKey);
157 switch(dwKey)
158 {
159 case KeySignature:
160 szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
161 break;
162 case KeyAuthentication:
163 szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
164 break;
165 case KeyConfidentiality:
166 szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
167 break;
168 default:
169 dwReturn = SCARD_E_NO_KEY_CONTAINER;
170 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
171 __leave;
172 }
173 memcpy(&TempAttributes, pAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
174 wTemp = TempAttributes.wExponentLengthInBit;
175 TempAttributes.wExponentLengthInBit = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
176 wTemp = TempAttributes.wModulusLengthInBit;
177 TempAttributes.wModulusLengthInBit = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
178
179 dwReturn = OCardWriteFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, (PBYTE) &TempAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
180 if (dwReturn)
181 {
182 __leave;
183 }
184 dwReturn = 0;
185 }
186 __finally
187 {
188 }
189 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
190 return dwReturn;
191 }
192
193 DWORD BuildSingleTlv(__in PBYTE buffer, __in BYTE bTlv, __in DWORD dwTlvSize, __inout PDWORD pdwOffset)
194 {
195 DWORD dwSize = 1;
196 buffer[(*pdwOffset)++] = bTlv;
197 // truncate if too long
198 if (dwTlvSize > 0xFFFF) dwTlvSize = 0xFFFF;
199 if (dwTlvSize < 0x7F)
200 {
201 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
202 dwSize++;
203 }
204 else if (dwTlvSize < 0xFF)
205 {
206 buffer[(*pdwOffset)++] = 0x81;
207 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
208 dwSize+=2;
209 }
210 else
211 {
212 buffer[(*pdwOffset)++] = 0x82;
213 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize / 0x100);
214 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize % 0x100);
215 dwSize+=3;
216 }
217 return dwSize;
218 }
219
220 DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
221 __in OPENPGP_KEY dwKey, __in BYTE bFormat,
222 __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
223 {
224 // structure of the keyblob
225 //BLOBHEADER blobheader;
226 //RSAPUBKEY rsapubkey;
227 //BYTE modulus[rsapubkey.bitlen/8];
228 //BYTE prime1[rsapubkey.bitlen/16];
229 //BYTE prime2[rsapubkey.bitlen/16];
230 //BYTE exponent1[rsapubkey.bitlen/16];
231 //BYTE exponent2[rsapubkey.bitlen/16];
232 //BYTE coefficient[rsapubkey.bitlen/16];
233 //BYTE privateExponent[rsapubkey.bitlen/8];
234 DWORD dwReturn = 0;
235
236 DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen;
237 PBYTE pbPublicKeyData = (PBYTE) &(pbPublicKeyBlob->modulus);
238 // 7F48 len is < 7F so its encoded len is 1 bytes
239 // 3 bytes max + length * 7 potential plv
240 BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48};
241 BYTE b5F48Header[3 + 2] = {0x5F, 0x48};
242 BYTE b4DHeader[3 + 1] = {0x4D};
243 DWORD dwOffset = 0;
244 DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize;
245 DWORD dwKeyDataSize, dwExtendedHeaderListSize;
246 DWORD dwI;
247 __try
248 {
249 // build the 7F48 header + the data into a buffer
250 dwOffset = 3;
251 dw7F48HeaderSize = 0;
252 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x91, sizeof(DWORD), &dwOffset);
253 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x92, bitlen / 16, &dwOffset);
254 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x93, bitlen / 16, &dwOffset);
255 if (bFormat & 2)
256 {
257 // add crt (chineese reminder theorem) template
258 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x94, bitlen / 16, &dwOffset);
259 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x95, bitlen / 16, &dwOffset);
260 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x96, bitlen / 16, &dwOffset);
261 }
262 if (bFormat & 1)
263 {
264 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x97, bitlen / 8, &dwOffset);
265 }
266 b7F48Header[2] = (BYTE) dw7F48HeaderSize;
267 dw7F48HeaderSize += 3; // before = only content, after += header size
268 // build 5F48 header in a buffer
269 // size of the data
270 dwKeyDataSize = sizeof(DWORD) // e
271 + bitlen / 16 //prime1
272 + bitlen / 16 //prime2
273 ;
274 if (bFormat & 2)
275 {
276 dwKeyDataSize+= bitlen / 16 //coefficient
277 + bitlen / 16 //exp1
278 + bitlen / 16 //exp2
279 ;
280 }
281 if (bFormat & 1)
282 {
283 dwKeyDataSize+= bitlen / 8 ; //modulus
284 }
285 dwOffset = 1;
286 dw5F48HeaderSize = 1 + BuildSingleTlv(b5F48Header, 0x48, dwKeyDataSize, &dwOffset);
287 // build the extended header list in a buffer
288 dwExtendedHeaderListSize = 2 // for the crt to indicate the private key
289 + dw7F48HeaderSize
290 + dw5F48HeaderSize
291 + dwKeyDataSize;
292 dwOffset = 0;
293 dw4DHeaderSize = BuildSingleTlv(b4DHeader, 0x4D, dwExtendedHeaderListSize, &dwOffset);
294
295 // allocate the memory
296 *pdwTlvSize = dw4DHeaderSize + dwExtendedHeaderListSize;
297 *ppbTlv = pCardData->pfnCspAlloc(*pdwTlvSize);
298 if (! *ppbTlv)
299 {
300 dwReturn = SCARD_E_NO_MEMORY;
301 __leave;
302 }
303 // 4D header
304 dwOffset = 0;
305 memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize);
306 dwOffset += dw4DHeaderSize;
307 // control reference templace
308 (*ppbTlv)[dwOffset++] = Keys[dwKey].bKeyTag;
309 (*ppbTlv)[dwOffset++] = 0;
310 // cardholder private key template
311 memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize);
312 dwOffset += dw7F48HeaderSize;
313 // Concatenation of key data header
314 memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize);
315 dwOffset += dw5F48HeaderSize;
316 // Concatenation of key data
317 // exponent little => big endian
318 (*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000);
319 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000);
320 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100);
321 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1);
322 // prime1
323 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2*bitlen)/16, bitlen / 16);
324 for(dwI = 0; dwI < bitlen / 16; dwI++)
325 {
326 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(3*bitlen)/16 - 1 - dwI];
327 }
328 dwOffset += bitlen / 16;
329
330 // prime2
331 for(dwI = 0; dwI < bitlen / 16; dwI++)
332 {
333 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(4*bitlen)/16 - 1 - dwI];
334 }
335 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (3*bitlen)/16, bitlen / 16);
336 dwOffset += bitlen / 16;
337 if (bFormat & 2)
338 {
339 // coeff
340 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 3) * bitlen / 16 , bitlen / 16);
341 for(dwI = 0; dwI < bitlen / 16; dwI++)
342 {
343 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(7*bitlen)/16 - 1 - dwI];
344 }
345 dwOffset += bitlen / 16;
346 // exponent1
347 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 1) * bitlen / 16 , bitlen / 16);
348 for(dwI = 0; dwI < bitlen / 16; dwI++)
349 {
350 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(5*bitlen)/16 - 1 - dwI];
351 }
352 dwOffset += bitlen / 16;
353 // exponent2
354 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 2) * bitlen / 16 , bitlen / 16);
355 for(dwI = 0; dwI < bitlen / 16; dwI++)
356 {
357 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(6*bitlen)/16 - 1 - dwI];
358 }
359 dwOffset += bitlen / 16;
360 }
361 if (bFormat & 1)
362 {
363 // modulus
364 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData, bitlen / 8);
365 for(dwI = 0; dwI < bitlen / 8; dwI++)
366 {
367 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[bitlen / 8 - 1 - dwI];
368 }
369 }
370 }
371 __finally
372 {
373 }
374 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d", dwReturn, dwKey);
375 return dwReturn;
376 }
377
378 DWORD CreateGenerationDateTime(__in PCARD_DATA pCardData,
379 __out PDWORD pdwSecondsSince1970)
380 {
381 LARGE_INTEGER UnixZeroTime = {0}, WindowsTime;
382 SYSTEMTIME WindowsSystemTime;
383 FILETIME WindowsFileTime;
384 UnixZeroTime.QuadPart = 116444736000000000I64; // january 1st 1970
385 GetSystemTime(&WindowsSystemTime);
386 SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
387 /* It is not recommended that you add and subtract values from the FILETIME
388 structure to obtain relative times. Instead, you should copy the low- and high-order
389 parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic
390 on the QuadPart member, and copy the LowPart and HighPart members into the
391 FILETIME structure.
392
393 Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER*
394 or __int64* value because it can cause alignment faults on 64-bit Windows.
395 */
396 WindowsTime.HighPart = WindowsFileTime.dwHighDateTime;
397 WindowsTime.LowPart = WindowsFileTime.dwLowDateTime;
398 *pdwSecondsSince1970 = (DWORD)((WindowsTime.QuadPart - UnixZeroTime.QuadPart) / 10000000);
399 return 0;
400 }
401
402
403 DWORD UpdateGenerationDateTime(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
404 __out DWORD dwSecondsSince1970)
405 {
406 DWORD dwReturn = 0;
407
408 BYTE pbCommand[] = {0x00, 0xDA, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
409 DWORD dwCommandSize = ARRAYSIZE(pbCommand);
410 __try
411 {
412
413
414 pbCommand[3] = Keys[dwKey].bDateTimeTag;
415 pbCommand[5] = (BYTE) (dwSecondsSince1970 / 0x1000000);
416 pbCommand[6] = (BYTE) ((dwSecondsSince1970 % 0x1000000) / 0x10000);
417 pbCommand[7] = (BYTE) ((dwSecondsSince1970 % 0x10000) / 0x100);
418 pbCommand[8] = (BYTE) ((dwSecondsSince1970 % 0x100) / 0x1);
419 dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
420 }
421 __finally
422 {
423 }
424 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn,dwKey);
425 return dwReturn;
426 }
427
428 DWORD CreateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
429 __in DWORD dwSecondsSince1970,
430 __inout BYTE pbFingerPrint[20])
431 {
432 // modulus in input are in big endian
433 // rfc4880 12.2
434 DWORD dwReturn = 0;
435 PBYTE pbBuffer = NULL;
436 DWORD dwBufferSize;
437 DWORD dwOffset = 0;
438 HCRYPTPROV hProv = 0;
439 HCRYPTHASH hHash = 0;
440 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
441 DWORD dwHashLen = 0x14, dwModulusSizeInBytes, dwModulusSizeInBit, dwExponent;
442 DWORD dwI;
443 __try
444 {
445 dwModulusSizeInBytes = pContext->dwModulusSizeInBytes[dwKey];
446 dwModulusSizeInBit = dwModulusSizeInBytes * 8;
447 dwExponent = pContext->dwExponent[dwKey];
448 dwBufferSize = dwModulusSizeInBytes + sizeof(DWORD) + 10 + 3;
449 pbBuffer = (PBYTE) pCardData->pfnCspAlloc(dwBufferSize);
450 if (!pbBuffer)
451 {
452 dwReturn = SCARD_E_NO_MEMORY;
453 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
454 __leave;
455 }
456
457 pbBuffer[dwOffset++] = 0x99;
458 // -3 because of the header size
459 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) / 0x100);
460 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) % 0x100);
461 // rfc4880 5.5.2
462 // version
463 pbBuffer[dwOffset++] = 4;
464 // timestamp
465 pbBuffer[dwOffset++] = (BYTE) (dwSecondsSince1970 / 0x1000000);
466 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x1000000) / 0x10000);
467 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x10000) / 0x100);
468 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x100) / 0x1);
469 // RSA
470 pbBuffer[dwOffset++] = 1;
471 // size of modulus
472 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x10000) / 0x100);
473 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x100) / 0x1);
474 // little endian => big endian
475 for(dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
476 {
477 pbBuffer[dwOffset + dwI] = pContext->pbModulusInLittleEndian[dwKey][dwModulusSizeInBytes - 1 - dwI];
478 }
479 // size of exponent
480 pbBuffer[dwOffset++] = 0;
481 pbBuffer[dwOffset++] = sizeof(DWORD);
482 // exponent
483 pbBuffer[dwOffset++] = (BYTE) (dwExponent / 0x1000000);
484 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x1000000) / 0x10000);
485 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x10000) / 0x100);
486 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x100) / 0x1);
487
488 // hash using SHA1
489 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
490 {
491 dwReturn = GetLastError();
492 Trace(WINEVENT_LEVEL_ERROR, L"CryptAcquireContext 0x%08X", dwReturn);
493 __leave;
494 }
495 if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
496 {
497 dwReturn = GetLastError();
498 Trace(WINEVENT_LEVEL_ERROR, L"CryptCreateHash 0x%08X", dwReturn);
499 __leave;
500 }
501 if(!CryptHashData(hHash, pbBuffer, dwBufferSize, 0))
502 {
503 dwReturn = GetLastError();
504 Trace(WINEVENT_LEVEL_ERROR, L"CryptHashData 0x%08X", dwReturn);
505 __leave;
506 }
507 if(!CryptGetHashParam(hHash, HP_HASHVAL, pbFingerPrint, &dwHashLen, 0)) {
508 dwReturn = GetLastError();
509 Trace(WINEVENT_LEVEL_ERROR, L"CryptGetHashParam 0x%08X", dwReturn);
510 __leave;
511 }
512
513
514 }
515 __finally
516 {
517 if (pbBuffer)
518 pCardData->pfnCspFree(pbBuffer);
519 if(hHash)
520 CryptDestroyHash(hHash);
521 if(hProv)
522 CryptReleaseContext(hProv,0);
523
524 }
525 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
526 return dwReturn;
527
528 }
529
530 DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
531 __inout BYTE pbFingerPrint[20])
532 {
533 BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};
534 DWORD dwCommandSize = ARRAYSIZE(pbCommand), dwReturn;
535 __try
536 {
537 pbCommand[3] = Keys[dwKey].bSignatureTag;
538 memcpy(pbCommand + 5, pbFingerPrint, 20);
539 dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
540 }
541 __finally
542 {
543 }
544 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn,dwKey);
545 return dwReturn;
546 }
547 DWORD OCardUpdateCachedPublicKey(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey)
548 {
549 PBYTE pbData = NULL;
550 DWORD dwResponseSize = 0, dwReturn;
551 BYTE pbCmd[] = {0x00,
552 0x47,
553 0x81,
554 0x00,
555 0x00,
556 0x00,
557 0x02,
558 0x00,
559 0x00,
560 0x00,
561 0x00
562 };
563 DWORD dwCmdSize;
564 DWORD dwTotalTlvSize, dwOffset;
565 DWORD dwModulusSizeInBytes;
566 PBYTE pbModulus;
567 DWORD dwI;
568 PBYTE pbExponent;
569 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
570 __try
571 {
572 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
573 if (dwKey >= KeyMax)
574 {
575 dwReturn = SCARD_E_NO_KEY_CONTAINER;
576 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
577 __leave;
578 }
579 if (pContext->pbModulusInLittleEndian[dwKey] != NULL)
580 {
581 pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
582 pContext->pbModulusInLittleEndian[dwKey] = NULL;
583 }
584 pbCmd[7] = Keys[dwKey].bKeyTag;
585 dwCmdSize = 9;
586 if (pContext->fExtentedLeLcFields)
587 {
588 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
589 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
590 }
591 else
592 {
593 pbCmd[dwCmdSize++] = 0xFF;
594 }
595
596 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
597 if (dwReturn)
598 {
599 __leave;
600 }
601 dwOffset = 2;
602 dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
603 if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize,&pbModulus,&dwModulusSizeInBytes))
604 {
605 dwReturn = SCARD_E_UNEXPECTED;
606 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
607 __leave;
608 }
609 if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
610 {
611 dwReturn = SCARD_E_UNEXPECTED;
612 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
613 __leave;
614 }
615 Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSizeInBytes * 8);
616
617 pContext->dwExponent[dwKey] = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
618 pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(dwModulusSizeInBytes);
619 if (!pContext->pbModulusInLittleEndian[dwKey])
620 {
621 dwReturn = SCARD_E_NO_MEMORY;
622 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_MEMORY");
623 __leave;
624 }
625 // convert big endian into little endian
626 for (dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
627 {
628 pContext->pbModulusInLittleEndian[dwKey][dwI] = pbModulus[dwModulusSizeInBytes - 1 - dwI];
629 }
630 pContext->dwModulusSizeInBytes[dwKey] = (WORD) dwModulusSizeInBytes;
631 dwReturn = 0;
632 }
633 __finally
634 {
635 if (pbData)
636 pCardData->pfnCspFree(pbData);
637 }
638 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
639 return dwReturn;
640 }
641
642 DWORD OCardUpdateCachedPublicKeyIfNeeded(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey)
643 {
644 PBYTE pbFingerPrint = NULL;
645 DWORD dwFingerPrintSize, dwReturn;
646 BOOL fHasToUpdateTheCache;
647 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
648 LARGE_INTEGER Now;
649 SYSTEMTIME WindowsSystemTime;
650 FILETIME WindowsFileTime;
651 __try
652 {
653 GetSystemTime(&WindowsSystemTime);
654 SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
655 Now.HighPart = WindowsFileTime.dwHighDateTime;
656 Now.LowPart = WindowsFileTime.dwLowDateTime;
657 // last read less than 0,2 s
658 if ((Now.QuadPart - pContext->LastCacheCheck[dwKey].QuadPart) < 2000000)
659 {
660 Trace(WINEVENT_LEVEL_INFO, L"Cache up to date");
661 pContext->LastCacheCheck[dwKey] = Now;
662 dwReturn = 0;
663 __leave;
664 }
665 Trace(WINEVENT_LEVEL_INFO, L"Updating cache");
666 // try to use the cache
667 dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPFingerprint, &pbFingerPrint, &dwFingerPrintSize);
668 if (dwReturn)
669 {
670 __leave;
671 }
672 if (dwFingerPrintSize != 60)
673 {
674 Trace(WINEVENT_LEVEL_ERROR, L"dwFingerPrintSize = %02X", dwFingerPrintSize);
675 dwReturn = SCARD_E_UNEXPECTED;
676 __leave;
677 }
678 // determine if we have to retrieve the modulus from the card
679 if (memcmp(pbFingerPrint + dwKey * 20, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) == 0)
680 {
681 // no public key => why want to read it ?
682 Trace(WINEVENT_LEVEL_ERROR, L"pbFingerPrint null for key %d", dwKey);
683 dwReturn = SCARD_E_NO_KEY_CONTAINER;
684 if (pContext->pbModulusInLittleEndian[dwKey])
685 {
686 pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
687 pContext->pbModulusInLittleEndian[dwKey] = NULL;
688 }
689 pContext->fHasKey[dwKey] = FALSE;
690 __leave;
691 }
692 if (memcmp(pbFingerPrint + dwKey * 20, pContext->bFingerPrint + dwKey * 20, 20) == 0)
693 {
694 if (pContext->pbModulusInLittleEndian[dwKey])
695 {
696 fHasToUpdateTheCache = FALSE;
697 }
698 else
699 {
700 fHasToUpdateTheCache = TRUE;
701 }
702 }
703 else
704 {
705 fHasToUpdateTheCache = TRUE;
706 }
707 if (fHasToUpdateTheCache)
708 {
709 dwReturn = OCardUpdateCachedPublicKey(pCardData, dwKey);
710 if (dwReturn)
711 {
712 __leave;
713 }
714 }
715 pContext->LastCacheCheck[dwKey] = Now;
716 }
717 __finally
718 {
719 if (pbFingerPrint)
720 pCardData->pfnCspFree(pbFingerPrint);
721 }
722 return dwReturn;
723 }
724
725 DWORD OCardGetKeyLengthInBytes(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey, __out PDWORD pdwLengthInBytes)
726 {
727 DWORD dwReturn;
728 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
729 __try
730 {
731 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
732 if (dwKey >= KeyMax)
733 {
734 dwReturn = SCARD_E_NO_KEY_CONTAINER;
735 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
736 __leave;
737 }
738 dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, dwKey);
739 if (dwReturn)
740 {
741 __leave;
742 }
743 *pdwLengthInBytes = pContext->dwModulusSizeInBytes[dwKey];
744 Trace(WINEVENT_LEVEL_VERBOSE, L"modulus size in bits= %d",*pdwLengthInBytes*8);
745 }
746 __finally
747 {
748 }
749 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
750 return dwReturn;
751 }
752
753 DWORD OCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_KEY dwKey, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
754 {
755 DWORD dwReturn;
756 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
757 PRSAPUBLICKEYBLOB pbBlob = NULL;
758 DWORD dwModulusSizeInBytes;
759 __try
760 {
761 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
762 if (dwKey >= KeyMax)
763 {
764 dwReturn = SCARD_E_NO_KEY_CONTAINER;
765 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
766 __leave;
767 }
768 dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, dwKey);
769 if (dwReturn)
770 {
771 __leave;
772 }
773 dwModulusSizeInBytes = pContext->dwModulusSizeInBytes[dwKey];
774 Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSizeInBytes * 8);
775 *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSizeInBytes - sizeof(DWORD);
776 *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
777 if (!*pbPublicKey)
778 {
779 dwReturn = SCARD_E_NO_MEMORY;
780 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY %d", dwKey);
781 __leave;
782 }
783 pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey;
784 memset(pbBlob,0,*pdwPublicKeySize);
785 pbBlob->blobheader.bType = PUBLICKEYBLOB;
786 pbBlob->blobheader.bVersion = CUR_BLOB_VERSION;
787 pbBlob->blobheader.reserved = 0;
788 pbBlob->blobheader.aiKeyAlg = Keys[dwKey].aiKeyAlg;
789 pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
790 pbBlob->rsapubkey.bitlen = dwModulusSizeInBytes*8;
791 pbBlob->rsapubkey.pubexp = pContext->dwExponent[dwKey];
792 memcpy(pbBlob->modulus, pContext->pbModulusInLittleEndian[dwKey], dwModulusSizeInBytes);
793 dwReturn = 0;
794 }
795 __finally
796 {
797 }
798 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
799 return dwReturn;
800 }
801
802 DWORD OCardCreateKey(PCARD_DATA pCardData, OPENPGP_KEY dwKey, DWORD dwBitLen)
803 {
804 DWORD dwReturn;
805 PBYTE pbData = NULL;
806 DWORD dwResponseSize = 0, dwCmdSize;
807 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
808 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
809 DWORD dwSecondsSince1970;
810 PBYTE pbModulus, pbExponent;
811 DWORD dwModulusSizeInBytes, dwExponent, dwI;
812 BYTE pbCmd[] = {0x00,
813 0x47,
814 0x80,
815 0x00,
816 0x00,
817 0x00,
818 0x02,
819 0x00,
820 0x00,
821 0x00,
822 0x00
823 };
824 DWORD dwTotalTlvSize, dwOffset;
825 BYTE pbFingerPrint[20];
826 __try
827 {
828 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
829 if (dwKey >= KeyMax)
830 {
831 dwReturn = SCARD_E_NO_KEY_CONTAINER;
832 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
833 __leave;
834 }
835 // key len
836 Attributes.wModulusLengthInBit = (unsigned short)dwBitLen;
837 Attributes.wExponentLengthInBit = 4 * 8;
838 Attributes.bAlgoId = 1;
839 Attributes.bFormat = 0;
840 dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
841 if (dwReturn)
842 {
843 __leave;
844 }
845
846 pbCmd[7] = Keys[dwKey].bKeyTag;
847 dwCmdSize = 9;
848 if (pContext->fExtentedLeLcFields)
849 {
850 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
851 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
852 }
853 else
854 {
855 pbCmd[dwCmdSize++] = 0xFF;
856 }
857
858 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
859 if (dwReturn)
860 {
861 __leave;
862 }
863 dwOffset = 2;
864 dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
865 if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize, &pbModulus,&dwModulusSizeInBytes))
866 {
867 dwReturn = SCARD_E_UNEXPECTED;
868 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
869 __leave;
870 }
871 if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
872 {
873 dwReturn = SCARD_E_UNEXPECTED;
874 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x82");
875 __leave;
876 }
877 dwExponent = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
878 // save in the cache
879 pContext->fHasKey[dwKey] = TRUE;
880 pContext->dwExponent[dwKey] = dwExponent;
881 pContext->dwModulusSizeInBytes[dwKey] = (WORD) dwModulusSizeInBytes;
882 if (pContext->pbModulusInLittleEndian[dwKey])
883 {
884 pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
885 }
886 pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(dwModulusSizeInBytes);
887 if (!pContext->pbModulusInLittleEndian[dwKey])
888 {
889 dwReturn = SCARD_E_NO_MEMORY;
890 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
891 __leave;
892 }
893 for (dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
894 {
895 pContext->pbModulusInLittleEndian[dwKey][dwI] = pbModulus[dwModulusSizeInBytes - 1 - dwI];
896 }
897 dwReturn = CreateGenerationDateTime(pCardData, &dwSecondsSince1970);
898 if (dwReturn)
899 {
900 __leave;
901 }
902 dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
903 if (dwReturn)
904 {
905 __leave;
906 }
907 // avoid two key having the same fingerprint if generated too fast
908 while (memcmp(pbFingerPrint, pContext->bFingerPrint, 20) == 0
909 || memcmp(pbFingerPrint, pContext->bFingerPrint + 20, 20) == 0
910 || memcmp(pbFingerPrint, pContext->bFingerPrint + 40, 20) == 0)
911 {
912 dwSecondsSince1970++;
913 dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
914 if (dwReturn)
915 {
916 __leave;
917 }
918 }
919 dwReturn = UpdateGenerationDateTime(pCardData, dwKey, dwSecondsSince1970);
920 if (dwReturn)
921 {
922 __leave;
923 }
924 dwReturn = UpdateFingerPrint(pCardData, dwKey, pbFingerPrint);
925 if (dwReturn)
926 {
927 __leave;
928 }
929 memcpy(pContext->bFingerPrint + 20 * dwKey, pbFingerPrint, 20);
930 }
931 __finally
932 {
933 if (pbData)
934 pCardData->pfnCspFree(pbData);
935 }
936 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
937 return dwReturn;
938 }
939
940 DWORD OCardImportKey(PCARD_DATA pCardData,
941 OPENPGP_KEY dwKey,
942 PBYTE pBlob,
943 DWORD dwKeySize)
944 {
945 DWORD dwReturn;
946 PSTR szAlgorithmAttributes = NULL;
947 PBYTE pbTlv = NULL;
948 DWORD dwTlvSize;
949 PBYTE pbCommand = NULL;
950 DWORD dwCommandSize;
951 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
952 PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
953 BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
954 DWORD dwSecondsSince1970;
955 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
956 BYTE pbFingerPrint[20];
957 __try
958 {
959 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwKey);
960 // check blob
961 if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
962 pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
963 {
964 Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
965 dwReturn = SCARD_E_INVALID_PARAMETER;
966 __leave;
967 }
968 if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
969 {
970 Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
971 dwReturn = SCARD_E_INVALID_PARAMETER;
972 __leave;
973 }
974 if (pbPublicKeyBlob->rsapubkey.magic != 0x32415352)
975 {
976 Trace(WINEVENT_LEVEL_ERROR, L"Wrong magic");
977 dwReturn = SCARD_E_INVALID_PARAMETER;
978 __leave;
979 }
980
981 Attributes.wModulusLengthInBit = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
982 Attributes.wExponentLengthInBit = 4 * 8;
983 Attributes.bAlgoId = 1;
984 Attributes.bFormat = 0;
985 dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
986 if (dwReturn)
987 {
988 __leave;
989 }
990 dwReturn = BuildPrivateKeyTlv(pCardData, pbPublicKeyBlob, dwKey, Attributes.bFormat, &pbTlv, &dwTlvSize);
991 if (dwReturn)
992 {
993 __leave;
994 }
995 if (dwTlvSize > 0xFF)
996 {
997 dwCommandSize = 7 + dwTlvSize;
998
999 }
1000 else
1001 {
1002 dwCommandSize = 5 + dwTlvSize;
1003 }
1004 pbCommand = pCardData->pfnCspAlloc(dwCommandSize);
1005 if (!pbCommand)
1006 {
1007 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
1008 dwReturn = SCARD_E_NO_MEMORY;
1009 __leave;
1010 }
1011 memcpy(pbCommand, bCommand, 4);
1012 if (dwTlvSize > 0xFF)
1013 {
1014 pbCommand[4] = 0;
1015 pbCommand[5] = (BYTE)(dwTlvSize / 0x100);
1016 pbCommand[6] = (BYTE)(dwTlvSize % 0x100);
1017 memcpy(pbCommand + 7, pbTlv, dwTlvSize);
1018 }
1019 else
1020 {
1021 pbCommand[4] = (BYTE) dwTlvSize;
1022 memcpy(pbCommand + 5, pbTlv, dwTlvSize);
1023 }
1024 dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
1025 if (dwReturn)
1026 {
1027 __leave;
1028 }
1029 // save in the cache
1030 pContext->fHasKey[dwKey] = TRUE;
1031 pContext->dwExponent[dwKey] = pbPublicKeyBlob->rsapubkey.pubexp;
1032 pContext->dwModulusSizeInBytes[dwKey] = (WORD) pbPublicKeyBlob->rsapubkey.bitlen / 8;
1033 if (pContext->pbModulusInLittleEndian[dwKey])
1034 {
1035 pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
1036 }
1037 pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(pContext->dwModulusSizeInBytes[dwKey]);
1038 if (!pContext->pbModulusInLittleEndian[dwKey])
1039 {
1040 dwReturn = SCARD_E_NO_MEMORY;
1041 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
1042 __leave;
1043 }
1044 memcpy(pContext->pbModulusInLittleEndian[dwKey],&(pbPublicKeyBlob->modulus),pContext->dwModulusSizeInBytes[dwKey]);
1045 dwReturn = CreateGenerationDateTime(pCardData, &dwSecondsSince1970);
1046 if (dwReturn)
1047 {
1048 __leave;
1049 }
1050 dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
1051 if (dwReturn)
1052 {
1053 __leave;
1054 }
1055 // avoid two key having the same fingerprint if generated too fast
1056 while (memcmp(pbFingerPrint, pContext->bFingerPrint, 20) == 0
1057 || memcmp(pbFingerPrint, pContext->bFingerPrint + 20, 20) == 0
1058 || memcmp(pbFingerPrint, pContext->bFingerPrint + 40, 20) == 0)
1059 {
1060 dwSecondsSince1970++;
1061 dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
1062 if (dwReturn)
1063 {
1064 __leave;
1065 }
1066 }
1067 dwReturn = UpdateGenerationDateTime(pCardData, dwKey, dwSecondsSince1970);
1068 if (dwReturn)
1069 {
1070 __leave;
1071 }
1072 dwReturn = UpdateFingerPrint(pCardData, dwKey, pbFingerPrint);
1073 if (dwReturn)
1074 {
1075 __leave;
1076 }
1077 memcpy(pContext->bFingerPrint + 20 * dwKey, pbFingerPrint, 20);
1078 }
1079 __finally
1080 {
1081 if (pbCommand)
1082 {
1083 SecureZeroMemory(pbCommand, dwCommandSize);
1084 pCardData->pfnCspFree(pbCommand);
1085 }
1086 if (pbTlv)
1087 {
1088 SecureZeroMemory(pbTlv, dwTlvSize);
1089 pCardData->pfnCspFree(pbTlv);
1090 }
1091 }
1092 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
1093 return dwReturn;
1094 }
1095
1096 DWORD OCardCheckSigningInfo(__in PCARD_SIGNING_INFO pInfo, __in BOOL fAllowNoOid, __out PDWORD pdwIndex)
1097 {
1098 DWORD dwReturn, dwI;
1099 __try
1100 {
1101 if (pInfo->dwSigningFlags & ~(CARD_PADDING_INFO_PRESENT | CARD_BUFFER_SIZE_ONLY | CRYPT_NOHASHOID | CRYPT_TYPE2_FORMAT))
1102 {
1103 Trace(WINEVENT_LEVEL_ERROR, L"wrong flag %d", pInfo->dwSigningFlags);
1104 dwReturn = SCARD_E_INVALID_PARAMETER;
1105 __leave;
1106 }
1107 if (pInfo->cbData > 256)
1108 {
1109 Trace(WINEVENT_LEVEL_ERROR, L"Error failure pInfo->cbData = %d",pInfo->cbData);
1110 dwReturn = SCARD_E_INVALID_PARAMETER;
1111 __leave;
1112 }
1113 if (pInfo->dwSigningFlags & CARD_PADDING_INFO_PRESENT)
1114 {
1115 if ( pInfo->dwPaddingType == CARD_PADDING_PKCS1)
1116 {
1117 BCRYPT_PKCS1_PADDING_INFO* padding = (BCRYPT_PKCS1_PADDING_INFO*) pInfo->pPaddingInfo;
1118 if (padding->pszAlgId == NULL)
1119 {
1120 if (fAllowNoOid)
1121 {
1122 *pdwIndex = OPENPGP_NO_OID;
1123 dwReturn = 0;
1124 __leave;
1125 }
1126 else
1127 {
1128 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %s", padding->pszAlgId);
1129 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1130 __leave;
1131 }
1132 }
1133 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
1134 {
1135 if (wcscmp(SignatureAlgorithm[dwI].szAlgId,padding->pszAlgId) == 0)
1136 {
1137 // found
1138 break;
1139 }
1140 }
1141 if (dwI >= dwSignatureAlgorithmCount)
1142 {
1143 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %s", padding->pszAlgId);
1144 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1145 __leave;
1146 }
1147 }
1148 else if (pInfo->dwPaddingType == CARD_PADDING_PSS)
1149 {
1150 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1151 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
1152 __leave;
1153 }
1154 else
1155 {
1156 dwReturn = SCARD_E_INVALID_PARAMETER;
1157 Trace(WINEVENT_LEVEL_ERROR, L"pInfo->dwPaddingType = %d", pInfo->dwPaddingType);
1158 __leave;
1159 }
1160 }
1161 else
1162 {
1163 if (!(pInfo->aiHashAlg & ALG_CLASS_HASH))
1164 {
1165 dwReturn = SCARD_E_INVALID_PARAMETER;
1166 Trace(WINEVENT_LEVEL_ERROR, L"pInfo->aiHashAlg == %d", pInfo->aiHashAlg);
1167 __leave;
1168 }
1169 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
1170 {
1171 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
1172 {
1173 // found
1174 break;
1175 }
1176 }
1177 if (dwI >= dwSignatureAlgorithmCount)
1178 {
1179 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
1180 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1181 __leave;
1182 }
1183 }
1184 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
1185 {
1186 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
1187 dwReturn = SCARD_E_INVALID_PARAMETER;
1188 __leave;
1189 }
1190 *pdwIndex = dwI;
1191 dwReturn = 0;
1192 }
1193 __finally
1194 {
1195 }
1196 return dwReturn;
1197 }
1198
1199 DWORD OCardSign(PCARD_DATA pCardData,
1200 PCARD_SIGNING_INFO pInfo)
1201 {
1202 DWORD dwReturn;
1203 PBYTE pbData = NULL;
1204 DWORD dwCmdSize = 0, dwIndex, dwI;
1205 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1206 BYTE pbCmd[6 + 256 + 256] = {0x00,
1207 0x2A,
1208 0x9E,
1209 0x9A,
1210 0x00,
1211 0x00,
1212 };
1213 __try
1214 {
1215 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1216 if (pInfo->bContainerIndex != ContainerSignature)
1217 {
1218 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1219 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1220 __leave;
1221 }
1222 dwReturn = OCardCheckSigningInfo(pInfo, FALSE, &dwIndex);
1223 if (dwReturn)
1224 {
1225 __leave;
1226 }
1227 if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
1228 {
1229 // optimisation :
1230 // return the buffer size only
1231 dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
1232 __leave;
1233 }
1234
1235 dwCmdSize = 5;
1236 if (pContext->fExtentedLeLcFields)
1237 {
1238 dwCmdSize++;
1239 }
1240 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);
1241 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);
1242 dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;
1243 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
1244 {
1245 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
1246 }*/
1247 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1248 dwCmdSize += pInfo->cbData;
1249
1250
1251 if (pContext->fExtentedLeLcFields)
1252 {
1253 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1254 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1255 }
1256 else
1257 {
1258 pbCmd[dwCmdSize++] = 0;
1259 }
1260 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
1261 if (dwReturn == SCARD_W_WRONG_CHV)
1262 {
1263 dwReturn = SCARD_W_SECURITY_VIOLATION;
1264 __leave;
1265 }
1266 if (dwReturn)
1267 {
1268 __leave;
1269 }
1270 // revert the BYTES
1271 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
1272 {
1273 BYTE bTemp = pInfo->pbSignedData[dwI];
1274 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
1275 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
1276 }
1277 }
1278 __finally
1279 {
1280 if (dwReturn)
1281 {
1282 if (pInfo->pbSignedData)
1283 pCardData->pfnCspFree(pInfo->pbSignedData);
1284 }
1285 }
1286 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1287 return dwReturn;
1288 }
1289 DWORD OCardIsConfidentialityKeyTheSameThanAuthentication(__in PCARD_DATA pCardData)
1290 {
1291 DWORD dwReturn;
1292 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1293 __try
1294 {
1295 // see if the confidentiality key is the same than the authentication key
1296 // if yes, confidentiality key can sign
1297 // else ... we don't follow ms guidelines which requiers every container
1298 // to be able to sign data
1299 dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerAuthentication);
1300 if (dwReturn)
1301 {
1302 __leave;
1303 }
1304 dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerConfidentiality);
1305 if (dwReturn)
1306 {
1307 __leave;
1308 }
1309 if (pContext->dwModulusSizeInBytes[ContainerAuthentication]
1310 != pContext->dwModulusSizeInBytes[ContainerConfidentiality])
1311 {
1312 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1313 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
1314 __leave;
1315 }
1316 if (memcmp(pContext->pbModulusInLittleEndian[ContainerAuthentication],
1317 pContext->pbModulusInLittleEndian[ContainerConfidentiality],
1318 pContext->dwModulusSizeInBytes[ContainerConfidentiality]) != 0)
1319 {
1320 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1321 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
1322 __leave;
1323 }
1324 // if we are here, then the confidentiality key can sign using the authentication key
1325 dwReturn = 0;
1326 }
1327 __finally
1328 {
1329 }
1330 return dwReturn;
1331 }
1332 DWORD OCardAuthenticate(PCARD_DATA pCardData,
1333 PCARD_SIGNING_INFO pInfo)
1334 {
1335 DWORD dwReturn;
1336 PBYTE pbData = NULL;
1337 DWORD dwCmdSize = 0, dwIndex, dwI;
1338 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1339 BYTE pbCmd[6 + 256 + 256] = {0x00,
1340 0x88,
1341 0x00,
1342 0x00,
1343 0x00,
1344 0x00,
1345 };
1346 __try
1347 {
1348 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1349
1350 if (pInfo->bContainerIndex != ContainerAuthentication && pInfo->bContainerIndex != ContainerConfidentiality)
1351 {
1352 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1353 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1354 __leave;
1355 }
1356 if (pInfo->bContainerIndex == ContainerConfidentiality)
1357 {
1358 dwReturn = OCardIsConfidentialityKeyTheSameThanAuthentication(pCardData);
1359 if (dwReturn)
1360 {
1361 __leave;
1362 }
1363 }
1364 dwReturn = OCardCheckSigningInfo(pInfo, TRUE, &dwIndex);
1365 if (dwReturn)
1366 {
1367 __leave;
1368 }
1369 if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
1370 {
1371 // optimisation :
1372 // return the buffer size only
1373 dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
1374 __leave;
1375 }
1376
1377 dwCmdSize = 5;
1378 if (pContext->fExtentedLeLcFields)
1379 {
1380 dwCmdSize++;
1381 }
1382 if (dwIndex == OPENPGP_NO_OID)
1383 {
1384 pbCmd[dwCmdSize++] = (BYTE) (pInfo->cbData);
1385 }
1386 else
1387 {
1388 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);
1389 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);
1390 dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;
1391 }
1392 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1393 dwCmdSize += pInfo->cbData;
1394
1395 if (pContext->fExtentedLeLcFields)
1396 {
1397 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1398 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1399 }
1400 else
1401 {
1402 pbCmd[dwCmdSize++] = 0;
1403 }
1404 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
1405 if (dwReturn == SCARD_W_WRONG_CHV)
1406 {
1407 dwReturn = SCARD_W_SECURITY_VIOLATION;
1408 __leave;
1409 }
1410 if (dwReturn)
1411 {
1412 __leave;
1413 }
1414 // revert the BYTES
1415 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
1416 {
1417 BYTE bTemp = pInfo->pbSignedData[dwI];
1418 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
1419 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
1420 }
1421 }
1422 __finally
1423 {
1424 if (dwReturn)
1425 {
1426 if (pInfo->pbSignedData)
1427 pCardData->pfnCspFree(pInfo->pbSignedData);
1428 }
1429 }
1430 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1431 return dwReturn;
1432 }
1433
1434 DWORD OCardDecrypt(PCARD_DATA pCardData,
1435 PCARD_RSA_DECRYPT_INFO pInfo)
1436 {
1437 DWORD dwReturn;
1438 PBYTE pbData = NULL;
1439 DWORD dwCmdSize = 0, dwResponseSize;
1440 BYTE pbCmd[6 + 256 + 256] = {0x00,
1441 0x2A,
1442 0x80,
1443 0x86,
1444 0x00,
1445 };
1446 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1447 DWORD dwI, dwModulusSizeInBytes;
1448 __try
1449 {
1450 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1451 if (pInfo->bContainerIndex >= ContainerMax)
1452 {
1453 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1454 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1455 __leave;
1456 }
1457 if (pInfo->bContainerIndex != ContainerConfidentiality)
1458 {
1459 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1460 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1461 __leave;
1462 }
1463 // check the buffer size
1464 dwModulusSizeInBytes = pContext->dwModulusSizeInBytes[pInfo->bContainerIndex];
1465 if (pInfo->cbData < dwModulusSizeInBytes)
1466 {
1467 dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
1468 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d", pInfo->cbData);
1469 __leave;
1470 }
1471 dwCmdSize = 5;
1472 if (pContext->fExtentedLeLcFields)
1473 {
1474 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
1475 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1476 }
1477 else
1478 {
1479 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1480 }
1481 pbCmd[dwCmdSize++] = 0;
1482 //little endian => big endian
1483 for(dwI = 0; dwI < pInfo->cbData; dwI++)
1484 {
1485 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData -1 -dwI];
1486 }
1487 dwCmdSize += pInfo->cbData;
1488 if (pContext->fExtentedLeLcFields)
1489 {
1490 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1491 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1492 }
1493 else
1494 {
1495 pbCmd[dwCmdSize++] = 0;
1496 }
1497 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
1498 if (dwReturn)
1499 {
1500 __leave;
1501 }
1502
1503 if ( pInfo->cbData < dwResponseSize + 3 + 11)
1504 {
1505 dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
1506 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
1507 __leave;
1508 }
1509 if (pInfo->dwVersion >= CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO)
1510 {
1511 // data field in reverse order (big endian => little endian)
1512 for(dwI = 0; dwI < dwResponseSize; dwI++)
1513 {
1514 pInfo->pbData[dwI] = pbData[dwResponseSize - 1 - dwI];
1515 }
1516 pInfo->cbData = dwResponseSize;
1517 }
1518 else
1519 {
1520 // CryptDecrypt expects the data decrypted using rsa (only the mathematical computation)
1521 // this means the data with the padding (removed by the card)
1522 // and in little endian (while the card return the data in big endian)
1523 // so we rebuilt the padding in reverse order
1524
1525 pInfo->pbData[pInfo->cbData - 1] = 0; // start byte
1526 pInfo->pbData[pInfo->cbData - 2] = 02; // block type
1527 // padding
1528 memset(pInfo->pbData + dwResponseSize + 1,1,pInfo->cbData - 3 - dwResponseSize);
1529 pInfo->pbData[dwResponseSize] = 0; // separator
1530 // data field in reverse order
1531 for(dwI = 0; dwI < dwResponseSize; dwI++)
1532 {
1533 pInfo->pbData[dwI] = pbData[dwResponseSize - 1 - dwI];
1534 }
1535 }
1536
1537 }
1538 __finally
1539 {
1540 if (pbData)
1541 {
1542 SecureZeroMemory(pbData, dwResponseSize);
1543 pCardData->pfnCspFree(pbData);
1544 }
1545 }
1546 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1547 return dwReturn;
1548 }
1549
1550
1551 DWORD OCardReadContainerMapFile(__in PCARD_DATA pCardData,
1552 __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize)
1553 {
1554 DWORD dwReturn = 0;
1555 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1556 DWORD dwSizeInBits;
1557 __try
1558 {
1559 PCONTAINER_MAP_RECORD pContainer = NULL;
1560 BOOL fIsDefaultContainerSet = FALSE;
1561 *pdwResponseSize = sizeof(CONTAINER_MAP_RECORD) * ContainerMax;
1562 *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
1563 if (! *ppbResponse )
1564 {
1565 dwReturn = SCARD_E_NO_MEMORY;
1566 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
1567 __leave;
1568 }
1569 pContainer = (PCONTAINER_MAP_RECORD) *ppbResponse;
1570 memset(pContainer,0,sizeof(CONTAINER_MAP_RECORD) * ContainerMax);
1571
1572 dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyAuthentication, &dwSizeInBits);
1573 if (dwReturn)
1574 {
1575 __leave;
1576 }
1577 pContainer[ContainerAuthentication].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
1578 swprintf_s(pContainer[ContainerAuthentication].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1579 L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Authenticate",
1580 pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
1581 pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1],
1582 pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1],
1583 pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]);
1584 if (pContext->fHasKey[KeyAuthentication])
1585 {
1586 pContainer[ContainerAuthentication].bFlags = CONTAINER_MAP_VALID_CONTAINER | CONTAINER_MAP_DEFAULT_CONTAINER;
1587 fIsDefaultContainerSet = TRUE;
1588 }
1589
1590 dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyConfidentiality, &dwSizeInBits);
1591 if (dwReturn)
1592 {
1593 __leave;
1594 }
1595 pContainer[ContainerConfidentiality].wKeyExchangeKeySizeBits = (WORD)dwSizeInBits * 8;
1596 swprintf_s(pContainer[ContainerConfidentiality].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1597 L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Confidential",
1598 pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
1599 pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1],
1600 pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1],
1601 pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]);
1602 if (pContext->fHasKey[KeyConfidentiality])
1603 {
1604 pContainer[ContainerConfidentiality].bFlags = CONTAINER_MAP_VALID_CONTAINER;
1605 if (!fIsDefaultContainerSet)
1606 {
1607 pContainer[ContainerConfidentiality].bFlags |= CONTAINER_MAP_DEFAULT_CONTAINER;
1608 fIsDefaultContainerSet = TRUE;
1609 }
1610 }
1611
1612 dwReturn = OCardGetKeyLengthInBytes(pCardData, KeySignature, &dwSizeInBits);
1613 if (dwReturn)
1614 {
1615 __leave;
1616 }
1617 pContainer[ContainerSignature].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
1618 swprintf_s(pContainer[ContainerSignature].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1619 L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Signature",
1620 pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
1621 pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1],
1622 pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1],
1623 pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]);
1624 if (pContext->fHasKey[KeySignature])
1625 {
1626 pContainer[ContainerSignature].bFlags = CONTAINER_MAP_VALID_CONTAINER;
1627 if (!fIsDefaultContainerSet)
1628 {
1629 pContainer[ContainerSignature].bFlags |= CONTAINER_MAP_DEFAULT_CONTAINER;
1630 fIsDefaultContainerSet = TRUE;
1631 }
1632 }
1633 }
1634 __finally
1635 {
1636 }
1637 return dwReturn;
1638 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26