/********************************************************************
	Created:	5:10:2003   14:38
	Filename: 	syskeytest.cpp
	Author:		Yubo
	
	Purpose:	TEST: rc2,rc4, des,des3 key!
*********************************************************************/

#include "stdafx.h"
#include "SysKeyTest.h"

SysKeyTest::SysKeyTest()
{
}
SysKeyTest::~SysKeyTest()
{
}
int SysKeyTest::TestKey(CK_ULONG ulALG)
{
	HCRYPTPROV hCryptProv = NULL;
	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");
		}
	}
	
	//Enum algs those CSP support:
	printf("CryptGetProvParam:");
	BYTE *ptr = NULL;
	DWORD i;
	ALG_ID aiAlgid;
	DWORD dwBits;
	DWORD dwNameLen;
	CHAR szName[100] = {0}; // Often allocated dynamically
	BYTE pbData[1000] = {0}; // Often allocated dynamically
	DWORD cbData;
	DWORD dwFlags;
	CHAR *pszAlgType = NULL;
	
	// Enumerate the supported algorithms.
	for(i=0 ; ; i++) 
	{
		// Set the CRYPT_FIRST flag the first time through the loop.
		if(i == 0) 
		{
			dwFlags = CRYPT_FIRST;
		} 
		else 
		{
			dwFlags = 0;
		}
		
		// Retrieve information about an algorithm.
		cbData = 1000;
		if(!CryptGetProvParam(hCryptProv, PP_ENUMALGS, pbData, &cbData, dwFlags)) 
		{
			if(GetLastError() == ERROR_NO_MORE_ITEMS)
			{
				// Exit the loop.
				break;
			}
			else 
			{
				printf("X X X X X CryptGetProvParam() 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");
		}
		// Extract algorithm information from the 'pbData' buffer.
		ptr = pbData;
		aiAlgid = *(ALG_ID *)ptr;
		ptr += sizeof(ALG_ID);
		dwBits = *(DWORD *)ptr;
		ptr += sizeof(DWORD);
		dwNameLen = *(DWORD *)ptr;
		ptr += sizeof(DWORD);
		strncpy(szName, (char *)ptr, dwNameLen);
		
		// Determine the algorithm type.
		switch(GET_ALG_CLASS(aiAlgid)) 
		{
		case ALG_CLASS_DATA_ENCRYPT: pszAlgType = "Encrypt ";
			break;
		case ALG_CLASS_HASH: pszAlgType = "Hash ";
			break;
		case ALG_CLASS_KEY_EXCHANGE: pszAlgType = "Exchange ";
			break;
		case ALG_CLASS_SIGNATURE: pszAlgType = "Signature";
			break;
		default: pszAlgType = "Unknown ";
		}
		
		// Print information about the algorithm.  
		printf("Algid:%8.8xh, Bits:%-4d, Type:%s, NameLen:%-2d, Name:%s\n",
			aiAlgid, dwBits, pszAlgType, dwNameLen, szName
			);
	}

	HCRYPTKEY hKey = 0;
	printf("\nCryptGenKey:"); 
	if (!CryptGenKey(hCryptProv, ulALG, /*CRYPT_EXPORTABLE*/0,  &hKey))//RC4/DES are similar!!!!!!!!!!!!!!!!!!!
	{
		printf("X X X X X CryptGenKey() 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("hKey=0x%0x\n", hKey); 
	}
	//Encrypt Data with a key:
#define BUF_SIZE  1024
	BYTE pData[BUF_SIZE] = {0};
	BYTE pOrinData[BUF_SIZE] = {0};
	DWORD dwLen = 45;
	DWORD dwRetLen = dwLen;
	for(BYTE j = 0; j < 255; ++j)
		pData[j] = j;
	printf("Data to be encrypted:\n"); 
	ShowData(pData, dwLen);
	memcpy(pOrinData, pData, dwLen);
	//encrypt:
	printf("\nCryptEncrypt:");
	//Get size:
	CryptEncrypt(hKey, NO_HASH, LAST_DATA, 0, NULL, &dwRetLen, BUF_SIZE);
	//Get encrypted value:
	if(!CryptEncrypt(hKey, NO_HASH, LAST_DATA, 0, pData, &dwLen, BUF_SIZE))
	{
		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");
		ShowData(pData, dwLen);
	}
	//Decrypt Data with a 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");
		ShowData(pData, dwLen);
	}
	if(0 != memcmp(pData, pOrinData, dwLen))
	{
		printf("\n..... Decrypted data != Orginal Data.  \n");
	}
	else
		printf("\nEncrypt and Decrypt are OK!\n");
	printf("CryptReleaseContext:");
	if(!CryptReleaseContext(hCryptProv, 0))
		printf("Err:CryptReleaseContext()!failed!ERR CODE=0x%0x\n",GetLastError());
	else
		printf("...OK!\n");
	return CSP_OK;
}





















