(2023-09-21 12:11:08 отредактировано Alex_Zorg)

Программно извлечь Рутокен по серийному номеру

Есть задача управления Рутокенами в Линукс.

Через интерес PKCS#11 API удается прочитать необходимые данные (серийный номер, отпечаток сертификата и т.п.)
Если данный Рутокен подключен к ЭВМ, для которой эксплуатация данного токена запрещена, то его нужно программно извлечь.

Для программной блокировки можно использовать доступ к sysfs (по Sysname/Syspash в нотации udev). Отслеживать
подключение Рутокенов как USB устройств можно с помощью событий udev. В этом нет проблем.

Если к системе подключается только ОДИН Рутокен, то нет проблем: Прочитали Serial/Number из слота PKCS#11, при необходимости удалили устройство Рутокена на USB шине.

Проблема возникает, если к ЭВМ подключается НЕСКОЛЬКО Рутокенов одновременно. Если Руктоены подключаются ПОСЛЕДОВАТЕЛЬНО - то тоже нет проблем, можно "склеивать" события подключения USB устройств и появления токенов в слотах PKCS#11 по времени. Проблема возникает при одновременном подключении нескольких токенов или, если токены подключены ДО старта программы (до старта ПЭВМ), тогда сложно установить взаимно однозначное соответствие между USB устройством (все токены на шине USB имеют одинаковый Serial="Aktiv_Rutoken_ECP") и слотом PKCS#11, для которого доступен уникальный серийный номер Рутокена и другие атрибуты объектов на нем.

Вероятно, если к ЭВМ будет подключаться "запрещенный" (не учтенный), Рутокен придется блокировать (удалять программно) все Рутокены сразу. Что конечно не изящно.

Быть может есть способ заблокировать работу Рутокена через PKCS#11 API?

Или как установить соответствие между номером слота PKCS#11 и номер устройства на шине USB?

Re: Программно извлечь Рутокен по серийному номеру

Alex_Zorg, добрый день!

Можем предложить вам:
1) Изменить запуск сервиса pcscd из systemd  на запуск с ведением лога (флаг -d).
2) Получать системное имя считывателя (например, Aktiv Rutoken ECP N) через PKCS11 (например, поле slotDescription из ответа функции C_GetSlotInfo()).
3) Затем искать это имя в pcscd-логе (пишется в syslog) и доставать путь к usb-устройству.
4) Блокировать Рутокен.

(2023-09-22 22:58:22 отредактировано Alex_Zorg)

Re: Программно извлечь Рутокен по серийному номеру

Павел Анфимов, Спасибо за идею!

Да, видим в логах pcscd что-то типа:

сен 22 22:51:14 midipc pcscd[8699]: 00194683 hotplug_libudev.c:647:HPEstablishUSBNotifications() USB Device add
сен 22 22:51:14 midipc pcscd[8699]: 00000210 hotplug_libudev.c:300:get_driver() Looking for a driver for VID: 0x0A89, PID: 0x0030, path: /dev/bus/usb/003/022
сен 22 22:51:14 midipc pcscd[8699]: 00000012 hotplug_libudev.c:421:HPAddDevice() Adding USB device: Aktiv Rutoken ECP
сен 22 22:51:14 midipc pcscd[8699]: 00000454 ifdhandler.c:111:CreateChannelByNameOrChannel() Lun: 0, device: usb:0a89/0030:libudev:0:/dev/bus/usb/003/022
сен 22 22:51:14 midipc pcscd[8699]: 00000008 ccid_usb.c:692:OpenUSBByName() Using USB bus/device: 3/22
сен 22 22:51:14 midipc pcscd[8699]: 00000972 ifdhandler.c:389:IFDHGetCapabilities() tag: 0xFB3, usb:0a89/0030:libudev:0:/dev/bus/usb/003/022 (lun: 0)
сен 22 22:51:14 midipc pcscd[8699]: 00000190 ifdhandler.c:389:IFDHGetCapabilities() tag: 0xFAE, usb:0a89/0030:libudev:0:/dev/bus/usb/003/022 (lun: 0)
сен 22 22:51:14 midipc pcscd[8699]: 00000380 ifdhandler.c:1246:IFDHPowerICC() action: PowerUp, usb:0a89/0030:libudev:0:/dev/bus/usb/003/022 (lun: 0)

/dev/bus/usb/003/022 - это как раз device node по которому можно используя udev (или еще как-то) отыскать syspath в /sys и сделать свои дела (например принудительно удалить незарегистрированное устройства).

Из минусов конечно придется до настраивать АРМ для включения логов pcscd.

Вероятно сделаем такой алгоритм параллельно с более простым и, если логи доступы будем действовать более точно и селективно.