Скачиваний:
3
Добавлен:
22.03.2025
Размер:
712.49 Кб
Скачать

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

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

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

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

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

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

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

__________

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

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

__________

Введение

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

1 Ход работы

Первоочередно был импортирован сертификат преподавателя, что представлено на рисунках 1.1 – 1.2.

Рисунок 1.1 – Процесс импорта сертификата

Рисунок 1.2 – Успешный импорт сертификата

Далее был создан сертификат студента с помощью утилиты makecert.exe, что представлено на рисунках 1.3 – 1.4.

Рисунок 1.3 – Процесс создания сертификата

Рисунок 1.4 – Отображение созданного сертификата

Далее был загружен проект работы и добавлены в него заголовки функций и глобальные переменные, что представлено на рисунке 1.5.

Рисунок 1.5 – Заголовки функций

Далее были добавленые функции ReadCertFromFile, которая обеспечивает чтение файла с сертификатом, GetX509Subject, которая предназначена для получения темы сертификата, CreateCertFromBlob, которая предназначена для создания файла с сертификатом на eToken, что представлено на рисунках 1.6 – 1.8.

Рисунок 1.6 – Функция ReadCertFromFile

Рисунок 1.7 – Функция GetX509Subject

Рисунок 1.8 – Функция CreateCertFromBlob

Для получения идентификатора слота, к которому подключен eToken используется функция GetFirstSlotId, представленная на рисунке 1.9.

Рисунок 1.9 – Функция GetFirstSlotId

Далее была разработана функция импорта сертификата в которой используются все вышеописанные функции, а также была добавлена функция C_Login, отвечающая за вход под ролью пользователя на токен, что представлено на рисунке 1.10.

Рисунок 1.10 – Функция ImportCertificate

После была разработана функция main и ее вывод как в консольном виде так и через eToken, что представлено на рисунках 1.11 – 1.14.

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

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

Рисунок 1.13 – Информация о сертификатах после выполнения программы

Рисунок 1.14 – Информация о сертификатах после выполнения программы

Заключение

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

Приложение 1

#include "stdlib.h"

#include "stdio.h"

#include "include\eTPkcs11.h"

#include <windows.h>

using namespace std;

void init();

void leave(const char*);

static bool ReadCertFromFile(const char* fileName, CK_BYTE_PTR* cert, DWORD* certSize);

static void GetX509Subject(CK_BYTE_PTR cert, int certSize, CK_BYTE_PTR* subject, int* subjectSize);

static bool CreateCertFromBlob(CK_SESSION_HANDLE hSession, CK_BYTE_PTR cert, int certSize, CK_BYTE_PTR subject, int subjSize);

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

CK_FUNCTION_LIST_PTR pFunctionList = NULL;

CK_C_GetFunctionList pGFL = 0;

bool wasInit = false;

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.");

}

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

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

{

leave("C_Initialize failed...");

}

wasInit = true;

}

static void leave(const char* message)

{

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

if (wasInit)

{

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

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

{

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

}

wasInit = false;

}

exit(message ? -1 : 0);

}

static bool ReadCertFromFile(const char* fileName, CK_BYTE_PTR* cert, DWORD* certSize)

{

HANDLE hFile = CreateFileA(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE)

{

printf("Failed to open file: %s\n", fileName);

return false;

}

*certSize = GetFileSize(hFile, NULL);

if (*certSize == INVALID_FILE_SIZE)

{

CloseHandle(hFile);

printf("Failed to get file size\n");

return false;

}

*cert = (CK_BYTE_PTR)malloc(*certSize);

if (*cert == NULL)

{

CloseHandle(hFile);

printf("Memory allocation failed for certificate\n");

return false;

}

DWORD bytesRead;

bool nFile = ReadFile(hFile, *cert, *certSize, &bytesRead, NULL);

CloseHandle(hFile);

if (!nFile || bytesRead != *certSize)

{

free(*cert);

*cert = NULL;

printf("Failed to read file contents\n");

return false;

}

return true;

}

static void GetX509Subject(CK_BYTE_PTR cert, int certSize, CK_BYTE_PTR* subject, int* subjectSize)

{

unsigned int i;

unsigned char* current = cert;

unsigned char* prev;

unsigned char* end = cert + certSize;

unsigned char tags[] = {0x30, 0, 0x30, 0, 0xa0, 1, 0x02, 1, 0x30, 1, 0x30, 1, 0x30, 1, 0x30, 1};

*subject = NULL;

*subjectSize = 0;

for (i = 0; i < sizeof(tags); i += 2)

{

unsigned char v;

unsigned int length = 0;

prev = current;

if (current + 2 > end) return;

if (*current++ != tags[i]) return;

v = *current++;

if ((v & 0x80) == 0) length = v;

else

{

unsigned char lenlen = v & 0x7f;

if (current + lenlen > end) return;

for (v = 0; v < lenlen; v++) length = (length << 8) + *current++;

}

if (tags[i + 1]) current += length;

}

*subject = prev;

*subjectSize = (int)(current - prev);

}

static bool CreateCertFromBlob(CK_SESSION_HANDLE hSession, CK_BYTE_PTR cert, int certSize, CK_BYTE_PTR subject, int subjSize)

{

CK_OBJECT_CLASS classAttr = CKO_CERTIFICATE;

CK_CERTIFICATE_TYPE certType = CKC_X_509;

unsigned long certCategory = 2;

CK_BBOOL trueVal = CK_TRUE;

CK_OBJECT_HANDLE hObject;

CK_ATTRIBUTE templateArray[] =

{

{CKA_CLASS, &classAttr, sizeof(classAttr)},

{CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)},

{CKA_TOKEN, &trueVal, sizeof(trueVal)},

{CKA_SUBJECT, subject, subjSize},

{CKA_VALUE, (void*)cert, certSize},

{CKA_CERTIFICATE_CATEGORY, (void*)&certCategory, sizeof(certCategory)},

};

int sizeOfTemplate = sizeof(templateArray) / sizeof(CK_ATTRIBUTE);

CK_RV rv = pFunctionList->C_CreateObject(hSession, templateArray, sizeOfTemplate, &hObject);

if (rv != CKR_OK)

{

printf("Failed to create certificate object\n");

return false;

}

return true;

}

static CK_ULONG GetFirstSlotId()

{

CK_ULONG slotID = -1;

CK_ULONG ulCount = 0;

CK_SLOT_ID_PTR pSlotIDs = NULL_PTR;

CK_ULONG i;

if (pFunctionList->C_GetSlotList(TRUE, NULL_PTR, &ulCount) == CKR_OK)

{

if (ulCount > 0)

{

pSlotIDs = new CK_SLOT_ID[ulCount];

if (pFunctionList->C_GetSlotList(TRUE, pSlotIDs, &ulCount) == CKR_OK)

{

for (i = 0; i < ulCount; i++)

{

CK_SLOT_INFO info;

if (pFunctionList->C_GetSlotInfo(pSlotIDs[i], &info) == CKR_OK)

{

if (info.flags & (CKF_HW_SLOT | CKF_TOKEN_PRESENT))

{

slotID = pSlotIDs[i];

break;

}

}

}

}

}

}

if (pSlotIDs)

{

delete[] pSlotIDs;

pSlotIDs = NULL_PTR;

}

return slotID;

}

static void ImportCertificate(const char* fileName, const char* password)

{

CK_BYTE_PTR cert = NULL;

DWORD certSize = 0;

CK_BYTE_PTR subject = NULL;

int subjSize = 0;

if (!ReadCertFromFile(fileName, &cert, &certSize) || cert == NULL || certSize == 0)

{

leave("Failed to read certificate from file.");

}

GetX509Subject(cert, certSize, &subject, &subjSize);

if (subject == NULL || subjSize == 0)

{

leave("Failed to extract subject from certificate.");

}

CK_SESSION_HANDLE hSession;

CK_RV rv = pFunctionList->C_OpenSession(GetFirstSlotId(), CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &hSession);

if (rv != CKR_OK)

{

leave("Failed to open session.");

}

rv = pFunctionList->C_Login(hSession, CKU_USER, (LPBYTE)password, strlen(password));

if (rv != CKR_OK)

{

pFunctionList->C_CloseSession(hSession);

switch(rv)

{

case CKR_PIN_INCORRECT:

leave("Incorrect PIN code.");

break;

case CKR_USER_ALREADY_LOGGED_IN:

leave("User is already logged in.");

break;

default:

leave("Failed to login with unknown error.");

break;

}

}

if (!CreateCertFromBlob(hSession, cert, certSize, subject, subjSize))

{

pFunctionList->C_Logout(hSession);

pFunctionList->C_CloseSession(hSession);

leave("Failed to create certificate.");

}

pFunctionList->C_Logout(hSession);

pFunctionList->C_CloseSession(hSession);

}

int main()

{

init();

char path[128] = "C:\\Users\\Admin\\Documents\\Лаб2\\KAD.cer";

char pin_code[5];

printf("Enter PIN code: ");

gets(pin_code);

ImportCertificate(path, pin_code);

leave(NULL);

return 0;

}

Томск 2025

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