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

Contents of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Tue Mar 2 18:54:34 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 37542 byte(s)
authentication 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 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
192 return dwReturn;
193 }
194
195 DWORD SetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
196 __in OPENPGP_CONTAINER dwContainer,
197 __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
198 {
199 DWORD dwReturn;
200 PSTR szAlgorithmAttributes = NULL;
201 OPENPGP_ALGORITHM_ATTRIBUTE TempAttributes;
202 WORD wTemp;
203 __try
204 {
205 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
206 switch(dwContainer)
207 {
208 case Signature:
209 szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
210 break;
211 case Authentication:
212 szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
213 break;
214 case Confidentiality:
215 szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
216 break;
217 default:
218 dwReturn = SCARD_E_NO_KEY_CONTAINER;
219 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
220 __leave;
221 }
222 memcpy(&TempAttributes, pAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
223 wTemp = TempAttributes.wExponentLength;
224 TempAttributes.wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
225 wTemp = TempAttributes.wModulusLength;
226 TempAttributes.wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
227
228 dwReturn = SCardWriteFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, (PBYTE) &TempAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
229 if (dwReturn)
230 {
231 __leave;
232 }
233 dwReturn = 0;
234 }
235 __finally
236 {
237 }
238 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
239 return dwReturn;
240 }
241
242 DWORD BuildSingleTlv(__in PBYTE buffer, __in BYTE bTlv, __in DWORD dwTlvSize, __inout PDWORD pdwOffset)
243 {
244 DWORD dwSize = 1;
245 buffer[(*pdwOffset)++] = bTlv;
246 // truncate if too long
247 if (dwTlvSize > 0xFFFF) dwTlvSize = 0xFFFF;
248 if (dwTlvSize < 0x7F)
249 {
250 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
251 dwSize++;
252 }
253 else if (dwTlvSize < 0xFF)
254 {
255 buffer[(*pdwOffset)++] = 0x81;
256 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
257 dwSize+=2;
258 }
259 else
260 {
261 buffer[(*pdwOffset)++] = 0x82;
262 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize / 0x100);
263 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize % 0x100);
264 dwSize+=3;
265 }
266 return dwSize;
267 }
268
269 DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
270 __in OPENPGP_CONTAINER dwContainer, __in BYTE bFormat,
271 __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
272 {
273 // structure of the keyblob
274 //BLOBHEADER blobheader;
275 //RSAPUBKEY rsapubkey;
276 //BYTE modulus[rsapubkey.bitlen/8];
277 //BYTE prime1[rsapubkey.bitlen/16];
278 //BYTE prime2[rsapubkey.bitlen/16];
279 //BYTE exponent1[rsapubkey.bitlen/16];
280 //BYTE exponent2[rsapubkey.bitlen/16];
281 //BYTE coefficient[rsapubkey.bitlen/16];
282 //BYTE privateExponent[rsapubkey.bitlen/8];
283 DWORD dwReturn = 0;
284
285 DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen;
286 PBYTE pbPublicKeyData = (PBYTE) &(pbPublicKeyBlob->modulus);
287 // 7F48 len is < 7F so its encoded len is 1 bytes
288 // 3 bytes max + length * 7 potential plv
289 BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48};
290 BYTE b5F48Header[3 + 2] = {0x5F, 0x48};
291 BYTE b4DHeader[3 + 1] = {0x4D};
292 DWORD dwOffset = 0;
293 DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize;
294 DWORD dwKeyDataSize, dwExtendedHeaderListSize;
295 DWORD dwI;
296 __try
297 {
298 // build the 7F48 header + the data into a buffer
299 dwOffset = 3;
300 dw7F48HeaderSize = 0;
301 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x91, sizeof(DWORD), &dwOffset);
302 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x92, bitlen / 16, &dwOffset);
303 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x93, bitlen / 16, &dwOffset);
304 if (bFormat & 2)
305 {
306 // add crt (chineese reminder theorem) template
307 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x94, bitlen / 16, &dwOffset);
308 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x95, bitlen / 16, &dwOffset);
309 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x96, bitlen / 16, &dwOffset);
310 }
311 if (bFormat & 1)
312 {
313 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x97, bitlen / 8, &dwOffset);
314 }
315 b7F48Header[2] = (BYTE) dw7F48HeaderSize;
316 dw7F48HeaderSize += 3; // before = only content, after += header size
317 // build 5F48 header in a buffer
318 // size of the data
319 dwKeyDataSize = sizeof(DWORD) // e
320 + bitlen / 16 //prime1
321 + bitlen / 16 //prime2
322 ;
323 if (bFormat & 2)
324 {
325 dwKeyDataSize+= bitlen / 16 //coefficient
326 + bitlen / 16 //exp1
327 + bitlen / 16 //exp2
328 ;
329 }
330 if (bFormat & 1)
331 {
332 dwKeyDataSize+= bitlen / 8 ; //modulus
333 }
334 dwOffset = 1;
335 dw5F48HeaderSize = 1 + BuildSingleTlv(b5F48Header, 0x48, dwKeyDataSize, &dwOffset);
336 // build the extended header list in a buffer
337 dwExtendedHeaderListSize = 2 // for the crt to indicate the private key
338 + dw7F48HeaderSize
339 + dw5F48HeaderSize
340 + dwKeyDataSize;
341 dwOffset = 0;
342 dw4DHeaderSize = BuildSingleTlv(b4DHeader, 0x4D, dwExtendedHeaderListSize, &dwOffset);
343
344 // allocate the memory
345 *pdwTlvSize = dw4DHeaderSize + dwExtendedHeaderListSize;
346 *ppbTlv = pCardData->pfnCspAlloc(*pdwTlvSize);
347 if (! *ppbTlv)
348 {
349 dwReturn = SCARD_E_NO_MEMORY;
350 __leave;
351 }
352 // 4D header
353 dwOffset = 0;
354 memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize);
355 dwOffset += dw4DHeaderSize;
356 // control reference templace
357 (*ppbTlv)[dwOffset++] = Containers[dwContainer].bKeyTag;
358 (*ppbTlv)[dwOffset++] = 0;
359 // cardholder private key template
360 memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize);
361 dwOffset += dw7F48HeaderSize;
362 // Concatenation of key data header
363 memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize);
364 dwOffset += dw5F48HeaderSize;
365 // Concatenation of key data
366 // exponent little => big endian
367 (*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000);
368 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000);
369 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100);
370 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1);
371 // prime1
372 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2*bitlen)/16, bitlen / 16);
373 for(dwI = 0; dwI < bitlen / 16; dwI++)
374 {
375 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(3*bitlen)/16 - 1 - dwI];
376 }
377 dwOffset += bitlen / 16;
378
379 // prime2
380 for(dwI = 0; dwI < bitlen / 16; dwI++)
381 {
382 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(4*bitlen)/16 - 1 - dwI];
383 }
384 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (3*bitlen)/16, 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 }
420 __finally
421 {
422 }
423 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
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 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
465 return dwReturn;
466 }
467
468 DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_CONTAINER dwContainer,
469 __in DWORD dwSecondsSince1970,
470 __in PBYTE pbModulus, __in DWORD dwModulusSizeInBit,
471 __in BOOL fIsModulusInBigEndian,
472 __in DWORD dwExponent)
473 {
474 // modulus in input are in big endian
475 // rfc4880 12.2
476 DWORD dwReturn = 0;
477 PBYTE pbBuffer = NULL;
478 DWORD dwBufferSize;
479 DWORD dwOffset = 0;
480 HCRYPTPROV hProv = 0;
481 HCRYPTHASH hHash = 0;
482 BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};
483 DWORD dwCommandSize = ARRAYSIZE(pbCommand);
484 DWORD dwHashLen = 0x14;
485 __try
486 {
487 dwBufferSize = dwModulusSizeInBit / 8 + sizeof(DWORD) + 10 + 3;
488 pbBuffer = (PBYTE) pCardData->pfnCspAlloc(dwBufferSize);
489 if (!pbBuffer)
490 {
491 dwReturn = SCARD_E_NO_MEMORY;
492 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
493 __leave;
494 }
495 pbBuffer[dwOffset++] = 0x99;
496 // -3 because of the header size
497 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) / 0x100);
498 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) % 0x100);
499 // rfc4880 5.5.2
500 // version
501 pbBuffer[dwOffset++] = 4;
502 // timestamp
503 pbBuffer[dwOffset++] = (BYTE) (dwSecondsSince1970 / 0x1000000);
504 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x1000000) / 0x10000);
505 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x10000) / 0x100);
506 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x100) / 0x1);
507 // RSA
508 pbBuffer[dwOffset++] = 1;
509 // size of modulus
510 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x10000) / 0x100);
511 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x100) / 0x1);
512 if (fIsModulusInBigEndian)
513 {
514 memcpy(pbBuffer + dwOffset, pbModulus, dwModulusSizeInBit / 8);
515 }
516 else
517 {
518 DWORD dwI;
519 for(dwI = 0; dwI < dwModulusSizeInBit / 8; dwI++)
520 {
521 pbBuffer[dwOffset + dwI] = pbModulus[dwModulusSizeInBit / 8 - 1 - dwI];
522 }
523 }
524 // size of exponent
525 pbBuffer[dwOffset++] = 0;
526 pbBuffer[dwOffset++] = sizeof(DWORD);
527 // exponent
528 pbBuffer[dwOffset++] = (BYTE) (dwExponent / 0x1000000);
529 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x1000000) / 0x10000);
530 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x10000) / 0x100);
531 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x100) / 0x1);
532
533 // hash using SHA1
534 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
535 {
536 dwReturn = GetLastError();
537 Trace(WINEVENT_LEVEL_ERROR, L"CryptAcquireContext 0x%08X", dwReturn);
538 __leave;
539 }
540 if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
541 {
542 dwReturn = GetLastError();
543 Trace(WINEVENT_LEVEL_ERROR, L"CryptCreateHash 0x%08X", dwReturn);
544 __leave;
545 }
546 if(!CryptHashData(hHash, pbBuffer, dwBufferSize, 0))
547 {
548 dwReturn = GetLastError();
549 Trace(WINEVENT_LEVEL_ERROR, L"CryptHashData 0x%08X", dwReturn);
550 __leave;
551 }
552 if(!CryptGetHashParam(hHash, HP_HASHVAL, pbCommand + 5, &dwHashLen, 0)) {
553 dwReturn = GetLastError();
554 Trace(WINEVENT_LEVEL_ERROR, L"CryptGetHashParam 0x%08X", dwReturn);
555 __leave;
556 }
557 pbCommand[3] = Containers[dwContainer].bSignatureTag;
558 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
559
560 }
561 __finally
562 {
563 if (pbBuffer)
564 pCardData->pfnCspFree(pbBuffer);
565 if(hHash)
566 CryptDestroyHash(hHash);
567 if(hProv)
568 CryptReleaseContext(hProv,0);
569
570 }
571 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
572 return dwReturn;
573
574 }
575
576 DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
577 {
578 DWORD dwReturn;
579 PBYTE pbData = NULL;
580 DWORD dwResponseSize = 0;
581 BYTE pbCmd[] = {0x00,
582 0x47,
583 0x81,
584 0x00,
585 0x00,
586 0x00,
587 0x02,
588 0x00,
589 0x00,
590 0x00,
591 0x00
592 };
593 DWORD dwCmdSize;
594 POPENPGP_CONTEXT pContext;
595 PBYTE pbModulus;
596 DWORD dwModulusSize, dwI;
597 PBYTE pbExponent;
598 PRSAPUBLICKEYBLOB pbBlob = NULL;
599 __try
600 {
601 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
602 if (dwContainer >= MaxContainer)
603 {
604 dwReturn = SCARD_E_NO_KEY_CONTAINER;
605 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
606 __leave;
607 }
608 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
609 pbCmd[7] = Containers[dwContainer].bKeyTag;
610 dwCmdSize = 9;
611 if (pContext->fExtentedLeLcFields)
612 {
613 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
614 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
615 }
616 else
617 {
618 pbCmd[dwCmdSize++] = 0xFF;
619 }
620
621 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
622 if (dwReturn)
623 {
624 __leave;
625 }
626 if (!find_tlv(pbData,0x81,&pbModulus,&dwModulusSize))
627 {
628 dwReturn = SCARD_E_UNEXPECTED;
629 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
630 __leave;
631 }
632 if (!find_tlv(pbData,0x82,(PBYTE*)&pbExponent,NULL))
633 {
634 dwReturn = SCARD_E_UNEXPECTED;
635 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
636 __leave;
637 }
638 Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSize * 8);
639 *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
640 *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
641 if (!*pbPublicKey)
642 {
643 dwReturn = SCARD_E_NO_MEMORY;
644 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY %d", dwContainer);
645 __leave;
646 }
647 pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey;
648 memset(pbBlob,0,*pdwPublicKeySize);
649 pbBlob->blobheader.bType = PUBLICKEYBLOB;
650 pbBlob->blobheader.bVersion = CUR_BLOB_VERSION;
651 pbBlob->blobheader.reserved = 0;
652 pbBlob->blobheader.aiKeyAlg = Containers[dwContainer].aiKeyAlg;
653 pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
654 pbBlob->rsapubkey.bitlen = dwModulusSize*8;
655 pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
656 // convert big endian into little endian
657 //memcpy(pbBlob->modulus, pbModulus, dwModulusSize);
658 for (dwI = 0; dwI < dwModulusSize; dwI++)
659 {
660 pbBlob->modulus[dwI] = pbModulus[dwModulusSize - 1 - dwI];
661 }
662
663 dwReturn = 0;
664 }
665 __finally
666 {
667 }
668 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
669 return dwReturn;
670 }
671
672 DWORD SCardCreateKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, DWORD dwBitLen)
673 {
674 DWORD dwReturn;
675 PBYTE pbData = NULL;
676 DWORD dwResponseSize = 0, dwCmdSize;
677 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
678 POPENPGP_CONTEXT pContext;
679 DWORD dwSecondsSince1970;
680 PBYTE pbModulus, pbExponent;
681 DWORD dwModulusSize, dwExponent;
682 BYTE pbCmd[] = {0x00,
683 0x47,
684 0x80,
685 0x00,
686 0x00,
687 0x00,
688 0x02,
689 0x00,
690 0x00,
691 0x00,
692 0x00
693 };
694 __try
695 {
696 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
697 if (dwContainer >= MaxContainer)
698 {
699 dwReturn = SCARD_E_NO_KEY_CONTAINER;
700 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
701 __leave;
702 }
703 // key len
704 dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
705 if (dwReturn == SCARD_E_FILE_NOT_FOUND)
706 {
707 Attributes.bAlgoId = 0x01;
708 Attributes.bFormat = 0;
709 Attributes.wExponentLength = 0x20;
710 }
711 else if (dwReturn)
712 {
713 __leave;
714 }
715 Attributes.wModulusLength = (WORD) dwBitLen;
716 dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
717 if (dwReturn)
718 {
719 __leave;
720 }
721
722 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
723 pbCmd[7] = Containers[dwContainer].bKeyTag;
724 dwCmdSize = 9;
725 if (pContext->fExtentedLeLcFields)
726 {
727 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
728 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
729 }
730 else
731 {
732 pbCmd[dwCmdSize++] = 0xFF;
733 }
734
735 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
736 if (dwReturn)
737 {
738 __leave;
739 }
740 if (!find_tlv(pbData,0x81,&pbModulus,&dwModulusSize))
741 {
742 dwReturn = SCARD_E_UNEXPECTED;
743 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
744 __leave;
745 }
746 if (!find_tlv(pbData,0x82,(PBYTE*)&pbExponent,NULL))
747 {
748 dwReturn = SCARD_E_UNEXPECTED;
749 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
750 __leave;
751 }
752 dwExponent = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
753 dwReturn = UpdateGenerationDateTime(pCardData, dwContainer, &dwSecondsSince1970);
754 if (dwReturn)
755 {
756 __leave;
757 }
758 dwReturn = UpdateFingerPrint(pCardData, dwContainer, dwSecondsSince1970,
759 pbModulus,
760 dwModulusSize * 8,
761 TRUE,
762 dwExponent
763 );
764 }
765 __finally
766 {
767 if (pbData)
768 pCardData->pfnCspFree(pbData);
769 }
770 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
771 return dwReturn;
772 }
773
774 DWORD SCardImportKey(PCARD_DATA pCardData,
775 OPENPGP_CONTAINER dwContainer,
776 PBYTE pBlob,
777 DWORD dwKeySize)
778 {
779 DWORD dwReturn;
780 PSTR szAlgorithmAttributes = NULL;
781 PBYTE pbTlv = NULL;
782 DWORD dwTlvSize;
783 PBYTE pbCommand = NULL;
784 DWORD dwCommandSize;
785 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
786 PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
787 BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
788 DWORD dwSecondsSince1970;
789 __try
790 {
791 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
792 // check blob
793 if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
794 pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
795 {
796 Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
797 dwReturn = SCARD_E_INVALID_PARAMETER;
798 __leave;
799 }
800 if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
801 {
802 Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
803 dwReturn = SCARD_E_INVALID_PARAMETER;
804 __leave;
805 }
806 if (pbPublicKeyBlob->rsapubkey.magic != 0x32415352)
807 {
808 Trace(WINEVENT_LEVEL_ERROR, L"Wrong magic");
809 dwReturn = SCARD_E_INVALID_PARAMETER;
810 __leave;
811 }
812
813 dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
814 if (dwReturn == SCARD_E_FILE_NOT_FOUND)
815 {
816 Attributes.bAlgoId = 0x01;
817 Attributes.bFormat = 0;
818 Attributes.wExponentLength = 0x20;
819 }
820 else if (dwReturn)
821 {
822 __leave;
823 }
824 Attributes.wModulusLength = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
825 dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
826 if (dwReturn)
827 {
828 __leave;
829 }
830 dwReturn = BuildPrivateKeyTlv(pCardData, pbPublicKeyBlob, dwContainer, Attributes.bFormat, &pbTlv, &dwTlvSize);
831 if (dwReturn)
832 {
833 __leave;
834 }
835 if (dwTlvSize > 0xFF)
836 {
837 dwCommandSize = 7 + dwTlvSize;
838
839 }
840 else
841 {
842 dwCommandSize = 5 + dwTlvSize;
843 }
844 pbCommand = pCardData->pfnCspAlloc(dwCommandSize);
845 if (!pbCommand)
846 {
847 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
848 dwReturn = SCARD_E_NO_MEMORY;
849 __leave;
850 }
851 memcpy(pbCommand, bCommand, 4);
852 if (dwTlvSize > 0xFF)
853 {
854 pbCommand[4] = 0;
855 pbCommand[5] = (BYTE)(dwTlvSize / 0x100);
856 pbCommand[6] = (BYTE)(dwTlvSize % 0x100);
857 memcpy(pbCommand + 7, pbTlv, dwTlvSize);
858 }
859 else
860 {
861 pbCommand[4] = (BYTE) dwTlvSize;
862 memcpy(pbCommand + 5, pbTlv, dwTlvSize);
863 }
864 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
865 if (dwReturn)
866 {
867 __leave;
868 }
869 dwReturn = UpdateGenerationDateTime(pCardData, dwContainer, &dwSecondsSince1970);
870 if (dwReturn)
871 {
872 __leave;
873 }
874 dwReturn = UpdateFingerPrint(pCardData, dwContainer, dwSecondsSince1970,
875 pbPublicKeyBlob->modulus,
876 pbPublicKeyBlob->rsapubkey.bitlen,
877 FALSE,
878 pbPublicKeyBlob->rsapubkey.pubexp
879 );
880 }
881 __finally
882 {
883 if (pbCommand)
884 {
885 SecureZeroMemory(pbCommand, dwCommandSize);
886 pCardData->pfnCspFree(pbCommand);
887 }
888 if (pbTlv)
889 {
890 SecureZeroMemory(pbTlv, dwTlvSize);
891 pCardData->pfnCspFree(pbTlv);
892 }
893 }
894 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
895 return dwReturn;
896 }
897
898 DWORD SCardSign(PCARD_DATA pCardData,
899 PCARD_SIGNING_INFO pInfo)
900 {
901 DWORD dwReturn;
902 PBYTE pbData = NULL;
903 DWORD dwCmdSize = 0, dwI;
904 POPENPGP_CONTEXT pContext;
905 BYTE pbCmd[6 + 256 + 256] = {0x00,
906 0x2A,
907 0x9E,
908 0x9A,
909 0x00,
910 0x00,
911 };
912 __try
913 {
914 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
915 if (pInfo->bContainerIndex != Signature)
916 {
917 dwReturn = SCARD_E_NO_KEY_CONTAINER;
918 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
919 __leave;
920 }
921 if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
922 {
923 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
924 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
925 __leave;
926 }
927 else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
928 {
929 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
930 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
931 __leave;
932 }
933 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
934 {
935 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
936 {
937 // found
938 break;
939 }
940 }
941 if (dwI >= dwSignatureAlgorithmCount)
942 {
943 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
944 __leave;
945 }
946 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
947 {
948 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
949 __leave;
950 }
951 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
952
953 dwCmdSize = 5;
954 if (pContext->fExtentedLeLcFields)
955 {
956 dwCmdSize++;
957 }
958 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
959 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
960 dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
961 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
962 {
963 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
964 }*/
965 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
966 dwCmdSize += pInfo->cbData;
967
968
969 if (pContext->fExtentedLeLcFields)
970 {
971 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
972 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
973 }
974 else
975 {
976 pbCmd[dwCmdSize++] = 0;
977 }
978 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
979 if (dwReturn == SCARD_W_WRONG_CHV)
980 {
981 dwReturn = SCARD_W_SECURITY_VIOLATION;
982 __leave;
983 }
984 if (dwReturn)
985 {
986 __leave;
987 }
988 // revert the BYTES
989 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
990 {
991 BYTE bTemp = pInfo->pbSignedData[dwI];
992 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
993 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
994 }
995 }
996 __finally
997 {
998 if (dwReturn)
999 {
1000 if (pInfo->pbSignedData)
1001 pCardData->pfnCspFree(pInfo->pbSignedData);
1002 }
1003 }
1004 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1005 return dwReturn;
1006 }
1007
1008 DWORD SCardAuthenticate(PCARD_DATA pCardData,
1009 PCARD_SIGNING_INFO pInfo)
1010 {
1011 DWORD dwReturn;
1012 PBYTE pbData = NULL;
1013 DWORD dwCmdSize = 0, dwI;
1014 POPENPGP_CONTEXT pContext;
1015 BYTE pbCmd[6 + 256 + 256] = {0x00,
1016 0x88,
1017 0x00,
1018 0x00,
1019 0x00,
1020 0x00,
1021 };
1022 __try
1023 {
1024 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1025 if (pInfo->bContainerIndex != Authentication)
1026 {
1027 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1028 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1029 __leave;
1030 }
1031 if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
1032 {
1033 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1034 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
1035 __leave;
1036 }
1037 else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
1038 {
1039 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1040 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
1041 __leave;
1042 }
1043 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
1044 {
1045 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
1046 {
1047 // found
1048 break;
1049 }
1050 }
1051 if (dwI >= dwSignatureAlgorithmCount)
1052 {
1053 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
1054 __leave;
1055 }
1056 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
1057 {
1058 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
1059 __leave;
1060 }
1061 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1062
1063 dwCmdSize = 5;
1064 if (pContext->fExtentedLeLcFields)
1065 {
1066 dwCmdSize++;
1067 }
1068 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
1069 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
1070 dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
1071 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
1072 {
1073 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
1074 }*/
1075 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1076 dwCmdSize += pInfo->cbData;
1077
1078
1079 if (pContext->fExtentedLeLcFields)
1080 {
1081 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
1082 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
1083 }
1084 else
1085 {
1086 pbCmd[dwCmdSize++] = 0;
1087 }
1088 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
1089 if (dwReturn == SCARD_W_WRONG_CHV)
1090 {
1091 dwReturn = SCARD_W_SECURITY_VIOLATION;
1092 __leave;
1093 }
1094 if (dwReturn)
1095 {
1096 __leave;
1097 }
1098 // revert the BYTES
1099 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
1100 {
1101 BYTE bTemp = pInfo->pbSignedData[dwI];
1102 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
1103 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
1104 }
1105 }
1106 __finally
1107 {
1108 if (dwReturn)
1109 {
1110 if (pInfo->pbSignedData)
1111 pCardData->pfnCspFree(pInfo->pbSignedData);
1112 }
1113 }
1114 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1115 return dwReturn;
1116 }
1117
1118 DWORD SCardDecrypt(PCARD_DATA pCardData,
1119 PCARD_RSA_DECRYPT_INFO pInfo)
1120 {
1121 DWORD dwReturn;
1122 PBYTE pbData = NULL;
1123 DWORD dwCmdSize = 0, dwResponseSize;
1124 BYTE pbCmd[6 + 256 + 256] = {0x00,
1125 0x2A,
1126 0x80,
1127 0x86,
1128 0x00,
1129 };
1130 POPENPGP_CONTEXT pContext;
1131 DWORD dwI;
1132 __try
1133 {
1134 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1135 if (pInfo->bContainerIndex >= MaxContainer)
1136 {
1137 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1138 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1139 __leave;
1140 }
1141 if (pInfo->bContainerIndex != Confidentiality)
1142 {
1143 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1144 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1145 __leave;
1146 }
1147 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1148 dwCmdSize = 5;
1149 if (pContext->fExtentedLeLcFields)
1150 {
1151 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
1152 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1153 }
1154 else
1155 {
1156 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1157 }
1158 pbCmd[dwCmdSize++] = 0;
1159 //little endian => big endian
1160 for(dwI = 0; dwI < pInfo->cbData; dwI++)
1161 {
1162 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData -1 -dwI];
1163 }
1164 dwCmdSize += pInfo->cbData;
1165 if (pContext->fExtentedLeLcFields)
1166 {
1167 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
1168 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
1169 }
1170 else
1171 {
1172 pbCmd[dwCmdSize++] = 0;
1173 }
1174 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
1175 if (dwReturn)
1176 {
1177 __leave;
1178 }
1179
1180 // CryptDecrypt expects the data decrypted using rsa (only the mathematical computation)
1181 // this means the data with the padding (removed by the card)
1182 // and in little endian (while the card return the data in big endian)
1183 // so we rebuilt the padding in reverse order
1184
1185 if ( pInfo->cbData < dwResponseSize + 3 + 11)
1186 {
1187 dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
1188 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
1189 __leave;
1190 }
1191
1192 pInfo->pbData[pInfo->cbData - 1] = 0; // start byte
1193 pInfo->pbData[pInfo->cbData - 2] = 02; // block type
1194 // padding
1195 memset(pInfo->pbData + dwResponseSize + 1,1,pInfo->cbData - 3 - dwResponseSize);
1196 pInfo->pbData[dwResponseSize] = 0; // separator
1197 // data field in reverse order
1198 for(dwI = 0; dwI < dwResponseSize; dwI++)
1199 {
1200 pInfo->pbData[dwI] = pbData[dwResponseSize - 1 - dwI];
1201 }
1202 }
1203 __finally
1204 {
1205 if (pbData)
1206 {
1207 SecureZeroMemory(pbData, dwResponseSize);
1208 pCardData->pfnCspFree(pbData);
1209 }
1210 }
1211 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1212 return dwReturn;
1213 }
1214
1215
1216 DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
1217 {
1218 DWORD dwReturn=0;
1219 __try
1220 {
1221 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
1222 switch(dwPinIndex)
1223 {
1224 case ROLE_SIGNATURE:
1225 pPinInfo->PinType = AlphaNumericPinType;
1226 pPinInfo->PinPurpose = DigitalSignaturePin;
1227 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1228 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1229 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1230 break;
1231 case ROLE_AUTHENTICATION:
1232 pPinInfo->PinType = AlphaNumericPinType;
1233 pPinInfo->PinPurpose = AuthenticationPin;
1234 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1235 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1236 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1237 break;
1238 case ROLE_CONFIDENTIALITY:
1239 pPinInfo->PinType = AlphaNumericPinType;
1240 pPinInfo->PinPurpose = EncryptionPin;
1241 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1242 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1243 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1244 break;
1245 default:
1246 Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
1247 dwReturn = SCARD_E_INVALID_PARAMETER ;
1248 __leave;
1249 }
1250 }
1251 __finally
1252 {
1253 }
1254 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1255 return dwReturn;
1256 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26