@@ -3029,11 +3029,13 @@ * NOTES * ... * */ static cackey_ret cackey_login(struct cackey_slot *slot, unsigned char *pin, unsigned long pin_len, int *tries_remaining_p) { + struct cackey_pcsc_identity *pcsc_identities; unsigned char cac_pin[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + unsigned long num_certs; uint16_t response_code; int tries_remaining; int send_ret; int key_reference = 0x00; @@ -3046,18 +3048,27 @@ if (pin_len >= 8) { memcpy(cac_pin, pin, 8); } else { memcpy(cac_pin, pin, pin_len); } + + /* PIV authentication uses a "key_reference" of 0x80 */ + pcsc_identities = cackey_read_certs(slot, NULL, &num_certs); + if (num_certs > 0 && pcsc_identities != NULL) { + switch (pcsc_identities[0].id_type) { + case CACKEY_ID_TYPE_PIV: + CACKEY_DEBUG_PRINTF("We recently had a PIV card, so we will attempt to authenticate using the PIV Application key reference"); + + key_reference = 0x80; + break; + default: + break; + } + } /* Issue PIN Verify */ send_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_VERIFY, 0x00, key_reference, sizeof(cac_pin), cac_pin, 0x00, &response_code, NULL, NULL); - if (send_ret != CACKEY_PCSC_S_OK && response_code == 0x6A88) { - key_reference = 0x80; - - send_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_VERIFY, 0x00, key_reference, sizeof(cac_pin), cac_pin, 0x00, &response_code, NULL, NULL); - } if (send_ret != CACKEY_PCSC_S_OK) { if ((response_code & 0x63C0) == 0x63C0) { tries_remaining = (response_code & 0xF);