26 |
|
|
27 |
OPENPGP_CONTAINER_INFO Containers[] = |
OPENPGP_CONTAINER_INFO Containers[] = |
28 |
{ |
{ |
29 |
{0xB6, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_SIGNATURE}, |
{0xB6, 0xCE, 0xC7, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_SIGNATURE}, |
30 |
{0xA4, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_AUTHENTICATION}, |
{0xA4, 0xD0, 0xC9, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_AUTHENTICATION}, |
31 |
{0xB8, CALG_RSA_KEYX, AT_KEYEXCHANGE, ROLE_CONFIDENTIALITY} |
{0xB8, 0xCF, 0xC8, CALG_RSA_KEYX, AT_KEYEXCHANGE, ROLE_CONFIDENTIALITY} |
32 |
|
|
33 |
}; |
}; |
34 |
|
|
281 |
DWORD dwReturn = 0; |
DWORD dwReturn = 0; |
282 |
|
|
283 |
DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen; |
DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen; |
284 |
PBYTE pbPublicKeyData = (PBYTE) pbPublicKeyBlob + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY); |
PBYTE pbPublicKeyData = (PBYTE) &(pbPublicKeyBlob->modulus); |
285 |
// 7F48 len is < 7F so its encoded len is 1 bytes |
// 7F48 len is < 7F so its encoded len is 1 bytes |
286 |
// 3 bytes max + length * 7 potential plv |
// 3 bytes max + length * 7 potential plv |
287 |
BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48}; |
BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48}; |
290 |
DWORD dwOffset = 0; |
DWORD dwOffset = 0; |
291 |
DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize; |
DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize; |
292 |
DWORD dwKeyDataSize, dwExtendedHeaderListSize; |
DWORD dwKeyDataSize, dwExtendedHeaderListSize; |
293 |
|
DWORD dwI; |
294 |
__try |
__try |
295 |
{ |
{ |
296 |
// build the 7F48 header + the data into a buffer |
// build the 7F48 header + the data into a buffer |
352 |
memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize); |
memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize); |
353 |
dwOffset += dw4DHeaderSize; |
dwOffset += dw4DHeaderSize; |
354 |
// control reference templace |
// control reference templace |
355 |
(*ppbTlv)[dwOffset++] = Containers[dwContainer].Tag; |
(*ppbTlv)[dwOffset++] = Containers[dwContainer].bKeyTag; |
356 |
(*ppbTlv)[dwOffset++] = 0; |
(*ppbTlv)[dwOffset++] = 0; |
357 |
// cardholder private key template |
// cardholder private key template |
358 |
memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize); |
memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize); |
361 |
memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize); |
memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize); |
362 |
dwOffset += dw5F48HeaderSize; |
dwOffset += dw5F48HeaderSize; |
363 |
// Concatenation of key data |
// Concatenation of key data |
364 |
// exponent in little endian |
// exponent little => big endian |
365 |
(*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000); |
(*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000); |
366 |
(*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000); |
(*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000); |
367 |
(*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100); |
(*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100); |
368 |
(*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1); |
(*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1); |
369 |
// prime1 |
// prime1 |
370 |
memcpy(*ppbTlv + dwOffset, pbPublicKeyData + bitlen/8 , bitlen / 16); |
//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; |
dwOffset += bitlen / 16; |
377 |
|
|
378 |
// prime2 |
// prime2 |
379 |
memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1) * bitlen / 16 , bitlen / 16); |
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; |
dwOffset += bitlen / 16; |
386 |
if (bFormat & 2) |
if (bFormat & 2) |
387 |
{ |
{ |
388 |
// coeff |
// coeff |
389 |
memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 3) * bitlen / 16 , bitlen / 16); |
//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; |
dwOffset += bitlen / 16; |
395 |
// exponent1 |
// exponent1 |
396 |
memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 1) * bitlen / 16 , bitlen / 16); |
//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; |
dwOffset += bitlen / 16; |
402 |
// exponent2 |
// exponent2 |
403 |
memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 2) * bitlen / 16 , bitlen / 16); |
//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; |
dwOffset += bitlen / 16; |
409 |
} |
} |
410 |
if (bFormat & 1) |
if (bFormat & 1) |
411 |
{ |
{ |
412 |
// modulus |
// modulus |
413 |
memcpy(*ppbTlv + dwOffset, pbPublicKeyData, bitlen / 8); |
//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 |
__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; |
return dwReturn; |
571 |
|
|
572 |
} |
} |
573 |
|
|
574 |
DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize) |
DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize) |
591 |
DWORD dwCmdSize; |
DWORD dwCmdSize; |
592 |
POPENPGP_CONTEXT pContext; |
POPENPGP_CONTEXT pContext; |
593 |
PBYTE pbModulus; |
PBYTE pbModulus; |
594 |
DWORD dwModulusSize; |
DWORD dwModulusSize, dwI; |
595 |
PBYTE pbExponent; |
PBYTE pbExponent; |
596 |
PRSAPUBLICKEYBLOB pbBlob = NULL; |
PRSAPUBLICKEYBLOB pbBlob = NULL; |
597 |
__try |
__try |
604 |
__leave; |
__leave; |
605 |
} |
} |
606 |
pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific; |
pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific; |
607 |
pbCmd[7] = Containers[dwContainer].Tag; |
pbCmd[7] = Containers[dwContainer].bKeyTag; |
608 |
dwCmdSize = 9; |
dwCmdSize = 9; |
609 |
if (pContext->fExtentedLeLcFields) |
if (pContext->fExtentedLeLcFields) |
610 |
{ |
{ |
634 |
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81"); |
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81"); |
635 |
__leave; |
__leave; |
636 |
} |
} |
637 |
|
Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSize * 8); |
638 |
*pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD); |
*pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD); |
639 |
*pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize); |
*pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize); |
640 |
if (!*pbPublicKey) |
if (!*pbPublicKey) |
641 |
{ |
{ |
642 |
dwReturn = SCARD_E_NO_MEMORY; |
dwReturn = SCARD_E_NO_MEMORY; |
643 |
Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_MEMORY %d", dwContainer); |
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY %d", dwContainer); |
644 |
__leave; |
__leave; |
645 |
} |
} |
646 |
pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey; |
pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey; |
652 |
pbBlob->rsapubkey.magic = 0x31415352; //'RSA1'; |
pbBlob->rsapubkey.magic = 0x31415352; //'RSA1'; |
653 |
pbBlob->rsapubkey.bitlen = dwModulusSize*8; |
pbBlob->rsapubkey.bitlen = dwModulusSize*8; |
654 |
pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3]; |
pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3]; |
655 |
memcpy(pbBlob->modulus, pbModulus, dwModulusSize); |
// convert big endian into little endian |
656 |
//TraceDump(WINEVENT_LEVEL_INFO, (PBYTE) pbBlob,*pdwPublicKeySize); |
//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; |
dwReturn = 0; |
664 |
} |
} |
665 |
__finally |
__finally |
675 |
DWORD dwResponseSize = 0, dwCmdSize; |
DWORD dwResponseSize = 0, dwCmdSize; |
676 |
OPENPGP_ALGORITHM_ATTRIBUTE Attributes; |
OPENPGP_ALGORITHM_ATTRIBUTE Attributes; |
677 |
POPENPGP_CONTEXT pContext; |
POPENPGP_CONTEXT pContext; |
678 |
|
DWORD dwSecondsSince1970; |
679 |
|
PBYTE pbModulus, pbExponent; |
680 |
|
DWORD dwModulusSize, dwExponent; |
681 |
BYTE pbCmd[] = {0x00, |
BYTE pbCmd[] = {0x00, |
682 |
0x47, |
0x47, |
683 |
0x80, |
0x80, |
719 |
} |
} |
720 |
|
|
721 |
pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific; |
pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific; |
722 |
pbCmd[7] = Containers[dwContainer].Tag; |
pbCmd[7] = Containers[dwContainer].bKeyTag; |
723 |
dwCmdSize = 9; |
dwCmdSize = 9; |
724 |
if (pContext->fExtentedLeLcFields) |
if (pContext->fExtentedLeLcFields) |
725 |
{ |
{ |
736 |
{ |
{ |
737 |
__leave; |
__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 |
__finally |
765 |
{ |
{ |
783 |
OPENPGP_ALGORITHM_ATTRIBUTE Attributes; |
OPENPGP_ALGORITHM_ATTRIBUTE Attributes; |
784 |
PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob; |
PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob; |
785 |
BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF}; |
BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF}; |
786 |
|
DWORD dwSecondsSince1970; |
787 |
__try |
__try |
788 |
{ |
{ |
789 |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer); |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer); |
865 |
{ |
{ |
866 |
__leave; |
__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 |
__finally |
881 |
{ |
{ |
962 |
pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData); |
pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData); |
963 |
memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize); |
memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize); |
964 |
dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize; |
dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize; |
965 |
for(dwI = 0 ; dwI < pInfo->cbData ; dwI++) |
/*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++) |
966 |
{ |
{ |
967 |
pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1]; |
pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1]; |
968 |
} |
}*/ |
969 |
//memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData); |
memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData); |
970 |
dwCmdSize += pInfo->cbData; |
dwCmdSize += pInfo->cbData; |
971 |
|
|
972 |
|
|
996 |
pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI]; |
pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI]; |
997 |
pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp; |
pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp; |
998 |
} |
} |
999 |
TraceDump(WINEVENT_LEVEL_ERROR,pInfo->pbSignedData,pInfo->cbSignedData); |
//TraceDump(WINEVENT_LEVEL_ERROR,pInfo->pbSignedData,pInfo->cbSignedData); |
1000 |
} |
} |
1001 |
__finally |
__finally |
1002 |
{ |
{ |
1022 |
0x00, |
0x00, |
1023 |
}; |
}; |
1024 |
POPENPGP_CONTEXT pContext; |
POPENPGP_CONTEXT pContext; |
1025 |
|
DWORD dwI; |
1026 |
__try |
__try |
1027 |
{ |
{ |
1028 |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex); |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex); |
1050 |
pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100); |
pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100); |
1051 |
} |
} |
1052 |
pbCmd[dwCmdSize++] = 0; |
pbCmd[dwCmdSize++] = 0; |
1053 |
memcpy(pbCmd + dwCmdSize, pInfo->pbData, pInfo->cbData); |
//memcpy(pbCmd + dwCmdSize, pInfo->pbData, pInfo->cbData); |
1054 |
|
for(dwI = 0; dwI < pInfo->cbData; dwI++) |
1055 |
|
{ |
1056 |
|
pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData -1 -dwI]; |
1057 |
|
} |
1058 |
dwCmdSize += pInfo->cbData; |
dwCmdSize += pInfo->cbData; |
1059 |
if (pContext->fExtentedLeLcFields) |
if (pContext->fExtentedLeLcFields) |
1060 |
{ |
{ |
1082 |
__finally |
__finally |
1083 |
{ |
{ |
1084 |
if (pbData) |
if (pbData) |
1085 |
|
{ |
1086 |
|
SecureZeroMemory(pbData, dwResponseSize); |
1087 |
pCardData->pfnCspFree(pbData); |
pCardData->pfnCspFree(pbData); |
1088 |
|
} |
1089 |
} |
} |
1090 |
return dwReturn; |
return dwReturn; |
1091 |
} |
} |