3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
|
* ...
*
* NOTES
* ...
*
*/
static cackey_ret cackey_login(struct cackey_slot *slot, unsigned char *pin, unsigned long pin_len, int *tries_remaining_p) {
unsigned char cac_pin[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint16_t response_code;
int tries_remaining;
int send_ret;
int key_reference = 0x00;
/* Indicate that we do not know about how many tries are remaining */
if (tries_remaining_p) {
*tries_remaining_p = -1;
}
/* Apparently, CAC PINs are *EXACTLY* 8 bytes long -- pad with 0xFF if too short */
if (pin_len >= 8) {
memcpy(cac_pin, pin, 8);
} else {
memcpy(cac_pin, pin, pin_len);
}
/* 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);
CACKEY_DEBUG_PRINTF("PIN Verification failed, %i tries remaining", tries_remaining);
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<
<
<
<
<
|
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
|
* ...
*
* 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;
/* Indicate that we do not know about how many tries are remaining */
if (tries_remaining_p) {
*tries_remaining_p = -1;
}
/* Apparently, CAC PINs are *EXACTLY* 8 bytes long -- pad with 0xFF if too short */
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) {
if ((response_code & 0x63C0) == 0x63C0) {
tries_remaining = (response_code & 0xF);
CACKEY_DEBUG_PRINTF("PIN Verification failed, %i tries remaining", tries_remaining);
|