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

Diff of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 9 by vletoux, Mon Mar 15 09:47:30 2010 UTC revision 10 by vletoux, Mon Mar 15 18:23:17 2010 UTC
# Line 29  Line 29 
29  OPENPGP_KEY_INFO Keys[] =  OPENPGP_KEY_INFO Keys[] =
30  {  {
31          {0xB6, 0xCE, 0xC7, CALG_RSA_SIGN}, // signature          {0xB6, 0xCE, 0xC7, CALG_RSA_SIGN}, // signature
32          {0xA4, 0xD0, 0xC9, CALG_RSA_SIGN}, // authentication          {0xB8, 0xCF, 0xC8, CALG_RSA_KEYX}, // confidentiality
33          {0xB8, 0xCF, 0xC8, CALG_RSA_KEYX}  // confidentiality          {0xA4, 0xD0, 0xC9, CALG_RSA_SIGN}  // authentication
34  };  };
35    
36  OPENPGP_CONTAINER_INFO Containers[] =  OPENPGP_CONTAINER_INFO Containers[] =
37  {  {
38          {ROLE_SIGNATURE, AT_SIGNATURE},          {ROLE_SIGNATURE, AT_SIGNATURE},
39          {ROLE_AUTHENTICATION, AT_SIGNATURE},          {ROLE_CONFIDENTIALITY, AT_KEYEXCHANGE},
40          {ROLE_CONFIDENTIALITY, AT_KEYEXCHANGE}          {ROLE_AUTHENTICATION, AT_SIGNATURE}
41  };  };
42  typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM  typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM
43  {  {
# Line 57  BYTE dwSHA384EncodedOid[] = {0x30, 0x41, Line 57  BYTE dwSHA384EncodedOid[] = {0x30, 0x41,
57  BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,  BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
58                          0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};                          0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
59    
60    #define OPENPGP_NO_OID 0xFFFFFFFF
61  OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =  OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =
62  {  {
63          {CALG_SHA1,20,          {CALG_SHA1,20,
# Line 103  DWORD OCardGetKeyAlgorithmAttributes(__i Line 104  DWORD OCardGetKeyAlgorithmAttributes(__i
104                          szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;                          szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
105                          break;                          break;
106                  case KeyAuthentication:                  case KeyAuthentication:
107                          szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;                          szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
108                          break;                          break;
109                  case KeyConfidentiality:                  case KeyConfidentiality:
110                          szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;                          szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
111                          break;                          break;
112                  default:                  default:
113                          dwReturn = SCARD_E_NO_KEY_CONTAINER;                          dwReturn = SCARD_E_NO_KEY_CONTAINER;
# Line 159  DWORD OCardSetKeyAlgorithmAttributes(__i Line 160  DWORD OCardSetKeyAlgorithmAttributes(__i
160                          szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;                          szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
161                          break;                          break;
162                  case KeyAuthentication:                  case KeyAuthentication:
163                          szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;                          szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
164                          break;                          break;
165                  case KeyConfidentiality:                  case KeyConfidentiality:
166                          szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;                          szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
167                          break;                          break;
168                  default:                  default:
169                          dwReturn = SCARD_E_NO_KEY_CONTAINER;                          dwReturn = SCARD_E_NO_KEY_CONTAINER;
# Line 185  DWORD OCardSetKeyAlgorithmAttributes(__i Line 186  DWORD OCardSetKeyAlgorithmAttributes(__i
186          __finally          __finally
187          {          {
188          }          }
189          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
190          return dwReturn;          return dwReturn;
191  }  }
192    
# Line 370  DWORD BuildPrivateKeyTlv(__in PCARD_DATA Line 371  DWORD BuildPrivateKeyTlv(__in PCARD_DATA
371          __finally          __finally
372          {          {
373          }          }
374          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d", dwReturn, dwKey);
375          return dwReturn;          return dwReturn;
376  }  }
377    
378  DWORD UpdateGenerationDateTime(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,  DWORD CreateGenerationDateTime(__in PCARD_DATA pCardData,
379                                                             __out PDWORD pdwSecondsSince1970)                                                             __out PDWORD pdwSecondsSince1970)
380  {  {
         DWORD dwReturn = 0;  
381          LARGE_INTEGER UnixZeroTime = {0}, WindowsTime;          LARGE_INTEGER UnixZeroTime = {0}, WindowsTime;
382          SYSTEMTIME WindowsSystemTime;          SYSTEMTIME WindowsSystemTime;
383          FILETIME WindowsFileTime;          FILETIME WindowsFileTime;
384            UnixZeroTime.QuadPart = 116444736000000000I64; // january 1st 1970
385            GetSystemTime(&WindowsSystemTime);
386            SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
387            /* It is not recommended that you add and subtract values from the FILETIME
388            structure to obtain relative times. Instead, you should copy the low- and high-order
389            parts of the file time to a ULARGE_INTEGER  structure, perform 64-bit arithmetic
390            on the QuadPart member, and copy the LowPart and HighPart  members into the
391            FILETIME structure.
392    
393            Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER*
394            or __int64* value because it can cause alignment faults on 64-bit Windows.
395            */
396            WindowsTime.HighPart = WindowsFileTime.dwHighDateTime;
397            WindowsTime.LowPart = WindowsFileTime.dwLowDateTime;
398            *pdwSecondsSince1970 = (DWORD)((WindowsTime.QuadPart - UnixZeroTime.QuadPart) / 10000000);
399            return 0;
400    }
401    
402    
403    DWORD UpdateGenerationDateTime(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
404                                                               __out DWORD dwSecondsSince1970)
405    {
406            DWORD dwReturn = 0;
407            
408          BYTE pbCommand[] = {0x00, 0xDA, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};          BYTE pbCommand[] = {0x00, 0xDA, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
409          DWORD dwCommandSize = ARRAYSIZE(pbCommand);          DWORD dwCommandSize = ARRAYSIZE(pbCommand);
410          __try          __try
411          {          {
412                  UnixZeroTime.QuadPart = 116444736000000000I64; // january 1st 1970                  
                 GetSystemTime(&WindowsSystemTime);  
                 SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);  
                 /* It is not recommended that you add and subtract values from the FILETIME  
                 structure to obtain relative times. Instead, you should copy the low- and high-order  
                 parts of the file time to a ULARGE_INTEGER  structure, perform 64-bit arithmetic  
                 on the QuadPart member, and copy the LowPart and HighPart  members into the  
                 FILETIME structure.  
   
                 Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER*  
                 or __int64* value because it can cause alignment faults on 64-bit Windows.  
                 */  
                 WindowsTime.HighPart = WindowsFileTime.dwHighDateTime;  
                 WindowsTime.LowPart = WindowsFileTime.dwLowDateTime;  
                 *pdwSecondsSince1970 = (DWORD)((WindowsTime.QuadPart - UnixZeroTime.QuadPart) / 10000000);  
413                                    
414                  pbCommand[3] = Keys[dwKey].bDateTimeTag;                  pbCommand[3] = Keys[dwKey].bDateTimeTag;
415                  pbCommand[5] = (BYTE) (*pdwSecondsSince1970 / 0x1000000);                  pbCommand[5] = (BYTE) (dwSecondsSince1970 / 0x1000000);
416                  pbCommand[6] = (BYTE) ((*pdwSecondsSince1970 % 0x1000000) / 0x10000);                  pbCommand[6] = (BYTE) ((dwSecondsSince1970 % 0x1000000) / 0x10000);
417                  pbCommand[7] = (BYTE) ((*pdwSecondsSince1970 % 0x10000) / 0x100);                  pbCommand[7] = (BYTE) ((dwSecondsSince1970 % 0x10000) / 0x100);
418                  pbCommand[8] = (BYTE) ((*pdwSecondsSince1970 % 0x100) / 0x1);                  pbCommand[8] = (BYTE) ((dwSecondsSince1970 % 0x100) / 0x1);
419                  dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);                  dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
420          }          }
421          __finally          __finally
422          {          {
423          }          }
424          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn,dwKey);
425          return dwReturn;          return dwReturn;
426  }  }
427    
428  DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,  DWORD CreateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
429                                                  __in DWORD dwSecondsSince1970,                                                  __in DWORD dwSecondsSince1970,
430                                                  __in PBYTE pbModulus, __in DWORD dwModulusSizeInBit,                                                  __inout BYTE pbFingerPrint[20])
                                                 __in BOOL fIsModulusInBigEndian,  
                                                 __in DWORD dwExponent)  
431  {  {
432          // modulus in input are in big endian          // modulus in input are in big endian
433          // rfc4880 12.2          // rfc4880 12.2
# Line 429  DWORD UpdateFingerPrint(__in PCARD_DATA Line 437  DWORD UpdateFingerPrint(__in PCARD_DATA
437          DWORD dwOffset = 0;          DWORD dwOffset = 0;
438          HCRYPTPROV hProv = 0;          HCRYPTPROV hProv = 0;
439          HCRYPTHASH hHash = 0;          HCRYPTHASH hHash = 0;
440          BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
441          DWORD dwCommandSize = ARRAYSIZE(pbCommand);          DWORD dwHashLen = 0x14, dwModulusSizeInBytes, dwModulusSizeInBit, dwExponent;
442          DWORD dwHashLen = 0x14;          DWORD dwI;
443          __try          __try
444          {          {
445                  dwBufferSize = dwModulusSizeInBit / 8 + sizeof(DWORD) + 10  + 3;                  dwModulusSizeInBytes = pContext->dwModulusSizeInBytes[dwKey];
446                    dwModulusSizeInBit = dwModulusSizeInBytes * 8;
447                    dwExponent = pContext->dwExponent[dwKey];
448                    dwBufferSize = dwModulusSizeInBytes + sizeof(DWORD) + 10  + 3;
449                  pbBuffer = (PBYTE) pCardData->pfnCspAlloc(dwBufferSize);                  pbBuffer = (PBYTE) pCardData->pfnCspAlloc(dwBufferSize);
450                  if (!pbBuffer)                  if (!pbBuffer)
451                  {                  {
# Line 442  DWORD UpdateFingerPrint(__in PCARD_DATA Line 453  DWORD UpdateFingerPrint(__in PCARD_DATA
453                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
454                          __leave;                          __leave;
455                  }                  }
456                    
457                  pbBuffer[dwOffset++] = 0x99;                  pbBuffer[dwOffset++] = 0x99;
458                  // -3 because of the header size                  // -3 because of the header size
459                  pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) / 0x100);                  pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) / 0x100);
# Line 459  DWORD UpdateFingerPrint(__in PCARD_DATA Line 471  DWORD UpdateFingerPrint(__in PCARD_DATA
471                  // size of modulus                  // size of modulus
472                  pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x10000) / 0x100);                  pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x10000) / 0x100);
473                  pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x100) / 0x1);                  pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x100) / 0x1);
474                  if (fIsModulusInBigEndian)                  // little endian => big endian
475                  {                  for(dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
                         memcpy(pbBuffer + dwOffset, pbModulus, dwModulusSizeInBit / 8);  
                 }  
                 else  
476                  {                  {
477                          DWORD dwI;                          pbBuffer[dwOffset + dwI] = pContext->pbModulusInLittleEndian[dwKey][dwModulusSizeInBytes - 1 - dwI];
                         for(dwI = 0; dwI < dwModulusSizeInBit / 8; dwI++)  
                         {  
                                 pbBuffer[dwOffset + dwI] = pbModulus[dwModulusSizeInBit / 8 - 1 - dwI];  
                         }  
478                  }                  }
479                  // size of exponent                  // size of exponent
480                  pbBuffer[dwOffset++] = 0;                  pbBuffer[dwOffset++] = 0;
# Line 499  DWORD UpdateFingerPrint(__in PCARD_DATA Line 504  DWORD UpdateFingerPrint(__in PCARD_DATA
504                          Trace(WINEVENT_LEVEL_ERROR, L"CryptHashData 0x%08X", dwReturn);                          Trace(WINEVENT_LEVEL_ERROR, L"CryptHashData 0x%08X", dwReturn);
505                          __leave;                          __leave;
506                  }                  }
507                  if(!CryptGetHashParam(hHash, HP_HASHVAL, pbCommand + 5, &dwHashLen, 0)) {                  if(!CryptGetHashParam(hHash, HP_HASHVAL, pbFingerPrint, &dwHashLen, 0)) {
508                          dwReturn = GetLastError();                          dwReturn = GetLastError();
509                          Trace(WINEVENT_LEVEL_ERROR, L"CryptGetHashParam 0x%08X", dwReturn);                          Trace(WINEVENT_LEVEL_ERROR, L"CryptGetHashParam 0x%08X", dwReturn);
510                          __leave;                          __leave;
511                  }                  }
512                  pbCommand[3] = Keys[dwKey].bSignatureTag;                  
                 dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);  
513    
514          }          }
515          __finally          __finally
# Line 518  DWORD UpdateFingerPrint(__in PCARD_DATA Line 522  DWORD UpdateFingerPrint(__in PCARD_DATA
522                          CryptReleaseContext(hProv,0);                          CryptReleaseContext(hProv,0);
523    
524          }          }
525          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
526          return dwReturn;          return dwReturn;
527    
528  }  }
529    
530  DWORD OCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_KEY dwKey, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)  DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey,
531                                                    __inout BYTE pbFingerPrint[20])
532    {
533            BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};
534            DWORD dwCommandSize = ARRAYSIZE(pbCommand), dwReturn;
535            __try
536            {
537                    pbCommand[3] = Keys[dwKey].bSignatureTag;
538                    memcpy(pbCommand + 5, pbFingerPrint, 20);
539                    dwReturn = OCardSendCommand(pCardData, pbCommand, dwCommandSize);
540            }
541            __finally
542            {
543            }
544            Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn,dwKey);
545            return dwReturn;
546    }
547    DWORD OCardUpdateCachedPublicKey(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey)
548  {  {
         DWORD dwReturn;  
549          PBYTE pbData = NULL;          PBYTE pbData = NULL;
550          DWORD dwResponseSize = 0;          DWORD dwResponseSize = 0, dwReturn;
551          BYTE pbCmd[] = {0x00,          BYTE pbCmd[] = {0x00,
552                                      0x47,                                      0x47,
553                                          0x81,                                          0x81,
# Line 541  DWORD OCardReadPublicKey(PCARD_DATA pCar Line 561  DWORD OCardReadPublicKey(PCARD_DATA pCar
561                                          0x00                                          0x00
562                                          };                                          };
563          DWORD dwCmdSize;          DWORD dwCmdSize;
564          POPENPGP_CONTEXT pContext;          DWORD dwTotalTlvSize, dwOffset;
565            DWORD dwModulusSizeInBytes;
566          PBYTE pbModulus;          PBYTE pbModulus;
567          DWORD dwModulusSize, dwI;          DWORD dwI;
568          PBYTE pbExponent;          PBYTE pbExponent;
569          PRSAPUBLICKEYBLOB pbBlob = NULL;          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
         DWORD dwTotalTlvSize, dwOffset;  
570          __try          __try
571          {          {
572                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
# Line 556  DWORD OCardReadPublicKey(PCARD_DATA pCar Line 576  DWORD OCardReadPublicKey(PCARD_DATA pCar
576                          Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);                          Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
577                          __leave;                          __leave;
578                  }                  }
579                  pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;                  if (pContext->pbModulusInLittleEndian[dwKey] != NULL)
580                    {
581                            pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
582                            pContext->pbModulusInLittleEndian[dwKey] = NULL;
583                    }
584                  pbCmd[7] = Keys[dwKey].bKeyTag;                  pbCmd[7] = Keys[dwKey].bKeyTag;
585                  dwCmdSize = 9;                  dwCmdSize = 9;
586                  if (pContext->fExtentedLeLcFields)                  if (pContext->fExtentedLeLcFields)
# Line 576  DWORD OCardReadPublicKey(PCARD_DATA pCar Line 600  DWORD OCardReadPublicKey(PCARD_DATA pCar
600                  }                  }
601                  dwOffset = 2;                  dwOffset = 2;
602                  dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;                  dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
603                  if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize,&pbModulus,&dwModulusSize))                  if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize,&pbModulus,&dwModulusSizeInBytes))
604                  {                  {
605                          dwReturn = SCARD_E_UNEXPECTED;                          dwReturn = SCARD_E_UNEXPECTED;
606                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
# Line 588  DWORD OCardReadPublicKey(PCARD_DATA pCar Line 612  DWORD OCardReadPublicKey(PCARD_DATA pCar
612                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
613                          __leave;                          __leave;
614                  }                  }
615                  Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSize * 8);                  Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSizeInBytes * 8);
616                  *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);                  
617                    pContext->dwExponent[dwKey] = pbExponent[0] * 0x1000000  + pbExponent[1] * 0x10000  + pbExponent[2] * 0x100 + pbExponent[3];
618                    pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(dwModulusSizeInBytes);
619                    if (!pContext->pbModulusInLittleEndian[dwKey])
620                    {
621                            dwReturn = SCARD_E_NO_MEMORY;
622                            Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_MEMORY");
623                            __leave;
624                    }
625                    // convert big endian into little endian
626                    for (dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
627                    {
628                            pContext->pbModulusInLittleEndian[dwKey][dwI] = pbModulus[dwModulusSizeInBytes - 1 - dwI];
629                    }
630                    pContext->dwModulusSizeInBytes[dwKey] = (WORD) dwModulusSizeInBytes;
631                    dwReturn = 0;
632            }
633            __finally
634            {
635                    if (pbData)
636                            pCardData->pfnCspFree(pbData);
637            }
638            Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
639            return dwReturn;
640    }
641    
642    DWORD OCardUpdateCachedPublicKeyIfNeeded(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey)
643    {
644            PBYTE pbFingerPrint = NULL;
645            DWORD dwFingerPrintSize, dwReturn;
646            BOOL fHasToUpdateTheCache;
647            POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
648            LARGE_INTEGER Now;
649            SYSTEMTIME WindowsSystemTime;
650            FILETIME WindowsFileTime;
651            __try
652            {
653                    GetSystemTime(&WindowsSystemTime);
654                    SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
655                    Now.HighPart = WindowsFileTime.dwHighDateTime;
656                    Now.LowPart = WindowsFileTime.dwLowDateTime;
657                    // last read less than 0,2 s
658                    if ((Now.QuadPart - pContext->LastCacheCheck[dwKey].QuadPart) < 2000000)
659                    {
660                            Trace(WINEVENT_LEVEL_INFO, L"Cache up to date");
661                            pContext->LastCacheCheck[dwKey] = Now;
662                            dwReturn = 0;
663                            __leave;
664                    }
665                    Trace(WINEVENT_LEVEL_INFO, L"Updating cache");
666                    // try to use the cache
667                    dwReturn = OCardReadFile(pCardData, szOpenPGPDir, szOpenPGPFingerprint, &pbFingerPrint, &dwFingerPrintSize);
668                    if (dwReturn)
669                    {
670                            __leave;
671                    }
672                    if (dwFingerPrintSize != 60)
673                    {
674                            Trace(WINEVENT_LEVEL_ERROR, L"dwFingerPrintSize = %02X", dwFingerPrintSize);
675                            dwReturn = SCARD_E_UNEXPECTED;
676                            __leave;
677                    }
678                    // determine if we have to retrieve the modulus from the card
679                    if (memcmp(pbFingerPrint + dwKey * 20, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) == 0)
680                    {
681                            // no public key => why want to read it ?
682                            Trace(WINEVENT_LEVEL_ERROR, L"pbFingerPrint null for key %d", dwKey);
683                            dwReturn = SCARD_E_NO_KEY_CONTAINER;
684                            if (pContext->pbModulusInLittleEndian[dwKey])
685                            {
686                                    pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
687                                    pContext->pbModulusInLittleEndian[dwKey] = NULL;
688                            }
689                            pContext->fHasKey[dwKey] = FALSE;
690                            __leave;
691                    }
692                    if (memcmp(pbFingerPrint + dwKey * 20, pContext->bFingerPrint + dwKey * 20, 20) == 0)
693                    {
694                            if (pContext->pbModulusInLittleEndian[dwKey])
695                            {
696                                    fHasToUpdateTheCache = FALSE;
697                            }
698                            else
699                            {
700                                    fHasToUpdateTheCache = TRUE;
701                            }
702                    }
703                    else
704                    {
705                            fHasToUpdateTheCache = TRUE;
706                    }
707                    if (fHasToUpdateTheCache)
708                    {
709                            dwReturn = OCardUpdateCachedPublicKey(pCardData, dwKey);
710                            if (dwReturn)
711                            {
712                                    __leave;
713                            }
714                    }
715                    pContext->LastCacheCheck[dwKey] = Now;
716            }
717            __finally
718            {
719                    if (pbFingerPrint)
720                            pCardData->pfnCspFree(pbFingerPrint);
721            }
722            return dwReturn;
723    }
724    
725    DWORD OCardGetKeyLengthInBytes(__in PCARD_DATA pCardData, __in OPENPGP_KEY dwKey, __out PDWORD pdwLengthInBytes)
726    {
727            DWORD dwReturn;
728            POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
729            __try
730            {
731                    Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
732                    if (dwKey >= KeyMax)
733                    {
734                            dwReturn = SCARD_E_NO_KEY_CONTAINER;
735                            Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
736                            __leave;
737                    }
738                    dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, dwKey);
739                    if (dwReturn)
740                    {
741                            __leave;
742                    }
743                    *pdwLengthInBytes = pContext->dwModulusSizeInBytes[dwKey];
744                    Trace(WINEVENT_LEVEL_VERBOSE, L"modulus size in bits= %d",*pdwLengthInBytes*8);
745            }
746            __finally
747            {
748            }
749            Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
750            return dwReturn;
751    }
752    
753    DWORD OCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_KEY dwKey, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
754    {
755            DWORD dwReturn;
756            POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
757            PRSAPUBLICKEYBLOB pbBlob = NULL;
758            DWORD dwModulusSizeInBytes;
759            __try
760            {
761                    Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
762                    if (dwKey >= KeyMax)
763                    {
764                            dwReturn = SCARD_E_NO_KEY_CONTAINER;
765                            Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwKey);
766                            __leave;
767                    }
768                    dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, dwKey);
769                    if (dwReturn)
770                    {
771                            __leave;
772                    }
773                    dwModulusSizeInBytes = pContext->dwModulusSizeInBytes[dwKey];
774                    Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSizeInBytes * 8);
775                    *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSizeInBytes - sizeof(DWORD);
776                  *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);                  *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
777                  if (!*pbPublicKey)                  if (!*pbPublicKey)
778                  {                  {
# Line 604  DWORD OCardReadPublicKey(PCARD_DATA pCar Line 787  DWORD OCardReadPublicKey(PCARD_DATA pCar
787                  pbBlob->blobheader.reserved = 0;                  pbBlob->blobheader.reserved = 0;
788                  pbBlob->blobheader.aiKeyAlg = Keys[dwKey].aiKeyAlg;                  pbBlob->blobheader.aiKeyAlg = Keys[dwKey].aiKeyAlg;
789                  pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';                  pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
790                  pbBlob->rsapubkey.bitlen = dwModulusSize*8;                  pbBlob->rsapubkey.bitlen = dwModulusSizeInBytes*8;
791                  pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000  + pbExponent[1] * 0x10000  + pbExponent[2] * 0x100 + pbExponent[3];                  pbBlob->rsapubkey.pubexp = pContext->dwExponent[dwKey];
792                  // convert big endian into little endian                  memcpy(pbBlob->modulus, pContext->pbModulusInLittleEndian[dwKey], dwModulusSizeInBytes);
                 //memcpy(pbBlob->modulus, pbModulus, dwModulusSize);  
                 for (dwI = 0; dwI < dwModulusSize; dwI++)  
                 {  
                         pbBlob->modulus[dwI] = pbModulus[dwModulusSize - 1 - dwI];  
                 }  
                   
793                  dwReturn = 0;                  dwReturn = 0;
794          }          }
795          __finally          __finally
796          {          {
                 if (pbData)  
                         pCardData->pfnCspFree(pbData);  
797          }          }
798          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
799          return dwReturn;          return dwReturn;
# Line 630  DWORD OCardCreateKey(PCARD_DATA pCardDat Line 805  DWORD OCardCreateKey(PCARD_DATA pCardDat
805          PBYTE pbData = NULL;          PBYTE pbData = NULL;
806          DWORD dwResponseSize = 0, dwCmdSize;          DWORD dwResponseSize = 0, dwCmdSize;
807          OPENPGP_ALGORITHM_ATTRIBUTE Attributes;          OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
808          POPENPGP_CONTEXT pContext;          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
809          DWORD dwSecondsSince1970;          DWORD dwSecondsSince1970;
810          PBYTE pbModulus, pbExponent;          PBYTE pbModulus, pbExponent;
811          DWORD dwModulusSize, dwExponent;          DWORD dwModulusSizeInBytes, dwExponent, dwI;
812          BYTE pbCmd[] = {0x00,          BYTE pbCmd[] = {0x00,
813                                      0x47,                                      0x47,
814                                          0x80,                                          0x80,
# Line 647  DWORD OCardCreateKey(PCARD_DATA pCardDat Line 822  DWORD OCardCreateKey(PCARD_DATA pCardDat
822                                          0x00                                          0x00
823                                          };                                          };
824          DWORD dwTotalTlvSize, dwOffset;          DWORD dwTotalTlvSize, dwOffset;
825            BYTE pbFingerPrint[20];
826          __try          __try
827          {          {
828                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwKey=%d",dwKey);
# Line 657  DWORD OCardCreateKey(PCARD_DATA pCardDat Line 833  DWORD OCardCreateKey(PCARD_DATA pCardDat
833                          __leave;                          __leave;
834                  }                  }
835                  // key len                  // key len
836                  dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);                  Attributes.wModulusLengthInBit = (unsigned short)dwBitLen * 8;
837                  if (dwReturn)                  Attributes.wExponentLengthInBit = 4 * 8;
838                  {                  Attributes.bAlgoId = 1;
839                          __leave;                  Attributes.bFormat = 0;
                 }  
                 Attributes.wModulusLengthInBit = (WORD) dwBitLen;  
840                  dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);                  dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
841                  if (dwReturn)                  if (dwReturn)
842                  {                  {
843                          __leave;                          __leave;
844                  }                  }
845    
                 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;  
846                  pbCmd[7] = Keys[dwKey].bKeyTag;                  pbCmd[7] = Keys[dwKey].bKeyTag;
847                  dwCmdSize = 9;                  dwCmdSize = 9;
848                  if (pContext->fExtentedLeLcFields)                  if (pContext->fExtentedLeLcFields)
# Line 689  DWORD OCardCreateKey(PCARD_DATA pCardDat Line 862  DWORD OCardCreateKey(PCARD_DATA pCardDat
862                  }                  }
863                  dwOffset = 2;                  dwOffset = 2;
864                  dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;                  dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
865                  if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize, &pbModulus,&dwModulusSize))                  if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize, &pbModulus,&dwModulusSizeInBytes))
866                  {                  {
867                          dwReturn = SCARD_E_UNEXPECTED;                          dwReturn = SCARD_E_UNEXPECTED;
868                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
# Line 698  DWORD OCardCreateKey(PCARD_DATA pCardDat Line 871  DWORD OCardCreateKey(PCARD_DATA pCardDat
871                  if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))                  if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
872                  {                  {
873                          dwReturn = SCARD_E_UNEXPECTED;                          dwReturn = SCARD_E_UNEXPECTED;
874                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x82");
875                          __leave;                          __leave;
876                  }                  }
877                  dwExponent = pbExponent[0] * 0x1000000  + pbExponent[1] * 0x10000  + pbExponent[2] * 0x100 + pbExponent[3];                  dwExponent = pbExponent[0] * 0x1000000  + pbExponent[1] * 0x10000  + pbExponent[2] * 0x100 + pbExponent[3];
878                  dwReturn = UpdateGenerationDateTime(pCardData, dwKey, &dwSecondsSince1970);                  // save in the cache
879                    pContext->fHasKey[dwKey] = TRUE;
880                    pContext->dwExponent[dwKey] = dwExponent;
881                    pContext->dwModulusSizeInBytes[dwKey] = (WORD) dwModulusSizeInBytes;
882                    if (pContext->pbModulusInLittleEndian[dwKey])
883                    {
884                            pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
885                    }
886                    pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(dwModulusSizeInBytes);
887                    if (!pContext->pbModulusInLittleEndian[dwKey])
888                    {
889                            dwReturn = SCARD_E_NO_MEMORY;
890                            Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
891                            __leave;
892                    }
893                    for (dwI = 0; dwI < dwModulusSizeInBytes; dwI++)
894                    {
895                            pContext->pbModulusInLittleEndian[dwKey][dwI] = pbModulus[dwModulusSizeInBytes - 1 - dwI];
896                    }
897                    dwReturn = CreateGenerationDateTime(pCardData, &dwSecondsSince1970);
898                  if (dwReturn)                  if (dwReturn)
899                  {                  {
900                          __leave;                          __leave;
901                  }                  }
902                  dwReturn = UpdateFingerPrint(pCardData, dwKey, dwSecondsSince1970,                  dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
                                                                                 pbModulus,  
                                                                                 dwModulusSize * 8,  
                                                                                 TRUE,  
                                                                                 dwExponent  
                                                                                 );  
903                  if (dwReturn)                  if (dwReturn)
904                  {                  {
905                          __leave;                          __leave;
906                  }                  }
907                  pContext->fHasKey[dwKey] = TRUE;                  // avoid two key having the same fingerprint if generated too fast
908                    while (memcmp(pbFingerPrint, pContext->bFingerPrint, 20) == 0
909                            || memcmp(pbFingerPrint, pContext->bFingerPrint + 20, 20) == 0
910                            || memcmp(pbFingerPrint, pContext->bFingerPrint + 40, 20) == 0)
911                    {
912                            dwSecondsSince1970++;
913                            dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
914                            if (dwReturn)
915                            {
916                                    __leave;
917                            }
918                    }
919                    dwReturn = UpdateGenerationDateTime(pCardData, dwKey, dwSecondsSince1970);
920                    if (dwReturn)
921                    {
922                            __leave;
923                    }
924                    dwReturn = UpdateFingerPrint(pCardData, dwKey, pbFingerPrint);
925                    if (dwReturn)
926                    {
927                            __leave;
928                    }
929                    memcpy(pContext->bFingerPrint + 20 * dwKey, pbFingerPrint, 20);
930          }          }
931          __finally          __finally
932          {          {
# Line 744  DWORD OCardImportKey(PCARD_DATA pCardDat Line 953  DWORD OCardImportKey(PCARD_DATA pCardDat
953          BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};          BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
954          DWORD dwSecondsSince1970;          DWORD dwSecondsSince1970;
955          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
956            BYTE pbFingerPrint[20];
957          __try          __try
958          {          {
959                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwKey);                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwKey);
# Line 768  DWORD OCardImportKey(PCARD_DATA pCardDat Line 978  DWORD OCardImportKey(PCARD_DATA pCardDat
978                          __leave;                          __leave;
979                  }                  }
980                                    
                 dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);  
                 if (dwReturn)  
                 {  
                         __leave;  
                 }  
981                  Attributes.wModulusLengthInBit = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;                  Attributes.wModulusLengthInBit = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
982                    Attributes.wExponentLengthInBit = 4 * 8;
983                    Attributes.bAlgoId = 1;
984                    Attributes.bFormat = 0;
985                  dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);                  dwReturn = OCardSetKeyAlgorithmAttributes(pCardData, dwKey, &Attributes);
986                  if (dwReturn)                  if (dwReturn)
987                  {                  {
# Line 818  DWORD OCardImportKey(PCARD_DATA pCardDat Line 1026  DWORD OCardImportKey(PCARD_DATA pCardDat
1026                  {                  {
1027                          __leave;                          __leave;
1028                  }                  }
1029                  dwReturn = UpdateGenerationDateTime(pCardData, dwKey, &dwSecondsSince1970);                  // save in the cache
1030                    pContext->fHasKey[dwKey] = TRUE;
1031                    pContext->dwExponent[dwKey] = pbPublicKeyBlob->rsapubkey.pubexp;
1032                    pContext->dwModulusSizeInBytes[dwKey] = (WORD) pbPublicKeyBlob->rsapubkey.bitlen / 8;
1033                    if (pContext->pbModulusInLittleEndian[dwKey])
1034                    {
1035                            pCardData->pfnCspFree(pContext->pbModulusInLittleEndian[dwKey]);
1036                    }
1037                    pContext->pbModulusInLittleEndian[dwKey] = pCardData->pfnCspAlloc(pContext->dwModulusSizeInBytes[dwKey]);
1038                    if (!pContext->pbModulusInLittleEndian[dwKey])
1039                    {
1040                            dwReturn = SCARD_E_NO_MEMORY;
1041                            Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
1042                            __leave;
1043                    }
1044                    memcpy(pContext->pbModulusInLittleEndian[dwKey],&(pbPublicKeyBlob->modulus),pContext->dwModulusSizeInBytes[dwKey]);
1045                    dwReturn = CreateGenerationDateTime(pCardData, &dwSecondsSince1970);
1046                  if (dwReturn)                  if (dwReturn)
1047                  {                  {
1048                          __leave;                          __leave;
1049                  }                  }
1050                  dwReturn = UpdateFingerPrint(pCardData, dwKey, dwSecondsSince1970,                  dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
                                                                                 pbPublicKeyBlob->modulus,  
                                                                                 pbPublicKeyBlob->rsapubkey.bitlen,  
                                                                                 FALSE,  
                                                                                 pbPublicKeyBlob->rsapubkey.pubexp  
                                                                                 );  
1051                  if (dwReturn)                  if (dwReturn)
1052                  {                  {
1053                          __leave;                          __leave;
1054                  }                  }
1055                  pContext->fHasKey[dwKey] = TRUE;                  // avoid two key having the same fingerprint if generated too fast
1056                    while (memcmp(pbFingerPrint, pContext->bFingerPrint, 20) == 0
1057                            || memcmp(pbFingerPrint, pContext->bFingerPrint + 20, 20) == 0
1058                            || memcmp(pbFingerPrint, pContext->bFingerPrint + 40, 20) == 0)
1059                    {
1060                            dwSecondsSince1970++;
1061                            dwReturn = CreateFingerPrint(pCardData, dwKey, dwSecondsSince1970, pbFingerPrint);
1062                            if (dwReturn)
1063                            {
1064                                    __leave;
1065                            }
1066                    }
1067                    dwReturn = UpdateGenerationDateTime(pCardData, dwKey, dwSecondsSince1970);
1068                    if (dwReturn)
1069                    {
1070                            __leave;
1071                    }
1072                    dwReturn = UpdateFingerPrint(pCardData, dwKey, pbFingerPrint);
1073                    if (dwReturn)
1074                    {
1075                            __leave;
1076                    }
1077                    memcpy(pContext->bFingerPrint + 20 * dwKey, pbFingerPrint, 20);
1078          }          }
1079          __finally          __finally
1080          {          {
# Line 848  DWORD OCardImportKey(PCARD_DATA pCardDat Line 1089  DWORD OCardImportKey(PCARD_DATA pCardDat
1089                          pCardData->pfnCspFree(pbTlv);                          pCardData->pfnCspFree(pbTlv);
1090                  }                  }
1091          }          }
1092          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X for key = %d",dwReturn, dwKey);
1093          return dwReturn;          return dwReturn;
1094  }  }
1095    
1096  DWORD OCardCheckSigningInfo(__in PCARD_SIGNING_INFO  pInfo, __out PDWORD pdwIndex)  DWORD OCardCheckSigningInfo(__in PCARD_SIGNING_INFO  pInfo, __in BOOL fAllowNoOid, __out PDWORD pdwIndex)
1097  {  {
1098          DWORD dwReturn, dwI;          DWORD dwReturn, dwI;
1099          __try          __try
# Line 868  DWORD OCardCheckSigningInfo(__in PCARD_S Line 1109  DWORD OCardCheckSigningInfo(__in PCARD_S
1109                          if ( pInfo->dwPaddingType == CARD_PADDING_PKCS1)                          if ( pInfo->dwPaddingType == CARD_PADDING_PKCS1)
1110                          {                          {
1111                                  BCRYPT_PKCS1_PADDING_INFO* padding = (BCRYPT_PKCS1_PADDING_INFO*) pInfo->pPaddingInfo;                                  BCRYPT_PKCS1_PADDING_INFO* padding = (BCRYPT_PKCS1_PADDING_INFO*) pInfo->pPaddingInfo;
1112                                    if (padding->pszAlgId == NULL)
1113                                    {
1114                                            if (fAllowNoOid)
1115                                            {
1116                                                    *pdwIndex = OPENPGP_NO_OID;
1117                                                    dwReturn = 0;
1118                                                    __leave;
1119                                            }
1120                                            else
1121                                            {
1122                                                    Trace(WINEVENT_LEVEL_ERROR, L"alg not found %s", padding->pszAlgId);
1123                                                    dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
1124                                                    __leave;
1125                                            }
1126                                    }
1127                                  for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)                                  for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
1128                                  {                                  {
1129                                          if (wcscmp(SignatureAlgorithm[dwI].szAlgId,padding->pszAlgId) == 0)                                          if (wcscmp(SignatureAlgorithm[dwI].szAlgId,padding->pszAlgId) == 0)
# Line 940  DWORD OCardSign(PCARD_DATA pCardData, Line 1196  DWORD OCardSign(PCARD_DATA pCardData,
1196          DWORD dwReturn;          DWORD dwReturn;
1197          PBYTE pbData = NULL;          PBYTE pbData = NULL;
1198          DWORD dwCmdSize = 0, dwIndex, dwI;          DWORD dwCmdSize = 0, dwIndex, dwI;
1199          POPENPGP_CONTEXT pContext;          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
         OPENPGP_ALGORITHM_ATTRIBUTE Attributes;  
1200          BYTE pbCmd[6 + 256 + 256] = {0x00,          BYTE pbCmd[6 + 256 + 256] = {0x00,
1201                                      0x2A,                                      0x2A,
1202                                          0x9E,                                          0x9E,
# Line 952  DWORD OCardSign(PCARD_DATA pCardData, Line 1207  DWORD OCardSign(PCARD_DATA pCardData,
1207          __try          __try
1208          {          {
1209                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
                 dwReturn = OCardCheckSigningInfo(pInfo, &dwIndex);  
                 if (dwReturn)  
                 {  
                         __leave;  
                 }  
1210                  if (pInfo->bContainerIndex != ContainerSignature)                  if (pInfo->bContainerIndex != ContainerSignature)
1211                  {                  {
1212                          dwReturn = SCARD_E_NO_KEY_CONTAINER;                          dwReturn = SCARD_E_NO_KEY_CONTAINER;
1213                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1214                          __leave;                          __leave;
1215                  }                  }
1216                    dwReturn = OCardCheckSigningInfo(pInfo, FALSE, &dwIndex);
1217                    if (dwReturn)
1218                    {
1219                            __leave;
1220                    }
1221                  if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)                  if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
1222                  {                  {
1223                          // optimisation :                          // optimisation :
1224                          // return the buffer size only                          // return the buffer size only
1225                          dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeySignature, &Attributes);                          dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
                         if (dwReturn)  
                         {  
                                 __leave;  
                         }  
                         pInfo->cbSignedData = Attributes.wModulusLengthInBit/8;  
                         dwReturn = 0;  
1226                          __leave;                          __leave;
1227                  }                  }
1228    
                 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;  
   
1229                  dwCmdSize = 5;                  dwCmdSize = 5;
1230                  if (pContext->fExtentedLeLcFields)                  if (pContext->fExtentedLeLcFields)
1231                  {                  {
# Line 1033  DWORD OCardSign(PCARD_DATA pCardData, Line 1280  DWORD OCardSign(PCARD_DATA pCardData,
1280          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);          Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1281          return dwReturn;          return dwReturn;
1282  }  }
1283    DWORD OCardIsConfidentialityKeyTheSameThanAuthentication(__in PCARD_DATA pCardData)
1284    {
1285            DWORD dwReturn;
1286            POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1287            __try
1288            {
1289            // see if the confidentiality key is the same than the authentication key
1290                            // if yes, confidentiality key can sign
1291                            // else ... we don't follow ms guidelines which requiers every container
1292                            // to be able to sign data
1293                            dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerAuthentication);
1294                            if (dwReturn)
1295                            {
1296                                    __leave;
1297                            }
1298                            dwReturn = OCardUpdateCachedPublicKeyIfNeeded(pCardData, ContainerConfidentiality);
1299                            if (dwReturn)
1300                            {
1301                                    __leave;
1302                            }
1303                            if (pContext->dwModulusSizeInBytes[ContainerAuthentication]
1304                                                            != pContext->dwModulusSizeInBytes[ContainerConfidentiality])
1305                            {
1306                                    dwReturn = SCARD_E_NO_KEY_CONTAINER;
1307                                    Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
1308                                    __leave;
1309                            }
1310                            if (memcmp(pContext->pbModulusInLittleEndian[ContainerAuthentication],
1311                                    pContext->pbModulusInLittleEndian[ContainerConfidentiality],
1312                                    pContext->dwModulusSizeInBytes[ContainerConfidentiality]) != 0)
1313                            {
1314                                    dwReturn = SCARD_E_NO_KEY_CONTAINER;
1315                                    Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER");
1316                                    __leave;
1317                            }
1318                            // if we are here, then the confidentiality key can sign using the authentication key
1319                            dwReturn = 0;
1320            }
1321            __finally
1322            {
1323            }
1324            return dwReturn;
1325    }
1326  DWORD OCardAuthenticate(PCARD_DATA pCardData,  DWORD OCardAuthenticate(PCARD_DATA pCardData,
1327                                  PCARD_SIGNING_INFO  pInfo)                                  PCARD_SIGNING_INFO  pInfo)
1328  {  {
1329          DWORD dwReturn;          DWORD dwReturn;
1330          PBYTE pbData = NULL;          PBYTE pbData = NULL;
1331          DWORD dwCmdSize = 0, dwIndex, dwI;          DWORD dwCmdSize = 0, dwIndex, dwI;
1332          POPENPGP_CONTEXT pContext;          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
         OPENPGP_ALGORITHM_ATTRIBUTE Attributes;  
1333          BYTE pbCmd[6 + 256 + 256] = {0x00,          BYTE pbCmd[6 + 256 + 256] = {0x00,
1334                                      0x88,                                      0x88,
1335                                          0x00,                                          0x00,
# Line 1052  DWORD OCardAuthenticate(PCARD_DATA pCard Line 1340  DWORD OCardAuthenticate(PCARD_DATA pCard
1340          __try          __try
1341          {          {
1342                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1343                  dwReturn = OCardCheckSigningInfo(pInfo, &dwIndex);                  
1344                  if (dwReturn)                  if (pInfo->bContainerIndex != ContainerAuthentication && pInfo->bContainerIndex != ContainerConfidentiality)
                 {  
                         __leave;  
                 }  
                 if (pInfo->bContainerIndex != ContainerAuthentication)  
1345                  {                  {
1346                          dwReturn = SCARD_E_NO_KEY_CONTAINER;                          dwReturn = SCARD_E_NO_KEY_CONTAINER;
1347                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1348                          __leave;                          __leave;
1349                  }                  }
1350                  if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)                  if (pInfo->bContainerIndex == ContainerConfidentiality)
1351                  {                  {
1352                          // optimisation :                          dwReturn = OCardIsConfidentialityKeyTheSameThanAuthentication(pCardData);
                         // return the buffer size only  
                         dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeyAuthentication, &Attributes);  
1353                          if (dwReturn)                          if (dwReturn)
1354                          {                          {
1355                                  __leave;                                  __leave;
1356                          }                          }
1357                          pInfo->cbSignedData = Attributes.wModulusLengthInBit/8;                  }
1358                          dwReturn = 0;                  dwReturn = OCardCheckSigningInfo(pInfo, TRUE, &dwIndex);
1359                    if (dwReturn)
1360                    {
1361                            __leave;
1362                    }
1363                    if (pInfo->dwSigningFlags & CARD_BUFFER_SIZE_ONLY)
1364                    {
1365                            // optimisation :
1366                            // return the buffer size only
1367                            dwReturn = OCardGetKeyLengthInBytes(pCardData, pInfo->bContainerIndex, &pInfo->cbSignedData);
1368                          __leave;                          __leave;
1369                  }                  }
   
                 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;  
1370    
1371                  dwCmdSize = 5;                  dwCmdSize = 5;
1372                  if (pContext->fExtentedLeLcFields)                  if (pContext->fExtentedLeLcFields)
1373                  {                  {
1374                          dwCmdSize++;                          dwCmdSize++;
1375                  }                  }
1376                  pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);                  if (dwIndex == OPENPGP_NO_OID)
                 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);  
                 dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;  
                 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)  
1377                  {                  {
1378                          pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];                          pbCmd[dwCmdSize++] = (BYTE) (pInfo->cbData);
1379                  }*/                  }
1380                    else
1381                    {
1382                            pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwIndex].dwEncodedOidSize + pInfo->cbData);
1383                            memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwIndex].pbEncodedOid,SignatureAlgorithm[dwIndex].dwEncodedOidSize);
1384                            dwCmdSize += SignatureAlgorithm[dwIndex].dwEncodedOidSize;
1385                    }
1386                  memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);                  memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1387                  dwCmdSize += pInfo->cbData;                  dwCmdSize += pInfo->cbData;
   
1388                                    
1389                  if (pContext->fExtentedLeLcFields)                  if (pContext->fExtentedLeLcFields)
1390                  {                  {
# Line 1146  DWORD OCardDecrypt(PCARD_DATA pCardData, Line 1437  DWORD OCardDecrypt(PCARD_DATA pCardData,
1437                                          0x86,                                          0x86,
1438                                          0x00,                                          0x00,
1439                                          };                                          };
1440          POPENPGP_CONTEXT pContext;          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1441          DWORD dwI;          DWORD dwI;
1442          OPENPGP_ALGORITHM_ATTRIBUTE Attributes;          OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
1443          __try          __try
# Line 1176  DWORD OCardDecrypt(PCARD_DATA pCardData, Line 1467  DWORD OCardDecrypt(PCARD_DATA pCardData,
1467                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d", pInfo->cbData);                          Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d", pInfo->cbData);
1468                          __leave;                          __leave;
1469                  }                  }
                 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;  
1470                  dwCmdSize = 5;                  dwCmdSize = 5;
1471                  if (pContext->fExtentedLeLcFields)                  if (pContext->fExtentedLeLcFields)
1472                  {                  {
# Line 1250  DWORD OCardReadContainerMapFile(__in PCA Line 1540  DWORD OCardReadContainerMapFile(__in PCA
1540  {  {
1541          DWORD dwReturn = 0;          DWORD dwReturn = 0;
1542          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;          POPENPGP_CONTEXT pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1543          OPENPGP_ALGORITHM_ATTRIBUTE Attributes;          DWORD dwSizeInBits;
1544          __try          __try
1545          {          {
1546                  PCONTAINER_MAP_RECORD pContainer = NULL;                  PCONTAINER_MAP_RECORD pContainer = NULL;
# Line 1266  DWORD OCardReadContainerMapFile(__in PCA Line 1556  DWORD OCardReadContainerMapFile(__in PCA
1556                  pContainer = (PCONTAINER_MAP_RECORD) *ppbResponse;                  pContainer = (PCONTAINER_MAP_RECORD) *ppbResponse;
1557                  memset(pContainer,0,sizeof(CONTAINER_MAP_RECORD) * ContainerMax);                  memset(pContainer,0,sizeof(CONTAINER_MAP_RECORD) * ContainerMax);
1558                                    
1559                  dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeyAuthentication, &Attributes);                  dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyAuthentication, &dwSizeInBits);
1560                  if (dwReturn)                  if (dwReturn)
1561                  {                  {
1562                          __leave;                          __leave;
1563                  }                  }
1564                  pContainer[ContainerAuthentication].wSigKeySizeBits = Attributes.wModulusLengthInBit;                  pContainer[ContainerAuthentication].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
1565                  swprintf_s(pContainer[ContainerAuthentication].wszGuid,MAX_CONTAINER_NAME_LEN + 1,                  swprintf_s(pContainer[ContainerAuthentication].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1566                          L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Authenticate",                          L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Authenticate",
1567                          pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],                          pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
# Line 1284  DWORD OCardReadContainerMapFile(__in PCA Line 1574  DWORD OCardReadContainerMapFile(__in PCA
1574                          fIsDefaultContainerSet = TRUE;                          fIsDefaultContainerSet = TRUE;
1575                  }                  }
1576    
1577                  dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeyConfidentiality, &Attributes);                  dwReturn = OCardGetKeyLengthInBytes(pCardData, KeyConfidentiality, &dwSizeInBits);
1578                  if (dwReturn)                  if (dwReturn)
1579                  {                  {
1580                          __leave;                          __leave;
1581                  }                  }
1582                  pContainer[ContainerConfidentiality].wKeyExchangeKeySizeBits = Attributes.wModulusLengthInBit;                  pContainer[ContainerConfidentiality].wKeyExchangeKeySizeBits = (WORD)dwSizeInBits * 8;
1583                  swprintf_s(pContainer[ContainerConfidentiality].wszGuid,MAX_CONTAINER_NAME_LEN + 1,                  swprintf_s(pContainer[ContainerConfidentiality].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1584                          L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Confidential",                          L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Confidential",
1585                          pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],                          pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],
# Line 1306  DWORD OCardReadContainerMapFile(__in PCA Line 1596  DWORD OCardReadContainerMapFile(__in PCA
1596                          }                          }
1597                  }                  }
1598    
1599                  dwReturn = OCardGetKeyAlgorithmAttributes(pCardData, KeySignature, &Attributes);                  dwReturn = OCardGetKeyLengthInBytes(pCardData, KeySignature, &dwSizeInBits);
1600                  if (dwReturn)                  if (dwReturn)
1601                  {                  {
1602                          __leave;                          __leave;
1603                  }                  }
1604                  pContainer[ContainerSignature].wSigKeySizeBits = Attributes.wModulusLengthInBit;                  pContainer[ContainerSignature].wSigKeySizeBits = (WORD)dwSizeInBits * 8;
1605                  swprintf_s(pContainer[ContainerSignature].wszGuid,MAX_CONTAINER_NAME_LEN + 1,                  swprintf_s(pContainer[ContainerSignature].wszGuid,MAX_CONTAINER_NAME_LEN + 1,
1606                          L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Signature",                          L"OPENPGP_%02X%02X_%02X%02X_%02X%02X%02X%02X_Signature",
1607                          pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],                          pContext->Aid.AidVersion[0],pContext->Aid.AidVersion[1],

Legend:
Removed from v.9  
changed lines
  Added in v.10

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26