#include <windows.h>
#include <stdio.h>
#include "eTPkcs11.h"
#define SLEEP_TIME 5000
#define LOGFILE "D:\\eTokenTest\\log.txt"
#define etPKCS11_MODULE_NAME "etpkcs11"
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
CK_FUNCTION_LIST_PTR funcs;
CK_SLOT_ID SlotId = 0;
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();
int WriteToLog(char* str)
{
FILE* log;
log = fopen(LOGFILE, "a+");
if (log == NULL)
return -1;
fprintf(log, "%s\n", str);
fclose(log);
return 0;
}
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "eTokenTestService";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
}
void ServiceMain(int argc, char** argv)
{
int error;
CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
CK_ATTRIBUTE attr_label[] = {
{CKA_LABEL, NULL, 0},
};
CK_OBJECT_HANDLE hObj;
CK_ULONG num = 0;
CK_UTF8CHAR label_buf[128];
CK_RV rc = CKR_OK;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(
"eTokenTestService",
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
// Initialize Service
error = InitService();
if (error)
{
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);
// The worker loop of a service
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
int result;
// Try to log in to token
rc = funcs->C_OpenSession(SlotId,
(CKF_SERIAL_SESSION | CKF_RW_SESSION),
NULL,
0,
&hSession);
if (rc != CKR_OK) {
WriteToLog("Unable to open session.");
return;
}
rc = funcs->C_Login(hSession,
CKU_USER,
(CK_UTF8CHAR_PTR)"1qaz2WSX3edc",
12);
if (rc != CKR_OK) {
WriteToLog("Unable to log in to token.");
return;
}
// Try to read list of token objects
rc = funcs->C_FindObjectsInit(hSession, NULL, 0);
if (rc != CKR_OK) {
WriteToLog("Unable to initialie a finding process.");
return;
}
do {
char log_mess[128] = {'\0'};
hObj = CK_INVALID_HANDLE;
num = 0;
rc = funcs->C_FindObjects(hSession, &hObj, 1, &num);
if (rc != CKR_OK) {
WriteToLog("Unable to find objects.");
return;
}
if(num <= 0)
break;
sprintf(log_mess, "Handle: 0x%x\t", hObj);
WriteToLog(log_mess);
if (hObj != CK_INVALID_HANDLE) {
memset(label_buf, 0, sizeof(label_buf));
rc = funcs->C_GetAttributeValue(hSession, hObj,
attr_label, sizeof(attr_label)/sizeof(CK_ATTRIBUTE));
if (rc != CKR_OK) {
WriteToLog("Unable to get object attribute.");
} else {
sprintf(log_mess, "label:'%s'\n", label_buf);
WriteToLog(log_mess);
}
}
} while (num > 0);
rc = funcs->C_FindObjectsFinal(hSession);
if (rc != CKR_OK) {
WriteToLog("Unable to finalie a finding process.");
return;
}
// Try to log out from token
rc = funcs->C_Logout(hSession);
if (rc != CKR_OK) {
WriteToLog("Unable to logout from token.");
return;
}
rc = funcs->C_CloseSession(hSession);
if (rc != CKR_OK) {
WriteToLog("Unable to close the session.");
return;
}
result = WriteToLog("OK.");
if (result)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
Sleep(SLEEP_TIME);
}
return;
}
// Service initialization
int InitService()
{
int result;
HMODULE dll;
CK_C_GetFunctionList pcGetFunctionList;
CK_SLOT_ID *pSlotList = NULL;
CK_ULONG ulSlotCount = 0;
CK_SLOT_INFO sinfo;
CK_ULONG i;
CK_RV rc = CKR_OK;
result = WriteToLog("Testing started.");
dll = LoadLibrary(etPKCS11_MODULE_NAME);
if(!dll) {
WriteToLog("Unable to load eTPkcs11 library.");
return(-1);
}
pcGetFunctionList = (CK_C_GetFunctionList)GetProcAddress(dll, "C_GetFunctionList");
rc = pcGetFunctionList(&funcs);
if (rc != CKR_OK) {
WriteToLog("Unable to get procedure addresses from eTPkcs11 library.");
return(FALSE);
}
rc = funcs->C_Initialize(NULL);
if (rc != CKR_OK) {
WriteToLog("Unable to initialize eTPkcs11 library.");
return(-1);
}
// Try to find token
rc = funcs->C_GetSlotList(CK_FALSE, NULL, &ulSlotCount);
if (rc != CKR_OK) {
WriteToLog("Unable to get slot list.");
return(-1);
}
if (ulSlotCount > 0)
{
pSlotList = (CK_SLOT_ID_PTR) calloc(ulSlotCount, sizeof(CK_SLOT_ID));
rc = funcs->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
if (rc != CKR_OK) {
WriteToLog("Unable to get slot list.");
return(-1);
}
} else {
WriteToLog("No slots found.");
return(-1);
}
for (i=0; i<ulSlotCount; i++) {
rc = funcs->C_GetSlotInfo(pSlotList[i], &sinfo);
if (rc == CKR_OK)
{
if ((sinfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT)
{
SlotId = pSlotList[i];
break;
}
}
}
if (i>=ulSlotCount) {
WriteToLog("No token present.");
}
return(0);
}
// Control handler function
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Testing stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Testing stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus (hStatus, &ServiceStatus);
return;
}
Путь к логу и пин к токену захардкодены в тестовых целях.