From b2f6abded3ad9b2c00bfe97f69e7433a6cefa632 Mon Sep 17 00:00:00 2001 From: Nuno Goncalves Date: Tue, 21 Jun 2016 12:49:06 +0100 Subject: [PATCH] card-gemsafeV1: use iso7816 pin_cmd implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GemsafeV1 is compatible with iso7816 pin commands, including SC_PIN_CMD_GET_INFO so it doesn't need to customize it. Acked-by: João Poupino Tested-by: Lukas Wunner Signed-off-by: Nuno Goncalves --- src/libopensc/card-gemsafeV1.c | 143 +-------------------------------- 1 file changed, 2 insertions(+), 141 deletions(-) diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index c14e2aba..4792e96b 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -229,6 +229,7 @@ static int gemsafe_init(struct sc_card *card) } } + card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; card->drv_data = exdata; return 0; @@ -563,146 +564,6 @@ static int gemsafe_get_challenge(sc_card_t *card, u8 *rnd, size_t len) return r; } -static int gemsafe_build_pin_apdu(struct sc_card *card, - struct sc_apdu *apdu, - struct sc_pin_cmd_data *data) -{ - static u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - int r, len = 0, pad = 0, use_pin_pad = 0, ins, p1 = 0; - - switch (data->pin_type) { - case SC_AC_CHV: - break; - default: - return SC_ERROR_INVALID_ARGUMENTS; - } - - if (data->flags & SC_PIN_CMD_NEED_PADDING) - pad = 1; - if (data->flags & SC_PIN_CMD_USE_PINPAD) - use_pin_pad = 1; - - data->pin1.offset = 5; - - switch (data->cmd) { - case SC_PIN_CMD_VERIFY: - ins = 0x20; - if ((r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0) - return r; - len = r; - break; - case SC_PIN_CMD_CHANGE: - ins = 0x24; - if (data->pin1.len != 0 || use_pin_pad) { - if ((r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0) - return r; - len += r; - } else { - /* implicit test */ - p1 = 1; - } - - data->pin2.offset = data->pin1.offset + len; - if ((r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0) - return r; - len += r; - break; - case SC_PIN_CMD_UNBLOCK: - ins = 0x2C; - if (data->pin1.len != 0 || use_pin_pad) { - if ((r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0) - return r; - len += r; - } else { - p1 |= 0x02; - } - - if (data->pin2.len != 0 || use_pin_pad) { - data->pin2.offset = data->pin1.offset + len; - if ((r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0) - return r; - len += r; - } else { - p1 |= 0x01; - } - break; - default: - return SC_ERROR_NOT_SUPPORTED; - } - - sc_format_apdu(card, apdu, SC_APDU_CASE_3_SHORT, - ins, p1, data->pin_reference); - - apdu->lc = len; - apdu->datalen = len; - apdu->data = sbuf; - apdu->resplen = 0; - - return 0; -} - -static int gemsafe_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, - int *tries_left) -{ - struct sc_apdu local_apdu, *apdu; - int r; - - if (tries_left) - *tries_left = -1; - - /* See if we've been called from another card driver, which is - * passing an APDU to us (this allows to write card drivers - * whose PIN functions behave "mostly like ISO" except in some - * special circumstances. - */ - if (data->apdu == NULL) { - r = gemsafe_build_pin_apdu(card, &local_apdu, data); - if (r < 0) - return r; - data->apdu = &local_apdu; - } - apdu = data->apdu; - - if (!(data->flags & SC_PIN_CMD_USE_PINPAD)) { - /* Transmit the APDU to the card */ - r = sc_transmit_apdu(card, apdu); - - /* Clear the buffer - it may contain pins */ - memset((void *) apdu->data, 0, apdu->datalen); - } else { - /* Call the reader driver to collect - * the PIN and pass on the APDU to the card */ - if (data->pin1.offset == 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "Card driver didn't set PIN offset"); - return SC_ERROR_INVALID_ARGUMENTS; - } - if (card->reader - && card->reader->ops - && card->reader->ops->perform_verify) { - r = card->reader->ops->perform_verify(card->reader, data); - /* sw1/sw2 filled in by reader driver */ - } else { - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, - "Card reader driver does not support " - "PIN entry through reader key pad"); - r = SC_ERROR_NOT_SUPPORTED; - } - } - - /* Don't pass references to local variables up to the caller. */ - if (data->apdu == &local_apdu) - data->apdu = NULL; - - SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); - if (apdu->sw1 == 0x63) { - if ((apdu->sw2 & 0xF0) == 0xC0 && tries_left != NULL) - *tries_left = apdu->sw2 & 0x0F; - return SC_ERROR_PIN_CODE_INCORRECT; - } - return sc_check_sw(card, apdu->sw1, apdu->sw2); -} - static struct sc_card_driver *sc_get_driver(void) { struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); @@ -721,7 +582,7 @@ static struct sc_card_driver *sc_get_driver(void) gemsafe_ops.compute_signature = gemsafe_compute_signature; gemsafe_ops.get_challenge = gemsafe_get_challenge; gemsafe_ops.process_fci = gemsafe_process_fci; - gemsafe_ops.pin_cmd = gemsafe_pin_cmd; + gemsafe_ops.pin_cmd = iso_ops->pin_cmd; return &gemsafe_drv; }