Page MenuHome GnuPG

improve pinentry behavior and texts in smart card context
Testing, NormalPublic

Description

Take a smart card where

PIN retry counter : 3 3 3

Try 3 times to sign a document with the key from the card. Give the wrong PIN every time.

You'll always get the error message wrong PIN in the results window:

This is inconsistent, as usually a separate window would pop up for pinentry errors.

It would be nice if you could try again to give the PIN for the same operation. As it is at the moment you have to initiate a new sign operation for the file, which is cumbersome.

This will then give you an pinentry with the additional info line "tries left: 2":

After the 3rd entry of the wrong PIN, this is exactly the same.
Here I would wish for not only the popup "wrong PIN" but additionally this popup should declare "PIN blocked".

At the moment I will get this information only after giving the password (wrong or right) a 4th time:


If you try "Change PIN" next, you will be asked for the PIN and 2x for the New PIN in altogether 3 pinentry windows before being informed that the PIN is blocked.


Here I would expect to get that information immediately when I click "Change PIN".

The same is true for trying to unblock the card with the PUK. Again I have to enter 3 PINs in 3 windows before being informed that the entry in the first window was wrong. Additionally, the text in window 1 is borked:




After giving the PUK wrong 3 times the last window will pop up immediately after clicking "unblock card", as reported in T6421

It would be nice if at least some of these workflows and information could be improved.

Details

Version
3.1.26

Event Timeline

werner added projects: Bug Report, scd.

With VS-Desktop-3.1.90.258-Beta I ran again into the last issue with "Wrong PIN". I had not realized that I had entered the PIN wrong before (as you have to enter the PIN several times anyway when generating a new key on a card and you do not get an error message on wrong PIN but instead only a new pinentry window...).

And when you use the action button "Generate new keys" you even get ~"New key could not be generated: General error". This made me wonder quite a long time what the issue could be.

The error would need to be something like "Card blocked" instead.

I propose to check the relevant pinentry counter before giving an error message of "Wrong PIN" or "General error" and change the message, if appropriate.

The issue is exacerbated by not listing the pinentry counter in the Smartcard management view, as we do on the command line.

ebo raised the priority of this task from Low to High.Nov 2 2023, 3:24 PM

as this really bugs me, I raise the prio.
And add the Kleo tag, as Werner said it might be that Kleopatra is responsible.

This is inconsistent, as usually a separate window would pop up for pinentry errors.

True, but this inconsistency also happens on the command line with gpg. I'm asked once for the PIN for a card key, but I'm asked up to three times for the password for an on-disk key.

After the 3rd entry of the wrong PIN, this is exactly the same.
Here I would wish for not only the popup "wrong PIN" but additionally this popup should declare "PIN blocked".

I think the only infallible way to find out if the PIN is blocked is to try to use the PIN. My guess is that gpg (and Kleopatra) simply show the error that is reported by the smart card.

At the moment I will get this information only after giving the password (wrong or right) a 4th time:

I assume that gpg still offers the PIN entry because the smart card could report a wrong retry counter. Again, the only way to find out if the PIN is really blocked is to try it.

In any case, all of the above is outside of Kleopatra's control and also happens on the command line.

If you try "Change PIN" next, you will be asked for the PIN and 2x for the New PIN in altogether 3 pinentry windows before being informed that the PIN is blocked.

The exact same thing happens on the command line

$ gpg --card-edit
[...]
gpg/card> passwd
gpg: OpenPGP card no. D2760001240100000006090745820000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1

Then you get three pin entries (old, new, repeat new) and then

Error changing the PIN: PIN blocked

The same is true for trying to unblock the card with the PUK. Again I have to enter 3 PINs in 3 windows before being informed that the entry in the first window was wrong. Additionally, the text in window 1 is borked

I couldn't reproduce this on the command line, but, although I did set a Reset Code (PUK), I was asked for the Admin PIN when I tried to unblock the PIN. (I didn't attempt to enter a wrong Admin PIN.) This may be related to the output PIN retry counter : 3 0 3, i.e. the PUK counter is 0. No idea what this means.

After a factory-reset I still get PIN retry counter : 3 0 3. Setting the Reset Code doesn't change anything. Maybe the old YubiKey I use doesn't support the Reset Code? Or I need to set some arcane option to enable it?

This may be related to the output PIN retry counter : 3 0 3, i.e. the PUK counter is 0. No idea what this means.

Usually, that the PUK is not set or that no retries are left.

The second retry counter is used by current cards for the Reset Code error counter. It is zero if no reset code has been set. It was used by card specs 1.x for the CHV2 only available there.

I found two places in scdaemon which return GPG_ERR_BAD_PIN. GPG_ERR_PIN_BLOCKED is relevant here.

diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 66ec9f4a9..77d428786 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -2859,7 +2859,7 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt, int *r_remaining)
   if (!remaining)
     {
       log_info (_("card is permanently locked!\n"));
-      return gpg_error (GPG_ERR_BAD_PIN);
+      return gpg_error (GPG_ERR_PIN_BLOCKED);
     }
 
   log_info (ngettext("%d Admin PIN attempt remaining before card"
@@ -5998,7 +5998,7 @@ do_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr,
       if (!count)
         {
           log_info (_("card is permanently locked!\n"));
-          return gpg_error (GPG_ERR_BAD_PIN);
+          return gpg_error (GPG_ERR_PIN_BLOCKED);
         }
       else if (count < 3)
         {

I'm going to push this change to master.

We would need to revise tools/card-call-scd.c:status_sc_op_failure and g10/card-util.c:write_sc_op_status to catch GPG_ERR_PIN_BLOCKED and GOG_ERR_NO_RESET_CODE.

Pushed the changes for ...sc_op_failure routines to master/2.4.

gniibe changed the task status from Open to Testing.Dec 26 2023, 7:17 AM
gniibe lowered the priority of this task from High to Normal.