219 lines
9.0 KiB
Go
219 lines
9.0 KiB
Go
|
package mtrtoken
|
|||
|
|
|||
|
/*
|
|||
|
#include <Common.h>
|
|||
|
|
|||
|
|
|||
|
//Шаблон для поиска сертификата
|
|||
|
|
|||
|
CK_ATTRIBUTE certificateTemplate[] =
|
|||
|
{
|
|||
|
{ CKA_CLASS, &certificateObject, sizeof(certificateObject)}, // Класс - сертификат
|
|||
|
{ CKA_TOKEN, &attributeTrue, sizeof(attributeTrue)}, // Сертификат является объектом токена
|
|||
|
{ CKA_PRIVATE, &attributeFalse, sizeof(attributeFalse)}, // Сертификат доступен без аутентификации
|
|||
|
{ CKA_CERTIFICATE_TYPE, &certificateType, sizeof(certificateType)}, // Тип сертификата - X.509
|
|||
|
{ CKA_ID, &keyPairIdGost2012_512_1, sizeof(keyPairIdGost2012_512_1) - 1}, // Идентификатор сертификата, должен совпадать с CKA_ID соответствующей ключевой пары
|
|||
|
{ CKA_CERTIFICATE_CATEGORY, &tokenUserCertificate, sizeof(tokenUserCertificate)}, // Категория сертификата - пользовательский
|
|||
|
};
|
|||
|
|
|||
|
int test()
|
|||
|
{
|
|||
|
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_OBJECT_HANDLE_PTR certificates; // Указатель на массив хэндлов объектов, соответствующих критериям поиска
|
|||
|
CK_ULONG objectCount; // Количество хэндлов объектов в массиве
|
|||
|
|
|||
|
CK_BYTE_PTR info; // Указатель на буфер, содержащий информацию о сертификате
|
|||
|
CK_ULONG size; // Размер буфера, содержащего информацию о сертификате, в байтах
|
|||
|
|
|||
|
CK_RV rv; // Код возврата. Могут быть возвращены только ошибки, определенные в PKCS#11
|
|||
|
int r; // Код возврата для функций, возвращающих int
|
|||
|
|
|||
|
int errorCode = 1; // Флаг ошибки
|
|||
|
|
|||
|
|
|||
|
//Выполнить действия для начала работы с библиотекой PKCS#11
|
|||
|
|
|||
|
printf("Initialization...\n");
|
|||
|
|
|||
|
|
|||
|
//Загрузить библиотеку
|
|||
|
|
|||
|
module = LoadLibrary(PKCS11ECP_LIBRARY_NAME);
|
|||
|
CHECK(" LoadLibrary", module != NULL, exit);
|
|||
|
|
|||
|
|
|||
|
//Получить адрес функции запроса структуры с указателями на функции
|
|||
|
|
|||
|
getFunctionList = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList");
|
|||
|
CHECK(" GetProcAddress (C_GetFunctionList)", getFunctionList != NULL, unload_pkcs11);
|
|||
|
|
|||
|
|
|||
|
//Получить адрес функции запроса структуры с указателями на функции
|
|||
|
//расширения стандарта PKCS#11
|
|||
|
|
|||
|
getFunctionListEx = (CK_C_EX_GetFunctionListExtended)GetProcAddress(module, "C_EX_GetFunctionListExtended");
|
|||
|
CHECK(" GetProcAddress (C_EX_GetFunctionListExtended)", getFunctionList != 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);
|
|||
|
|
|||
|
|
|||
|
//Открыть RW сессию в первом доступном слоте
|
|||
|
|
|||
|
rv = functionList->C_OpenSession(slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session);
|
|||
|
CHECK_AND_LOG(" C_OpenSession", rv == CKR_OK, rvToStr(rv), free_slots);
|
|||
|
|
|||
|
|
|||
|
//Выполнить аутентификацию Пользователя
|
|||
|
|
|||
|
rv = functionList->C_Login(session, CKU_USER, USER_PIN, USER_PIN_LEN);
|
|||
|
CHECK_AND_LOG(" C_Login", rv == CKR_OK, rvToStr(rv), close_session);
|
|||
|
printf("Initialization has been completed successfully.\n");
|
|||
|
|
|||
|
|
|||
|
//Получение информации о сертификате
|
|||
|
|
|||
|
printf("\nGetting information...\n");
|
|||
|
|
|||
|
|
|||
|
//Получить массив хэндлов сертификатов
|
|||
|
|
|||
|
printf(" Getting certificates...\n");
|
|||
|
r = findObjects(functionList, session, certificateTemplate, arraysize(certificateTemplate),
|
|||
|
&certificates, &objectCount);
|
|||
|
CHECK(" findObjects", r == 0, logout);
|
|||
|
|
|||
|
CHECK_AND_LOG(" Checking number of certificates", objectCount != 0, "No objects found\n", logout);
|
|||
|
|
|||
|
|
|||
|
//Получение информации о сертификате
|
|||
|
|
|||
|
rv = functionListEx->C_EX_GetCertificateInfoText(session, certificates[0], &info, &size);
|
|||
|
CHECK_AND_LOG(" C_EX_GetCertificateInfoText", rv == CKR_OK, rvToStr(rv), logout);
|
|||
|
|
|||
|
|
|||
|
//Распечатать буфер, содержащий информацию о сертификате
|
|||
|
|
|||
|
r = printUTF8String(info);
|
|||
|
CHECK(" Print info", r == 0, free_buffer);
|
|||
|
|
|||
|
printf("Information has been acquired successfully.\n");
|
|||
|
|
|||
|
|
|||
|
//Выставить признак успешного завершения программы
|
|||
|
|
|||
|
errorCode = 0;
|
|||
|
|
|||
|
|
|||
|
//Выполнить действия для завершения работы с библиотекой PKCS#11
|
|||
|
|
|||
|
printf("\nFinalizing... \n");
|
|||
|
|
|||
|
|
|||
|
//Освобождение буфера, содержащего информацию о сертификате
|
|||
|
|
|||
|
free_buffer:
|
|||
|
rv = functionListEx->C_EX_FreeBuffer(info);
|
|||
|
CHECK_RELEASE_AND_LOG(" C_EX_FreeBuffer", rv == CKR_OK, rvToStr(rv), errorCode);
|
|||
|
|
|||
|
|
|||
|
//Сбросить права доступа
|
|||
|
|
|||
|
logout:
|
|||
|
rv = functionList->C_Logout(session);
|
|||
|
CHECK_RELEASE_AND_LOG(" C_Logout", rv == CKR_OK, rvToStr(rv), errorCode);
|
|||
|
|
|||
|
|
|||
|
//Закрыть открытую сессию в слоте
|
|||
|
|
|||
|
close_session:
|
|||
|
rv = functionList->C_CloseSession(session);
|
|||
|
CHECK_RELEASE_AND_LOG(" C_CloseSession", rv == CKR_OK, rvToStr(rv), errorCode);
|
|||
|
|
|||
|
|
|||
|
//Очистить память из-под слотов
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
*/
|
|||
|
import "C"
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
func main() {
|
|||
|
fmt.Printf("Invoking c library...\n")
|
|||
|
C.test()
|
|||
|
time.Sleep(16 * time.Second)
|
|||
|
// fmt.Println("Done ", C.x(10) )
|
|||
|
}
|