iasecc: use PIN PAD with variable PIN length
This commit is contained in:
parent
5757d82cc9
commit
3e2d51e0ba
|
@ -1801,15 +1801,14 @@ iasecc_chv_verify_pinpad(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd,
|
|||
LOG_FUNC_RETURN(ctx, SC_ERROR_READER);
|
||||
}
|
||||
|
||||
sc_log(ctx, "reader %s", card->reader->name);
|
||||
if (strstr(card->reader->name, "Gemalto GemPC Pinpad") == card->reader->name) {
|
||||
sc_log(ctx, "reader %s", card->reader->name);
|
||||
if (pin_cmd->pin1.min_length != pin_cmd->pin1.max_length) {
|
||||
sc_log(ctx, "Bogus Gemalto GemPC Pinpad do not accept different values for min and max PIN lengths.");
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
pin_cmd->pin1.len = pin_cmd->pin1.min_length;
|
||||
/* 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;
|
||||
|
@ -2039,21 +2038,22 @@ iasecc_chv_change_pinpad(struct sc_card *card, unsigned reference, int *tries_le
|
|||
rv = iasecc_pin_get_policy(card, &pin_cmd);
|
||||
LOG_TEST_RET(ctx, rv, "Get 'PIN policy' error");
|
||||
|
||||
if (strstr(card->reader->name, "Gemalto GemPC Pinpad") == card->reader->name)
|
||||
if (pin_cmd.pin1.min_length != pin_cmd.pin1.max_length)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED,
|
||||
"Bogus Gemalto GemPC Pinpad do not accept different values for min and max PIN lengths.");
|
||||
/* Some pin-pads do not support mode with Lc=0.
|
||||
* Give them a chance to work with some cards.
|
||||
*/
|
||||
if ((pin_cmd.pin1.min_length == pin_cmd.pin1.stored_length) && (pin_cmd.pin1.max_length == pin_cmd.pin1.min_length))
|
||||
pin_cmd.pin1.len = pin_cmd.pin1.stored_length;
|
||||
else
|
||||
pin_cmd.pin1.len = 0;
|
||||
|
||||
if (pin_cmd.pin1.min_length < 4)
|
||||
pin_cmd.pin1.min_length = 4;
|
||||
pin_cmd.pin1.len = pin_cmd.pin1.min_length;
|
||||
pin_cmd.pin1.length_offset = 5;
|
||||
pin_cmd.pin1.data = pin1_data;
|
||||
|
||||
memcpy(&pin_cmd.pin2, &pin_cmd.pin1, sizeof(pin_cmd.pin1));
|
||||
pin_cmd.pin2.data = pin2_data;
|
||||
|
||||
sc_log(ctx, "PIN1 max/min: %i/%i", pin_cmd.pin1.max_length, pin_cmd.pin1.min_length);
|
||||
sc_log(ctx, "PIN2 max/min: %i/%i", pin_cmd.pin2.max_length, pin_cmd.pin2.min_length);
|
||||
sc_log(ctx, "PIN1 max/min/stored: %i/%i/%i", pin_cmd.pin1.max_length, pin_cmd.pin1.min_length, pin_cmd.pin1.stored_length);
|
||||
sc_log(ctx, "PIN2 max/min/stored: %i/%i/%i", pin_cmd.pin2.max_length, pin_cmd.pin2.min_length, pin_cmd.pin2.stored_length);
|
||||
rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left);
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
|
@ -2087,18 +2087,17 @@ iasecc_chv_set_pinpad(struct sc_card *card, unsigned char reference)
|
|||
rv = iasecc_pin_get_policy(card, &pin_cmd);
|
||||
LOG_TEST_RET(ctx, rv, "Get 'PIN policy' error");
|
||||
|
||||
if (strstr(card->reader->name, "Gemalto GemPC Pinpad") == card->reader->name)
|
||||
if (pin_cmd.pin1.min_length != pin_cmd.pin1.max_length)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED,
|
||||
"Bogus Gemalto GemPC Pinpad do not accept different values for min and max PIN lengths.");
|
||||
if ((pin_cmd.pin1.min_length == pin_cmd.pin1.stored_length) && (pin_cmd.pin1.max_length == pin_cmd.pin1.min_length))
|
||||
pin_cmd.pin1.len = pin_cmd.pin1.stored_length;
|
||||
else
|
||||
pin_cmd.pin1.len = 0;
|
||||
|
||||
if (pin_cmd.pin1.min_length < 4)
|
||||
pin_cmd.pin1.min_length = 4;
|
||||
pin_cmd.pin1.len = pin_cmd.pin1.min_length;
|
||||
pin_cmd.pin1.length_offset = 5;
|
||||
pin_cmd.pin1.data = pin_data;
|
||||
|
||||
memcpy(&pin_cmd.pin2, &pin_cmd.pin1, sizeof(pin_cmd.pin1));
|
||||
memset(&pin_cmd.pin1, 0, sizeof(pin_cmd.pin1));
|
||||
pin_cmd.flags |= SC_PIN_CMD_IMPLICIT_CHANGE;
|
||||
|
||||
sc_log(ctx, "PIN1(max:%i,min:%i)", pin_cmd.pin1.max_length, pin_cmd.pin1.min_length);
|
||||
sc_log(ctx, "PIN2(max:%i,min:%i)", pin_cmd.pin2.max_length, pin_cmd.pin2.min_length);
|
||||
|
@ -2158,6 +2157,7 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data)
|
|||
if (sdo.docp.acls_contact.size == 0)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Extremely strange ... there is no ACLs");
|
||||
|
||||
sc_log(ctx, "iasecc_pin_get_policy() sdo.docp.size.size %i %02X:%02X", sdo.docp.size.size, *(sdo.docp.size.value + 0), *(sdo.docp.size.value + 1));
|
||||
for (ii=0; ii<sizeof(sdo.docp.scbs); ii++) {
|
||||
struct iasecc_se_info se;
|
||||
unsigned char scb = sdo.docp.scbs[ii];
|
||||
|
@ -2214,6 +2214,10 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data)
|
|||
data->pin1.max_tries = *sdo.docp.tries_maximum.value;
|
||||
if (sdo.docp.tries_remaining.value)
|
||||
data->pin1.tries_left = *sdo.docp.tries_remaining.value;
|
||||
if (sdo.docp.size.value) {
|
||||
for (ii=0; ii<sdo.docp.size.size; ii++)
|
||||
data->pin1.stored_length = ((data->pin1.stored_length) << 8) + *(sdo.docp.size.value + ii);
|
||||
}
|
||||
|
||||
data->pin1.encoding = SC_PIN_ENCODING_ASCII;
|
||||
data->pin1.offset = 5;
|
||||
|
@ -2400,6 +2404,7 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_
|
|||
unsigned char se_num = scb & IASECC_SCB_METHOD_MASK_REF;
|
||||
|
||||
if (scb & IASECC_SCB_METHOD_USER_AUTH) {
|
||||
sc_log(ctx, "Verify PIN in SE %X", se_num);
|
||||
rv = iasecc_pin_verify(card, SC_AC_SEN, se_num, data->pin1.data, data->pin1.len, tries_left);
|
||||
LOG_TEST_RET(ctx, rv, "iasecc_pin_reset() verify PUK error");
|
||||
|
||||
|
@ -2421,6 +2426,7 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_
|
|||
iasecc_sdo_free_fields(card, &sdo);
|
||||
|
||||
if (data->pin2.len) {
|
||||
sc_log(ctx, "Reset PIN %X and set new value", reference);
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2C, 0x02, reference);
|
||||
apdu.data = data->pin2.data;
|
||||
apdu.datalen = data->pin2.len;
|
||||
|
@ -2432,6 +2438,7 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_
|
|||
LOG_TEST_RET(ctx, rv, "PIN cmd failed");
|
||||
}
|
||||
else if (data->pin2.data) {
|
||||
sc_log(ctx, "Reset PIN %X and set new value", reference);
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2C, 3, reference);
|
||||
|
||||
rv = sc_transmit_apdu(card, &apdu);
|
||||
|
@ -2440,8 +2447,13 @@ iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_
|
|||
LOG_TEST_RET(ctx, rv, "PIN cmd failed");
|
||||
}
|
||||
else {
|
||||
sc_log(ctx, "Reset PIN %X and set new value with PIN-PAD", reference);
|
||||
#if 0
|
||||
rv = iasecc_chv_set_pinpad(card, reference);
|
||||
sc_log(ctx, "Set CHV with PIN pad returned %i", rv);
|
||||
LOG_TEST_RET(ctx, rv, "Reset PIN failed");
|
||||
#else
|
||||
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Reset retry counter with PIN PAD not supported ");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (save_current) {
|
||||
|
|
Loading…
Reference in New Issue