Библиотека "librtpkcs11ecp.so" не работает с Alt Linux
Добрый день,
Собрал и запустил такой тестовый пример на Alt Simply Linux 10.2 (Captain Finn):
#include <cryptoki/rtpkcs11.h>
#include <dlfcn.h>
#include <iostream>
#include <string>
#include <vector>
int main(int argc, const char* argv[]) {
CK_FUNCTION_LIST_PTR functionList;
CK_C_GetFunctionList pGetFunctionList;
void* handle = dlopen("./librtpkcs11ecp.so", RTLD_NOW);
if (!handle) {
std::cerr << "Can't upload PKCS#11 library\n" << dlerror() << std::endl;
return 1;
}
//**************************************************************************
pGetFunctionList = (CK_C_GetFunctionList)dlsym(handle, "C_GetFunctionList");
if (!pGetFunctionList) {
std::cerr << "Can't find C_GetFunctionList." << std::endl;
return 1;
}
//**************************************************************************
CK_RV rv = pGetFunctionList(&functionList);
if (rv != CKR_OK) {
std::cerr << "C_GetFunctionList error: " << rv << std::endl;
return 1;
}
//**************************************************************************
CK_C_INITIALIZE_ARGS initArgs = {NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR, CKF_OS_LOCKING_OK, NULL_PTR};
rv = functionList->C_Initialize(&initArgs);
// rv = functionList->C_Initialize(NULL_PTR);
if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
std::cerr << "C_Initialize error: " << rv << std::endl;
return 1;
}
//**************************************************************************
CK_INFO info;
rv = functionList->C_GetInfo(&info);
if (rv != CKR_OK) {
std::cerr << "C_GetInfo error: " << rv << std::endl;
return 1;
}
std::cout << "C_GetInfo.desc = \""
<< std::string((const char*)info.libraryDescription, sizeof(info.libraryDescription)) << "\""
<< std::endl;
std::cout << "C_GetInfo.flags = " << info.flags << std::endl;
std::cout << "C_GetInfo.cryptokiVer = " << (int)info.cryptokiVersion.major << "." << (int)info.cryptokiVersion.minor
<< std::endl;
std::cout << "C_GetInfo.libraryVer = " << (int)info.libraryVersion.major << "." << (int)info.libraryVersion.minor
<< std::endl;
//**************************************************************************
CK_ULONG counter;
rv = functionList->C_GetSlotList(CK_FALSE, NULL_PTR, &counter);
if (rv != CKR_OK) {
std::cerr << "C_GetSlotList(FALSE) error: " << rv << std::endl;
return 1;
}
std::cout << "C_GetSlotList(FALSE).counter = " << counter << std::endl;
//**************************************************************************
rv = functionList->C_GetSlotList(CK_TRUE, NULL_PTR, &counter);
if (rv != CKR_OK) {
std::cerr << "C_GetSlotList(TRUE) error: " << rv << std::endl;
return 1;
}
std::cout << "C_GetSlotList(TRUE).counter = " << counter << std::endl;
//**************************************************************************
std::cout << "before C_Finalize" << std::endl;
rv = functionList->C_Finalize(NULL);
if (rv != CKR_OK) {
std::cerr << "C_Finalize error: " << rv << std::endl;
return 1;
}
std::cout << "after C_Finalize" << std::endl;
dlclose(handle);
return 0;
}
Библиотека берется отсюда:
"RutokenSDK\pkcs11\lib\linux_glibc-x86_64\librtpkcs11ecp.so"
1. Программа виснет на вызове C_Finalize().
[user@host-15 RutokenTest]$ ./RutokenTest
C_GetInfo.desc = "Rutoken ECP PKCS #11 library "
C_GetInfo.flags = 0
C_GetInfo.cryptokiVer = 2.40
C_GetInfo.libraryVer = 2.13
C_GetSlotList(FALSE).counter = 15
C_GetSlotList(TRUE).counter = 0
before C_Finalize
Без разницы которая из C_Initialize вызвана:
rv = functionList->C_Initialize(&initArgs);
или rv = functionList->C_Initialize(NULL_PTR);
CALL STACK:
Зависание происходит как при наличии подключенных токенов, так и при их отсутствии.
2. Подключил два токена Rutoken ECP 3.0, программ их не видит:
[user@host-15 RutokenTest]$ ./RutokenTest
C_GetInfo.desc = "Rutoken ECP PKCS #11 library "
C_GetInfo.flags = 0
C_GetInfo.cryptokiVer = 2.40
C_GetInfo.libraryVer = 2.13
C_GetSlotList(FALSE).counter = 15
C_GetSlotList(TRUE).counter = 0
before C_Finalize
Библиотека сообщает об отсутствии подключенных токенов. C_GetSlotList(TRUE).counter = 0
Если добавить такой код:
std::vector<CK_SLOT_ID> slots(counter);
rv = functionList->C_GetSlotList(CK_FALSE, slots.data(), &counter);
if (rv != CKR_OK) {
std::cerr << "C_GetSlotList(FALSE, data) error: " << rv << std::endl;
return 1;
}
for (auto& slot : slots) {
CK_SLOT_INFO slotInfo;
rv = functionList->C_GetSlotInfo(slot, &slotInfo);
if (rv != CKR_OK) {
std::cerr << "C_GetSlotInfo error: " << rv << " slot: " << slot << std::endl;
return 1;
}
std::cout << "slot: " << slot << std::endl;
std::cout << "C_GetSlotInfo.desc = \""
<< std::string((const char*)slotInfo.slotDescription, sizeof(slotInfo.slotDescription)) << "\""
<< std::endl;
std::cout << "C_GetSlotInfo.flags = " << slotInfo.flags << std::endl;
}
Программа распечатает 15 пустышек:
slot: 0
C_GetSlotInfo.desc = " "
C_GetSlotInfo.flags = 6
slot: 1
C_GetSlotInfo.desc = " "
C_GetSlotInfo.flags = 6
...
Что может быть причиной проблем с зависанием и неспособностью увидеть подключенный токен?
P.S. На Astra Linux 1.8, этот пример работает корректно...