Let pinentry or gnupg handle bad smartcard pins
Open, NormalPublic

Assigned To
Authored By
timegrid
Jul 15 2026, 11:24 AM

Description

Currently, if a smartcard user tries to e.g. encrypt/sign a file and enters a bad PIN, the pinentry process is cancelled and the error displayed in Kleopatra:

To be able to retry, the whole encrypt/sign process has to be started again (choosing the file, etc), which is tedious.
Pinentry should handle the retries on bad PIN instead, which would also meet the user's expectation.


Split from T6425: improve pinentry behavior and texts in smart card context

Details

Version
gpg4win-5.1.0-beta658 @ win11

Event Timeline

timegrid triaged this task as Normal priority.Jul 15 2026, 11:24 AM
timegrid created this task.
timegrid created this object with edit policy "Contributor (Project)".

I don't think that Kleopatra can influence that gpg/gpgsm/gpg-agent shows a second pinentry if on the first try a wrong passphrase was entered. Therefore I think the "retry" has to be implemented in GnuPG.

Independently of this, explicit canceling of the pinentry shouldn't abort the sign/encrypt operation in Kleopatra.

So, this ticket is actually two.

• ikloecker raised the priority of this task from Normal to Needs Triage.Sep 2 2026, 9:33 AM
• ikloecker edited projects, added gnupg26; removed gpd5x, kleopatra.

I have created T8433: Kleopatra: Allow easy retry of sign/encrypt files operation if password request failed or was aborted for improving Kleopatra. This leaves the problem that entering a bad smartcard PIN (or password) aborts a sign operation without repeating the PIN/password request. I think this needs to be addressed in GnuPG. -> I re-tag this ticket and request another triage.

I guess it's fine to decide not to change GnuPG. Once Kleopatra allows for an easy retry of a sign/encrypt operation a change in GnuPG will be unnecessary for users of Kleopatra.

• ikloecker renamed this task from Kleopatra: Let pinentry handle bad smartcard pins to Let pinentry or gnupg handle bad smartcard pins.Sep 2 2026, 9:34 AM
• gniibe mentioned this in Unknown Object (Maniphest Task).Sep 7 2026, 3:53 AM
• werner triaged this task as Normal priority.Sep 7 2026, 4:53 PM

For OpenPGP card, here is an attempt for supporting the idea:

Reading the code around, it seems for me that adding loop here means loosing simplicity of the design, though.

We need to do similar things for each card supported. And also for gpg-agent, in case of key in a file.

We need to do similar things for each card supported. And also for gpg-agent, in case of key in a file.

gpg-agent already has a loop for asking multiple times for a PIN/passphrase:

for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)

When asked for the passphrase for a signing key stored on disk I've seen a second pinentry (with "try 2 of 3"). I'm not sure why it isn't used when asking for the PIN.

@ikloecker Thank you for pointing out how gpg-agent works.

Indeed, in gpg-agent, it uses agent_askpin with the callback to unprotect the key in a file; When the callback fails, it loops to ask a user again.

Currently, scdaemon uses assuan_inquire to let gpg-agent call agent_askpin, and in this use case, the callback is not used.

Let me consider again, if we can utilize the feature of agent_askpin callback by scdaemon.

I created a branch gniibe/t8353 for this task.
My plan is:

  • scd: refactor scd/*.c for use of pinentry
  • agent: introduce a thread for handling NEEDPIN inquery to enhance the interaction allowing check_cb with scdaemon
  • scd: update scd/*.c to use new feature of NEEDPIN
• gniibe mentioned this in Unknown Object (Maniphest Task).Sep 14 2026, 3:54 AM

Here is an idea to enhance the inquiry protocol from scdaemon to gpg-agent:
Currently, it's simply:

scdaemon --NEEDPIN--> gpg-agent
         <---- pin --

Extended version will be:

scdaemon --NEEDPIN_BEGIN--> gpg-agent
          <-- OK
          -- GETPIN -->
          <--- pin 0 --
          -- GETPIN failure-message -->
          <--- pin 1 --
          ...
          --NEEDPIN_END-->
          <-- OK

gpg-agent creates a thread for pinentry interactions by NEEDPIN_BEGIN inquiry.
It interacts by following GETPIN inquiries, and finished by NEEDPIN_END inquiry.

Remember that there might also be a PIN-pad which would need yet another scheme.

• gniibe mentioned this in Unknown Object (Maniphest Task).Sep 21 2026, 3:41 AM
• gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Sep 28, 2:25 AM
• gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Oct 5, 3:26 AM
• gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Oct 12, 3:48 AM
• gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Oct 19, 4:07 AM
• gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Oct 26, 3:32 AM