/[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 1 by vletoux, Tue Feb 23 19:18:59 2010 UTC revision 2 by vletoux, Wed Feb 24 07:13:15 2010 UTC
# Line 237  DWORD SetKeyAlgorithmAttributes(__in PCA Line 237  DWORD SetKeyAlgorithmAttributes(__in PCA
237          return dwReturn;          return dwReturn;
238  }  }
239    
240  DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,  DWORD BuildSingleTlv(__in PBYTE buffer, __in BYTE bTlv, __in DWORD dwTlvSize, __inout PDWORD pdwOffset)
241    {
242            DWORD dwSize = 1;
243            buffer[(*pdwOffset)++] = bTlv;
244            // truncate if too long
245            if (dwTlvSize > 0xFFFF) dwTlvSize = 0xFFFF;
246            if (dwTlvSize < 0x7F)
247            {
248                    buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
249                    dwSize++;
250            }
251            else if (dwTlvSize < 0xFF)
252            {
253                    buffer[(*pdwOffset)++] = 0x81;
254                    buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
255                    dwSize+=2;
256            }
257            else
258            {
259                    buffer[(*pdwOffset)++] = 0x82;
260                    buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize / 0x100);
261                    buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize % 0x100);
262                    dwSize+=3;
263            }
264            return dwSize;
265    }
266    
267    DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
268                                                      __in OPENPGP_CONTAINER dwContainer, __in BYTE bFormat,
269                                                   __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)                                                   __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
270  {  {
271          DWORD dwReturn;          // structure of the keyblob
272            //BLOBHEADER blobheader;
273            //RSAPUBKEY rsapubkey;
274            //BYTE modulus[rsapubkey.bitlen/8];
275            //BYTE prime1[rsapubkey.bitlen/16];
276            //BYTE prime2[rsapubkey.bitlen/16];
277            //BYTE exponent1[rsapubkey.bitlen/16];
278            //BYTE exponent2[rsapubkey.bitlen/16];
279            //BYTE coefficient[rsapubkey.bitlen/16];
280            //BYTE privateExponent[rsapubkey.bitlen/8];
281            DWORD dwReturn = 0;
282            
283            DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen;
284            PBYTE pbPublicKeyData = (PBYTE) pbPublicKeyBlob + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY);
285            // 7F48 len is < 7F so its encoded len is 1 bytes
286            // 3 bytes max + length * 7 potential plv
287            BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48};
288            BYTE b5F48Header[3 + 2] = {0x5F, 0x48};
289            BYTE b4DHeader[3 + 1] = {0x4D};
290            DWORD dwOffset = 0;
291            DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize;
292            DWORD dwKeyDataSize, dwExtendedHeaderListSize;
293          __try          __try
294          {          {
295                    // build the 7F48 header + the data into a buffer
296                    dwOffset = 3;
297                    dw7F48HeaderSize = 0;
298                    dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x91, sizeof(DWORD), &dwOffset);
299                    dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x92, bitlen / 16, &dwOffset);
300                    dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x93, bitlen / 16, &dwOffset);
301                    if (bFormat & 2)
302                    {
303                            // add crt (chineese reminder theorem) template
304                            dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x94, bitlen / 16, &dwOffset);
305                            dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x95, bitlen / 16, &dwOffset);
306                            dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x96, bitlen / 16, &dwOffset);
307                    }
308                    if (bFormat & 1)
309                    {
310                            dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x97, bitlen / 8, &dwOffset);
311                    }
312                    b7F48Header[2] = (BYTE) dw7F48HeaderSize;
313                    dw7F48HeaderSize += 3; // before = only content, after += header size
314                    // build 5F48 header in a buffer
315                    // size of the data
316                    dwKeyDataSize = sizeof(DWORD) // e
317                                                                                    + bitlen / 16 //prime1
318                                                                                    + bitlen / 16 //prime2
319                                                                                    ;
320                    if (bFormat & 2)
321                    {
322                            dwKeyDataSize+= bitlen / 16 //coefficient
323                                                                                    + bitlen / 16 //exp1
324                                                                                    + bitlen / 16 //exp2
325                                                                                    ;
326                    }
327                    if (bFormat & 1)
328                    {
329                            dwKeyDataSize+= bitlen / 8 ; //modulus
330                    }
331                    dwOffset = 1;
332                    dw5F48HeaderSize = 1 + BuildSingleTlv(b5F48Header, 0x48, dwKeyDataSize, &dwOffset);
333                    // build the extended header list in a buffer
334                    dwExtendedHeaderListSize = 2 // for the crt to indicate the private key
335                                                                    + dw7F48HeaderSize
336                                                                    + dw5F48HeaderSize
337                                                                    + dwKeyDataSize;
338                    dwOffset = 0;
339                    dw4DHeaderSize = BuildSingleTlv(b4DHeader, 0x4D, dwExtendedHeaderListSize, &dwOffset);
340    
341                    // allocate the memory
342                    *pdwTlvSize = dw4DHeaderSize + dwExtendedHeaderListSize;
343                    *ppbTlv = pCardData->pfnCspAlloc(*pdwTlvSize);
344                    if (! *ppbTlv)
345                    {
346                            dwReturn = SCARD_E_NO_MEMORY;
347                            __leave;
348                    }
349                    // 4D header
350                    dwOffset = 0;
351                    memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize);
352                    dwOffset += dw4DHeaderSize;
353                    // control reference templace
354                    (*ppbTlv)[dwOffset++] = Containers[dwContainer].Tag;
355                    (*ppbTlv)[dwOffset++] = 0;
356                    // cardholder private key template
357                    memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize);
358                    dwOffset += dw7F48HeaderSize;
359                    // Concatenation of key data header
360                    memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize);
361                    dwOffset += dw5F48HeaderSize;
362                    // Concatenation of key data
363                    // exponent in little endian
364                    (*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000);
365                    (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000);
366                    (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100);
367                    (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1);
368                    // prime1
369                    memcpy(*ppbTlv + dwOffset, pbPublicKeyData + bitlen/8 , bitlen / 16);
370                    dwOffset += bitlen / 16;
371                    // prime2
372                    memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1) * bitlen / 16 , bitlen / 16);
373                    dwOffset += bitlen / 16;
374                    if (bFormat & 2)
375                    {
376                            // coeff
377                            memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 3) * bitlen / 16 , bitlen / 16);
378                            dwOffset += bitlen / 16;
379                            // exponent1
380                            memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 1) * bitlen / 16 , bitlen / 16);
381                            dwOffset += bitlen / 16;
382                            // exponent2
383                            memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 2) * bitlen / 16 , bitlen / 16);
384                            dwOffset += bitlen / 16;
385                    }
386                    if (bFormat & 1)
387                    {
388                            // modulus
389                            memcpy(*ppbTlv + dwOffset, pbPublicKeyData, bitlen / 8);
390                    }
391          }          }
392          __finally          __finally
393          {          {
# Line 421  DWORD SCardImportKey(PCARD_DATA pCardDat Line 566  DWORD SCardImportKey(PCARD_DATA pCardDat
566  {  {
567          DWORD dwReturn;          DWORD dwReturn;
568          PSTR szAlgorithmAttributes = NULL;          PSTR szAlgorithmAttributes = NULL;
569          PBYTE pbData = NULL;          PBYTE pbTlv = NULL;
570          DWORD dwResponseSize;          DWORD dwTlvSize;
571            PBYTE pbCommand = NULL;
572            DWORD dwCommandSize;
573          OPENPGP_ALGORITHM_ATTRIBUTE Attributes;          OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
574          PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;          PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
575            BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
576          __try          __try
577          {          {
578                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);                  Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
579                  // check blob                  // check blob
580                  if (pbPublicKeyBlob->blobheader.aiKeyAlg != Containers[dwContainer].aiKeyAlg)                  if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
581                            pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
582                  {                  {
583                          Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);                          Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
584                          dwReturn = SCARD_E_INVALID_PARAMETER;                          dwReturn = SCARD_E_INVALID_PARAMETER;
585                          __leave;                          __leave;
586                  }                  }
587                  if (pbPublicKeyBlob->blobheader.bType != PUBLICKEYBLOB)                  if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
588                  {                  {
589                          Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);                          Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
590                          dwReturn = SCARD_E_INVALID_PARAMETER;                          dwReturn = SCARD_E_INVALID_PARAMETER;
# Line 465  DWORD SCardImportKey(PCARD_DATA pCardDat Line 614  DWORD SCardImportKey(PCARD_DATA pCardDat
614                  {                  {
615                          __leave;                          __leave;
616                  }                  }
617                    dwReturn = BuildPrivateKeyTlv(pCardData, pbPublicKeyBlob, dwContainer, Attributes.bFormat, &pbTlv, &dwTlvSize);
618                    if (dwReturn)
619                    {
620                            __leave;
621                    }
622                    //TraceDump(WINEVENT_LEVEL_VERBOSE, pbTlv, dwTlvSize);
623                    if (dwTlvSize > 0xFF)
624                    {
625                            dwCommandSize = 7 + dwTlvSize;
626                            
627                    }
628                    else
629                    {
630                            dwCommandSize = 5 + dwTlvSize;
631                    }
632                    pbCommand = pCardData->pfnCspAlloc(dwCommandSize);
633                    if (!pbCommand)
634                    {
635                            Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
636                            dwReturn = SCARD_E_NO_MEMORY;
637                            __leave;
638                    }
639                    memcpy(pbCommand, bCommand, 4);
640                    if (dwTlvSize > 0xFF)
641                    {
642                            pbCommand[4] = 0;
643                            pbCommand[5] = (BYTE)(dwTlvSize / 0x100);
644                            pbCommand[6] = (BYTE)(dwTlvSize % 0x100);
645                            memcpy(pbCommand + 7, pbTlv, dwTlvSize);
646                    }
647                    else
648                    {
649                            pbCommand[4] = (BYTE) dwTlvSize;
650                            memcpy(pbCommand + 5, pbTlv, dwTlvSize);
651                    }
652                    dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
653                    if (dwReturn)
654                    {
655                            __leave;
656                    }
657          }          }
658          __finally          __finally
659          {          {
660                  if (dwReturn)                  if (pbCommand)
661                  {                  {
662                                                    SecureZeroMemory(pbCommand, dwCommandSize);
663                            pCardData->pfnCspFree(pbCommand);
664                    }
665                    if (pbTlv)
666                    {
667                            SecureZeroMemory(pbTlv, dwTlvSize);
668                            pCardData->pfnCspFree(pbTlv);
669                  }                  }
670          }          }
671          return dwReturn;          return dwReturn;

Legend:
Removed from v.1  
changed lines
  Added in v.2

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26