OpenVPN клиент зависает / не запрашивает PIN-код от Рутокена

Описание

При попытке подключения к OpenVPN серверу через linux клиент с ключами на Рутокен ЭЦП процесс подключения зависает и не пытается спросить PIN-код от Рутокена.

Причина

Проблема в библиотеке libpkcs11-helper которая, будучи вызвана в дочернем процессе (fork), дважды вызывает функцию C_Initialize и плохо обрабатывает ошибку CKR_CRYPTOKI_ALREADY_INITIALIZED

Проявление (имитация поведения):

$ pkcs11-tool --test-fork --module ./librtpkcs11ecp.so

Решение

Пересборка библиотеки libpkcs11-helper с флагами --disable-threading и --disable-slotevent и подмена системной библиотеки libpkcs11-helper

Пошаговое решение на примере Ubuntu Linux 32 bit

Подготовка окружения

Установите набор пакетов необходимых для сборки:

$ sudo apt-get install git automake autoconf checkinstall libtool libssl-dev pkg-config

Загрузите исходные коды pkcs11-helper:

$ git clone https://github.com/OpenSC/pkcs11-helper.git

Сборка пакета

Создаем пакет с библиотекой из исходных кодов.

$ cd pkcs11-helper
$ autoreconf -i
$ ./configure --disable-threading --disable-slotevent 
$ make
$ sudo checkinstall

В процессе chekinstall, измените Name на pkcs11-helper, а Version на 1.21

Проверка

Теперь, когда библиотека собрана, нужно подложить ее вместо системной.

Проверим, что она находится в папке /usr/local/lib

$ find /usr/local/lib -name "libpkcs*"
$ ls -la /usr/local/lib | grep libpkcs11

Если библиотека libpkcs11-helper.so находится - значит сборка и установка пакета были успешно завершены.

Для начала сохраним системную библиотеку под другим именем:

$ sudo mv /usr/lib/i386-linux-gnu/libpkcs11-helper.so.1.0.0 /usr/lib/i386-linux-gnu/libpkcs11-helper.so.1.0.0-original

Внимание! Если вы используете 64-битную версию ОС Ubuntu, то вместо /usr/lib/i386-linux-gnu используйте /usr/lib/x86_64-linux-gnu

Копируем новую библиотеку вместо старой.

$ sudo cp /usr/local/lib/libpkcs11-helper.so /usr/lib/i386-linux-gnu/libpkcs11-helper.so.1.0.0

Также будет не лишним переделать символическую ссылку

$ sudo rm /usr/lib/i386-linux-gnu/libpkcs11-helper.so.1
$ sudo ln -s /usr/lib/i386-linux-gnu/libpkcs11-helper.so.1.0.0 /usr/lib/i386-linux-gnu/libpkcs11-helper.so.1

Внимание! Если вы используете 64-битную версию ОС Ubuntu, то вместо /usr/lib/i386-linux-gnu используйте /usr/lib/x86_64-linux-gnu

Теперь можно посмотреть что в системной папке все в порядке

$ ls -la /usr/lib/i386-linux-gnu/ | grep libpkcs11

Перезапустите openvpn клиент и теперь процесс подключения к серверу запросит PIN-код и, если все остальные настройки в порядке, подключится к серверу

Очистка

После сборки и установки пакета можно удалить исходные коды pkcs11-helper.

Для удаления собранного пакета из системы по каким-либо причинам выполните:

$ dpkg -r pkcs11-helper

или воспользуйтесь вашим стандартным менеджером пакетов, например, Synaptic.