Не удаляется контейнер 'Aktiv ruToken CSP v1.0' на Rutoken Lite
Доброго времени суток.
После форматирования Rutoken Lite с помощью rtPKCS11ECP.dll невозможно удалить контейнер с помощью криптопровайдера 'Aktiv ruToken CSP v1.0'. Проблемы нет, если форматирование производить с помощью библиотеки rtPKCS11.dll.
При вызове 'CryptAcquireContext(&prov2, full_container_name.c_str(), g_prov_name, g_prov_type, CRYPT_SILENT | CRYPT_DELETEKEYSET)' возникает ошибка 0x8007001f.
Проблема воспроизводится на драйверах:
v.2.100.00.0542_20.11.2014
v.4.0.0.0_31.08.2015
v.4.0.1.0_14.10.2015
v.4.0.2.0_23.10.2015
v.4.0.5.0_30.12.2015
На более ранних версиях ошибка не воспроизводится.
Проверено на операционных системах: windows 7 x64, windows 8.1 x64 и windows 8.1 x86
В примере файл Common.h взят из SDK
Пример:
#include <Windows.h>
#include <WinCrypt.h>
#include <iostream>
#include <string>
#include "Common.h"
#define MAX_ADMIN_RETRY_COUNT 10
#define MAX_USER_RETRY_COUNT 10
DWORD g_prov_type = 0x1;
LPCSTR g_prov_name = "Aktiv ruToken CSP v1.0";
LPCSTR g_token_pass = "12345678";
bool InitTokenEx();
bool InitToken();
bool DeleteContainer(LPCSTR container_name, LPCSTR reader_name);
bool GenerateKeyPair(LPCSTR container_name, LPCSTR reader_name);
int main()
{
LPCSTR container_name = "Test container!";
LPCSTR reader_name = "\\\\.\\Aktiv Rutoken lite 0\\";
//LPCSTR reader_name = "\\\\.\\Aktiv Rutoken ECP 0\\";
//LPCSTR reader_name = "\\\\.\\Aktiv Co. ruToken 0\\";
if (!InitTokenEx())
{
return 0;
}
if (!GenerateKeyPair(container_name, reader_name))
{
return 0;
}
if (!DeleteContainer(container_name, reader_name))
{
return 0;
}
std::cout << "Success!" << std::endl;
return 0;
}
bool InitTokenEx()
{
HMODULE module = NULL_PTR;
CK_SESSION_HANDLE session = NULL_PTR;
CK_FUNCTION_LIST_PTR function_list = NULL_PTR;
CK_C_GetFunctionList get_function_list_func = NULL_PTR;
CK_FUNCTION_LIST_EXTENDED_PTR function_list_ex = NULL_PTR;
CK_C_EX_GetFunctionListExtended get_function_list_func_ex = NULL_PTR;
CK_SLOT_ID_PTR slots = NULL_PTR;
CK_ULONG slot_count = 0;
CK_RV rv = CKR_OK;
module = LoadLibrary(PKCS11ECP_LIBRARY_NAME);
if (module == NULL_PTR)
{
std::cout << "Function 'LoadLibrary' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
get_function_list_func = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList");
if (get_function_list_func == NULL_PTR)
{
std::cout << "Function 'GetProcAddress' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
rv = get_function_list_func(&function_list);
if (rv != CKR_OK)
{
std::cout << "Function 'C_GetFunctionList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
get_function_list_func_ex = (CK_C_EX_GetFunctionListExtended)GetProcAddress(module, "C_EX_GetFunctionListExtended");
if (get_function_list_func == NULL_PTR)
{
std::cout << "Function 'GetProcAddress' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
rv = get_function_list_func(&function_list);
if (rv != CKR_OK)
{
std::cout << "Function 'C_GetFunctionList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = get_function_list_func_ex(&function_list_ex);
if (rv != CKR_OK)
{
std::cout << "Function 'CK_C_EX_GetFunctionList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_Initialize(NULL_PTR);
if (rv != CKR_OK)
{
std::cout << "Function 'C_Initialize' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_GetSlotList(CK_TRUE, NULL_PTR, &slot_count);
if (rv != CKR_OK)
{
std::cout << "Function 'C_GetSlotList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
if (slot_count == 0)
{
std::cout << "Function 'C_GetSlotList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
slots = (CK_SLOT_ID*)malloc(slot_count * sizeof(CK_SLOT_ID));
memset(slots, 0, (slot_count * sizeof(CK_SLOT_ID)));
rv = function_list->C_GetSlotList(CK_TRUE, slots, &slot_count);
if (rv != CKR_OK)
{
std::cout << "Function 'C_GetSlotList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
static CK_UTF8CHAR NEW_USER_PIN[] = {'1', '2', '3', '4', '5', '6', '7', '8'};
static CK_UTF8CHAR SO_PIN[] = {'8', '7', '6', '5', '4', '3', '2', '1'};
static CK_CHAR TOKEN_STD_LABEL[] = {"!!!Sample Rutoken label!!!"};
CK_RUTOKEN_INIT_PARAM initInfo_st;
CK_BBOOL bIsRutokenECP = TRUE;
::memset(&initInfo_st, 0, sizeof(CK_RUTOKEN_INIT_PARAM));
initInfo_st.ulSizeofThisStructure = sizeof(CK_RUTOKEN_INIT_PARAM);
initInfo_st.UseRepairMode = 0;
initInfo_st.pNewAdminPin = SO_PIN;
initInfo_st.ulNewAdminPinLen = sizeof(SO_PIN);
initInfo_st.pNewUserPin = NEW_USER_PIN;
initInfo_st.ulNewUserPinLen = sizeof(NEW_USER_PIN);
initInfo_st.ulMinAdminPinLen = bIsRutokenECP ? 6 : 1;
initInfo_st.ulMinUserPinLen = bIsRutokenECP ? 6 : 1;
initInfo_st.ChangeUserPINPolicy = (TOKEN_FLAGS_ADMIN_CHANGE_USER_PIN | TOKEN_FLAGS_USER_CHANGE_USER_PIN);
initInfo_st.ulMaxAdminRetryCount = MAX_ADMIN_RETRY_COUNT;
initInfo_st.ulMaxUserRetryCount = MAX_USER_RETRY_COUNT;
initInfo_st.pTokenLabel = TOKEN_STD_LABEL;
initInfo_st.ulLabelLen = sizeof(TOKEN_STD_LABEL);
rv = function_list_ex->C_EX_InitToken(slots[0], SO_PIN, arraysize(SO_PIN), &initInfo_st);
if (rv != CKR_OK)
{
std::cout << "Function 'C_EX_InitToken' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_CloseAllSessions(slots[0]);
if (rv != CKR_OK)
{
std::cout << "Function 'C_CloseAllSessions' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
return true;
}
bool InitToken()
{
HMODULE module = NULL_PTR;
CK_SESSION_HANDLE session = NULL_PTR;
CK_FUNCTION_LIST_PTR function_list = NULL_PTR;
CK_C_GetFunctionList get_function_list_func = NULL_PTR;
CK_SLOT_ID_PTR slots = NULL_PTR;
CK_ULONG slot_count = 0;
CK_RV rv = CKR_OK;
module = LoadLibrary(PKCS11_LIBRARY_NAME);
if (module == NULL_PTR)
{
std::cout << "Function 'LoadLibrary' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
get_function_list_func = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList");
if (get_function_list_func == NULL_PTR)
{
std::cout << "Function 'GetProcAddress' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
rv = get_function_list_func(&function_list);
if (rv != CKR_OK)
{
std::cout << "Function 'C_GetFunctionList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_Initialize(NULL_PTR);
if (rv != CKR_OK)
{
std::cout << "Function 'C_Initialize' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_GetSlotList(CK_TRUE, NULL_PTR, &slot_count);
if (rv != CKR_OK)
{
std::cout << "Function 'C_GetSlotList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
if (slot_count == 0)
{
std::cout << "Function 'C_GetSlotList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
slots = (CK_SLOT_ID*)malloc(slot_count * sizeof(CK_SLOT_ID));
memset(slots, 0, (slot_count * sizeof(CK_SLOT_ID)));
rv = function_list->C_GetSlotList(CK_TRUE, slots, &slot_count);
if (rv != CKR_OK)
{
std::cout << "Function 'C_GetSlotList' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_InitToken(slots[0], SO_PIN, sizeof(SO_PIN), TOKEN_LABEL);
if (rv != CKR_OK)
{
std::cout << "Function 'C_InitToken' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_OpenSession(slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session);
if (rv != CKR_OK)
{
std::cout << "Function 'C_OpenSession' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_Login(session, CKU_SO, SO_PIN, sizeof(SO_PIN));
if (rv != CKR_OK)
{
std::cout << "Function 'C_OpenSession' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_InitPIN(session, USER_PIN, sizeof(USER_PIN));
if (rv != CKR_OK)
{
std::cout << "Function 'C_OpenSession' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_Logout(session);
if ((rv != CKR_OK) && (rv != CKR_USER_NOT_LOGGED_IN))
{
std::cout << "Function 'C_Logout' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
rv = function_list->C_CloseAllSessions(slots[0]);
if (rv != CKR_OK)
{
std::cout << "Function 'C_CloseAllSessions' failed! Error: 0x" << std::hex << rv << std::endl;
return false;
}
return true;
}
bool DeleteContainer(LPCSTR container_name, LPCSTR reader_name)
{
std::string full_container_name = std::string(reader_name) + std::string(container_name);
HCRYPTPROV prov = 0;
if (!::CryptAcquireContext(&prov, reader_name, g_prov_name, g_prov_type, CRYPT_DEFAULT_CONTAINER_OPTIONAL | CRYPT_SILENT))
{
std::cout << "Function 'CryptAcquireContext' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
if (!::CryptSetProvParam(prov, PP_KEYEXCHANGE_PIN, (BYTE*)g_token_pass, 0))
{
std::cout << "Function 'CryptSetProvParam' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
HCRYPTPROV prov2 = 0;
if (!::CryptAcquireContext(&prov2, full_container_name.c_str(), g_prov_name, g_prov_type, CRYPT_SILENT | CRYPT_DELETEKEYSET))
{
std::cout << "Function 'CryptAcquireContext' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
::CryptReleaseContext(prov2, 0);
::CryptReleaseContext(prov, 0);
return true;
}
bool GenerateKeyPair(LPCSTR container_name, LPCSTR reader_name)
{
std::string full_container_name = std::string(reader_name) + std::string(container_name);
HCRYPTPROV prov = 0;
if (!::CryptAcquireContext(&prov, reader_name, g_prov_name, g_prov_type, CRYPT_DEFAULT_CONTAINER_OPTIONAL | CRYPT_SILENT))
{
std::cout << "Function 'CryptAcquireContext' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
if (!::CryptSetProvParam(prov, PP_KEYEXCHANGE_PIN, (BYTE*)g_token_pass, 0))
{
std::cout << "Function 'CryptSetProvParam' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
HCRYPTPROV prov2 = 0;
HCRYPTKEY key = 0;
if (!::CryptAcquireContext(&prov2, full_container_name.c_str(), g_prov_name, g_prov_type, CRYPT_NEWKEYSET | CRYPT_SILENT))
{
std::cout << "Function 'CryptAcquireContext' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
if (!::CryptGenKey(prov2, AT_KEYEXCHANGE, 0, &key))
{
std::cout << "Function 'CryptGenKey' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
::CryptDestroyKey(key);
key = 0;
if (!::CryptGetUserKey(prov2, AT_KEYEXCHANGE, &key))
{
std::cout << "Function 'CryptGetUserKey' failed! Error: 0x" << std::hex << HRESULT_FROM_WIN32(::GetLastError()) << std::endl;
return false;
}
::CryptDestroyKey(key);
::CryptReleaseContext(prov2, 0);
::CryptReleaseContext(prov, 0);
return true;
}