/********************************************************************
	Created:	5:3:2003   9:26
	Filename: 	derivekeytest.cpp
	Author:		Yubo
	Copyright:	
				Copyright(C) 1998-2004, Feitian Technologies Co., Ltd.
				All rights reserved.
				
	Purpose:	Derive a key(RC4 or DES) and use it encrypt ,decrypt!
	            Testing EP1CSP32.DAT[Upgrate!].
*********************************************************************/

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DeriveKeyTest.h"
DeriveKeyTest::DeriveKeyTest()
{

}

DeriveKeyTest::~DeriveKeyTest()
{

}

int DeriveKeyTest::Testkey(CK_ULONG ulALG)
{
	HCRYPTPROV hCryptProv = NULL;
	HCRYPTKEY hKey = 0;
	HCRYPTHASH hHash = 0;
	char* szPassword = "UsbToken Derive key test!";
	DWORD dwLength;
	printf("\n\nNOTICE:Get the handle from UsbToken...\n");
	printf("CryptAcquireContext\n");
	char cKeyContainer[32] = {0};
	srand( (unsigned)time( NULL ) );
	unsigned long ulName = rand() * rand();
	ltoa(ulName, cKeyContainer, 16);
	printf("\nCSP name:%s\n", EPS1K_CSP_NAME);
	if(!CryptAcquireContext(&hCryptProv,CONTAINER,EPS1K_CSP_NAME,PROV_RSA_FULL,0))
	{
		if(!CryptAcquireContext(&hCryptProv, CONTAINER, EPS1K_CSP_NAME, PROV_RSA_FULL, CRYPT_NEWKEYSET))
		{
			printf("X X X X X CryptAcquireContext() failed: ERR CODE=0x%0x\n", GetLastError());
			return CSP_FUNC_FAILED;
		}
		else
		{
			printf("...OK!\n");
		}
	}
	// Create a hash object.
	printf("CryptCreateHash\n");
	if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) 
	{
		printf("X X X X X Error %x during CryptCreateHash!\n", GetLastError());
		printf("CryptReleaseContext:");
		if(!CryptReleaseContext(hCryptProv, 0))
			printf("Err:CryptReleaseContext()!failed!ERR CODE=0x%0x\n",GetLastError());
		else
			printf("...OK!\n");
		return CSP_FUNC_FAILED;
	}
	else
	{
		printf("...OK!\n");
	}
	
	// Hash the password string.
	dwLength = strlen(szPassword);
	if(dwLength%8 != 0)
	{
		dwLength = (dwLength/8 + 1)*8;
	}
	printf("CryptHashData\n");
	if(!CryptHashData(hHash, (BYTE *)szPassword, dwLength, 0)) 
	{
		printf("X X X X X Error %x during CryptHashData!\n", GetLastError());
		printf("CryptReleaseContext:");
		if(!CryptReleaseContext(hCryptProv, 0))
			printf("Err:CryptReleaseContext()!failed!ERR CODE=0x%0x\n",GetLastError());
		else
			printf("...OK!\n");
		return CSP_FUNC_FAILED;
	}
	else
	{
		printf("...OK!\n");
	}
	
	// Create a block cipher session key based on the hash of the password.
	printf("CryptDeriveKey\n");
	if(!CryptDeriveKey(hCryptProv, ulALG, hHash, CRYPT_EXPORTABLE, &hKey))
	{
		printf("X X X X X Error %x during CryptDeriveKey!\n", GetLastError());
		printf("CryptReleaseContext:");
		if(!CryptReleaseContext(hCryptProv, 0))
			printf("Err:CryptReleaseContext()!failed!ERR CODE=0x%0x\n",GetLastError());
		else
			printf("...OK!\n");
		return CSP_FUNC_FAILED;
	}
	else
	{
		printf("...OK!\n"); 
		printf("\n Derive hKey= 0x%0x\n", hKey);
	}
	//Encrypt Data with RC2 key:
	BYTE pData[1024] = "UsbToken: Encrypt Data with the derive key (des or rc4) /!\0";
	DWORD dwLen = 60;
//	DWORD dwBufferLen=0;
//	if(0 != dwLen%8)
//	{
//		unsigned long ulMod = dwLen/8;
//		dwBufferLen = (ulMod+1)*8;
//	}
//	else
//		dwBufferLen=dwLen;
//	BYTE* pDataBuffer=new BYTE[dwBufferLen];
//	pDataBuffer=pData;
	printf("Data to be encrypted:\n"); 
	printf("\t\t%s\n", pData);
	printf("Data Length= %d", dwLen);
	//encrypt:
	printf("\nCryptEncrypt:");
	if(!CryptEncrypt(hKey, NO_HASH, LAST_DATA, 0, pData, &dwLen, 1024))
	{
		printf("X X X X X CryptEncrypt() failed: ERR CODE=0x%0x\n", GetLastError());
		printf("CryptReleaseContext:");
		if(!CryptReleaseContext(hCryptProv, 0))
			printf("Err:CryptReleaseContext()!failed!ERR CODE=0x%0x\n",GetLastError());
		else
			printf("...OK!\n");
		return CSP_FUNC_FAILED;
	}
	else
	{
		printf("...OK!\n");
		printf("Data after encrypted:\n");
		printf("\t\t%s\n", pData);
		printf("Data Length= %d\n", dwLen);
	}
	//Decrypt Data with RC2 key:
	printf("\nCryptDecrypt:");
	if(!CryptDecrypt(hKey, NO_HASH, LAST_DATA, 0, pData, &dwLen))
	{
		printf("X X X X X CryptDecrypt() failed: ERR CODE=0x%0x\n", GetLastError());
		printf("CryptReleaseContext:");
		if(!CryptReleaseContext(hCryptProv, 0))
			printf("Err:CryptReleaseContext()!failed!ERR CODE=0x%0x\n",GetLastError());
		else
			printf("...OK!\n");
		return CSP_FUNC_FAILED;
	}
	else
	{
			printf("...OK!\n");
			printf("Decrypt data:\n\t\t%s\n", pData);
	}
	//delete pDataBuffer;
	printf("CryptReleaseContext:");
	if(!CryptReleaseContext(hCryptProv, 0))
		printf("Err:CryptReleaseContext()!failed!ERR CODE=0x%0x\n",GetLastError());
	else
		printf("...OK!\n");
	return CSP_OK;
}
