d-e-s-o / nitrocli

A command line tool for interacting with Nitrokey devices.
30 stars 10 forks source link

"Wrong password, please reenter" after device reconnection #175

Closed bircoph closed 3 years ago

bircoph commented 3 years ago

Hi!

If I used device successfully, than unplugged it and reconnected later, nitrocli will fail old password if cached:

unset NITROCLI_NO_CACHE
nitrocli pws get 1
<enter password>
<unplug and reattach nitrokey device>
nitrocli pws get 1
<Wrong password, please reenter>
<enter password>

and even worse if passwords are not cached: first entered password will be always invalid, so user have to enter password twice:

export NITROCLI_NO_CACHE=true
nitrocli pws get 1
<enter password>
<unplug and reattach nitrokey device>
nitrocli pws get 1
<enter password>
<Wrong password, please reenter>
<enter password>

Curious, but after "wrong password, please reenter" message user retry count is not changed:

 $ nitrocli status
Status:
  model:             Nitrokey Pro
  serial number:     XXXXXXXX
  firmware version:  v0.10
  user retry count:  3
  admin retry count: 3

I use nitrocli-0.4.0, though this bug was present in earlier versions as well (at least in 0.3.5).

While this problem is not critical, it is really irritating to enter password twice. And often disconnect the device, so it is used only per on-needed basis.

robinkrahl commented 3 years ago

Thank you for the bug report! Unfortunately, I cannot reproduce this issue with 0.4.0. Do you only use a single Nitrokey device or multiple devices?

robinkrahl commented 3 years ago

And could you please try if you can reproduce this on the devel branch? We recently fixed a bug that messed up the PIN cache when using multiple devices (#145).

@d-e-s-o Could you please publish a bug-fix release with #145? I’m not sure if it is related to this issue, but I think it would be useful anyway. I often run into this problem when switching between my demo keys and my production key.

d-e-s-o commented 3 years ago

I also fail to reproduce. Hm.

@d-e-s-o Could you please publish a bug-fix release with #145?

Sure, will do.

It sounds as if the issues with and without cache may have the same root cause. Would it be possible for you to set a different user password (e.g., the default 123456; nitrocli pin set user) and retry, @bircoph? Perhaps we can narrow it down a bit.

bircoph commented 3 years ago

Thank you for the bug report! Unfortunately, I cannot reproduce this issue with 0.4.0. Do you only use a single Nitrokey device or multiple devices?

Single device only. On each reinsertion it gets new usb minor number:

Bus 003 Device 116
Bus 003 Device 117

Could this be a cause?

bircoph commented 3 years ago

It sounds as if the issues with and without cache may have the same root cause. Would it be possible for you to set a different user password (e.g., the default 123456; nitrocli pin set user) and retry, @bircoph? Perhaps we can narrow it down a bit.

Hm, it works fine with default 123456. But I can reproduce the problem with 20-chars password, e.g. "12345678901234567890".

robinkrahl commented 3 years ago

Hm, it works fine with default 123456. But I can reproduce the problem with 20-chars password, e.g. "12345678901234567890".

Interesting. I still can’t reproduce the issue even with that user PIN.

d-e-s-o commented 3 years ago

Hm, it works fine with default 123456. But I can reproduce the problem with 20-chars password, e.g. "12345678901234567890".

Interesting. I still can’t reproduce the issue even with that user PIN.

Yeah, same here. And I am on the same firmware version.

bircoph commented 3 years ago

I'll try devel version of nitrocli, but it will take some time.

My gnupg version is 2.2.27, though problem was present with older versions as well. pinentry's version is quite old, I'll try to update it as well.

robinkrahl commented 3 years ago

Single device only. On each reinsertion it gets new usb minor number:

Bus 003 Device 116
Bus 003 Device 117

Could this be a cause?

No, it should not be a problem, and the I see the same behavior on my machine.

bircoph commented 3 years ago

I tried new pinentry (1.1.1) — the problem persists, it is not a cause.

Looks like I found what makes difference between my and your tests. Nitrokey provides hardware TRNG, so I utilize that to feed to the system entropy using scdrand (https://incenp.org/dvlpt/scdtools.html, app-crypt/scdrand in Gentoo). I don't run it as a daemon, since reads from TRNG by scdaemon may interfere with other device operations (e.g. gnupg signing and nitrocli actions), but I use it once using udev rule which effectively runs scdrand 4096 and without such run bug is not reproducible. Since this machinery works automatically and in background, I even forgot it was there until I started to research why we have different behavior.

So necessary steps to reproduce are: 1) Set 20-chars users password and use it (e.g. nitrocli pws get). 2) Disconnect and reconnect device. 3) Run scdrand 4096 4) Try to use nitrocli again (e.g. nitrocli pws get).

First I thought scdrand somehow resets cache, but if I run it without reconnecting the device, password entered is recognized from the first try.

robinkrahl commented 3 years ago

Really strange. I’ll try to install scdrand to reproduce this issue.

In the mean time, could you try to run this snippet directly using libnitrokey instead of nitrocli to see if this issue also occurs when directly accessing the device without pinentry etc.?

#include <stdio.h>
#include <stdlib.h>
#include <libnitrokey/NK_C_API.h>

static const char *USER_PIN = "123456";

int main(void)
{
    NK_set_debug(true);
    if (NK_login_auto() != 1) {
        fprintf(stderr, "No Nitrokey device found.\n");
        return 1;
    }

    int result = NK_enable_password_safe(USER_PIN);
    if (result) {
        fprintf(stderr, "Failed to enable password safe: %d\n", result);
        return 1;
    }

    char *slot_name = NK_get_password_safe_slot_name(1);
    if (!slot_name) {
        fprintf(stderr, "Failed to query PWS slot: %d\n",
                NK_get_last_command_status());
        return 1;
    }
    printf("Slot 1: '%s'\n", slot_name);
    free(slot_name);

    NK_logout();
    return 0;
}

Change the USER_PIN constant and compile with gcc -o pws-get pws-get.c -lnitrokey.

d-e-s-o commented 3 years ago

In the mean time, could you try to run this snippet directly using libnitrokey instead of nitrocli to see if this issue also occurs when directly accessing the device without pinentry etc.?

Should it use OTP functionality, though? Seems like we are introducing another unknown by switching over to PWS.

d-e-s-o commented 3 years ago

In the mean time, could you try to run this snippet directly using libnitrokey instead of nitrocli to see if this issue also occurs when directly accessing the device without pinentry etc.?

Should it use OTP functionality, though? Seems like we are introducing another unknown by switching over to PWS.

d-e-s-o commented 3 years ago

Grrrr.

d-e-s-o commented 3 years ago

Please disregard my comment. I was confused.

bircoph commented 3 years ago

Really strange. I’ll try to install scdrand to reproduce this issue.

In the mean time, could you try to run this snippet directly using libnitrokey instead of nitrocli to see if this issue also occurs when directly accessing the device without pinentry etc.? [...] Change the USER_PIN constant and compile with gcc -o pws-get pws-get.c -lnitrokey.

Yes, this also happens with libnitrokey (I use version 3.6). First run fails:

$ ./nitrokey
[Sun May  2 22:06:32 2021][DEBUG_L1]    Connection success: 1 ()
[Sun May  2 22:06:32 2021][DEBUG_L1]    Connection success: 0 ()
[Sun May  2 22:06:32 2021][DEBUG_L1]    Connection success: 0 ()
[Sun May  2 22:06:32 2021][DEBUG_L1]    Disconnection: handle already freed: 1 ()
[Sun May  2 22:06:32 2021][DEBUG_L1]    Disconnection: handle already freed: 1 ()
[Sun May  2 22:06:32 2021][DEBUG]       -------------------
[Sun May  2 22:06:32 2021][DEBUG]       Outgoing HID packet:
[Sun May  2 22:06:32 2021][DEBUG]       Contents:
Command ID:     DETECT_SC_AES
CRC:    26769a05
Payload:
 user_password: ***********

[Sun May  2 22:06:32 2021][DEBUG_L1]    => DETECT_SC_AES
[Sun May  2 22:06:32 2021][DEBUG_L1]    <= DETECT_SC_AES 0 0
[Sun May  2 22:06:32 2021][DEBUG]       Incoming HID packet:
[Sun May  2 22:06:32 2021][DEBUG]       Device status:  0 OK
Command ID:     DETECT_SC_AES hex: 6a
Last command CRC:       26769a05
Last command status:    4 STICK10::COMMAND_STATUS::WRONG_PASSWORD
CRC:    3e98932b
Payload:
Empty Payload.
[Sun May  2 22:06:32 2021][DEBUG_L1]    Throw: CommandFailedException 4
[Sun May  2 22:06:32 2021][DEBUG]       CommandFailedException, status: 4
Failed to enable password safe: 4

Second run works:

./nitrokey
[Sun May  2 22:06:35 2021][DEBUG_L1]    Connection success: 1 ()
[Sun May  2 22:06:35 2021][DEBUG_L1]    Connection success: 0 ()
[Sun May  2 22:06:35 2021][DEBUG_L1]    Connection success: 0 ()
[Sun May  2 22:06:35 2021][DEBUG_L1]    Disconnection: handle already freed: 1 ()
[Sun May  2 22:06:35 2021][DEBUG_L1]    Disconnection: handle already freed: 1 ()
[Sun May  2 22:06:35 2021][DEBUG]       -------------------
[Sun May  2 22:06:35 2021][DEBUG]       Outgoing HID packet:
[Sun May  2 22:06:35 2021][DEBUG]       Contents:
Command ID:     DETECT_SC_AES
CRC:    26769a05
Payload:
 user_password: ***********

[Sun May  2 22:06:35 2021][DEBUG_L1]    => DETECT_SC_AES
.
[Sun May  2 22:06:36 2021][DEBUG_L1]    <= DETECT_SC_AES 0 0
[Sun May  2 22:06:36 2021][DEBUG]       Incoming HID packet:
[Sun May  2 22:06:36 2021][DEBUG]       Device status:  0 OK
Command ID:     DETECT_SC_AES hex: 6a
Last command CRC:       26769a05
Last command status:    0 STICK10::COMMAND_STATUS::OK
CRC:    5f7699f2
Payload:
Empty Payload.
[Sun May  2 22:06:36 2021][DEBUG]       -------------------
[Sun May  2 22:06:36 2021][DEBUG]       Outgoing HID packet:
[Sun May  2 22:06:36 2021][DEBUG]       Contents:
Command ID:     PW_SAFE_ENABLE
CRC:    3520f28d
Payload:
 user_password: ***********

Sun May  2 22:06:36 2021][DEBUG_L1]    => PW_SAFE_ENABLE
.
[Sun May  2 22:06:36 2021][DEBUG_L1]    <= PW_SAFE_ENABLE 0 0
[Sun May  2 22:06:36 2021][DEBUG]       Incoming HID packet:
[Sun May  2 22:06:36 2021][DEBUG]       Device status:  0 OK
Command ID:     PW_SAFE_ENABLE hex: 67
Last command CRC:       3520f28d
Last command status:    0 STICK10::COMMAND_STATUS::OK
CRC:    75bb48a7
Payload:
Empty Payload.
[Sun May  2 22:06:36 2021][DEBUG]       -------------------
[Sun May  2 22:06:36 2021][DEBUG]       Outgoing HID packet:
[Sun May  2 22:06:36 2021][DEBUG]       Contents:
Command ID:     GET_PW_SAFE_SLOT_NAME
CRC:    6a1f2ce2
Payload:
slot_number     1

[Sun May  2 22:06:36 2021][DEBUG_L1]    => GET_PW_SAFE_SLOT_NAME
[Sun May  2 22:06:36 2021][DEBUG_L1]    <= GET_PW_SAFE_SLOT_NAME 0 0
[Sun May  2 22:06:36 2021][DEBUG]       Incoming HID packet:
[Sun May  2 22:06:36 2021][DEBUG]       Device status:  0 OK
Command ID:     GET_PW_SAFE_SLOT_NAME hex: 61
Last command CRC:       6a1f2ce2
Last command status:    0 STICK10::COMMAND_STATUS::OK
CRC:    37eebaf4
Payload:
 slot_name:     ***********

Slot 1: 'xxx'
robinkrahl commented 3 years ago

Thank you. I’ve created a libnitrokey issue: https://github.com/Nitrokey/libnitrokey/issues/201

Does the problem only occur if you remove the device? Or is it sufficient to just call scdrand?

Unfortunately, scdrand does not work on my machine: scdrand: Cannot add entropy: Operation not permitted.

bircoph commented 3 years ago

Does the problem only occur if you remove the device? Or is it sufficient to just call scdrand?

Both conditions must be fullfilled. Only running scdrand is not sufficient.

Unfortunately, scdrand does not work on my machine: scdrand: Cannot add entropy: Operation not permitted.

You need permission to write to /dev/random under user running scdrand. Try to enable SUID bit on it.

robinkrahl commented 3 years ago

You need permission to write to /dev/random under user running scdrand. Try to enable SUID bit on it.

Thanks. I had set the SUID bit but forgot to chown. Now I can reproduce the issue too.

d-e-s-o commented 3 years ago

Can we close this issue? It seems as if there is nothing that nitrocli can do on this front. Once the lower layers are fixed, it should "just work", correct?

robinkrahl commented 3 years ago

Once the lower layers are fixed, it should "just work", correct?

Most likely, yes.

d-e-s-o commented 3 years ago

Then let's close this issue as there is nothing actionable on the nitrocli side of things.