1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

scd: Factor common PIN status check out.

* scd/iso7816.h (ISO7816_VERIFY_ERROR): New.
(ISO7816_VERIFY_NO_PIN): New.
(ISO7816_VERIFY_BLOCKED): New.
(ISO7816_VERIFY_NULLPIN): New.
(ISO7816_VERIFY_NOT_NEEDED): New.
* scd/iso7816.c (iso7816_verify_status): New.
* scd/app-nks.c (get_chv_status): Use new function.
* scd/app-piv.c (get_chv_status): Ditto.
(verify_chv): Ditto.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-04-07 18:25:41 +02:00
parent 5ec1f66793
commit 60d018f6a9
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
5 changed files with 58 additions and 83 deletions

View file

@ -780,42 +780,17 @@ get_dispserialno (app_t app, int failmode)
/* The verify command can be used to retrieve the security status of
* the card. Given the PIN name (e.g. "PIV.80" for the application
* pin, a status is returned:
*
* -1 = Error retrieving the data,
* -2 = No such PIN,
* -3 = PIN blocked,
* -5 = Verified and still valid,
* n >= 0 = Number of verification attempts left.
*/
* pin, a ISO7817_VERIFY_* code is returned or a non-negative number
* of verification attempts left. */
static int
get_chv_status (app_t app, const char *keyrefstr)
{
unsigned char apdu[4];
unsigned int sw;
int result;
int keyref;
keyref = parse_chv_keyref (keyrefstr);
if (!keyrefstr)
return -1;
apdu[0] = 0x00;
apdu[1] = ISO7816_VERIFY;
apdu[2] = 0x00;
apdu[3] = keyref;
if (!iso7816_apdu_direct (app_get_slot (app), apdu, 4, 0, &sw, NULL, NULL))
result = -5; /* No need to verification. */
else if (sw == 0x6a88 || sw == 0x6a80)
result = -2; /* No such PIN. */
else if (sw == 0x6983)
result = -3; /* PIN is blocked. */
else if ((sw & 0xfff0) == 0x63C0)
result = (sw & 0x000f);
else
result = -1; /* Error. */
return result;
return ISO7816_VERIFY_ERROR;
return iso7816_verify_status (app_get_slot (app), keyref);
}
@ -1999,29 +1974,22 @@ verify_chv (app_t app, ctrl_t ctrl, int keyref, int force,
gpg_error_t (*pincb)(void*,const char *,char **), void *pincb_arg)
{
gpg_error_t err;
unsigned char apdu[4];
unsigned int sw;
int remaining;
char *pin = NULL;
unsigned int pinlen, unpaddedpinlen;
/* First check whether a verify is at all needed. This is done with
* P1 being 0 and no Lc and command data send. */
apdu[0] = 0x00;
apdu[1] = ISO7816_VERIFY;
apdu[2] = 0x00;
apdu[3] = keyref;
if (!iso7816_apdu_direct (app_get_slot (app), apdu, 4, 0, &sw, NULL, NULL))
/* First check whether a verify is at all needed. */
remaining = iso7816_verify_status (app_get_slot (app), keyref);
if (remaining == ISO7816_VERIFY_NOT_NEEDED)
{
if (!force) /* No need to verification. */
return 0; /* All fine. */
remaining = -1;
}
else if ((sw & 0xfff0) == 0x63C0)
remaining = (sw & 0x000f); /* PIN has REMAINING tries left. */
else
else if (remaining < 0) /* We don't care about other errors. */
remaining = -1;
err = ask_and_prepare_chv (app, ctrl, keyref, 0, remaining, force,
pincb, pincb_arg,
&pin, &pinlen, &unpaddedpinlen);