// KeyGenTest.cpp: implementation of the KeyGenTest class.
//
//////////////////////////////////////////////////////////////////////

#include "KeyGenTest.h"
#include <malloc.h>

#define  DLENGTH 1024
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

KeyGenTest::KeyGenTest()
{

}

KeyGenTest::~KeyGenTest()
{

}

void KeyGenTest::RunRC2KeyGenerationTest(CK_SESSION_HANDLE hSession)
{
	START_OP("\n///////////////////////////////////////////////////////");
	START_OP("Init RC2 key...");
	CK_RV rv;
	CK_OBJECT_HANDLE hKey = 0;
	CK_BYTE pbMsg[] = "UsbToken RunRC2KeyGenerationTest.";
	CK_ULONG ulMsgLen = strlen((const char *)pbMsg);
	if(0 != ulMsgLen%8)
	{
		CK_ULONG Mod8 = ulMsgLen/8;
		ulMsgLen =(Mod8+1)*8;
	}

	CK_BYTE bCipherBuffer[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulCipherLen = 0;
	CK_BYTE bRestoredMsg[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulRestoredMsgLen = 0;
	do
	{
		//login first:
		CK_BYTE bPIN[MAX_PIN_LEN + 1] = {0}; // 4 bytes <= PIN <= 8 bytes
		memset(bPIN, 0, MAX_PIN_LEN + 1); 
		SHOW_INFO("\n\nPlease enter your USER-PIN\n")
		scanf ("%s", bPIN);
		START_OP("Try to login as user with USER-PIN.")
			CK_ULONG pinlen = strlen((char *)bPIN);
		rv =  C_Login(hSession, CKU_USER, bPIN, pinlen);
		CHECK_OP(rv)
		
		CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
		CK_KEY_TYPE keyType = CKK_RC2; 
		CK_BBOOL bTrue = true;
		CK_BBOOL bFalse = false;
		CK_ULONG ulLen = 127;//bytes:1~128
		CK_BYTE_PTR ucKey = new CK_BYTE [ulLen];
		memset(ucKey, 0, ulLen);
		CK_MECHANISM mechanism = {CKM_RC2_KEY_GEN, 0, ulLen};
		
		CK_ATTRIBUTE rc2tem[] = {
			{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
			{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
			{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
			{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
			{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_VALUE, ucKey, ulLen},
			{CKA_VALUE_LEN, &ulLen, sizeof(CK_ULONG)}, 
		};
		CK_ULONG ulCount = 8;
		//generate key:
		START_OP("generate RC2 key...")
			rv =  C_GenerateKey(hSession, &mechanism, rc2tem, ulCount, &hKey); 
		CHECK_OP(rv)
			
		CK_MECHANISM ckMechanism = {CKM_RC2_ECB, bCipherBuffer, sizeof(bCipherBuffer)};
		
		START_OP("Encrypting initialize.")  
			rv =  C_EncryptInit(hSession, &ckMechanism, hKey); 
		CHECK_OP(rv)
			
			START_OP("Encrypt the message.")
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			ulMsgLen = ulCipherLen;
		CHECK_OP(rv)
			
			START_OP("Encrypt message Final.")
			rv =  C_EncryptFinal(hSession, bCipherBuffer, &ulCipherLen);
		CHECK_OP(rv)
			
			START_OP("Decrypting initialize.")
			rv =  C_DecryptInit(hSession, &ckMechanism, hKey);
		printf("\nEncrypted data:%s", bCipherBuffer);
		CHECK_OP(rv)
			
			START_OP("Decrypt the message.")
			ulCipherLen =  ulMsgLen;
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			START_OP("Decrypt message Final...")
			rv =  C_DecryptFinal(hSession, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			// Decrypt a message. 
			SHOW_INFO("\nThe message decrypted is \"")
			SHOW_INFO((char*)bRestoredMsg)
			SHOW_INFO("\".");
		
		START_OP("Verify the message.")
			if(0 == memcmp(pbMsg, bRestoredMsg, ulRestoredMsgLen))
				CHECK_OP(CKR_OK)
				else
				SHOW_INFO("....[FAILED]\n")
				rv =  C_Logout(hSession);
			
			delete [] ucKey;
			ucKey = NULL_PTR;

			START_OP("Logout normally...")
				rv = C_Logout(hSession);
			CHECK_OP(rv);
	}while(0);
}


/////////////////////////////RC4/////
void KeyGenTest::RunRC4KeyGenerationTest(CK_SESSION_HANDLE hSession)
{
	START_OP("\n///////////////////////////////////////////////////////");
	START_OP("Init RC4 key...");
	CK_RV rv;
	CK_OBJECT_HANDLE hKey = 0;
	CK_BYTE pbMsg[] = "UsbToken RunRC4KeyGenerationTest.";
	CK_ULONG ulMsgLen = strlen((const char *)pbMsg);
	if(0 != ulMsgLen%8)
	{
		CK_ULONG Mod8 = ulMsgLen/8;
		ulMsgLen =(Mod8+1)*8;
	}

	CK_BYTE bCipherBuffer[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulCipherLen = 0;
	CK_BYTE bRestoredMsg[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulRestoredMsgLen = 0;
	do
	{
		//login first:
		CK_BYTE bPIN[MAX_PIN_LEN + 1] = {0}; // 4 bytes <= PIN <= 8 bytes
		memset(bPIN, 0, MAX_PIN_LEN + 1); 
		SHOW_INFO("\n\nPlease enter your USER-PIN\n")
		scanf ("%s", bPIN);
		START_OP("Try to login as user with USER-PIN.")
			CK_ULONG pinlen = strlen((char *)bPIN);
		rv =  C_Login(hSession, CKU_USER, bPIN, pinlen);
		CHECK_OP(rv)
		
		CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
		CK_KEY_TYPE keyType = CKK_RC4; 
		CK_BBOOL bTrue = true;
		CK_BBOOL bFalse = false;
		CK_ULONG ulLen = 255;//bytes:1~256
		CK_BYTE_PTR ucKey = new CK_BYTE [ulLen];
		memset(ucKey, 0, ulLen);
		CK_MECHANISM mechanism = {CKM_RC4_KEY_GEN, 0, ulLen};
		
		CK_ATTRIBUTE rc4tem[] = {
			{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
			{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
			{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
			{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
			{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_VALUE, ucKey, ulLen},
			{CKA_VALUE_LEN, &ulLen, sizeof(CK_ULONG)}, 
		};
		CK_ULONG ulCount = 8;
		//generate key:
		START_OP("generate RC4 key...")
			rv =  C_GenerateKey(hSession, &mechanism, rc4tem, ulCount, &hKey); 
		CHECK_OP(rv)
			
		CK_MECHANISM ckMechanism = {CKM_RC4, bCipherBuffer, sizeof(bCipherBuffer)};
		
		START_OP("Encrypting initialize.")  
			rv =  C_EncryptInit(hSession, &ckMechanism, hKey); 
		CHECK_OP(rv)
			
			START_OP("Encrypt the message.")
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			ulMsgLen = ulCipherLen;
		CHECK_OP(rv)
			
			START_OP("Encrypt message Final.")
			rv =  C_EncryptFinal(hSession, bCipherBuffer, &ulCipherLen);
		CHECK_OP(rv)
		printf("\nEncrypted data:%s", bCipherBuffer);	
			START_OP("Decrypting initialize.")
			rv =  C_DecryptInit(hSession, &ckMechanism, hKey);
		CHECK_OP(rv)
			
			START_OP("Decrypt the message.")
			ulCipherLen =  ulMsgLen;
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			START_OP("Decrypt message Final...")
			rv =  C_DecryptFinal(hSession, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			// Decrypt a message. 
			SHOW_INFO("\nThe message decrypted is \"")
			SHOW_INFO((char*)bRestoredMsg)
			SHOW_INFO("\".");
		
		START_OP("Verify the message.")
			if(0 == memcmp(pbMsg, bRestoredMsg, ulRestoredMsgLen))
				CHECK_OP(CKR_OK)
				else
				SHOW_INFO("....[FAILED]\n")
			START_OP("Logout normally...")
				rv = C_Logout(hSession);
			CHECK_OP(rv);
			
			delete [] ucKey;
			ucKey = NULL_PTR;
	}while(0);
}

////


/////////
void KeyGenTest::RunDESKeyGenerationTest(CK_SESSION_HANDLE hSession)
{
	START_OP("\n///////////////////////////////////////////////////////");
	START_OP("Init Des key...");
	CK_RV rv;
	CK_OBJECT_HANDLE hKey = 0;
	CK_BYTE pbMsg[] = "UsbToken RunDESKeyGenerationTest.";
	CK_ULONG ulMsgLen = strlen((const char *)pbMsg);
	if(0 != ulMsgLen%8)
	{
		CK_ULONG Mod8 = ulMsgLen/8;
		ulMsgLen =(Mod8+1)*8;
	}

	CK_BYTE bCipherBuffer[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulCipherLen = 0;
	CK_BYTE bRestoredMsg[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulRestoredMsgLen = 0;
	do
	{
		//login first:
		CK_BYTE bPIN[MAX_PIN_LEN + 1] = {0}; // 4 bytes <= PIN <= 8 bytes
		memset(bPIN, 0, MAX_PIN_LEN + 1); 
		SHOW_INFO("\n\nPlease enter your USER-PIN\n")
		scanf ("%s", bPIN);
		START_OP("Try to login as user with USER-PIN.")
			CK_ULONG pinlen = strlen((char *)bPIN);
		rv =  C_Login(hSession, CKU_USER, bPIN, pinlen);
		CHECK_OP(rv)
		
		CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
		CK_KEY_TYPE keyType = CKK_DES; 
		CK_BBOOL bTrue = true;
		CK_BBOOL bFalse = false;
		CK_ULONG ulLen = 8;//bytes:8
		CK_BYTE ucKey[8] = "123456\0";
		memset(ucKey, 0, ulLen);
		CK_MECHANISM mechanism = {CKM_DES_KEY_GEN, 0, ulLen};
		
		CK_ATTRIBUTE Destem[] = {
			{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
			{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
			{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
			{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
			{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_VALUE, NULL_PTR, 0},
		};
		CK_ULONG ulCount = 7;
		
		CK_MECHANISM mechDES = { CKM_DES_KEY_GEN, NULL_PTR, 0 };
		//Set the key length,
		//CK_MECHANISM mechDES = { CKM_DES_KEY_GEN, 0, 8/*key_length*/ };
			CK_OBJECT_HANDLE hSecretKey;
		rv = C_GenerateKey(hSession, &mechDES, NULL_PTR, 0, &hSecretKey);
		
		//generate key:
		START_OP("generate DES key...")
			rv =  C_GenerateKey(hSession, &mechanism, NULL_PTR, 0, &hKey); 
		CHECK_OP(rv)
			
		CK_MECHANISM ckMechanism = {CKM_DES_ECB, bCipherBuffer, sizeof(bCipherBuffer)};
		
		START_OP("Encrypting initialize.")  
			rv =  C_EncryptInit(hSession, &ckMechanism, hKey); 
		CHECK_OP(rv)
			
			START_OP("Encrypt the message.")
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			ulMsgLen = ulCipherLen;
		CHECK_OP(rv)
			
			START_OP("Encrypt message Final.")
			rv =  C_EncryptFinal(hSession, bCipherBuffer, &ulCipherLen);
			printf("\nEncrypted data:%s", bCipherBuffer);
		CHECK_OP(rv)
			
			START_OP("Decrypting initialize.")
			rv =  C_DecryptInit(hSession, &ckMechanism, hKey);
		CHECK_OP(rv)
			
			START_OP("Decrypt the message.")
			ulCipherLen =  ulMsgLen;
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			START_OP("Decrypt message Final...")
			rv =  C_DecryptFinal(hSession, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			// Decrypt a message. 
			SHOW_INFO("\nThe message decrypted is \"")
			SHOW_INFO((char*)bRestoredMsg)
			SHOW_INFO("\".");
		
		START_OP("Verify the message.")
			if(0 == memcmp(pbMsg, bRestoredMsg, ulRestoredMsgLen))
				CHECK_OP(CKR_OK)
				else
				SHOW_INFO("....[FAILED]\n")
			START_OP("Logout normally...")
				rv = C_Logout(hSession);
			CHECK_OP(rv);
			
	}while(0);
}
///////////////////////////////////

//3des
void KeyGenTest::RunDES3KeyGenerationTest(CK_SESSION_HANDLE hSession)
{
	START_OP("\n///////////////////////////////////////////////////////");
	START_OP("\nInit Des3 key...");
	CK_RV rv;
	CK_OBJECT_HANDLE hKey = 0;
	CK_BYTE pbMsg[] = "UsbToken: RunDES3KeyGenerationTest.";
	CK_ULONG ulMsgLen = strlen((const char *)pbMsg);
	if(0 != ulMsgLen%8)
	{
		CK_ULONG Mod8 = ulMsgLen/8;
		ulMsgLen =(Mod8+1)*8;
	}

	CK_BYTE bCipherBuffer[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulCipherLen = 0;
	CK_BYTE bRestoredMsg[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulRestoredMsgLen = 0;
	do
	{
		//login first:
		CK_BYTE bPIN[MAX_PIN_LEN + 1] = {0}; // 4 bytes <= PIN <= 8 bytes
		memset(bPIN, 0, MAX_PIN_LEN + 1); 
		SHOW_INFO("\n\nPlease enter your USER-PIN\n")
		scanf ("%s", bPIN);
		START_OP("Try to login as user with USER-PIN.")
			CK_ULONG pinlen = strlen((char *)bPIN);
		rv =  C_Login(hSession, CKU_USER, bPIN, pinlen);
		CHECK_OP(rv)
		
		CK_OBJECT_CLASS oClass = CKO_SECRET_KEY;
		CK_KEY_TYPE keyType = CKK_DES3; 
		CK_BBOOL bTrue = true;
		CK_BBOOL bFalse = false;
		CK_ULONG ulLen = 24;//bytes:8
		CK_BYTE ucKey[24] = "1234561234561234561234\0";
		memset(ucKey, 0, ulLen);
		CK_MECHANISM mechanism = {CKM_DES3_KEY_GEN, 0, ulLen};
		
		CK_ATTRIBUTE Des3tem[] = {
			{CKA_CLASS, &oClass, sizeof(CK_OBJECT_CLASS)},
			{CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE)},
			{CKA_TOKEN, &bFalse, sizeof(CK_BBOOL)},
			{CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL)},
			{CKA_ENCRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_DECRYPT, &bTrue, sizeof(CK_BBOOL)},
			{CKA_VALUE, NULL_PTR, 0},
		};
		CK_ULONG ulCount = 7;
		//generate key:
		START_OP("generate DES3 key...")
			rv =  C_GenerateKey(hSession, &mechanism,NULL_PTR, 0, &hKey); 
		CHECK_OP(rv)
			
		CK_MECHANISM ckMechanism = {CKM_DES3_ECB, bCipherBuffer, sizeof(bCipherBuffer)};
		
		START_OP("Encrypting initialize.")  
			rv =  C_EncryptInit(hSession, &ckMechanism, hKey); 
		CHECK_OP(rv)
			
			START_OP("Encrypt the message.")
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, bCipherBuffer, &ulCipherLen);
			ulMsgLen = ulCipherLen;
		CHECK_OP(rv)
			
			START_OP("Encrypt message Final.")
			rv =  C_EncryptFinal(hSession, bCipherBuffer, &ulCipherLen);
			printf("\nEncrypt data:%s", bCipherBuffer);
		CHECK_OP(rv)

			
			START_OP("Decrypting initialize.")
			rv =  C_DecryptInit(hSession, &ckMechanism, hKey);
		CHECK_OP(rv)
			
			START_OP("Decrypt the message.")
			ulCipherLen =  ulMsgLen;
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
			rv =  C_Decrypt(hSession, bCipherBuffer, ulCipherLen, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			START_OP("Decrypt message Final...")
			rv =  C_DecryptFinal(hSession, bRestoredMsg, &ulRestoredMsgLen);
		CHECK_OP(rv)
			
			// Decrypt a message. 
			SHOW_INFO("\nThe message decrypted is \"")
			SHOW_INFO((char*)bRestoredMsg)
			SHOW_INFO("\".");
		
		START_OP("Verify the message.")
			if(0 == memcmp(pbMsg, bRestoredMsg, ulRestoredMsgLen))
				CHECK_OP(CKR_OK)
				else
				SHOW_INFO("....[FAILED]\n")
			START_OP("Logout normally...")
				rv = C_Logout(hSession);
			CHECK_OP(rv);
			
	}while(0);
}

//////////////////////////////////////////////////////////////////////////
//	RunRsaKeyGenerationTest()
//
//	Provide example on how to generate a public/private key pair, such as 
//	an RSA key, and use the key pair to sign and verify messages.
//
//	The objects created are "token" objects that reside in the token. 
//////////////////////////////////////////////////////////////////////////
void KeyGenTest::RunRsaKeyGenerationTest (CK_SESSION_HANDLE	hSession)
{
	START_OP("\n///////////////////////////////////////////////////////");
	SHOW_INFO("\n\nThe next demo will generate a RSA key pair on UsbToken.")
	CK_RV rv;
	CK_BBOOL bTrue = TRUE;
	CK_BBOOL bFalse = FALSE;
	CK_BYTE bPIN[MAX_PIN_LEN + 1]; // 4 bytes <= PIN <= 8 bytes
	CK_ULONG ulModulusBits = MODULUS_BIT_LENGTH; 
	CK_BYTE subject[] = "Sample RSA Key Pair";
	CK_ULONG keyType = CKK_RSA;

	CK_OBJECT_HANDLE hPubKey = 0;
	CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
	CK_ATTRIBUTE pubTemplate[] = { 
		{CKA_CLASS,			&pubClass,		sizeof(pubClass)},
		{CKA_KEY_TYPE,		&keyType,		sizeof(keyType)},
		{CKA_SUBJECT,		subject,		sizeof(subject)},
		{CKA_MODULUS_BITS,	&ulModulusBits, sizeof(ulModulusBits)},
		{CKA_ENCRYPT,		&bTrue,			sizeof(bTrue)},
		{CKA_TOKEN,			&bFalse,			sizeof(bTrue)},
		{CKA_WRAP,			&bTrue,			sizeof(bTrue)},
	};	// Without specifying CKA_PRIVATE attribute in this case, 
		// a public key will be created by default. 

	CK_OBJECT_HANDLE hPriKey		= 0;
	CK_OBJECT_CLASS priClass	= CKO_PRIVATE_KEY;
	CK_ATTRIBUTE priTemplate[] = {
		{CKA_CLASS,			&priClass,	sizeof(priClass)},
		{CKA_KEY_TYPE,		&keyType,	sizeof(keyType)},
		{CKA_SUBJECT,		subject,	sizeof(subject)},
		{CKA_DECRYPT,		&bTrue,		sizeof(bTrue)},
		{CKA_PRIVATE,		&bTrue,		sizeof(bTrue)},
		{CKA_SENSITIVE,		&bTrue,		sizeof(bTrue)},
		{CKA_TOKEN,			&bFalse,		sizeof(bTrue)},
		{CKA_EXTRACTABLE,	&bTrue,		sizeof(bTrue)},
		{CKA_UNWRAP,		&bTrue,		sizeof(bTrue)},
	};

    CK_MECHANISM keyGenMechanism = {
		CKM_RSA_PKCS_KEY_PAIR_GEN, 
		NULL_PTR, 
		0
	};	
	CK_MECHANISM ckMechanism = {CKM_RSA_PKCS, NULL_PTR, 0};
	CK_BYTE pbMsg[DLENGTH] = {0};
	CK_ULONG ulMsgLen = strlen((const char *)pbMsg);
	CK_BYTE bSignatureBuffer[MODULUS_BIT_LENGTH] = {0};
	CK_ULONG ulSignatureLen = 0;
	CK_BYTE_PTR pbCipherBuffer = NULL;
	CK_ULONG ulCipherLen = 0;
	
	CK_ULONG ulRestoredMsgLen = 0;

	SHOW_INFO("\nYou will need to enter your USER-PIN to log in.")

	do{
		// When the CKA_TOKEN attribute is set to TRUE, the key objects are	
		// to be created on the token. In this case, user logon is required
		// before a "token" object can be stored in the hardware token.

				memset(bPIN, 0, MAX_PIN_LEN + 1); 
				SHOW_INFO("\nPlease enter your USER-PIN\n")
				scanf ("%s", bPIN);
		
				START_OP("Try to login as user with USER-PIN.")
				CK_ULONG pinlen = strlen((char *)bPIN);
				rv =  C_Login(hSession, CKU_USER, bPIN, pinlen);
				//rv =  C_Login(hSession, CKU_USER, bPIN, (CK_ULONG)strlen((char *)bPIN));
				CHECK_OP(rv)
	}while (rv != CKR_OK);

	if(rv == CKR_OK)
	{
		do {
			// Generate a 1024-bit RSA key pair on the token.
			START_OP("Generating public/private key pair.");
			rv =  C_GenerateKeyPair(hSession, &keyGenMechanism,
								   pubTemplate, countof(pubTemplate),
								   priTemplate, countof(priTemplate),
								   &hPubKey, &hPriKey);
			CHECK_OP(rv)
/*
			// Try Sign and Verify operations with the key pair.

			// Sign a message. 
			SHOW_INFO("\nThe message to be signed is \"")
			SHOW_INFO(pbMsg)
			SHOW_INFO("\".");

			ulSignatureLen	= sizeof(bSignatureBuffer);

			START_OP("Signing initialize.");
			rv =  C_SignInit(hSession, &ckMechanism, hPriKey);
			CHECK_OP(rv);

			START_OP("Sign the message.")
			rv =  C_Sign(hSession, 
				pbMsg,
				ulMsgLen, 
				bSignatureBuffer, &ulSignatureLen);
			CHECK_OP(rv)

			// Verify the previously signed message.
			START_OP("Verifying initialize.")
			rv =  C_VerifyInit(hSession, &ckMechanism, hPubKey);
			CHECK_OP(rv)
	
			START_OP("Verify the message.")
			rv =  C_Verify(hSession, 
				pbMsg, ulMsgLen, 
				bSignatureBuffer, ulSignatureLen);
			CHECK_OP(rv)

			// Encrypt a message. 
			SHOW_INFO("\nThe message to be Encrypt is \"")
			SHOW_INFO(pbMsg)
			SHOW_INFO("\".");
*/

for(int i=0;i<DLENGTH;i++)
{
	pbMsg[i] = 'A';
	printf("%d = %d, ", i, pbMsg[i]);
}

ulMsgLen = sizeof(pbMsg);

			START_OP("Encrypting initialize.")
			rv =  C_EncryptInit(hSession,
				&ckMechanism,
				hPubKey);
			CHECK_OP(rv)

			START_OP("Obtain the size of the encrypted message.")
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, NULL_PTR, &ulCipherLen);
			CHECK_OP(rv)

			START_OP("Allocate buffer for the encrypted message.")
			pbCipherBuffer = (CK_BYTE_PTR)malloc(ulCipherLen);
			if (! pbCipherBuffer)
				CHECK_OP(CKR_HOST_MEMORY)
			else
			{
				memset(pbCipherBuffer, 0, ulCipherLen);
				CHECK_OP(CKR_OK);
			}

			START_OP("Encrypt the message.");
			CK_ULONG 	ulCipherLen2;
			rv =  C_Encrypt(hSession, pbMsg, ulMsgLen, pbCipherBuffer, &ulCipherLen2);
			CHECK_OP(rv);

			START_OP("Decrypting initialize.")
			rv =  C_DecryptInit(hSession,
				&ckMechanism,
				hPriKey);
			CHECK_OP(rv)

			START_OP("Obtain the size of the decrypted message.")
			rv =  C_Decrypt(hSession, pbCipherBuffer, ulCipherLen2, NULL_PTR, &ulRestoredMsgLen);
			CHECK_OP(rv);

			START_OP("Allocate buffer for the decrypted message.");

/*
						if(pbRestoredMsg)
							pbRestoredMsg = NULL_PTR;
						pbRestoredMsg = (CK_BYTE_PTR) malloc(ulRestoredMsgLen);
						if (! pbRestoredMsg)
							CHECK_OP(CKR_HOST_MEMORY) 
						else
						{
							memset(pbRestoredMsg, 0, ulRestoredMsgLen);
							CHECK_OP(CKR_OK);
						}*/
			

			START_OP("Decrypt the message.")

			CK_BYTE pbRestoredMsg[1024] = {0};

			rv =  C_Decrypt(hSession, pbCipherBuffer, ulCipherLen2, pbRestoredMsg, &ulRestoredMsgLen);
			CHECK_OP(rv)

			// Decrypt a message. 
			SHOW_INFO("\nThe message decrypted is \"")
			//SHOW_INFO((char*)pbRestoredMsg)
			for(int ii=0;ii<DLENGTH;ii++)
			{
				if(pbRestoredMsg[ii] != 'A')
					printf("\n%d = error!", ii);
				else
					printf("%d = %d, ", ii, pbRestoredMsg[ii]);
			}


			START_OP("Verify the message.");
			if(0 == memcmp(pbMsg, pbRestoredMsg, ulMsgLen))
				CHECK_OP(CKR_OK)
			else
				SHOW_INFO("....[FAILED]\n")

			// Remove the RSA key pair from the UsbToken.
			START_OP("Proceed to remove the RSA key pair from the token.");
			rv =  C_DestroyObject(hSession, hPubKey);
			CHECK_OP(rv);

			START_OP("Remove private key obeject.");
			rv =  C_DestroyObject(hSession, hPriKey);
			CHECK_OP(rv);

			START_OP("Logout normally...")
				rv = C_Logout(hSession);
			CHECK_OP(rv);
		}while (0);

		// Release the memory.
		if(pbCipherBuffer)
		{
			free(pbCipherBuffer);
			pbCipherBuffer = NULL;
		}
//		if(pbRestoredMsg)
//		{
//			 free(pbRestoredMsg);
//			pbCipherBuffer = NULL;
//		}
	}
}
