// object_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "../pkcs11_wrapper.h"


int _tmain(int argc, _TCHAR* argv[])
{
	if(argc < 2)
		return 1;

	char * p11_dll = argv[1];

	pkcs11_wrapper p11_wrapper;

	if(0 != p11_wrapper.pkcs11_initialize(p11_dll))
	{
		return 1;
	}

	CK_FUNCTION_LIST_PTR pToken = p11_wrapper.GetFunctionsPtr();
	CK_RV rv = CKR_OK;

	CK_SLOT_ID_PTR pSlotList;
	CK_ULONG ulCount;
	CK_SESSION_HANDLE hSession;

	rv = pToken->C_GetSlotList(CK_TRUE, NULL_PTR, &ulCount);
	ERROR_THROW(rv);

	pSlotList = (CK_SLOT_ID_PTR)new CK_SLOT_ID[ulCount];;
	rv = pToken->C_GetSlotList(CK_TRUE, pSlotList, &ulCount);
	ERROR_THROW(rv);

	//Create a session
	rv = pToken->C_OpenSession(pSlotList[0], CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSession);
	ERROR_THROW(rv);

	CK_UTF8CHAR uPin[] = "11111111";
	rv = pToken->C_Login(hSession, CKU_USER, uPin, 8);
	ERROR_THROW(rv);

	CK_ULONG maxCount = 1024;
	CK_ULONG objCount3 = 0;
	pToken->C_FindObjectsInit(hSession, NULL_PTR, 0);
	pToken->C_FindObjects(hSession, NULL_PTR,maxCount, &objCount3);
	pToken->C_FindObjectsFinal(hSession);

	{
		CK_OBJECT_CLASS objClass = CKO_DATA;
		CK_UTF8CHAR label[] = "A data object";
		CK_UTF8CHAR application[] = "An application";
		CK_BYTE data[] = "Sample data";
		CK_BBOOL ckTrue = CK_TRUE;
		CK_ATTRIBUTE templateDataObject[] = {
			{CKA_CLASS, &objClass, sizeof(objClass)},
			{CKA_TOKEN, &ckTrue, sizeof(ckTrue)},
			{CKA_LABEL, label, sizeof(label)-1},
			{CKA_APPLICATION, application, sizeof(application)-1},
			{CKA_VALUE, data, sizeof(data)}
		};

		ulCount = sizeof(templateDataObject) / sizeof(CK_ATTRIBUTE);

		CK_OBJECT_HANDLE hDataObject;
		rv = pToken->C_CreateObject(hSession, templateDataObject, ulCount, &hDataObject);
		ERROR_THROW(rv);

	/*	CK_BYTE newData[8192] ={0};
		CK_ATTRIBUTE objValue[] ={
			{CKA_VALUE, newData, sizeof(newData)}
		};

		ulCount = sizeof(objValue) / sizeof(CK_ATTRIBUTE);

		rv = pToken->C_SetAttributeValue(hSession, hDataObject, objValue, ulCount);
		ERROR_THROW(rv);
		*/
	}

 	CK_ULONG objCount = 0;
	pToken->C_FindObjectsInit(hSession, NULL_PTR, 0);
	pToken->C_FindObjects(hSession, NULL_PTR,maxCount, &objCount);
	pToken->C_FindObjectsFinal(hSession);


	{ //Create cert object
		CK_OBJECT_CLASS cerClass = CKO_CERTIFICATE; 
		CK_CERTIFICATE_TYPE certType = CKC_X_509; 
		CK_UTF8CHAR label[] = "A certificate object"; 
		CK_BYTE subject[] = {"cert subject"}; 
		CK_BYTE id[] = {123}; 
		CK_BYTE certificate[] = {1,2,3,4,5,6,7,8,9}; 
		CK_BBOOL bTrue = CK_TRUE; 
		CK_ATTRIBUTE templateCert[] = { 
			{CKA_CLASS, &cerClass, sizeof(cerClass)}, 
			{CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)},
			{CKA_TOKEN, &bTrue, sizeof(bTrue)}, 
			{CKA_LABEL, label, sizeof(label)-1}, 
			{CKA_SUBJECT, subject, sizeof(subject)}, 
			{CKA_ID, id, sizeof(id)}, 
			{CKA_VALUE, certificate, sizeof(certificate)} 
		}; 

		ulCount = sizeof(templateCert) / sizeof(CK_ATTRIBUTE);

		CK_OBJECT_HANDLE hObject;
		rv = pToken->C_CreateObject(hSession, templateCert, ulCount, &hObject);
		ERROR_THROW(rv);
		
	
	}

	CK_ULONG objCount2 = 0;
	pToken->C_FindObjectsInit(hSession, NULL_PTR, 0);
	pToken->C_FindObjects(hSession, NULL_PTR,maxCount, &objCount2);
	pToken->C_FindObjectsFinal(hSession);

	if(objCount2 - objCount > 1)
	{
		rv = CKR_FUNCTION_FAILED;
		ERROR_THROW(rv);
	}

		
	
END_OF_FUN:
	if(rv != CKR_OK)
	{
		printf("Error = %0x \n", rv);
	}
	else
	{
		printf("Successfully!\n");
	}

	getchar();
	return 0;
}

