Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid getting metadata in auth-verifyresponse #478

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ ykpiv_rc _ykpiv_transfer_data(
int *sw);

/* authentication functions not ready for public api */
ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, unsigned long *challenge_len);
ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, unsigned long response_len);
ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, ykpiv_metadata *metadata, uint8_t *challenge, unsigned long *challenge_len);
ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, ykpiv_metadata *metadata, uint8_t *response, unsigned long response_len);
ykpiv_rc ykpiv_auth_deauthenticate(ykpiv_state *state);

typedef enum _setting_source_t {
Expand Down
5 changes: 3 additions & 2 deletions lib/tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,8 @@ static void test_authenticate_helper(bool full) {

// Test external auth
data_len = sizeof(data);
res = ykpiv_auth_getchallenge(g_state, data, &data_len);
ykpiv_metadata metadata = {0};
res = ykpiv_auth_getchallenge(g_state, &metadata, data, &data_len);
ck_assert_int_eq(res, YKPIV_OK);

crc = cipher_import_key(YKPIV_ALGO_3DES, key, key_len, &cipher);
Expand All @@ -703,7 +704,7 @@ static void test_authenticate_helper(bool full) {
crc = cipher_destroy_key(cipher);
ck_assert_int_eq(crc, CIPHER_OK);

res = ykpiv_auth_verifyresponse(g_state, data, data_len);
res = ykpiv_auth_verifyresponse(g_state, &metadata, data, data_len);
ck_assert_int_eq(res, YKPIV_OK);

// Metadata support implies AES support for YKPIV_KEY_CARDMGM
Expand Down
24 changes: 9 additions & 15 deletions lib/ykpiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2105,22 +2105,24 @@ ykpiv_rc ykpiv_get_metadata(ykpiv_state *state, const unsigned char key, unsigne
return res;
}

ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, unsigned long *challenge_len) {
ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, ykpiv_metadata *metadata, uint8_t *challenge, unsigned long *challenge_len) {
ykpiv_rc res;

if (NULL == state) return YKPIV_ARGUMENT_ERROR;
if (NULL == metadata) return YKPIV_ARGUMENT_ERROR;
if (NULL == challenge) return YKPIV_ARGUMENT_ERROR;
if (NULL == challenge_len) return YKPIV_ARGUMENT_ERROR;

if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return res;
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;

ykpiv_metadata metadata = {YKPIV_ALGO_3DES};
metadata->algorithm = YKPIV_ALGO_3DES;

unsigned char data[256] = {0};
unsigned long recv_len = sizeof(data);
res = _ykpiv_get_metadata(state, YKPIV_KEY_CARDMGM, data, &recv_len);
if (res == YKPIV_OK) {
res = ykpiv_util_parse_metadata(data, recv_len, &metadata);
res = ykpiv_util_parse_metadata(data, recv_len, metadata);
if (res != YKPIV_OK) {
goto Cleanup;
}
Expand All @@ -2129,7 +2131,7 @@ ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, unsigne
/* get a challenge from the card */
APDU apdu = {0};
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
apdu.st.p1 = metadata.algorithm;
apdu.st.p1 = metadata->algorithm;
apdu.st.p2 = YKPIV_KEY_CARDMGM; /* management key */
apdu.st.lc = 0x04;
apdu.st.data[0] = 0x7c;
Expand Down Expand Up @@ -2160,31 +2162,24 @@ ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, uint8_t *challenge, unsigne
return res;
}

ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, unsigned long response_len) {
ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, ykpiv_metadata *metadata, uint8_t *response, unsigned long response_len) {
ykpiv_rc res;

if (NULL == state) return YKPIV_ARGUMENT_ERROR;
if (NULL == metadata) return YKPIV_ARGUMENT_ERROR;
if (NULL == response) return YKPIV_ARGUMENT_ERROR;
if (16 < response_len) return YKPIV_ARGUMENT_ERROR;

if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return res;
/* note: do not select the applet here, as it resets the challenge state */

ykpiv_metadata metadata = {YKPIV_ALGO_3DES};
unsigned char data[256] = {0};
unsigned long recv_len = sizeof(data);
res = _ykpiv_get_metadata(state, YKPIV_KEY_CARDMGM, data, &recv_len);
if (res == YKPIV_OK) {
res = ykpiv_util_parse_metadata(data, recv_len, &metadata);
if (res != YKPIV_OK) {
goto Cleanup;
}
}

/* send the response to the card. */
APDU apdu = {0};
apdu.st.ins = YKPIV_INS_AUTHENTICATE;
apdu.st.p1 = metadata.algorithm;
apdu.st.p1 = metadata->algorithm;
apdu.st.p2 = YKPIV_KEY_CARDMGM; /* management key */
unsigned char *dataptr = apdu.st.data;
*dataptr++ = 0x7c;
Expand All @@ -2195,7 +2190,6 @@ ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, uint8_t *response, unsign
dataptr += response_len;
apdu.st.lc = (unsigned char)(dataptr - apdu.st.data);
int sw = 0;
recv_len = sizeof(data);
if ((res = _ykpiv_send_apdu(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
goto Cleanup;
}
Expand Down
Loading