[PATCH] scd:openpgp: Fix CHV1 retry counter byte index.

Mikhail Filippov mikhail at filippov.me
Sat Jun 6 19:09:30 CEST 2026


 From 0000000000000000000000000000000000000001 Mon Sep 17 00:00:00 2001
From: Mikhail Filippov <mikhail at filippov.me>
Date: Wed, 13 May 2026 00:30:00 +0200
Subject: [PATCH] scd:openpgp: Fix CHV1 retry counter byte index.

* scd/app-openpgp.c (get_remaining_tries): Read value[4] not value[1]
for chvno==1.
--

Regression introduced by commit 2239f687bb14428b6167517f92ae74077f96b8b7
("scd:openpgp: UI improvement for use of PIN-entry.", GnuPG-bug-id 6425),
which refactored the function from the boolean parameter "adminpw"
(with byte index 4 for the user PIN) to a "chvno" integer.  In the
rewrite the CHV1 branch ended up reading value[1], which is the PW1
max-length byte of DO 0x00C4, not the PW1 error counter byte.  Per the
OpenPGP card 3.x spec the PW Status Bytes are laid out
[validity, PW1 max, RC max, PW3 max, PW1 err, RC err, PW3 err]
(0-indexed: 0..6), so the correct index for the CHV1 retry counter is 4.

The consequence is that get_remaining_tries always returns the PW1 max
length (commonly 127) for chvno==1 instead of the real retry counter.
Downstream this means build_enter_pin_prompt sees remaining=127, which
then fails the "remaining < 3" guard in get_prompt_info, so the
"Remaining attempts: N" warning is never appended to the SETDESC
payload sent to pinentry.  Users with a lowered CHV1 (1 or 2 tries
left) get no warning before they lock the card.

The CHV3 branch (value[6]) is unaffected and the CHV2 branch (value[5],
RC error counter) was added by the same refactor and is correct.

Signed-off-by: Mikhail Filippov <mikhail at filippov.me>
---
  scd/app-openpgp.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index abcdef0..abcdef1 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -1511,7 +1511,7 @@ get_remaining_tries (app_t app, int chvno)
        xfree (relptr);
        return -1;
      }
-  remaining = value[(chvno == 3)? 6 : ((chvno == 2)? 5: 1)];
+  remaining = value[(chvno == 3)? 6 : ((chvno == 2)? 5: 4)];
    xfree (relptr);
    return remaining;
  }
--
2.54.0.windows.1


-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x9B2CA65FC13232FD.asc
Type: application/pgp-keys
Size: 7705 bytes
Desc: OpenPGP public key
URL: <https://lists.gnupg.org/pipermail/gnupg-devel/attachments/20260606/827e9bea/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.gnupg.org/pipermail/gnupg-devel/attachments/20260606/827e9bea/attachment.sig>


More information about the Gnupg-devel mailing list