Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Болтушкин Л.С., группа 712-2, лабораторная 3

.docx
Скачиваний:
0
Добавлен:
20.02.2026
Размер:
510.9 Кб
Скачать

Министерство науки и высшего образования Российской Федерации

Федеральное государственное автономное образовательное учреждение высшего образования

ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР)

Кафедра комплексной информационной безопасности электронно-вычислительных систем (КИБЭВС)

ЗНАКОМСТВО С ETOKEN API

Отчет по лабораторной работе №3

по дисциплине «Программно-аппаратные средства защиты информации»

Выполнил:

Студент гр. 712-2

_______ Л.С. Болтушкин

_______ 2026

Руководитель

Преподаватель кафедры КИБЭВС

_______ С.А. Пашкевич

_______ 2026

Введение

Целью данной лабораторной работы является ознакомление с основами работы с eToken API, изучение базовых функций, связанные с определением наличия eToken в системе, научиться получать информацию о подключенном eToken.

1 ХОД РАБОТЫ

Для начала был загружен проект «Lab1» в Visual Studio и добавлен заголовочный файл «eTPkcs11.h» и следующий код, представленный на рисунке 1.1.

Рисунок 1.1 – Добавление заголовочного файла и инициализация методов и глобальных переменных

Далее для использования функции библиотеки PKCS#11 была произведена ее инициализация, а также добавлена функция выдачи сообщение о соответствующей ошибке и завершение работы программы (рисунок 1.2 – 1.3).

Рисунок 1.2 – Функция инициализации библиотеки

Рисунок 1.3 – Функция выхода из программы

Для того, чтобы получить информацию о библиотеке PKCS#11 была написана функция (рисунок 1.4).

Рисунок 1.4 – Описание функции отображения информации о библиотеке

На рисунке 1.5 представлено выведение в консоль информации о библиотеке PKCS#11.

Рисунок 1.5 – Вывод выполнения функции

Далее была написана функция для отображения информации о подключенном eToken путем опознания идентификатора виртуального слота (рисунок 1.6 – 1.7).

Рисунок 1.6 – Описание функции отображения информации о eToken, часть 1

Рисунок 1.7 – Описание функции отображения информации о eToken, часть 2

Также написана функция, проверяющая возникновение событий подключения и отключения eToken к компьютеру (рисунок 1.8).

Рисунок 1.8 – Описание функции проверки наличия eToken

Последним шагом было дополнение функции main, чтобы в ней производилась инициализация библиотеки, выводилась информация о библиотеке, запускался поток ожидания событий и завершалась работа библиотеки (рисунок 1.9).

Рисунок 1.9 – Описание функции main

На рисунке 1.10 изображен полный вывод функции main с информацией о библиотеке, токене и информации, согласно индивидуальному варианту №3 – label, serialNumber, ulSessionCount, ulMaxRwSessionCount, ulTotalPublicMemory, ulFreePublicMemory, CKF_RNG и CKF_LOGIN_REQUIRED.

Рисунок 1.10 – Вывод функции main

Полный код программы представлен в Приложении А.

Заключение

В ходе выполнения данной лабораторной работы было произведено ознакомление с основами работы с eToken API, изучены базовые функции, связанные с определением наличия eToken в системе, обучены получать информацию о подключенном eToken.

Приложение А

(обязательное)

Листинг программы

#include "stdlib.h"

#include "stdio.h"

#include <windows.h>

#include "include\eTPkcs11.h"

using namespace std;

// Прототипы

void init();

void leave(const char*);

void displayLibraryInfo();

void displayTokenInfo(CK_SLOT_ID slotId);

void checkAllSlots();

// Глобальные переменные

CK_FUNCTION_LIST_PTR pFunctionList = NULL;

CK_C_GetFunctionList pGFL = 0;

bool wasInit = false;

static HANDLE hThread = 0;

// Инициализация

void init()

{

// Загружаем dll

HINSTANCE hLib = LoadLibraryA("etpkcs11.DLL");

if (hLib == NULL)

{

leave("Cannot load DLL.");

}

// Ищем точку входа для C_GetFunctionList

(FARPROC&)pGFL = GetProcAddress(hLib, "C_GetFunctionList");

if (pGFL == NULL)

{

leave("Cannot find GetFunctionList().");

}

// Берем список функций

if (CKR_OK != pGFL(&pFunctionList))

{

leave("Can't get function list. \n");

}

// Инициализируем библиотеку PKCS#11

if (CKR_OK != pFunctionList->C_Initialize(0))

{

leave("C_Initialize failed...\n");

}

wasInit = true;

}

// Завершение работы

static void leave(const char* message)

{

if (message) printf("%s ", message);

if(wasInit)

{

// Закрываем библиотеку PKCS#11

if (CKR_OK != pFunctionList->C_Finalize(0))

{

printf("C_Finalize failed...\n");

}

// Ждем завершения работы потока, иначе убиваем его.

WaitForSingleObject(hThread, 5000);

if (hThread)

{

TerminateThread(hThread, 0);

CloseHandle(hThread);

}

hThread = 0;

wasInit = false;

}

exit(message ? -1 : 0);

}

// Информация о библиотеке

void displayLibraryInfo()

{

CK_INFO lib_info;

if (CKR_OK != pFunctionList->C_GetInfo(&lib_info))

{

printf("C_GetInfo failed.\n");

return;

}

printf("<Common Library Information>\n");

printf("Version - %d.%d\n", lib_info.cryptokiVersion.major, lib_info.cryptokiVersion.minor);

printf("Manufacturer - %.*s\n", 32, lib_info.manufacturerID);

printf("Description eToken PKCS - %.*s\n", 32, lib_info.libraryDescription);

printf("Library version - %d.%d\n\n", lib_info.libraryVersion.major, lib_info.libraryVersion.minor);

}

// Информация о токене (3 вариант)

void displayTokenInfo(CK_SLOT_ID slotId)

{

CK_SLOT_INFO slotInfo;

CK_TOKEN_INFO tokenInfo;

// Получаем информацию о слоте

if (CKR_OK != pFunctionList->C_GetSlotInfo(slotId, &slotInfo))

{

printf("\n----- Event on Slot ID: %lu -----\n", slotId);

printf("C_GetSlotInfo failed.\n");

return;

}

printf("\n----- Event on Slot ID: %lu -----\n", slotId);

printf("Slot description: %.*s\n", 64, slotInfo.slotDescription);

printf("Manufacturer ID: %.*s\n", 32, slotInfo.manufacturerID);

if (!(slotInfo.flags & CKF_TOKEN_PRESENT))

{

printf("Token NOT present in this slot.\n");

return;

}

// Получаем информацию о токене

if (CKR_OK != pFunctionList->C_GetTokenInfo(slotId, &tokenInfo))

{

printf("C_GetTokenInfo failed.\n");

return;

}

printf("\n========== TOKEN INFO (Variant 3) ==========\n");

// 1. label

printf("Label: %.*s\n", 32, tokenInfo.label);

// 2. serialNumber

printf("Serial Number: %.*s\n", 16, tokenInfo.serialNumber);

// 3. ulSessionCount

printf("Session Count: %lu\n", tokenInfo.ulSessionCount);

// 4. ulMaxRwSessionCount

printf("Max Read/Write Sessions: %lu\n", tokenInfo.ulMaxRwSessionCount);

// 5. ulTotalPublicMemory

printf("Total Public Memory: %lu bytes\n", tokenInfo.ulTotalPublicMemory);

// 6. ulFreePublicMemory

printf("Free Public Memory: %lu bytes\n", tokenInfo.ulFreePublicMemory);

// 7. CKF_RNG

printf("CKF_RNG (Random Generator): %s\n",

(tokenInfo.flags & CKF_RNG) ? "Present" : "Not present");

// 8. CKF_LOGIN_REQUIRED

printf("CKF_LOGIN_REQUIRED: %s\n",

(tokenInfo.flags & CKF_LOGIN_REQUIRED) ? "Yes" : "No");

printf("============================================\n\n");

}

// Проверка всех слотов

void checkAllSlots()

{

CK_ULONG slotCount;

CK_SLOT_ID_PTR pSlotList = NULL;

// Получаем количество слотов

if (CKR_OK != pFunctionList->C_GetSlotList(TRUE, NULL, &slotCount))

{

printf("Failed to get slot list\n");

return;

}

if (slotCount == 0)

{

printf("\nNo tokens found\n");

return;

}

pSlotList = (CK_SLOT_ID_PTR)malloc(slotCount * sizeof(CK_SLOT_ID));

if (pSlotList == NULL)

{

printf("Memory allocation failed\n");

return;

}

if (CKR_OK != pFunctionList->C_GetSlotList(TRUE, pSlotList, &slotCount))

{

printf("Failed to get slot list\n");

free(pSlotList);

return;

}

printf("\n=== Currently connected tokens ===\n");

for (CK_ULONG i = 0; i < slotCount; i++)

{

displayTokenInfo(pSlotList[i]);

}

free(pSlotList);

}

// Поток ожидания событий

static DWORD __stdcall TokenNotifyThread(void*)

{

while (true)

{

CK_SLOT_ID slotId;

int res = pFunctionList->C_WaitForSlotEvent(0, &slotId, 0);

if (res == CKR_OK)

{

displayTokenInfo(slotId);

}

else

{

break;

}

}

return 0;

}

// Главная функция

int main()

{

// Устанавливаем UTF-8 для консоли

SetConsoleOutputCP(CP_UTF8);

printf("Laba №3 - Variant 3\n");

printf("==============================\n");

init();

displayLibraryInfo();

printf("Checking for tokens...\n");

checkAllSlots();

// Запуск потока

hThread = CreateThread(NULL, 0, TokenNotifyThread, NULL, 0, NULL);

if (hThread == NULL)

{

leave("Failed to create thread");

}

printf("\nWaiting for token events... Press any key to exit.\n");

getchar();

leave(NULL);

return 0;

}

Томск 2026