Simlified low-level CHV verification function:

- Removed special PIN-pad case, moving logic into high-level function.
- Use ISO 7816 layer to avoid code duplication.
This commit is contained in:
Zoltan Kelemen 2020-07-01 08:54:51 +02:00 committed by Frank Morgner
parent 8c2d629f94
commit d0b3e90431
1 changed files with 7 additions and 81 deletions

View File

@ -1852,97 +1852,23 @@ iasecc_set_security_env(struct sc_card *card,
static int
iasecc_chv_verify_pinpad(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, int *tries_left)
iasecc_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, unsigned char *scbs,
int *tries_left)
{
struct sc_context *ctx = card->ctx;
unsigned char buffer[0x100];
unsigned char scb = scbs[IASECC_ACLS_CHV_VERIFY];
int rv;
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "CHV PINPAD PIN reference %i", pin_cmd->pin_reference);
sc_log(ctx, "Verify CHV PIN(ref:%i,len:%i,scb:%X)", pin_cmd->pin_reference, pin_cmd->pin1.len,
scb);
rv = iasecc_pin_is_verified(card, pin_cmd, tries_left);
if (!rv)
if (scb & IASECC_SCB_METHOD_SM) {
rv = iasecc_sm_pin_verify(card, scb & IASECC_SCB_METHOD_MASK_REF, pin_cmd, tries_left);
LOG_FUNC_RETURN(ctx, rv);
if (!card->reader || !card->reader->ops || !card->reader->ops->perform_verify) {
sc_log(ctx, "Reader not ready for PIN PAD");
LOG_FUNC_RETURN(ctx, SC_ERROR_READER);
}
/* When PIN stored length available
* P10 verify data contains full template of 'VERIFY PIN' APDU.
* Without PIN stored length
* pin-pad has to set the Lc and fill PIN data itself.
* Not all pin-pads support this case
*/
pin_cmd->pin1.len = pin_cmd->pin1.stored_length;
pin_cmd->pin1.length_offset = 5;
memset(buffer, 0xFF, sizeof(buffer));
pin_cmd->pin1.data = buffer;
pin_cmd->cmd = SC_PIN_CMD_VERIFY;
pin_cmd->flags |= SC_PIN_CMD_USE_PINPAD;
/*
if (card->reader && card->reader->ops && card->reader->ops->load_message) {
rv = card->reader->ops->load_message(card->reader, card->slot, 0, "Here we are!");
sc_log(ctx, "Load message returned %i", rv);
}
*/
rv = iso_ops->pin_cmd(card, pin_cmd, tries_left);
sc_log(ctx, "rv %i", rv);
LOG_FUNC_RETURN(ctx, rv);
}
static int
iasecc_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd,
int *tries_left)
{
struct sc_context *ctx = card->ctx;
struct sc_acl_entry acl = pin_cmd->pin1.acls[IASECC_ACLS_CHV_VERIFY];
struct sc_apdu apdu;
int rv;
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "Verify CHV PIN(ref:%i,len:%i,acl:%X:%X)", pin_cmd->pin_reference, pin_cmd->pin1.len,
acl.method, acl.key_ref);
if (acl.method & IASECC_SCB_METHOD_SM) {
rv = iasecc_sm_pin_verify(card, acl.key_ref, pin_cmd, tries_left);
LOG_FUNC_RETURN(ctx, rv);
}
if (pin_cmd->pin1.data && !pin_cmd->pin1.len) {
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, pin_cmd->pin_reference);
}
else if (pin_cmd->pin1.data && pin_cmd->pin1.len) {
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0, pin_cmd->pin_reference);
apdu.data = pin_cmd->pin1.data;
apdu.datalen = pin_cmd->pin1.len;
apdu.lc = pin_cmd->pin1.len;
}
else if ((card->reader->capabilities & SC_READER_CAP_PIN_PAD) && !pin_cmd->pin1.data && !pin_cmd->pin1.len) {
rv = iasecc_chv_verify_pinpad(card, pin_cmd, tries_left);
sc_log(ctx, "Result of verifying CHV with PIN pad %i", rv);
LOG_FUNC_RETURN(ctx, rv);
}
else {
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
}
rv = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(ctx, rv, "APDU transmit failed");
if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0)
*tries_left = apdu.sw2 & 0x0F;
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
LOG_FUNC_RETURN(ctx, rv);
}