Nitrokey / pynitrokey

Python client for Nitrokey devices
Apache License 2.0
100 stars 27 forks source link

0.4.31: Switching of identies often fails #295

Open dvzrv opened 1 year ago

dvzrv commented 1 year ago

Hi! Since updating to 0.4.31, I noticed that a lot of times the switching of identities fails and only re-plugging the device (Nitrokey Start) helps.

nitropy will show this:

nitropy start set-identity 0
Command line tool to interact with Nitrokey devices 0.4.31
Setting identity to 0
Identity not changed - device is busy or the selected identity is already active

After replugging I get:

nitropy start set-identity 0
Command line tool to interact with Nitrokey devices 0.4.31
Setting identity to 0
Device: Nitrokey Start FSIJ-1.2.19-XXXXXXXX
reset done - now active identity: 0
szszszsz commented 1 year ago

Hi! I was touching this recently - will check that. The intention was to signalize real case, that the identity was not changed, because device already uses it. Worth more tests probably.

dvzrv commented 1 year ago

It would be nice if you could look into this. It appears that re-plugging the device is now a hard requirement if one wants to switch the identity. This is even required if one has just re-plugged, but before calling nitropy start set-identity the password has been queried again (e.g. by pressing OK in the dialog requesting to plug in a specific token providing the key). One has to re-plug the device again. This worked fine with 0.4.30.

szszszsz commented 1 year ago

I see. It looked fine for me yesterday. Can you elaborate that in a reproduction scenario with steps listed? I will re-check it.

dvzrv commented 1 year ago

There are two scenarios (both using two identities):

Not plugged in

  1. No nitrokey plugged in, identity 1 selected
  2. Start gnupg action requiring identity 0 (gnupg launches dialog requiring to plug in token providing key)
  3. Plug in nitrokey
  4. Press OK in window requesting the token
  5. Use nitropy start set-identity 0, which leads to
    Command line tool to interact with Nitrokey devices 0.4.31
    Setting identity to 0
    Identity not changed - device is busy or the selected identity is already active
  6. Re-plug nitrokey and rerun nitropy start set-identity 0

Plugged in

  1. Nitrokey plugged in, identity 1 selected
  2. Start gnupg action requiring identity 0 (gnupg launches dialog requiring to plug in token providing key)
  3. Use nitropy start set-identity 0, which leads to
    Command line tool to interact with Nitrokey devices 0.4.31
    Setting identity to 0
    Identity not changed - device is busy or the selected identity is already active
  4. Re-plug nitrokey and rerun nitropy start set-identity 0
szszszsz commented 1 year ago

On my setup I reproduce the "Plugged In" scenario on the previous version as well. Looking further. Command:

pipx run "pynitrokey==0.4.30" start set-identity 1
szszszsz commented 1 year ago

@dvzrv Current master branch contains improved identities switching. Can you install it directly and test within your environment? Hopefully this would help. Please reopen otherwise.

dvzrv commented 1 year ago

Sorry, but that made it worse:

nitropy start set-identity 1
Command line tool to interact with Nitrokey devices 0.4.31
Setting identity to 1
Could not connect to the device. Attempting to close other smart card services.
*** Running: sudo systemctl stop pcscd pcscd.socket
[sudo] password for xxxx:

pcscd is not running and privilege escalation should not be needed to switch an identity:

systemctl status -a -l pcscd pcscd.socket
○ pcscd.service - PC/SC Smart Card Daemon
     Loaded: loaded (/usr/lib/systemd/system/pcscd.service; indirect; preset: disabled)
     Active: inactive (dead)
TriggeredBy: ○ pcscd.socket
       Docs: man:pcscd(8)

○ pcscd.socket - PC/SC Smart Card Daemon Activation Socket
     Loaded: loaded (/usr/lib/systemd/system/pcscd.socket; disabled; preset: disabled)
     Active: inactive (dead)
   Triggers: ● pcscd.service
     Listen: /run/pcscd/pcscd.comm (Stream)
dvzrv commented 1 year ago

Argh, and this just YOLO starts a system service and socket. Please don't do stuff like that!

szszszsz commented 1 year ago
  1. Yes, I wanted to make a reliable workaround for that, but that's not the case for your scenario apparently.
  2. Can you debug what's taking the smart card handle? If that's not pcscd, then scdaemon I presume?
dvzrv commented 1 year ago

Yes, I'm only using scdaemon. Should I (also) use pcscd?

My scdaemon.conf currently only contains disable-pinpad and gpg-agent successfully starts an instance of /usr/lib/gnupg/scdaemon --multi-server.

szszszsz commented 1 year ago

I have removed the systemctl calls and pushed that to master - you can try again. If so, then scdaemon takes the ownership of the smart card by design, and has to be closed before continuing.

Or, you could use gpg-connect-agent "SCD APDU 00 85 00 0<IDENTITY>" instead. I am not sure how to handle multiple readers here though.

dvzrv commented 1 year ago

I have removed the systemctl calls and pushed that to master - you can try again.

This change does not work yet either:

nitropy start set-identity 1
Command line tool to interact with Nitrokey devices 0.4.31
Setting identity to 1
Device is occupied by some other service and cannot be connected to. Identity not changed.

FWIW, 0.4.30 works as intended for me!

If so, then scdaemon takes the ownership of the smart card by design, and has to be closed before continuing.

That seems to be done with 0.4.30:

nitropy start set-identity 0
Command line tool to interact with Nitrokey devices 0.4.30
Setting identity to 0
Could not connect to device, trying to close scdaemon
Device: Nitrokey Start FSIJ-1.2.19-XXXXXXXX
reset done - now active identity: 0

Or, you could use gpg-connect-agent "SCD APDU 00 85 00 0" instead. I am not sure how to handle multiple readers here though.

I also have 0 clue how multiple nitrokey starts are supported. It seems the last one plugged in gets its identity set (if there is more than one).

szszszsz commented 1 year ago

@dvzrv In #305 I have added patches to use the whatever service connected to the smart card at the given moment, without changing the state of the system services. Hopefully this would work for you. Can you check it?

It's not possible to select the device by serial number yet.

Quick snippet:

$ cd /tmp
$ python -m venv env
$ env/bin/pip install pynitrokey[pcsc]
$ env/bin/pip install git+https://github.com/Nitrokey/pynitrokey.git@295-switching-id-without-sudo
$ env/bin/nitropy start set-identity 1
dvzrv commented 1 year ago

Using the changes in #305 the output is rather verbose, but switching identities is now seemingly faster and it doesn't require elevated privileges anymore! Thanks!