Improved PIN info retrieval, now returning verification status, and attempts

left even when previously not available (due to card not providing it in the
SDO).
This commit is contained in:
Zoltan Kelemen 2020-07-01 08:16:27 +02:00 committed by Frank Morgner
parent 19063932f0
commit ca911e342c
1 changed files with 41 additions and 1 deletions

View File

@ -133,6 +133,7 @@ static int iasecc_sdo_get_data(struct sc_card *card, struct iasecc_sdo *sdo);
static int iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct iasecc_pin_policy *pin);
static int iasecc_pin_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, int *tries_left);
static int iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left);
static int iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left);
static int iasecc_get_free_reference(struct sc_card *card, struct iasecc_ctl_get_free_reference *ctl_data);
static int iasecc_sdo_put_data(struct sc_card *card, struct iasecc_sdo_update *update);
@ -2309,6 +2310,45 @@ err:
}
static int
iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
{
struct sc_context *ctx = card->ctx;
struct iasecc_pin_policy policy;
int rv;
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "iasecc_pin_get_info(card:%p)", card);
/*
* Get PIN status first and thereafter update with info from PIN policy, when available.
* The first one is typically used for the PIN verification status and number of remaining
* tries, and the second one for the maximum tries. If a field is present in both, the
* policy takes precedence.
*/
rv = iasecc_pin_get_status(card, data, tries_left);
LOG_TEST_RET(ctx, rv, "Failed to get PIN status");
rv = iasecc_pin_get_policy(card, data, &policy);
LOG_TEST_RET(ctx, rv, "Failed to get PIN policy");
/*
* We only care about the tries_xxx fields in the PIN policy, since the other ones are not
* commonly expected or used in a SC_PIN_CMD_GET_INFO response. Note that max_tries is
* always taken from the policy, since it is never expected to be available in status (it
* is set to -1 when not available in policy).
*/
data->pin1.max_tries = policy.tries_maximum;
if (policy.tries_remaining >= 0)
data->pin1.tries_left = policy.tries_remaining;
if (tries_left)
*tries_left = data->pin1.tries_left;
LOG_FUNC_RETURN(ctx, rv);
}
static int
iasecc_keyset_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
{
@ -2550,7 +2590,7 @@ iasecc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_le
rv = iasecc_pin_reset(card, data, tries_left);
break;
case SC_PIN_CMD_GET_INFO:
rv = iasecc_pin_get_policy(card, data);
rv = iasecc_pin_get_info(card, data, tries_left);
break;
default:
sc_log(ctx, "Other pin commands not supported yet: 0x%X", data->cmd);