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

Contents of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (show annotations)
Mon Mar 15 18:23:17 2010 UTC (15 years, 1 month ago) by vletoux
File MIME type: text/plain
File size: 50469 byte(s)
first beta version
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_CONFIDENTIALITY, 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 * 8;
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->dwSigningFlags & CARD_PADDING_INFO_PRESENT)
1108 {
1109 if ( pInfo->dwPaddingType == CARD_PADDING_PKCS1)
1110 {
1111 BCRYPT_PKCS1_PADDING_INFO* padding = (BCRYPT_PKCS1_PADDING_INFO*) pInfo->pPaddingInfo;
1112 if (padding->pszAlgId == NULL)
1113 {
1114 if (fAllowNoOid)
1115 {
1116 *pdwIndex = OPENPGP_NO_OID;
1117 dwReturn = 0;
1118 __leave;
1119 }
1120 else
1121 {
1122 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %s", padding->pszAlgId);
1123 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1124 __leave;
1125 }
1126 }
1127 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
1128 {
1129 if (wcscmp(SignatureAlgorithm[dwI].szAlgId,padding->pszAlgId) == 0)
1130 {
1131 // found
1132 break;
1133 }
1134 }
1135 if (dwI >= dwSignatureAlgorithmCount)
1136 {
1137 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %s", padding->pszAlgId);
1138 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1139 __leave;
1140 }
1141 }
1142 else if (pInfo->dwPaddingType == CARD_PADDING_PSS)
1143 {
1144 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1145 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
1146 __leave;
1147 }
1148 else
1149 {
1150 dwReturn = SCARD_E_INVALID_PARAMETER;
1151 Trace(WINEVENT_LEVEL_ERROR, L"pInfo->dwPaddingType = %d", pInfo->dwPaddingType);
1152 __leave;
1153 }
1154 }
1155 else
1156 {
1157 if (!(pInfo->aiHashAlg & ALG_CLASS_HASH))
1158 {
1159 dwReturn = SCARD_E_INVALID_PARAMETER;
1160 Trace(WINEVENT_LEVEL_ERROR, L"pInfo->aiHashAlg == %d", pInfo->aiHashAlg);
1161 __leave;
1162 }
1163 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
1164 {
1165 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
1166 {
1167 // found
1168 break;
1169 }
1170 }
1171 if (dwI >= dwSignatureAlgorithmCount)
1172 {
1173 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
1174 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1175 __leave;
1176 }
1177 }
1178 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
1179 {
1180 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
1181 dwReturn = SCARD_E_INVALID_PARAMETER;
1182 __leave;
1183 }
1184 *pdwIndex = dwI;
1185 dwReturn = 0;
1186 }
1187 __finally
1188 {
1189 }
1190 return dwReturn;
1191 }
1192
1193 DWORD OCardSign(PCARD_DATA pCardData,
1194 PCARD_SIGNING_INFO pInfo)
1195 {
1196 DWORD dwReturn;
1197 PBYTE pbData = NULL;
1198 DWORD dwCmdSize = 0, dwIndex, dwI;
1199 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1200 BYTE pbCmd[6 + 256 + 256] = {0x00,
1201 0x2A,
1202 0x9E,
1203 0x9A,
1204 0x00,
1205 0x00,
1206 };
1207 __try
1208 {
1209 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1210 if (pInfo->bContainerIndex != ContainerSignature)
1211 {
1212 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1213 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1214 __leave;
1215 }
1216 dwReturn = OCardCheckSigningInfo(pInfo, FALSE, &dwIndex);
1217 if (dwReturn)
1218 {
1219 __leave;
1220 }
1221 if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
1222 {
1223 // optimisation :
1224 // return the buffer size only
1225 dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
1226 __leave;
1227 }
1228
1229 dwCmdSize = 5;
1230 if (pContext->fExtentedLeLcFields)
1231 {
1232 dwCmdSize++;
1233 }
1234 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);
1235 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);
1236 dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;
1237 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
1238 {
1239 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
1240 }*/
1241 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1242 dwCmdSize += pInfo->cbData;
1243
1244
1245 if (pContext->fExtentedLeLcFields)
1246 {
1247 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1248 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1249 }
1250 else
1251 {
1252 pbCmd[dwCmdSize++] = 0;
1253 }
1254 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
1255 if (dwReturn == SCARD_W_WRONG_CHV)
1256 {
1257 dwReturn = SCARD_W_SECURITY_VIOLATION;
1258 __leave;
1259 }
1260 if (dwReturn)
1261 {
1262 __leave;
1263 }
1264 // revert the BYTES
1265 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
1266 {
1267 BYTE bTemp = pInfo->pbSignedData[dwI];
1268 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
1269 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
1270 }
1271 }
1272 __finally
1273 {
1274 if (dwReturn)
1275 {
1276 if (pInfo->pbSignedData)
1277 pCardData->pfnCspFree(pInfo->pbSignedData);
1278 }
1279 }
1280 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1281 return dwReturn;
1282 }
1283 DWORD OCardIsConfidentialityKeyTheSameThanAuthentication(__in PCARD_DATA pCardData)
1284 {
1285 DWORD dwReturn;
1286 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1287 __try
1288 {
1289 // see if the confidentiality key is the same than the authentication key
1290 // if yes, confidentiality key can sign
1291 // else ... we don't follow ms guidelines which requiers every container
1292 // to be able to sign data
1293 dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerAuthentication);
1294 if (dwReturn)
1295 {
1296 __leave;
1297 }
1298 dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerConfidentiality);
1299 if (dwReturn)
1300 {
1301 __leave;
1302 }
1303 if (pContext->dwModulusSizeInBytes[ContainerAuthentication]
1304 != pContext->dwModulusSizeInBytes[ContainerConfidentiality])
1305 {
1306 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1307 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
1308 __leave;
1309 }
1310 if (memcmp(pContext->pbModulusInLittleEndian[ContainerAuthentication],
1311 pContext->pbModulusInLittleEndian[ContainerConfidentiality],
1312 pContext->dwModulusSizeInBytes[ContainerConfidentiality]) != 0)
1313 {
1314 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1315 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
1316 __leave;
1317 }
1318 // if we are here, then the confidentiality key can sign using the authentication key
1319 dwReturn = 0;
1320 }
1321 __finally
1322 {
1323 }
1324 return dwReturn;
1325 }
1326 DWORD OCardAuthenticate(PCARD_DATA pCardData,
1327 PCARD_SIGNING_INFO pInfo)
1328 {
1329 DWORD dwReturn;
1330 PBYTE pbData = NULL;
1331 DWORD dwCmdSize = 0, dwIndex, dwI;
1332 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1333 BYTE pbCmd[6 + 256 + 256] = {0x00,
1334 0x88,
1335 0x00,
1336 0x00,
1337 0x00,
1338 0x00,
1339 };
1340 __try
1341 {
1342 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1343
1344 if (pInfo->bContainerIndex != ContainerAuthentication && pInfo->bContainerIndex != ContainerConfidentiality)
1345 {
1346 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1347 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1348 __leave;
1349 }
1350 if (pInfo->bContainerIndex == ContainerConfidentiality)
1351 {
1352 dwReturn = OCardIsConfidentialityKeyTheSameThanAuthentication(pCardData);
1353 if (dwReturn)
1354 {
1355 __leave;
1356 }
1357 }
1358 dwReturn = OCardCheckSigningInfo(pInfo, TRUE, &dwIndex);
1359 if (dwReturn)
1360 {
1361 __leave;
1362 }
1363 if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
1364 {
1365 // optimisation :
1366 // return the buffer size only
1367 dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
1368 __leave;
1369 }
1370
1371 dwCmdSize = 5;
1372 if (pContext->fExtentedLeLcFields)
1373 {
1374 dwCmdSize++;
1375 }
1376 if (dwIndex == OPENPGP_NO_OID)
1377 {
1378 pbCmd[dwCmdSize++] = (BYTE) (pInfo->cbData);
1379 }
1380 else
1381 {
1382 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);
1383 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);
1384 dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;
1385 }
1386 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1387 dwCmdSize += pInfo->cbData;
1388
1389 if (pContext->fExtentedLeLcFields)
1390 {
1391 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1392 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1393 }
1394 else
1395 {
1396 pbCmd[dwCmdSize++] = 0;
1397 }
1398 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
1399 if (dwReturn == SCARD_W_WRONG_CHV)
1400 {
1401 dwReturn = SCARD_W_SECURITY_VIOLATION;
1402 __leave;
1403 }
1404 if (dwReturn)
1405 {
1406 __leave;
1407 }
1408 // revert the BYTES
1409 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
1410 {
1411 BYTE bTemp = pInfo->pbSignedData[dwI];
1412 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
1413 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
1414 }
1415 }
1416 __finally
1417 {
1418 if (dwReturn)
1419 {
1420 if (pInfo->pbSignedData)
1421 pCardData->pfnCspFree(pInfo->pbSignedData);
1422 }
1423 }
1424 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1425 return dwReturn;
1426 }
1427
1428 DWORD OCardDecrypt(PCARD_DATA pCardData,
1429 PCARD_RSA_DECRYPT_INFO pInfo)
1430 {
1431 DWORD dwReturn;
1432 PBYTE pbData = NULL;
1433 DWORD dwCmdSize = 0, dwResponseSize;
1434 BYTE pbCmd[6 + 256 + 256] = {0x00,
1435 0x2A,
1436 0x80,
1437 0x86,
1438 0x00,
1439 };
1440 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1441 DWORD dwI;
1442 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
1443 __try
1444 {
1445 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1446 if (pInfo->bContainerIndex >= ContainerMax)
1447 {
1448 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1449 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1450 __leave;
1451 }
1452 if (pInfo->bContainerIndex != ContainerConfidentiality)
1453 {
1454 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1455 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1456 __leave;
1457 }
1458 // check the buffer size
1459 dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeyConfidentiality, &Attributes);
1460 if (dwReturn)
1461 {
1462 __leave;
1463 }
1464 if (pInfo->cbData < (DWORD)(Attributes.wModulusLengthInBit/8))
1465 {
1466 dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
1467 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d", pInfo->cbData);
1468 __leave;
1469 }
1470 dwCmdSize = 5;
1471 if (pContext->fExtentedLeLcFields)
1472 {
1473 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
1474 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1475 }
1476 else
1477 {
1478 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1479 }
1480 pbCmd[dwCmdSize++] = 0;
1481 //little endian => big endian
1482 for(dwI = 0; dwI < pInfo->cbData; dwI++)
1483 {
1484 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData -1 -dwI];
1485 }
1486 dwCmdSize += pInfo->cbData;
1487 if (pContext->fExtentedLeLcFields)
1488 {
1489 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1490 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1491 }
1492 else
1493 {
1494 pbCmd[dwCmdSize++] = 0;
1495 }
1496 dwReturn = OCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
1497 if (dwReturn)
1498 {
1499 __leave;
1500 }
1501
1502 // CryptDecrypt expects the data decrypted using rsa (only the mathematical computation)
1503 // this means the data with the padding (removed by the card)
1504 // and in little endian (while the card return the data in big endian)
1505 // so we rebuilt the padding in reverse order
1506
1507 if ( pInfo->cbData < dwResponseSize + 3 + 11)
1508 {
1509 dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
1510 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
1511 __leave;
1512 }
1513
1514 pInfo->pbData[pInfo->cbData - 1] = 0; // start byte
1515 pInfo->pbData[pInfo->cbData - 2] = 02; // block type
1516 // padding
1517 memset(pInfo->pbData + dwResponseSize + 1,1,pInfo->cbData - 3 - dwResponseSize);
1518 pInfo->pbData[dwResponseSize] = 0; // separator
1519 // data field in reverse order
1520 for(dwI = 0; dwI < dwResponseSize; dwI++)
1521 {
1522 pInfo->pbData[dwI] = pbData[dwResponseSize - 1 - dwI];
1523 }
1524 }
1525 __finally
1526 {
1527 if (pbData)
1528 {
1529 SecureZeroMemory(pbData, dwResponseSize);
1530 pCardData->pfnCspFree(pbData);
1531 }
1532 }
1533 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1534 return dwReturn;
1535 }
1536
1537
1538 DWORD OCardReadContainerMapFile(__in PCARD_DATA pCardData,
1539 __in PBYTE* ppbResponse, __in PDWORD pdwResponseSize)
1540 {
1541 DWORD dwReturn = 0;
1542 POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1543 DWORD dwSizeInBits;
1544 __try
1545 {
1546 PCONTAINER_MAP_RECORD pContainer = NULL;
1547 BOOL fIsDefaultContainerSet = FALSE;
1548 *pdwResponseSize = sizeof(CONTAINER_MAP_RECORD) * ContainerMax;
1549 *ppbResponse = pCardData->pfnCspAlloc(*pdwResponseSize);
1550 if (! *ppbResponse )
1551 {
1552 dwReturn = SCARD_E_NO_MEMORY;
1553 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
1554 __leave;
1555 }
1556 pContainer = (PCONTAINER_MAP_RECORD) *ppbResponse;
1557 memset(pContainer,0,sizeof(CONTAINER_MAP_RECORD) * ContainerMax);
1558
1559 dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyAuthentication, &dwSizeInBits);
1560 if (dwReturn)
1561 {
1562 __leave;
1563 }
1564 pContainer[ContainerAuthentication].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
1565 swprintf_s(pContainer[ContainerAuthentication].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1566 L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Authenticate",
1567 pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
1568 pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1],
1569 pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1],
1570 pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]);
1571 if (pContext->fHasKey[KeyAuthentication])
1572 {
1573 pContainer[ContainerAuthentication].bFlags = CONTAINER_MAP_VALID_CONTAINER | CONTAINER_MAP_DEFAULT_CONTAINER;
1574 fIsDefaultContainerSet = TRUE;
1575 }
1576
1577 dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyConfidentiality, &dwSizeInBits);
1578 if (dwReturn)
1579 {
1580 __leave;
1581 }
1582 pContainer[ContainerConfidentiality].wKeyExchangeKeySizeBits = (WORD)dwSizeInBits * 8;
1583 swprintf_s(pContainer[ContainerConfidentiality].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1584 L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Confidential",
1585 pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
1586 pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1],
1587 pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1],
1588 pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]);
1589 if (pContext->fHasKey[KeyConfidentiality])
1590 {
1591 pContainer[ContainerConfidentiality].bFlags = CONTAINER_MAP_VALID_CONTAINER;
1592 if (!fIsDefaultContainerSet)
1593 {
1594 pContainer[ContainerConfidentiality].bFlags |= CONTAINER_MAP_DEFAULT_CONTAINER;
1595 fIsDefaultContainerSet = TRUE;
1596 }
1597 }
1598
1599 dwReturn = OCardGetKeyLengthInBytes(pCardData, KeySignature, &dwSizeInBits);
1600 if (dwReturn)
1601 {
1602 __leave;
1603 }
1604 pContainer[ContainerSignature].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
1605 swprintf_s(pContainer[ContainerSignature].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1606 L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Signature",
1607 pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
1608 pContext->Aid.AidManufacturer[0],pContext->Aid.AidManufacturer[1],
1609 pContext->Aid.AidSerialNumber[0],pContext->Aid.AidSerialNumber[1],
1610 pContext->Aid.AidSerialNumber[2],pContext->Aid.AidSerialNumber[3]);
1611 if (pContext->fHasKey[KeySignature])
1612 {
1613 pContainer[ContainerSignature].bFlags = CONTAINER_MAP_VALID_CONTAINER;
1614 if (!fIsDefaultContainerSet)
1615 {
1616 pContainer[ContainerSignature].bFlags |= CONTAINER_MAP_DEFAULT_CONTAINER;
1617 fIsDefaultContainerSet = TRUE;
1618 }
1619 }
1620 }
1621 __finally
1622 {
1623 }
1624 return dwReturn;
1625 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26