[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