Рутокен ЭЦП SC и Raspbian OS

Всем привет!
В одном из моих проектов мне необходимо реализовать механизм создания цифровой подписи при помощи смарт карт.
Для этих целей у меня есть смарт карты Рутокен ЭЦП SC и кард ридер ACR38U-I1.
При решении этой задачи я столкнулся с проблемой отсутствия сборки библиотеки PKCS#11 для Raspbian OS (имеющиеся сборки под debian и ubuntu по понятным причинам не подходят).
В результате мне пришлось искать альтернативные реализации стандарта PKCS11 от сторонних разработчиков. Выбор пал на opensc-pkcs11 и pyKCS11(обертку для стандарта pkcs11 для взаимодействия из Python).
После установки указанных библиотек я решил запустить тестовый пример из библиотеки pyKCS11 и получил следующие ошибки:

root@raspberrypi:/home/pi/EDS/PyKCS11-1.3.0/samples/LowLevel# python InitTokenPin.py
src/dyn_unix.c:34:SYS_dyn_LoadLibrary() pkcs11_lib.dll: cannot open shared object file: No such file or directory
и
root@raspberrypi:/home/pi/EDS/PyKCS11-1.3.0/samples/LowLevel# python test.py
src/dyn_unix.c:34:SYS_dyn_LoadLibrary() incryptoki2.dll: cannot open shared object file: No such file or directory

Просмотрел все имеющиеся библиотеки внутри папки /usr/ и не нашел их. Возможно opensc-pkcs11 не предоставляет соответствующих библиотек (либо они называются как-то иначе).
В связи с этим, у меня возникает вопрос, - приходилось ли кому-нибудь сталкиваться с аналогичной проблемой. И если да, то как удалось ее решить?

Re: Рутокен ЭЦП SC и Raspbian OS

Добрый день, библиотека для ARM процессоров существует, но пока предоставляется только по запросу.
Напишите пожалуйста нам на hotline@rutoken.ru

(2015-11-23 07:15:44 отредактировано Altynbek)

Re: Рутокен ЭЦП SC и Raspbian OS

Еще раз спасибо за предоставленную библиотеку rtpkcs11ecp для ОС raspbian.
Однако у меня возникла проблема. Дело в том, что я пытаюсь загрузить библиотеку с помощью с++ кода (как продемонстрировано в документации на сайте).
В этом скрипте я подключил заголовочный файл rtpkcs11.h, предоставленный мне вместе с библиотекой.
Я подключил его следующим образом:
#include "rtpkcs11/rtpkcs11.h"

И, скомпилировав свою программу следующим образом  gcc sign.cpp -lstdc++
получил следующие ошибки:
pi@raspberrypi ~/Desktop/au-gateway/POC $ gcc sign.cpp -lstdc++
sign.cpp: In function ‘int main()’:
sign.cpp:31:2: error: ‘HMODULE’ was not declared in this scope
sign.cpp:31:10: error: expected ‘;’ before ‘hModule’
sign.cpp:41:6: error: ‘hModule’ was not declared in this scope
sign.cpp:41:47: error: ‘LoadLibrary’ was not declared in this scope
sign.cpp:51:91: error: ‘GetProcAddress’ was not declared in this scope
sign.cpp:72:6: error: ‘hModule’ was not declared in this scope
sign.cpp:75:29: error: ‘FreeLibrary’ was not declared in this scope

Проверил все предоставленные мне заголовочные файлы и не обнаружил определений для типов данных hModule и методов LoadLibrary() и GetProcAddress().
И потому у меня возникает вопрос, где можно их взять, чтобы устранить вышеуказанную проблему?

Это исходник примера, взятого из документации, который я пытаюсь скомпилировать:
#include <iostream>
#include <stdio.h>

#include "rtpkcs11/rtpkcs11.h"

#ifdef __unix__
/* Библиотека для Рутокен Lite, Рутокен ЭЦП, Рутокен PINPad, поддерживает алгоритмы ГОСТ и RSA */
    #define PKCS11_LIBRARY_NAME         "/usr/lib/pkcs11-arm/rtpkcs11ecp/librtpkcs11ecp.so"
    #define PKCS11ECP_LIBRARY_NAME      "/usr/lib/pkcs11-arm/rtpkcs11ecp/librtpkcs11ecp.so"
#endif

int main()
{
    HMODULE hModule = NULL_PTR;                                     // Хэндл загруженной библиотеки PKCS#11
    CK_FUNCTION_LIST_PTR pFunctionList = NULL_PTR;                  // Указатель на список функций PKCS#11, хранящийся в структуре CK_FUNCTION_LIST
    CK_C_GetFunctionList pfGetFunctionList = NULL_PTR;              // Указатель на функцию C_GetFunctionList
    CK_RV rv = CKR_OK;                                              // Вспомогательная переменная для хранения кода возврата

    while (TRUE)
    {
        // Загрузить библиотеку
        printf("Loading library %s", PKCS11_LIBRARY_NAME);
        hModule = LoadLibrary(PKCS11_LIBRARY_NAME);
        if (hModule == NULL_PTR)
        {
            printf(" -> Failed to load rtPKCS11ECP library\n");
            break;
        }
    
        // Получить адрес функции запроса структуры с указателями на функции
        printf(" -> Getting GetFunctionList function");
        pfGetFunctionList = (CK_C_GetFunctionList)GetProcAddress(hModule, "C_GetFunctionList");
        if (pfGetFunctionList == NULL_PTR)
        {
            printf(" -> Failed to get function list\n");
            break;
        }
    
        // Получить структуру с указателями на функции
        printf("Getting function list");
        rv = pfGetFunctionList(&pFunctionList);
        if (rv != CKR_OK)
        {
            printf(" -> Failed\n");
            break;
        }
        break;
    }
    
    // Выгрузить библиотеку из памяти
    if (hModule)
    {
        printf("Unloading library");
        if (FreeLibrary(hModule) != TRUE)
            printf(" -> Failed to unload library\n");
        hModule = NULL_PTR;
    }
}

Re: Рутокен ЭЦП SC и Raspbian OS

Добрый день.

Конечно, в linux таких функций и типов просто нет, так как для динамической загрузки используются dlopen, dlclose, dlsym
Вы можете подключить файл common.h из нашего SDK так чтобы они транслировались автоматически.

Все это уже было для вас сделано в файле makefile.
Почему вы им не воспользовались?

(2015-11-23 15:04:51 отредактировано Altynbek)

Re: Рутокен ЭЦП SC и Raspbian OS

Здравствуйте!
Полагаю, по незнанию ))
Просто в сборке, присланной мне на почту не было ни файлов Common.h, ни makefile'ов.

Re: Рутокен ЭЦП SC и Raspbian OS

SDK надо брать здесь и больше нигде https://www.rutoken.ru/developers/sdk/

Re: Рутокен ЭЦП SC и Raspbian OS

В таком случае, у меня вопрос.
Я скачал SDK с вышеуказанного адреса. Как его теперь установить на Raspbian OS?
Дело в том, что мне не удалось найти ни одного мануала по установке Вашего SDK.

Что касается файлов Common.h, то я взял его из папки /samples вашего sdk и подключил в своем примере (плюс файлы win2nix.h и wintypes.h, так как этого требовал компилятор).
Скомпилировал свой пример и получил следующее исключение:

In file included from rtpkcs11/Common.h:37:0,
                 from sign.cpp:4:
rtpkcs11/win2nix.h: In function ‘pthread_t CreateProc(pthread_t*, pthread_attr_t*, void*, void*)’:
rtpkcs11/win2nix.h:72:41: error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’ [-fpermissive]
/usr/include/pthread.h:225:12: error:   initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’ [-fpermissive]

Вопрос, что я сделал не так ?

Re: Рутокен ЭЦП SC и Raspbian OS

Altynbek, здравствуйте.
Пока вы выполняете сборку исключительно для тестирования функциональности, можете добавить при сборке флаг компилятора -fpermissive (как сам компилятор и предлагает в описании ошибки):

gcc sign.cpp -fpermissive -lstdc++