Не ищет ключевую пару. SDK/pkcs11/samples/std/SignGOST34.10-2012-256
Здравствуйте. Вставил в компьютер токен рутокен ЭЦП 2.0, запускаю изложенный пример, а там выводит следующее:
В коде ничего не менял. В чём может быть причина? На пк скачал драйвера для windows с вашего сайта, установил панель управления рутокен. Получил сертификат от тестового УЦ CryptoPro с парой ключей на токен.
Запарывается программа на этом месте:
/*************************************************************************
* Получить массив хэндлов закрытых ключей *
*************************************************************************/
printf(" Getting signing key...\n");
r = findObjects(functionList, session, privateKeyTemplate, arraysize(privateKeyTemplate),
&objects, &objectCount);
CHECK(" findObjects", r == 0, logout);
Если рассмотреть шаблон privateKeyTemplate
CK_ATTRIBUTE privateKeyTemplate[] =
{
{ CKA_ID, &keyPairIdGost2012_256_1, sizeof(keyPairIdGost2012_256_1) - 1 }, // ID пары
{ CKA_CLASS, &privateKeyObject, sizeof(privateKeyObject) } // Класс - закрытый ключ
};
то можно увидеть использование ID пары, может её надо мне подправить? Стандартное определение:
/* DEMO ID пары ключей #1 ГОСТ Р 34.10-2012(256) */
static CK_BYTE keyPairIdGost2012_256_1[] = { "GOST R 34.10-2012 (256 bits) sample key pair 1 ID (Aktiv Co.)" };
Пробовал заменить на имя ключа, которое отображается в панели управления Рутокен, но ничего не изменилось:
static CK_BYTE keyPairIdGost2012_256_1[] = { "te-3dadf386-fdf2-4a01-b888-8726b8f9adb8" }
Что нужно мне сделать, чтобы пример заработал? Спасибо за Ваше внимание.
Если вдруг нужен код примера всего то вставлю, мало ли:
/*************************************************************************
* Rutoken *
* Copyright (c) 2003-2019, CJSC Aktiv-Soft. All rights reserved. *
* Подробная информация: http://www.rutoken.ru *
*------------------------------------------------------------------------*
* Пример работы с Рутокен при помощи библиотеки PKCS#11 на языке C *
*------------------------------------------------------------------------*
* Использование команд вычисления/проверки ЭП на ключах *
* ГОСТ Р 34.10-2012 для длины ключа 256 бит: *
* - установление соединения с Рутокен в первом доступном слоте; *
* - выполнение аутентификации Пользователя; *
* - внутреннее хэширование и подпись сообщения *
* на демонстрационном ключе; *
* - сброс прав доступа Пользователя на Рутокен и закрытие соединения *
* с Рутокен. *
*------------------------------------------------------------------------*
* Пример использует объекты, созданные в памяти Рутокен примером *
* CreateGOST34.10-2012-256. *
*************************************************************************/
#include "stdafx.h"
#include <Common.h>
/*************************************************************************
* Данные для цифровой подписи *
*************************************************************************/
CK_BYTE data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
/*************************************************************************
* Шаблон для поиска закрытого ключа для цифровой подписи *
*************************************************************************/
CK_ATTRIBUTE privateKeyTemplate[] =
{
{ CKA_ID, &keyPairIdGost2012_256_1, sizeof(keyPairIdGost2012_256_1) - 1 }, // ID пары
{ CKA_CLASS, &privateKeyObject, sizeof(privateKeyObject) } // Класс - закрытый ключ
};
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_SLOT_ID_PTR slots; // Массив идентификаторов слотов
CK_ULONG slotCount; // Количество идентификаторов слотов в массиве
CK_MECHANISM_TYPE_PTR mechanisms; // Массив поддерживаемых механизмов
CK_ULONG mechanismCount; // Количество поддерживаемых механизмов
CK_OBJECT_HANDLE_PTR objects; // Массив хэндлов объектов, соответствующих критериям поиска
CK_ULONG objectCount; // Количество хэндлов объектов в массиве
CK_BYTE_PTR signature; // Указатель на буфер, содержащий цифровую подпись для данных
CK_ULONG signatureSize; // Размер буфера, содержащего цифровую подпись для данных, в байтах
CK_RV rv; // Код возврата. Могут быть возвращены только ошибки, определенные в PKCS#11
int r; // Код возврата для функций, возвращающих int
CK_ULONG i; // Вспомогательная переменная-счетчик в циклах
int isGostR3410w3411_256Supported = 0; // Флаги для проверки поддержки токеном CKM_GOSTR3410_WITH_GOSTR3411_12_256
int errorCode = 1; // Флаг ошибки
/*************************************************************************
* Выполнить действия для начала работы с библиотекой PKCS#11 *
*************************************************************************/
printf("Initialization...\n");
/*************************************************************************C
* Загрузить библиотеку *
*************************************************************************/
module = LoadLibrary(PKCS11ECP_LIBRARY_NAME);
CHECK(" LoadLibrary", module != NULL, exit);
/*************************************************************************
* Получить адрес функции запроса структуры с указателями на функции *
*************************************************************************/
getFunctionList = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList");
CHECK(" GetProcAddress", getFunctionList != NULL, unload_pkcs11);
/*************************************************************************
* Получить структуру с указателями на функции *
*************************************************************************/
rv = getFunctionList(&functionList);
CHECK_AND_LOG(" Get function list", 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, 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);
/*************************************************************************
* Получить список поддерживаемых токеном механизмов *
*************************************************************************/
rv = functionList->C_GetMechanismList(slots[0], NULL_PTR, &mechanismCount);
CHECK_AND_LOG(" C_GetMechanismList (number of mechanisms)", rv == CKR_OK, rvToStr(rv), free_slots);
CHECK_AND_LOG(" Checking mechanisms available", mechanismCount > 0, " No mechanisms available", free_slots);
mechanisms = (CK_MECHANISM_TYPE_PTR)malloc(mechanismCount * sizeof(CK_MECHANISM_TYPE));
CHECK(" Memory allocation for mechanisms", mechanisms != NULL_PTR, free_slots);
rv = functionList->C_GetMechanismList(slots[0], mechanisms, &mechanismCount);
CHECK_AND_LOG(" C_GetMechanismList", rv == CKR_OK, rvToStr(rv), free_mechanisms);
/*************************************************************************
* Определение поддерживаемых токеном механизмов *
*************************************************************************/
for (i = 0; i < mechanismCount; ++i) {
if (mechanisms[i] == CKM_GOSTR3410_WITH_GOSTR3411_12_256) {
isGostR3410w3411_256Supported = 1;
break;
}
}
CHECK_AND_LOG(" Checking CKM_GOSTR3410_WITH_GOSTR3411_12_256 support", isGostR3410w3411_256Supported,
"CKM_GOSTR3410_WITH_GOSTR3411_12_256 isn`t supported!\n", free_mechanisms);
/*************************************************************************
* Открыть 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_mechanisms);
/*************************************************************************
* Выполнить аутентификацию Пользователя *
*************************************************************************/
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");
/*************************************************************************
* Сформировать цифровую подпись данных по алгоритму *
* ГОСТ Р 34.10-2012(256) *
*************************************************************************/
printf("\nSigning data...\n");
/*************************************************************************
* Получить массив хэндлов закрытых ключей *
*************************************************************************/
printf(" Getting signing key...\n");
r = findObjects(functionList, session, privateKeyTemplate, arraysize(privateKeyTemplate),
&objects, &objectCount);
CHECK(" findObjects", r == 0, logout);
CHECK_AND_LOG(" Checking number of keys found", objectCount > 0, "No objects found\n", logout);
/*************************************************************************
* Сформировать цифровую подпись данных по алгоритму *
* ГОСТ Р 34.10-2012(256) *
*************************************************************************/
printf(" Signing data...\n");
/*************************************************************************
* Инициализировать операцию подписи данных *
*************************************************************************/
rv = functionList->C_SignInit(session, &gostR3410_2012_256SigVerMech_WithInternalHash, objects[0]);
CHECK_AND_LOG(" C_SignInit", rv == CKR_OK, rvToStr(rv), free_objects);
/*************************************************************************
* Определить размер данных подписи *
*************************************************************************/
rv = functionList->C_Sign(session, data, sizeof(data), NULL_PTR, &signatureSize);
CHECK_AND_LOG(" C_Sign (get size)", rv == CKR_OK, rvToStr(rv), free_objects);
/*************************************************************************
* Подписать данные *
************************************************************************/
signature = (CK_BYTE*)malloc(signatureSize * sizeof(CK_BYTE));
CHECK(" Memory allocation for signature", signature != NULL, free_objects);
rv = functionList->C_Sign(session, data, sizeof(data), signature, &signatureSize);
CHECK_AND_LOG(" C_Sign (signing)", rv == CKR_OK, rvToStr(rv), free_signature);
/*************************************************************************
* Распечатать буфер, содержащий подпись *
*************************************************************************/
printf(" Signature buffer is: \n");
printHex(signature, signatureSize);
printf("Data has been signed successfully.\n");
/*************************************************************************
* Выставить признак успешного завершения программы *
*************************************************************************/
errorCode = 0;
/*************************************************************************
* Выполнить действия для завершения работы с библиотекой PKCS#11 *
*************************************************************************/
printf("\nFinalizing... \n");
/*************************************************************************
* Очистить память, выделенную под хэш-коды, подпись и объекты *
*************************************************************************/
free_signature:
free(signature);
free_objects:
free(objects);
/*************************************************************************
* Сбросить права доступа *
*************************************************************************/
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_mechanisms:
free(mechanisms);
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;
}