Nitrokey / libnitrokey

Communicate with Nitrokey devices in a clean and easy manner
https://nitrokey.com/
GNU Lesser General Public License v3.0
65 stars 34 forks source link

NK3 ccid/gnupg udev rules #222

Closed jjakob closed 1 year ago

jjakob commented 1 year ago

Now that NK3 firmware has opcard-rs 1.0.0, should ccid udev rules for NK3 devices be added? Or is it still not stable enough? I had to add this to get my NK3A NFC user-accessible:

ATTR{idVendor}=="20a0", ATTR{idProduct}=="42b2", ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg", TAG+="uaccess"
szszszsz commented 1 year ago

Hi!

  1. Opcard is officially stable, and available to all stable firmware users.
  2. You are right, indeed it lacks the usual GnuPG ENV settings. Are you sure however it is really necessary? What OS distribution and version are you using?
jjakob commented 1 year ago

Re: 2. I'm using Gentoo with OpenRC (no systemd), eudev, elogind. The libnitrokey package installs data/41-nitrokey.rules. Without those rules, my user (uid 1000) doesn't have access to the usb or hidraw devices, so neither nitropy nor gpg work. With 41-nitrokey.rules nitropy works with both NK3 and NK Pro. The ccid (openpgp, gnupg) part of the rules work for a Nitrokey Pro, but not for a Nitrokey 3A NFC as it doesn't set uaccess on the device file. I'm talking about gnupg scdaemon's internal ccid driver, without using pcsc-lite. Even if pcsc-lite is started and has access to the NK3, scdaemon still won't be able to use the card: it tries to open the USB device but fails with a permission error:

scdaemon[17491] DBG: ccid-driver: usb_open failed: LIBUSB_ERROR_ACCESS
scdaemon[17491] ccid open error: skip
scdaemon[17491] check permission of USB device at Bus 007 Device 028

I think this makes it not try to use pcsc even if it is running, so it just error exits. The builtin ccid driver has to be manually disabled by setting "disable-ccid" in scdaemon.conf. (this is also required if you want to use pcsc-lite anyway, so it's nothing unusual) If I use pcsc-lite + ccid driver and set 'disable-ccid' in gnupg scdaemon.conf, NK3 works in gnupg, as ccid and pcsc-lite install their own udev rules. pcscd user is also added to the usb group by default, which grants it access to all usb devices. Other than via udev rules, the other way I could give access to my user to usb devices is adding it to the usb group. But that would give it access to all usb devices, which is less safe than udev granting just for those that need it.

One peculiarity I found when looking at the pcsc udev rules: they match on the usb interface id, which grants access to all usb readers with the ccid protocol. For example, 70-openct.rules contains:

# ccid
ATTR{bInterfaceClass}=="0b", ATTR{bInterfaceSubClass}=="00", ATTR{bInterfaceProtocol}=="00", ATTRS{idVendor}=="?*"  RUN+="/lib/udev/openct_usb
/dev/$parent"

This would also match on all NK usb devices that have that CCID interface. I think the nitrokey rules could be simplified by merging all the separate rules (for the ccid/openpgp device) into one, like OpenCT does.

A thing to watch out for: the rules from OpenCT, pcsc-lite, ccid and libnitrokey will interact so if the user has more than one of those installed, even if stopped, the rules will be loaded. I don't think it will break anything though as, for example, the aforementioned openct_usb checks if openct is running, and does nothing if it's not. pcsc-ccid rules have this:

# generic CCID device (bInterfaceClass = 0x0b)
# change group from default "root" to "pcscd"
ENV{ID_USB_INTERFACES}=="*:0b0000:*", ENV{PCSCD}="1"

this works the same way as openct rules, but in a different syntax.

This part of the rules has also been removed in the latest ccid driver versions so the rules don't do anything for ccid devices. So there's even less chance of interaction.

In short, ccid part of the nitrokey rules is necessary for user access via gnupg's builtin scdaemon. Other programs (pcsc-lite, OpenCT) install their own rules so they don't need the nitrokey rules. The hidraw part is still necessary for user access via e.g. libnitrokey using programs, nitropy,...

jjakob commented 1 year ago

Actually I think this is because eudev does not ship a rule like I described above that would match every CCID device. systemd udev does ship 60-fido-id.rules, which will match any CCID device. There, a NK3 will already work with gpg without 41-nitrokey.rules. So the better solution is to add 60-fido-id.rules (or an equivalent) to eudev. I also think all the gpg rules can be deleted from 41-nitrokey.rules, as systemd udev will already handle them with 60-fido-id.rules.

jjakob commented 1 year ago

Closing because this is not needed with systemd udev, it's an eudev issue.