Fix PIN length handling in ykpiv_verify*()

This commit is contained in:
Trevor Bentley
2017-10-10 17:42:53 +02:00
parent de065ae36e
commit aa293dcc31
+17 -16
View File
@@ -926,36 +926,33 @@ static ykpiv_rc _cache_pin(ykpiv_state *state, const char *pin, size_t len) {
if (state->pin == NULL) { if (state->pin == NULL) {
return YKPIV_MEMORY_ERROR; return YKPIV_MEMORY_ERROR;
} }
memcpy(state->pin, pin, len + 1); memcpy(state->pin, pin, len);
state->pin[len] = 0;
} }
return YKPIV_OK; return YKPIV_OK;
#endif #endif
} }
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) { static ykpiv_rc _verify(ykpiv_state *state, const char *pin, const size_t pin_len, int *tries) {
// TREV TODO: pin len?
APDU apdu; APDU apdu;
unsigned char data[261]; unsigned char data[261];
uint32_t recv_len = sizeof(data); uint32_t recv_len = sizeof(data);
int sw; int sw;
size_t len = 0;
ykpiv_rc res; ykpiv_rc res;
if(pin) {
len = strlen(pin);
}
if(len > 8) { if (pin_len > 8) {
return YKPIV_SIZE_ERROR; return YKPIV_SIZE_ERROR;
} }
memset(apdu.raw, 0, sizeof(apdu.raw)); memset(apdu.raw, 0, sizeof(apdu.raw));
apdu.st.ins = YKPIV_INS_VERIFY; apdu.st.ins = YKPIV_INS_VERIFY;
apdu.st.p1 = 0x00; apdu.st.p1 = 0x00;
apdu.st.p2 = 0x80; apdu.st.p2 = 0x80;
apdu.st.lc = pin ? 0x08 : 0; apdu.st.lc = pin ? 0x08 : 0;
if (pin) { if (pin) {
memcpy(apdu.st.data, pin, len); memcpy(apdu.st.data, pin, pin_len);
if(len < 8) { if (pin_len < 8) {
memset(apdu.st.data + len, 0xff, 8 - len); memset(apdu.st.data + pin_len, 0xff, 8 - pin_len);
} }
} }
if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) { if ((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
@@ -963,7 +960,7 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
} else if (sw == SW_SUCCESS) { } else if (sw == SW_SUCCESS) {
// Intentionally ignore errors. If the PIN fails to save, it will only // Intentionally ignore errors. If the PIN fails to save, it will only
// be a problem if a reconnect is attempted. Failure deferred until then. // be a problem if a reconnect is attempted. Failure deferred until then.
_cache_pin(state, pin, len + 1); _cache_pin(state, pin, pin_len);
if (tries) *tries = (sw & 0xf); if (tries) *tries = (sw & 0xf);
return YKPIV_OK; return YKPIV_OK;
} else if ((sw >> 8) == 0x63) { } else if ((sw >> 8) == 0x63) {
@@ -977,13 +974,17 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
} }
} }
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
return ykpiv_verify_select(state, pin, pin ? strlen(pin) : 0, tries, false);
}
ykpiv_rc ykpiv_verify_select(ykpiv_state *state, const char *pin, const size_t pin_len, int *tries, bool force_select) { ykpiv_rc ykpiv_verify_select(ykpiv_state *state, const char *pin, const size_t pin_len, int *tries, bool force_select) {
ykpiv_rc res = YKPIV_OK; ykpiv_rc res = YKPIV_OK;
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) goto Cleanup; if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) goto Cleanup;
if (force_select) { if (force_select) {
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup; if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
} }
res = ykpiv_verify(state, pin, tries); res = _verify(state, pin, pin_len, tries);
Cleanup: Cleanup:
_ykpiv_end_transaction(state); _ykpiv_end_transaction(state);
@@ -1096,7 +1097,7 @@ ykpiv_rc ykpiv_change_pin(ykpiv_state *state, const char * current_pin, size_t c
if (res == YKPIV_OK && new_pin != NULL) { if (res == YKPIV_OK && new_pin != NULL) {
// Intentionally ignore errors. If the PIN fails to save, it will only // Intentionally ignore errors. If the PIN fails to save, it will only
// be a problem if a reconnect is attempted. Failure deferred until then. // be a problem if a reconnect is attempted. Failure deferred until then.
_cache_pin(state, new_pin, new_pin_len + 1); _cache_pin(state, new_pin, new_pin_len);
} }
Cleanup: Cleanup:
@@ -1358,7 +1359,7 @@ ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, const s
ykpiv_rc res = YKPIV_OK; ykpiv_rc res = YKPIV_OK;
APDU apdu = { 0 }; APDU apdu = { 0 };
unsigned char data[261] = { 0 }; unsigned char data[261] = { 0 };
unsigned long recv_len = sizeof(data); uint32_t recv_len = sizeof(data);
int sw = 0; int sw = 0;
if (NULL == state) return YKPIV_GENERIC_ERROR; if (NULL == state) return YKPIV_GENERIC_ERROR;
@@ -1396,7 +1397,7 @@ ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, const
ykpiv_rc res = YKPIV_OK; ykpiv_rc res = YKPIV_OK;
APDU apdu = { 0 }; APDU apdu = { 0 };
unsigned char data[261] = { 0 }; unsigned char data[261] = { 0 };
unsigned long recv_len = sizeof(data); uint32_t recv_len = sizeof(data);
int sw = 0; int sw = 0;
unsigned char *dataptr = apdu.st.data; unsigned char *dataptr = apdu.st.data;