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

Contents of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations)
Sun Feb 28 09:39:34 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 36456 byte(s)
decryption is now working !
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 <cardmod.h>
20 #include "Tracing.h"
21 #include "Context.h"
22 #include "SmartCard.h"
23 #include "CryptoOperations.h"
24 #include "PinOperations.h"
25 #include "PublicDataOperations.h"
26
27 OPENPGP_CONTAINER_INFO Containers[] =
28 {
29 {0xB6, 0xCE, 0xC7, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_SIGNATURE},
30 {0xA4, 0xD0, 0xC9, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_AUTHENTICATION},
31 {0xB8, 0xCF, 0xC8, CALG_RSA_KEYX, AT_KEYEXCHANGE, ROLE_CONFIDENTIALITY}
32
33 };
34
35 typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM
36 {
37 ALG_ID aiHashAlg;
38 DWORD dwHashSize;
39 PBYTE pbEncodedOid;
40 DWORD dwEncodedOidSize;
41 } OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM, *POPENPGP_SUPPORTED_SIGNATURE_ALGORITHM;
42
43 BYTE dwSHA1EncodedOid[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
44 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
45 BYTE dwSHA256EncodedOid[] = {0x30, 0x31, 0x30, 0x0D,0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
46 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
47 BYTE dwSHA384EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
48 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
49 BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
50 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
51
52 OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =
53 {
54 {CALG_SHA1,20,
55 dwSHA1EncodedOid,
56 ARRAYSIZE(dwSHA1EncodedOid)},
57 {CALG_SHA-256,32,
58 dwSHA256EncodedOid,
59 ARRAYSIZE(dwSHA256EncodedOid)},
60 {CALG_SHA-384,48,
61 dwSHA384EncodedOid,
62 ARRAYSIZE(dwSHA384EncodedOid)},
63 {CALG_SHA-512,64,
64 dwSHA512EncodedOid,
65 ARRAYSIZE(dwSHA512EncodedOid)},
66 };
67
68 DWORD dwSignatureAlgorithmCount = ARRAYSIZE(SignatureAlgorithm);
69
70 #pragma pack(push,1)
71 typedef struct _OPENPGP_ALGORITHM_ATTRIBUTE
72 {
73 BYTE bAlgoId;
74 unsigned short wModulusLength;
75 unsigned short wExponentLength;
76 BYTE bFormat;
77 } OPENPGP_ALGORITHM_ATTRIBUTE, *POPENPGP_ALGORITHM_ATTRIBUTE;
78 #pragma pack(pop)
79
80 typedef struct _RSAPUBLICKEYBLOB
81 {
82 BLOBHEADER blobheader;
83 RSAPUBKEY rsapubkey;
84 BYTE modulus[sizeof(DWORD)];
85 } RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB;
86
87 DWORD getTlvSize(__in PBYTE pbPointer, __in PDWORD pdwOffset)
88 {
89 DWORD dwSize;
90 switch(*pbPointer)
91 {
92 case 0x81:
93 *pdwOffset+=2;
94 dwSize = pbPointer[1];
95 break;
96 case 0x82:
97 *pdwOffset+=3;
98 dwSize = pbPointer[1] * 0x100 + pbPointer[2];
99 break;
100 default:
101 dwSize = *pbPointer;
102 *pdwOffset+=1;
103 break;
104 }
105 return dwSize;
106 }
107
108 BOOL find_tlv(__in PBYTE pbData, __in BYTE bCode, __out PBYTE *pbDataOut, __out_opt PDWORD pdwSize)
109 {
110 DWORD dwOffset = 2;
111 DWORD dwSize;
112 DWORD dwTotalSize = getTlvSize(pbData + 2,&dwOffset) + 2;
113 while (dwOffset < dwTotalSize)
114 {
115 if (bCode == pbData[dwOffset])
116 {
117 dwOffset++;
118 // size sequence
119 dwSize = getTlvSize(pbData + dwOffset,&dwOffset);
120 if (pdwSize)
121 {
122 *pdwSize = dwSize;
123 }
124 *pbDataOut = pbData + dwOffset;
125 return TRUE;
126 }
127 else
128 {
129 dwOffset++;
130 dwSize = getTlvSize(pbData + dwOffset,&dwOffset);
131 dwOffset += dwSize;
132 }
133 }
134 return FALSE;
135 }
136
137
138 DWORD GetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
139 __in OPENPGP_CONTAINER dwContainer,
140 __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
141 {
142 DWORD dwReturn;
143 PSTR szAlgorithmAttributes = NULL;
144 PBYTE pbData = NULL;
145 DWORD dwResponseSize;
146 WORD wTemp;
147 __try
148 {
149 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
150 switch(dwContainer)
151 {
152 case Signature:
153 szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
154 break;
155 case Authentication:
156 szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
157 break;
158 case Confidentiality:
159 szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
160 break;
161 default:
162 dwReturn = SCARD_E_NO_KEY_CONTAINER;
163 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
164 __leave;
165 }
166 dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, &pbData, &dwResponseSize);
167 if (dwReturn)
168 {
169 __leave;
170 }
171 if (dwResponseSize != sizeof(OPENPGP_ALGORITHM_ATTRIBUTE))
172 {
173 dwReturn = SCARD_E_UNEXPECTED;
174 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED");
175 __leave;
176 }
177 memcpy(pAttributes, pbData, dwResponseSize);
178 // big endian, little endian ...
179 wTemp = pAttributes->wExponentLength;
180 pAttributes->wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
181 wTemp = pAttributes->wModulusLength;
182 pAttributes->wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
183
184 dwReturn = 0;
185 }
186 __finally
187 {
188 if (pbData)
189 pCardData->pfnCspFree(pbData);
190 }
191 return dwReturn;
192 }
193
194 DWORD SetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
195 __in OPENPGP_CONTAINER dwContainer,
196 __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
197 {
198 DWORD dwReturn;
199 PSTR szAlgorithmAttributes = NULL;
200 OPENPGP_ALGORITHM_ATTRIBUTE TempAttributes;
201 WORD wTemp;
202 __try
203 {
204 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
205 switch(dwContainer)
206 {
207 case Signature:
208 szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
209 break;
210 case Authentication:
211 szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
212 break;
213 case Confidentiality:
214 szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
215 break;
216 default:
217 dwReturn = SCARD_E_NO_KEY_CONTAINER;
218 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
219 __leave;
220 }
221 memcpy(&TempAttributes, pAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
222 wTemp = TempAttributes.wExponentLength;
223 TempAttributes.wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
224 wTemp = TempAttributes.wModulusLength;
225 TempAttributes.wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
226
227 dwReturn = SCardWriteFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, (PBYTE) &TempAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
228 if (dwReturn)
229 {
230 __leave;
231 }
232 dwReturn = 0;
233 }
234 __finally
235 {
236 }
237 return dwReturn;
238 }
239
240 DWORD BuildSingleTlv(__in PBYTE buffer, __in BYTE bTlv, __in DWORD dwTlvSize, __inout PDWORD pdwOffset)
241 {
242 DWORD dwSize = 1;
243 buffer[(*pdwOffset)++] = bTlv;
244 // truncate if too long
245 if (dwTlvSize > 0xFFFF) dwTlvSize = 0xFFFF;
246 if (dwTlvSize < 0x7F)
247 {
248 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
249 dwSize++;
250 }
251 else if (dwTlvSize < 0xFF)
252 {
253 buffer[(*pdwOffset)++] = 0x81;
254 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
255 dwSize+=2;
256 }
257 else
258 {
259 buffer[(*pdwOffset)++] = 0x82;
260 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize / 0x100);
261 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize % 0x100);
262 dwSize+=3;
263 }
264 return dwSize;
265 }
266
267 DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
268 __in OPENPGP_CONTAINER dwContainer, __in BYTE bFormat,
269 __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
270 {
271 // structure of the keyblob
272 //BLOBHEADER blobheader;
273 //RSAPUBKEY rsapubkey;
274 //BYTE modulus[rsapubkey.bitlen/8];
275 //BYTE prime1[rsapubkey.bitlen/16];
276 //BYTE prime2[rsapubkey.bitlen/16];
277 //BYTE exponent1[rsapubkey.bitlen/16];
278 //BYTE exponent2[rsapubkey.bitlen/16];
279 //BYTE coefficient[rsapubkey.bitlen/16];
280 //BYTE privateExponent[rsapubkey.bitlen/8];
281 DWORD dwReturn = 0;
282
283 DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen;
284 PBYTE pbPublicKeyData = (PBYTE) &(pbPublicKeyBlob->modulus);
285 // 7F48 len is < 7F so its encoded len is 1 bytes
286 // 3 bytes max + length * 7 potential plv
287 BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48};
288 BYTE b5F48Header[3 + 2] = {0x5F, 0x48};
289 BYTE b4DHeader[3 + 1] = {0x4D};
290 DWORD dwOffset = 0;
291 DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize;
292 DWORD dwKeyDataSize, dwExtendedHeaderListSize;
293 DWORD dwI;
294 __try
295 {
296 // build the 7F48 header + the data into a buffer
297 dwOffset = 3;
298 dw7F48HeaderSize = 0;
299 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x91, sizeof(DWORD), &dwOffset);
300 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x92, bitlen / 16, &dwOffset);
301 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x93, bitlen / 16, &dwOffset);
302 if (bFormat & 2)
303 {
304 // add crt (chineese reminder theorem) template
305 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x94, bitlen / 16, &dwOffset);
306 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x95, bitlen / 16, &dwOffset);
307 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x96, bitlen / 16, &dwOffset);
308 }
309 if (bFormat & 1)
310 {
311 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x97, bitlen / 8, &dwOffset);
312 }
313 b7F48Header[2] = (BYTE) dw7F48HeaderSize;
314 dw7F48HeaderSize += 3; // before = only content, after += header size
315 // build 5F48 header in a buffer
316 // size of the data
317 dwKeyDataSize = sizeof(DWORD) // e
318 + bitlen / 16 //prime1
319 + bitlen / 16 //prime2
320 ;
321 if (bFormat & 2)
322 {
323 dwKeyDataSize+= bitlen / 16 //coefficient
324 + bitlen / 16 //exp1
325 + bitlen / 16 //exp2
326 ;
327 }
328 if (bFormat & 1)
329 {
330 dwKeyDataSize+= bitlen / 8 ; //modulus
331 }
332 dwOffset = 1;
333 dw5F48HeaderSize = 1 + BuildSingleTlv(b5F48Header, 0x48, dwKeyDataSize, &dwOffset);
334 // build the extended header list in a buffer
335 dwExtendedHeaderListSize = 2 // for the crt to indicate the private key
336 + dw7F48HeaderSize
337 + dw5F48HeaderSize
338 + dwKeyDataSize;
339 dwOffset = 0;
340 dw4DHeaderSize = BuildSingleTlv(b4DHeader, 0x4D, dwExtendedHeaderListSize, &dwOffset);
341
342 // allocate the memory
343 *pdwTlvSize = dw4DHeaderSize + dwExtendedHeaderListSize;
344 *ppbTlv = pCardData->pfnCspAlloc(*pdwTlvSize);
345 if (! *ppbTlv)
346 {
347 dwReturn = SCARD_E_NO_MEMORY;
348 __leave;
349 }
350 // 4D header
351 dwOffset = 0;
352 memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize);
353 dwOffset += dw4DHeaderSize;
354 // control reference templace
355 (*ppbTlv)[dwOffset++] = Containers[dwContainer].bKeyTag;
356 (*ppbTlv)[dwOffset++] = 0;
357 // cardholder private key template
358 memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize);
359 dwOffset += dw7F48HeaderSize;
360 // Concatenation of key data header
361 memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize);
362 dwOffset += dw5F48HeaderSize;
363 // Concatenation of key data
364 // exponent little => big endian
365 (*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000);
366 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000);
367 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100);
368 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1);
369 // prime1
370 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2*bitlen)/16, bitlen / 16);
371 for(dwI = 0; dwI < bitlen / 16; dwI++)
372 {
373 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(3*bitlen)/16 - 1 - dwI];
374 }
375 TraceDump(WINEVENT_LEVEL_VERBOSE, *ppbTlv + dwOffset, bitlen / 16);
376 dwOffset += bitlen / 16;
377
378 // prime2
379 for(dwI = 0; dwI < bitlen / 16; dwI++)
380 {
381 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(4*bitlen)/16 - 1 - dwI];
382 }
383 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (3*bitlen)/16, bitlen / 16);
384 TraceDump(WINEVENT_LEVEL_VERBOSE, *ppbTlv + dwOffset, bitlen / 16);
385 dwOffset += bitlen / 16;
386 if (bFormat & 2)
387 {
388 // coeff
389 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 3) * bitlen / 16 , bitlen / 16);
390 for(dwI = 0; dwI < bitlen / 16; dwI++)
391 {
392 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(7*bitlen)/16 - 1 - dwI];
393 }
394 dwOffset += bitlen / 16;
395 // exponent1
396 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 1) * bitlen / 16 , bitlen / 16);
397 for(dwI = 0; dwI < bitlen / 16; dwI++)
398 {
399 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(5*bitlen)/16 - 1 - dwI];
400 }
401 dwOffset += bitlen / 16;
402 // exponent2
403 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 2) * bitlen / 16 , bitlen / 16);
404 for(dwI = 0; dwI < bitlen / 16; dwI++)
405 {
406 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(6*bitlen)/16 - 1 - dwI];
407 }
408 dwOffset += bitlen / 16;
409 }
410 if (bFormat & 1)
411 {
412 // modulus
413 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData, bitlen / 8);
414 for(dwI = 0; dwI < bitlen / 8; dwI++)
415 {
416 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[bitlen / 8 - 1 - dwI];
417 }
418 }
419 TraceDump(WINEVENT_LEVEL_VERBOSE, pbPublicKeyData, bitlen / 8);
420 }
421 __finally
422 {
423 }
424 return dwReturn;
425 }
426
427 DWORD UpdateGenerationDateTime(__in PCARD_DATA pCardData, __in OPENPGP_CONTAINER dwContainer,
428 __out PDWORD pdwSecondsSince1970)
429 {
430 DWORD dwReturn = 0;
431 LARGE_INTEGER UnixZeroTime = {0}, WindowsTime;
432 SYSTEMTIME WindowsSystemTime;
433 FILETIME WindowsFileTime;
434 BYTE pbCommand[] = {0x00, 0xDA, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
435 DWORD dwCommandSize = ARRAYSIZE(pbCommand);
436 __try
437 {
438 UnixZeroTime.QuadPart = 116444736000000000I64; // january 1st 1970
439 GetSystemTime(&WindowsSystemTime);
440 SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
441 /* It is not recommended that you add and subtract values from the FILETIME
442 structure to obtain relative times. Instead, you should copy the low- and high-order
443 parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic
444 on the QuadPart member, and copy the LowPart and HighPart members into the
445 FILETIME structure.
446
447 Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER*
448 or __int64* value because it can cause alignment faults on 64-bit Windows.
449 */
450 WindowsTime.HighPart = WindowsFileTime.dwHighDateTime;
451 WindowsTime.LowPart = WindowsFileTime.dwLowDateTime;
452 *pdwSecondsSince1970 = (DWORD)((WindowsTime.QuadPart - UnixZeroTime.QuadPart) / 10000000);
453
454 pbCommand[3] = Containers[dwContainer].bDateTimeTag;
455 pbCommand[5] = (BYTE) (*pdwSecondsSince1970 / 0x1000000);
456 pbCommand[6] = (BYTE) ((*pdwSecondsSince1970 % 0x1000000) / 0x10000);
457 pbCommand[7] = (BYTE) ((*pdwSecondsSince1970 % 0x10000) / 0x100);
458 pbCommand[8] = (BYTE) ((*pdwSecondsSince1970 % 0x100) / 0x1);
459 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
460 }
461 __finally
462 {
463 }
464 return dwReturn;
465 }
466
467 DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_CONTAINER dwContainer,
468 __in DWORD dwSecondsSince1970,
469 __in PBYTE pbModulus, __in DWORD dwModulusSizeInBit,
470 __in BOOL fIsModulusInBigEndian,
471 __in DWORD dwExponent)
472 {
473 // modulus in input are in big endian
474 // rfc4880 12.2
475 DWORD dwReturn = 0;
476 PBYTE pbBuffer = NULL;
477 DWORD dwBufferSize;
478 DWORD dwOffset = 0;
479 HCRYPTPROV hProv = 0;
480 HCRYPTHASH hHash = 0;
481 BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};
482 DWORD dwCommandSize = ARRAYSIZE(pbCommand);
483 DWORD dwHashLen = 0x14;
484 __try
485 {
486 dwBufferSize = dwModulusSizeInBit / 8 + sizeof(DWORD) + 10 + 3;
487 pbBuffer = (PBYTE) pCardData->pfnCspAlloc(dwBufferSize);
488 if (!pbBuffer)
489 {
490 dwReturn = SCARD_E_NO_MEMORY;
491 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
492 __leave;
493 }
494 pbBuffer[dwOffset++] = 0x99;
495 // -3 because of the header size
496 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) / 0x100);
497 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) % 0x100);
498 // rfc4880 5.5.2
499 // version
500 pbBuffer[dwOffset++] = 4;
501 // timestamp
502 pbBuffer[dwOffset++] = (BYTE) (dwSecondsSince1970 / 0x1000000);
503 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x1000000) / 0x10000);
504 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x10000) / 0x100);
505 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x100) / 0x1);
506 // RSA
507 pbBuffer[dwOffset++] = 1;
508 // size of modulus
509 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x10000) / 0x100);
510 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x100) / 0x1);
511 if (fIsModulusInBigEndian)
512 {
513 memcpy(pbBuffer + dwOffset, pbModulus, dwModulusSizeInBit / 8);
514 }
515 else
516 {
517 DWORD dwI;
518 for(dwI = 0; dwI < dwModulusSizeInBit / 8; dwI++)
519 {
520 pbBuffer[dwOffset + dwI] = pbModulus[dwModulusSizeInBit / 8 - 1 - dwI];
521 }
522 }
523 // size of exponent
524 pbBuffer[dwOffset++] = 0;
525 pbBuffer[dwOffset++] = sizeof(DWORD);
526 // exponent
527 pbBuffer[dwOffset++] = (BYTE) (dwExponent / 0x1000000);
528 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x1000000) / 0x10000);
529 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x10000) / 0x100);
530 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x100) / 0x1);
531
532 // hash using SHA1
533 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
534 {
535 dwReturn = GetLastError();
536 Trace(WINEVENT_LEVEL_ERROR, L"CryptAcquireContext 0x%08X", dwReturn);
537 __leave;
538 }
539 if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
540 {
541 dwReturn = GetLastError();
542 Trace(WINEVENT_LEVEL_ERROR, L"CryptCreateHash 0x%08X", dwReturn);
543 __leave;
544 }
545 if(!CryptHashData(hHash, pbBuffer, dwBufferSize, 0))
546 {
547 dwReturn = GetLastError();
548 Trace(WINEVENT_LEVEL_ERROR, L"CryptHashData 0x%08X", dwReturn);
549 __leave;
550 }
551 if(!CryptGetHashParam(hHash, HP_HASHVAL, pbCommand + 5, &dwHashLen, 0)) {
552 dwReturn = GetLastError();
553 Trace(WINEVENT_LEVEL_ERROR, L"CryptGetHashParam 0x%08X", dwReturn);
554 __leave;
555 }
556 pbCommand[3] = Containers[dwContainer].bSignatureTag;
557 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
558
559 }
560 __finally
561 {
562 if (pbBuffer)
563 pCardData->pfnCspFree(pbBuffer);
564 if(hHash)
565 CryptDestroyHash(hHash);
566 if(hProv)
567 CryptReleaseContext(hProv,0);
568
569 }
570 return dwReturn;
571
572 }
573
574 DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
575 {
576 DWORD dwReturn;
577 PBYTE pbData = NULL;
578 DWORD dwResponseSize = 0;
579 BYTE pbCmd[] = {0x00,
580 0x47,
581 0x81,
582 0x00,
583 0x00,
584 0x00,
585 0x02,
586 0x00,
587 0x00,
588 0x00,
589 0x00
590 };
591 DWORD dwCmdSize;
592 POPENPGP_CONTEXT pContext;
593 PBYTE pbModulus;
594 DWORD dwModulusSize, dwI;
595 PBYTE pbExponent;
596 PRSAPUBLICKEYBLOB pbBlob = NULL;
597 __try
598 {
599 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
600 if (dwContainer >= MaxContainer)
601 {
602 dwReturn = SCARD_E_NO_KEY_CONTAINER;
603 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
604 __leave;
605 }
606 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
607 pbCmd[7] = Containers[dwContainer].bKeyTag;
608 dwCmdSize = 9;
609 if (pContext->fExtentedLeLcFields)
610 {
611 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
612 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
613 }
614 else
615 {
616 pbCmd[dwCmdSize++] = 0xFF;
617 }
618
619 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
620 if (dwReturn)
621 {
622 __leave;
623 }
624 //TraceDump(WINEVENT_LEVEL_INFO, pbData,dwSize);
625 if (!find_tlv(pbData,0x81,&pbModulus,&dwModulusSize))
626 {
627 dwReturn = SCARD_E_UNEXPECTED;
628 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
629 __leave;
630 }
631 if (!find_tlv(pbData,0x82,(PBYTE*)&pbExponent,NULL))
632 {
633 dwReturn = SCARD_E_UNEXPECTED;
634 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
635 __leave;
636 }
637 Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSize * 8);
638 *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
639 *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
640 if (!*pbPublicKey)
641 {
642 dwReturn = SCARD_E_NO_MEMORY;
643 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY %d", dwContainer);
644 __leave;
645 }
646 pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey;
647 memset(pbBlob,0,*pdwPublicKeySize);
648 pbBlob->blobheader.bType = PUBLICKEYBLOB;
649 pbBlob->blobheader.bVersion = CUR_BLOB_VERSION;
650 pbBlob->blobheader.reserved = 0;
651 pbBlob->blobheader.aiKeyAlg = Containers[dwContainer].aiKeyAlg;
652 pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
653 pbBlob->rsapubkey.bitlen = dwModulusSize*8;
654 pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
655 // convert big endian into little endian
656 //memcpy(pbBlob->modulus, pbModulus, dwModulusSize);
657 for (dwI = 0; dwI < dwModulusSize; dwI++)
658 {
659 pbBlob->modulus[dwI] = pbModulus[dwModulusSize - 1 - dwI];
660 }
661
662 //TraceDump(WINEVENT_LEVEL_VERBOSE, pbModulus, dwModulusSize);
663 dwReturn = 0;
664 }
665 __finally
666 {
667 }
668 return dwReturn;
669 }
670
671 DWORD SCardCreateKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, DWORD dwBitLen)
672 {
673 DWORD dwReturn;
674 PBYTE pbData = NULL;
675 DWORD dwResponseSize = 0, dwCmdSize;
676 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
677 POPENPGP_CONTEXT pContext;
678 DWORD dwSecondsSince1970;
679 PBYTE pbModulus, pbExponent;
680 DWORD dwModulusSize, dwExponent;
681 BYTE pbCmd[] = {0x00,
682 0x47,
683 0x80,
684 0x00,
685 0x00,
686 0x00,
687 0x02,
688 0x00,
689 0x00,
690 0x00,
691 0x00
692 };
693 __try
694 {
695 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
696 if (dwContainer >= MaxContainer)
697 {
698 dwReturn = SCARD_E_NO_KEY_CONTAINER;
699 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
700 __leave;
701 }
702 // key len
703 dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
704 if (dwReturn == SCARD_E_FILE_NOT_FOUND)
705 {
706 Attributes.bAlgoId = 0x01;
707 Attributes.bFormat = 0;
708 Attributes.wExponentLength = 0x20;
709 }
710 else if (dwReturn)
711 {
712 __leave;
713 }
714 Attributes.wModulusLength = (WORD) dwBitLen;
715 dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
716 if (dwReturn)
717 {
718 __leave;
719 }
720
721 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
722 pbCmd[7] = Containers[dwContainer].bKeyTag;
723 dwCmdSize = 9;
724 if (pContext->fExtentedLeLcFields)
725 {
726 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
727 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
728 }
729 else
730 {
731 pbCmd[dwCmdSize++] = 0xFF;
732 }
733
734 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
735 if (dwReturn)
736 {
737 __leave;
738 }
739 if (!find_tlv(pbData,0x81,&pbModulus,&dwModulusSize))
740 {
741 dwReturn = SCARD_E_UNEXPECTED;
742 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
743 __leave;
744 }
745 if (!find_tlv(pbData,0x82,(PBYTE*)&pbExponent,NULL))
746 {
747 dwReturn = SCARD_E_UNEXPECTED;
748 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
749 __leave;
750 }
751 dwExponent = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
752 dwReturn = UpdateGenerationDateTime(pCardData, dwContainer, &dwSecondsSince1970);
753 if (dwReturn)
754 {
755 __leave;
756 }
757 dwReturn = UpdateFingerPrint(pCardData, dwContainer, dwSecondsSince1970,
758 pbModulus,
759 dwModulusSize * 8,
760 TRUE,
761 dwExponent
762 );
763 }
764 __finally
765 {
766 if (pbData)
767 pCardData->pfnCspFree(pbData);
768 }
769 return dwReturn;
770 }
771
772 DWORD SCardImportKey(PCARD_DATA pCardData,
773 OPENPGP_CONTAINER dwContainer,
774 PBYTE pBlob,
775 DWORD dwKeySize)
776 {
777 DWORD dwReturn;
778 PSTR szAlgorithmAttributes = NULL;
779 PBYTE pbTlv = NULL;
780 DWORD dwTlvSize;
781 PBYTE pbCommand = NULL;
782 DWORD dwCommandSize;
783 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
784 PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
785 BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
786 DWORD dwSecondsSince1970;
787 __try
788 {
789 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
790 // check blob
791 if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
792 pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
793 {
794 Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
795 dwReturn = SCARD_E_INVALID_PARAMETER;
796 __leave;
797 }
798 if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
799 {
800 Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
801 dwReturn = SCARD_E_INVALID_PARAMETER;
802 __leave;
803 }
804 if (pbPublicKeyBlob->rsapubkey.magic != 0x32415352)
805 {
806 Trace(WINEVENT_LEVEL_ERROR, L"Wrong magic");
807 dwReturn = SCARD_E_INVALID_PARAMETER;
808 __leave;
809 }
810
811 dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
812 if (dwReturn == SCARD_E_FILE_NOT_FOUND)
813 {
814 Attributes.bAlgoId = 0x01;
815 Attributes.bFormat = 0;
816 Attributes.wExponentLength = 0x20;
817 }
818 else if (dwReturn)
819 {
820 __leave;
821 }
822 Attributes.wModulusLength = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
823 dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
824 if (dwReturn)
825 {
826 __leave;
827 }
828 dwReturn = BuildPrivateKeyTlv(pCardData, pbPublicKeyBlob, dwContainer, Attributes.bFormat, &pbTlv, &dwTlvSize);
829 if (dwReturn)
830 {
831 __leave;
832 }
833 //TraceDump(WINEVENT_LEVEL_VERBOSE, pbTlv, dwTlvSize);
834 if (dwTlvSize > 0xFF)
835 {
836 dwCommandSize = 7 + dwTlvSize;
837
838 }
839 else
840 {
841 dwCommandSize = 5 + dwTlvSize;
842 }
843 pbCommand = pCardData->pfnCspAlloc(dwCommandSize);
844 if (!pbCommand)
845 {
846 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
847 dwReturn = SCARD_E_NO_MEMORY;
848 __leave;
849 }
850 memcpy(pbCommand, bCommand, 4);
851 if (dwTlvSize > 0xFF)
852 {
853 pbCommand[4] = 0;
854 pbCommand[5] = (BYTE)(dwTlvSize / 0x100);
855 pbCommand[6] = (BYTE)(dwTlvSize % 0x100);
856 memcpy(pbCommand + 7, pbTlv, dwTlvSize);
857 }
858 else
859 {
860 pbCommand[4] = (BYTE) dwTlvSize;
861 memcpy(pbCommand + 5, pbTlv, dwTlvSize);
862 }
863 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
864 if (dwReturn)
865 {
866 __leave;
867 }
868 dwReturn = UpdateGenerationDateTime(pCardData, dwContainer, &dwSecondsSince1970);
869 if (dwReturn)
870 {
871 __leave;
872 }
873 dwReturn = UpdateFingerPrint(pCardData, dwContainer, dwSecondsSince1970,
874 pbPublicKeyBlob->modulus,
875 pbPublicKeyBlob->rsapubkey.bitlen,
876 FALSE,
877 pbPublicKeyBlob->rsapubkey.pubexp
878 );
879 }
880 __finally
881 {
882 if (pbCommand)
883 {
884 SecureZeroMemory(pbCommand, dwCommandSize);
885 pCardData->pfnCspFree(pbCommand);
886 }
887 if (pbTlv)
888 {
889 SecureZeroMemory(pbTlv, dwTlvSize);
890 pCardData->pfnCspFree(pbTlv);
891 }
892 }
893 return dwReturn;
894 }
895
896 DWORD SCardSign(PCARD_DATA pCardData,
897 PCARD_SIGNING_INFO pInfo)
898 {
899 DWORD dwReturn;
900 PBYTE pbData = NULL;
901 DWORD dwCmdSize = 0, dwI;
902 POPENPGP_CONTEXT pContext;
903 BYTE pbCmd[6 + 256 + 256] = {0x00,
904 0x2A,
905 0x9E,
906 0x9A,
907 0x00,
908 0x00,
909 };
910 __try
911 {
912 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
913 if (pInfo->bContainerIndex >= MaxContainer)
914 {
915 dwReturn = SCARD_E_NO_KEY_CONTAINER;
916 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
917 __leave;
918 }
919 if (pInfo->bContainerIndex != Signature)
920 {
921 dwReturn = SCARD_E_NO_KEY_CONTAINER;
922 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
923 __leave;
924 }
925 if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
926 {
927 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
928 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
929 __leave;
930 }
931 else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
932 {
933 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
934 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
935 __leave;
936 }
937 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
938 {
939 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
940 {
941 // found
942 break;
943 }
944 }
945 if (dwI >= dwSignatureAlgorithmCount)
946 {
947 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
948 __leave;
949 }
950 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
951 {
952 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
953 __leave;
954 }
955 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
956
957 dwCmdSize = 5;
958 if (pContext->fExtentedLeLcFields)
959 {
960 dwCmdSize++;
961 }
962 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
963 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
964 dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
965 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
966 {
967 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
968 }*/
969 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
970 dwCmdSize += pInfo->cbData;
971
972
973 if (pContext->fExtentedLeLcFields)
974 {
975 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
976 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
977 }
978 else
979 {
980 pbCmd[dwCmdSize++] = 0;
981 }
982 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
983 if (dwReturn == SCARD_W_WRONG_CHV)
984 {
985 dwReturn = SCARD_W_SECURITY_VIOLATION;
986 __leave;
987 }
988 if (dwReturn)
989 {
990 __leave;
991 }
992 // revert the BYTES
993 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
994 {
995 BYTE bTemp = pInfo->pbSignedData[dwI];
996 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
997 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
998 }
999 //TraceDump(WINEVENT_LEVEL_ERROR,pInfo->pbSignedData,pInfo->cbSignedData);
1000 }
1001 __finally
1002 {
1003 if (dwReturn)
1004 {
1005 if (pInfo->pbSignedData)
1006 pCardData->pfnCspFree(pInfo->pbSignedData);
1007 }
1008 }
1009 return dwReturn;
1010 }
1011
1012 DWORD SCardDecrypt(PCARD_DATA pCardData,
1013 PCARD_RSA_DECRYPT_INFO pInfo)
1014 {
1015 DWORD dwReturn;
1016 PBYTE pbData = NULL;
1017 DWORD dwCmdSize = 0, dwResponseSize;
1018 BYTE pbCmd[6 + 256 + 256] = {0x00,
1019 0x2A,
1020 0x80,
1021 0x86,
1022 0x00,
1023 };
1024 POPENPGP_CONTEXT pContext;
1025 DWORD dwI;
1026 __try
1027 {
1028 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1029 if (pInfo->bContainerIndex >= MaxContainer)
1030 {
1031 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1032 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1033 __leave;
1034 }
1035 if (pInfo->bContainerIndex != Confidentiality)
1036 {
1037 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1038 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1039 __leave;
1040 }
1041 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1042 dwCmdSize = 5;
1043 if (pContext->fExtentedLeLcFields)
1044 {
1045 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
1046 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1047 }
1048 else
1049 {
1050 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1051 }
1052 pbCmd[dwCmdSize++] = 0;
1053 //little endian => big endian
1054 for(dwI = 0; dwI < pInfo->cbData; dwI++)
1055 {
1056 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData -1 -dwI];
1057 }
1058 dwCmdSize += pInfo->cbData;
1059 if (pContext->fExtentedLeLcFields)
1060 {
1061 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
1062 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
1063 }
1064 else
1065 {
1066 pbCmd[dwCmdSize++] = 0;
1067 }
1068 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
1069 if (dwReturn)
1070 {
1071 __leave;
1072 }
1073
1074 // CryptDecrypt expects the data decrypted using rsa (only the mathematical computation)
1075 // this means the data with the padding (removed by the card)
1076 // and in little endian (while the card return the data in big endian)
1077 // so we rebuilt the padding in reverse order
1078
1079 if ( pInfo->cbData < dwResponseSize + 3 + 11)
1080 {
1081 dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
1082 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
1083 __leave;
1084 }
1085
1086 pInfo->pbData[pInfo->cbData - 1] = 0; // start byte
1087 pInfo->pbData[pInfo->cbData - 2] = 02; // block type
1088 // padding
1089 memset(pInfo->pbData + dwResponseSize + 1,1,pInfo->cbData - 3 - dwResponseSize);
1090 pInfo->pbData[dwResponseSize] = 0; // separator
1091 // data field in reverse order
1092 for(dwI = 0; dwI < dwResponseSize; dwI++)
1093 {
1094 pInfo->pbData[dwI] = pbData[dwResponseSize - 1 - dwI];
1095 }
1096 }
1097 __finally
1098 {
1099 if (pbData)
1100 {
1101 SecureZeroMemory(pbData, dwResponseSize);
1102 pCardData->pfnCspFree(pbData);
1103 }
1104 }
1105 return dwReturn;
1106 }
1107
1108 DWORD SCardAuthenticate(PCARD_DATA pCardData,
1109 PCARD_SIGNING_INFO pInfo)
1110 {
1111 DWORD dwReturn;
1112 PBYTE pbData = NULL;
1113 DWORD dwSize = 0, dwI;
1114 BYTE pbCmd[6 + 256 + 256] = {0x00,
1115 0x88,
1116 0x00,
1117 0x00,
1118 0x00,
1119 };
1120 __try
1121 {
1122 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1123 if (pInfo->bContainerIndex >= MaxContainer)
1124 {
1125 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1126 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1127 __leave;
1128 }
1129 if (pInfo->bContainerIndex != Authentication)
1130 {
1131 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1132 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1133 __leave;
1134 }
1135 if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
1136 {
1137 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1138 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
1139 __leave;
1140 }
1141 else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
1142 {
1143 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1144 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
1145 __leave;
1146 }
1147 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
1148 {
1149 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
1150 {
1151 // found
1152 break;
1153 }
1154 }
1155 if (dwI >= dwSignatureAlgorithmCount)
1156 {
1157 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
1158 __leave;
1159 }
1160 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
1161 {
1162 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
1163 __leave;
1164 }
1165 memcpy(pbCmd +5, SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
1166 memcpy(pbCmd +5 + SignatureAlgorithm[dwI].dwEncodedOidSize, pInfo->pbData,pInfo->cbData);
1167
1168 dwReturn = SCardGetData(pCardData, pbCmd, ARRAYSIZE(pbCmd), &(pInfo->pbSignedData), &(pInfo->cbSignedData));
1169 if (dwReturn)
1170 {
1171 __leave;
1172 }
1173 }
1174 __finally
1175 {
1176 }
1177 return dwReturn;
1178 }
1179
1180 DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
1181 {
1182 DWORD dwReturn=0;
1183 __try
1184 {
1185 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
1186 switch(dwPinIndex)
1187 {
1188 case ROLE_SIGNATURE:
1189 pPinInfo->PinType = AlphaNumericPinType;
1190 pPinInfo->PinPurpose = DigitalSignaturePin;
1191 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1192 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1193 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1194 break;
1195 case ROLE_AUTHENTICATION:
1196 pPinInfo->PinType = AlphaNumericPinType;
1197 pPinInfo->PinPurpose = AuthenticationPin;
1198 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1199 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1200 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1201 break;
1202 case ROLE_CONFIDENTIALITY:
1203 pPinInfo->PinType = AlphaNumericPinType;
1204 pPinInfo->PinPurpose = EncryptionPin;
1205 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1206 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1207 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1208 break;
1209 default:
1210 Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
1211 dwReturn = SCARD_E_INVALID_PARAMETER ;
1212 __leave;
1213 }
1214 }
1215 __finally
1216 {
1217 }
1218 return dwReturn;
1219 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26