[Openpgpmdrv-commits] r2 - trunk/OpenPGPminidriver
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Feb 24 08:13:16 CET 2010
Author: vletoux
Date: 2010-02-24 08:13:15 +0100 (Wed, 24 Feb 2010)
New Revision: 2
Modified:
trunk/OpenPGPminidriver/CryptoOperations.c
Log:
fix key import
Modified: trunk/OpenPGPminidriver/CryptoOperations.c
===================================================================
--- trunk/OpenPGPminidriver/CryptoOperations.c 2010-02-23 19:18:59 UTC (rev 1)
+++ trunk/OpenPGPminidriver/CryptoOperations.c 2010-02-24 07:13:15 UTC (rev 2)
@@ -237,12 +237,157 @@
return dwReturn;
}
-DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
+DWORD BuildSingleTlv(__in PBYTE buffer, __in BYTE bTlv, __in DWORD dwTlvSize, __inout PDWORD pdwOffset)
+{
+ DWORD dwSize = 1;
+ buffer[(*pdwOffset)++] = bTlv;
+ // truncate if too long
+ if (dwTlvSize > 0xFFFF) dwTlvSize = 0xFFFF;
+ if (dwTlvSize < 0x7F)
+ {
+ buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
+ dwSize++;
+ }
+ else if (dwTlvSize < 0xFF)
+ {
+ buffer[(*pdwOffset)++] = 0x81;
+ buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
+ dwSize+=2;
+ }
+ else
+ {
+ buffer[(*pdwOffset)++] = 0x82;
+ buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize / 0x100);
+ buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize % 0x100);
+ dwSize+=3;
+ }
+ return dwSize;
+}
+
+DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
+ __in OPENPGP_CONTAINER dwContainer, __in BYTE bFormat,
__out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
{
- DWORD dwReturn;
+ // structure of the keyblob
+ //BLOBHEADER blobheader;
+ //RSAPUBKEY rsapubkey;
+ //BYTE modulus[rsapubkey.bitlen/8];
+ //BYTE prime1[rsapubkey.bitlen/16];
+ //BYTE prime2[rsapubkey.bitlen/16];
+ //BYTE exponent1[rsapubkey.bitlen/16];
+ //BYTE exponent2[rsapubkey.bitlen/16];
+ //BYTE coefficient[rsapubkey.bitlen/16];
+ //BYTE privateExponent[rsapubkey.bitlen/8];
+ DWORD dwReturn = 0;
+
+ DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen;
+ PBYTE pbPublicKeyData = (PBYTE) pbPublicKeyBlob + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY);
+ // 7F48 len is < 7F so its encoded len is 1 bytes
+ // 3 bytes max + length * 7 potential plv
+ BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48};
+ BYTE b5F48Header[3 + 2] = {0x5F, 0x48};
+ BYTE b4DHeader[3 + 1] = {0x4D};
+ DWORD dwOffset = 0;
+ DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize;
+ DWORD dwKeyDataSize, dwExtendedHeaderListSize;
__try
{
+ // build the 7F48 header + the data into a buffer
+ dwOffset = 3;
+ dw7F48HeaderSize = 0;
+ dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x91, sizeof(DWORD), &dwOffset);
+ dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x92, bitlen / 16, &dwOffset);
+ dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x93, bitlen / 16, &dwOffset);
+ if (bFormat & 2)
+ {
+ // add crt (chineese reminder theorem) template
+ dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x94, bitlen / 16, &dwOffset);
+ dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x95, bitlen / 16, &dwOffset);
+ dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x96, bitlen / 16, &dwOffset);
+ }
+ if (bFormat & 1)
+ {
+ dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x97, bitlen / 8, &dwOffset);
+ }
+ b7F48Header[2] = (BYTE) dw7F48HeaderSize;
+ dw7F48HeaderSize += 3; // before = only content, after += header size
+ // build 5F48 header in a buffer
+ // size of the data
+ dwKeyDataSize = sizeof(DWORD) // e
+ + bitlen / 16 //prime1
+ + bitlen / 16 //prime2
+ ;
+ if (bFormat & 2)
+ {
+ dwKeyDataSize+= bitlen / 16 //coefficient
+ + bitlen / 16 //exp1
+ + bitlen / 16 //exp2
+ ;
+ }
+ if (bFormat & 1)
+ {
+ dwKeyDataSize+= bitlen / 8 ; //modulus
+ }
+ dwOffset = 1;
+ dw5F48HeaderSize = 1 + BuildSingleTlv(b5F48Header, 0x48, dwKeyDataSize, &dwOffset);
+ // build the extended header list in a buffer
+ dwExtendedHeaderListSize = 2 // for the crt to indicate the private key
+ + dw7F48HeaderSize
+ + dw5F48HeaderSize
+ + dwKeyDataSize;
+ dwOffset = 0;
+ dw4DHeaderSize = BuildSingleTlv(b4DHeader, 0x4D, dwExtendedHeaderListSize, &dwOffset);
+
+ // allocate the memory
+ *pdwTlvSize = dw4DHeaderSize + dwExtendedHeaderListSize;
+ *ppbTlv = pCardData->pfnCspAlloc(*pdwTlvSize);
+ if (! *ppbTlv)
+ {
+ dwReturn = SCARD_E_NO_MEMORY;
+ __leave;
+ }
+ // 4D header
+ dwOffset = 0;
+ memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize);
+ dwOffset += dw4DHeaderSize;
+ // control reference templace
+ (*ppbTlv)[dwOffset++] = Containers[dwContainer].Tag;
+ (*ppbTlv)[dwOffset++] = 0;
+ // cardholder private key template
+ memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize);
+ dwOffset += dw7F48HeaderSize;
+ // Concatenation of key data header
+ memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize);
+ dwOffset += dw5F48HeaderSize;
+ // Concatenation of key data
+ // exponent in little endian
+ (*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000);
+ (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000);
+ (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100);
+ (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1);
+ // prime1
+ memcpy(*ppbTlv + dwOffset, pbPublicKeyData + bitlen/8 , bitlen / 16);
+ dwOffset += bitlen / 16;
+ // prime2
+ memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1) * bitlen / 16 , bitlen / 16);
+ dwOffset += bitlen / 16;
+ if (bFormat & 2)
+ {
+ // coeff
+ memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 3) * bitlen / 16 , bitlen / 16);
+ dwOffset += bitlen / 16;
+ // exponent1
+ memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 1) * bitlen / 16 , bitlen / 16);
+ dwOffset += bitlen / 16;
+ // exponent2
+ memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 2) * bitlen / 16 , bitlen / 16);
+ dwOffset += bitlen / 16;
+ }
+ if (bFormat & 1)
+ {
+ // modulus
+ memcpy(*ppbTlv + dwOffset, pbPublicKeyData, bitlen / 8);
+ }
}
__finally
{
@@ -421,21 +566,25 @@
{
DWORD dwReturn;
PSTR szAlgorithmAttributes = NULL;
- PBYTE pbData = NULL;
- DWORD dwResponseSize;
+ PBYTE pbTlv = NULL;
+ DWORD dwTlvSize;
+ PBYTE pbCommand = NULL;
+ DWORD dwCommandSize;
OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
+ BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
__try
{
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
// check blob
- if (pbPublicKeyBlob->blobheader.aiKeyAlg != Containers[dwContainer].aiKeyAlg)
+ if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
+ pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
{
Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
dwReturn = SCARD_E_INVALID_PARAMETER;
__leave;
}
- if (pbPublicKeyBlob->blobheader.bType != PUBLICKEYBLOB)
+ if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
{
Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
dwReturn = SCARD_E_INVALID_PARAMETER;
@@ -465,13 +614,59 @@
{
__leave;
}
+ dwReturn = BuildPrivateKeyTlv(pCardData, pbPublicKeyBlob, dwContainer, Attributes.bFormat, &pbTlv, &dwTlvSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
+ //TraceDump(WINEVENT_LEVEL_VERBOSE, pbTlv, dwTlvSize);
+ if (dwTlvSize > 0xFF)
+ {
+ dwCommandSize = 7 + dwTlvSize;
+
+ }
+ else
+ {
+ dwCommandSize = 5 + dwTlvSize;
+ }
+ pbCommand = pCardData->pfnCspAlloc(dwCommandSize);
+ if (!pbCommand)
+ {
+ Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
+ dwReturn = SCARD_E_NO_MEMORY;
+ __leave;
+ }
+ memcpy(pbCommand, bCommand, 4);
+ if (dwTlvSize > 0xFF)
+ {
+ pbCommand[4] = 0;
+ pbCommand[5] = (BYTE)(dwTlvSize / 0x100);
+ pbCommand[6] = (BYTE)(dwTlvSize % 0x100);
+ memcpy(pbCommand + 7, pbTlv, dwTlvSize);
+ }
+ else
+ {
+ pbCommand[4] = (BYTE) dwTlvSize;
+ memcpy(pbCommand + 5, pbTlv, dwTlvSize);
+ }
+ dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
+ if (dwReturn)
+ {
+ __leave;
+ }
}
__finally
{
- if (dwReturn)
+ if (pbCommand)
{
-
+ SecureZeroMemory(pbCommand, dwCommandSize);
+ pCardData->pfnCspFree(pbCommand);
}
+ if (pbTlv)
+ {
+ SecureZeroMemory(pbTlv, dwTlvSize);
+ pCardData->pfnCspFree(pbTlv);
+ }
}
return dwReturn;
}
More information about the Openpgpmdrv-commits
mailing list