Вот так, например:
#include <Common.h>
int main(void)
{
HMODULE module; // Хэндл загруженной библиотеки PKCS#11
CK_SESSION_HANDLE session; // Хэндл открытой сессии
CK_FUNCTION_LIST_PTR functionList; // Указатель на список функций PKCS#11, хранящийся в структуре CK_FUNCTION_LIST
CK_C_GetFunctionList getFunctionList; // Указатель на функцию C_GetFunctionList
CK_FUNCTION_LIST_EXTENDED_PTR functionListEx; // Указатель на список функций расширения PKCS#11, хранящийся в структуре CK_FUNCTION_LIST_EXTENDED
CK_C_EX_GetFunctionListExtended getFunctionListEx; // Указатель на функцию C_EX_GetFunctionListExtended
CK_SLOT_ID_PTR slots; // Массив идентификаторов слотов
CK_ULONG slotCount; // Количество идентификаторов слотов в массиве
CK_TOKEN_INFO_EXTENDED tokenInfoEx; // Структура данных типа CK_TOKEN_INFO_EXTENDED с информацией о токене
CK_CHAR_PTR tokenName; // Указатель на метку токена
CK_ULONG tokenNameLength; // Размер метки токена
CK_RUTOKEN_INIT_PARAM initParam; // Структура данных типа CK_RUTOKEN_INIT_PARAM, содержащая параметры для работы функции C_EX_InitToken
CK_RV rv; // Код возврата. Могут быть возвращены только ошибки, определенные в PKCS#11
CK_ULONG i; // Вспомогательная переменная-счетчик в циклах
int isRutokenS; // Вспомогательная переменная для хранения признака типа токена
int errorCode = 1; // Флаг ошибки
/*************************************************************************
* Выполнить действия для начала работы с библиотекой PKCS#11 *
*************************************************************************/
printf("Initialization...\n");
/*************************************************************************
* Загрузить библиотеку *
*************************************************************************/
module = LoadLibrary(PKCS11_LIBRARY_NAME);
CHECK(" LoadLibrary", module != NULL, exit);
/*************************************************************************
* Получить адрес функции запроса структуры с указателями на функции *
*************************************************************************/
getFunctionList = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList");
CHECK(" GetProcAddress", getFunctionList != NULL, unload_pkcs11);
/*************************************************************************
* Получить адрес функции запроса структуры с указателями на *
* расширенные функции *
*************************************************************************/
getFunctionListEx = (CK_C_EX_GetFunctionListExtended)GetProcAddress(module, "C_EX_GetFunctionListExtended");
CHECK(" GetProcAddress", getFunctionListEx != NULL, unload_pkcs11);
/*************************************************************************
* Получить структуру с указателями на функции *
*************************************************************************/
rv = getFunctionList(&functionList);
CHECK_AND_LOG(" Get function list", rv == CKR_OK, rvToStr(rv), unload_pkcs11);
/*************************************************************************
* Получить структуру с указателями на расширенные функции *
*************************************************************************/
rv = getFunctionListEx(&functionListEx);
CHECK_AND_LOG(" Get function list extended", rv == CKR_OK, rvToStr(rv), unload_pkcs11);
/*************************************************************************
* Инициализировать библиотеку *
*************************************************************************/
rv = functionList->C_Initialize(NULL_PTR);
CHECK_AND_LOG(" C_Initialize", rv == CKR_OK, rvToStr(rv), unload_pkcs11);
/*************************************************************************
* Получить количество слотов c подключенными токенами *
*************************************************************************/
rv = functionList->C_GetSlotList(CK_TRUE, NULL_PTR, &slotCount);
CHECK_AND_LOG(" C_GetSlotList (number of slots)", rv == CKR_OK, rvToStr(rv), finalize_pkcs11);
CHECK_AND_LOG(" Checking available tokens", slotCount > 0, " No tokens available", finalize_pkcs11);
/*************************************************************************
* Получить список слотов c подключенными токенами *
*************************************************************************/
slots = (CK_SLOT_ID_PTR)malloc(slotCount * sizeof(CK_SLOT_ID));
CHECK(" Memory allocation for slots", slots != NULL_PTR, finalize_pkcs11);
rv = functionList->C_GetSlotList(CK_TRUE, slots, &slotCount);
CHECK_AND_LOG(" C_GetSlotList", rv == CKR_OK, rvToStr(rv), free_slots);
printf(" Slots available: %d\n", (int)slotCount);
printf("Initialization has been completed successfully.\n");
/*************************************************************************
* Получить расширенную информацию о подключенном токене *
*************************************************************************/
printf("\nGetting extended token information...\n");
tokenInfoEx.ulSizeofThisStructure = sizeof(tokenInfoEx);
rv = functionListEx->C_EX_GetTokenInfoExtended(slots[0], &tokenInfoEx);
CHECK_AND_LOG(" C_EX_GetTokenInfoExtended", rv == CKR_OK, rvToStr(rv), free_slots);
/*************************************************************************
* Определить класс токена *
*************************************************************************/
if (tokenInfoEx.ulTokenClass == TOKEN_CLASS_S) {
isRutokenS = 1;
} else {
isRutokenS = 0;
}
printf("Extended token information has been got successfully.\n");
printf(" Max admin retry counter: 0x%8.8x \n", (int)tokenInfoEx.ulMaxAdminRetryCount);
printf(" Admin retry counter: 0x%8.8x \n", (int)tokenInfoEx.ulAdminRetryCountLeft);
printf(" Max user retry counter: 0x%8.8x \n", (int)tokenInfoEx.ulMaxUserRetryCount);
printf(" User retry counter: 0x%8.8x \n", (int)tokenInfoEx.ulUserRetryCountLeft);
printf("\nExtended info test has been completed successfully.\n");
/*************************************************************************
* Выставить признак успешного завершения программы *
*************************************************************************/
errorCode = 0;
/*************************************************************************
* Выполнить действия для завершения работы с библиотекой PKCS#11 *
*************************************************************************/
printf("\nFinalizing... \n");
/*************************************************************************
* Очистить память, выделенную под слоты *
*************************************************************************/
free_slots:
free(slots);
/*************************************************************************
* Деинициализировать библиотеку *
*************************************************************************/
finalize_pkcs11:
rv = functionList->C_Finalize(NULL_PTR);
CHECK_RELEASE_AND_LOG(" C_Finalize", rv == CKR_OK, rvToStr(rv), errorCode);
/*************************************************************************
* Выгрузить библиотеку из памяти *
*************************************************************************/
unload_pkcs11:
CHECK_RELEASE(" FreeLibrary", FreeLibrary(module), errorCode);
exit:
if (errorCode) {
printf("\n\nSome error occurred. Sample failed.\n");
} else {
printf("\n\nSample has been completed successfully.\n");
}
return errorCode;
}
С уважением, Алексей Лазарев, Компания "Актив"