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

Add support for moving and deleting keys #463

Merged
merged 4 commits into from
Jan 23, 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
30 changes: 30 additions & 0 deletions lib/ykpiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2205,3 +2205,33 @@ static ykpiv_rc _ykpiv_auth_deauthenticate(ykpiv_state *state) {

return res;
}

//static bool check_version(ykpiv_state *state, uint8_t major, uint8_t minor) {
// return state->ver.major > major || (state->ver.major == major && state->ver.minor >= minor);
//}

// if to_slot is set to 0xff, the key will be deleted
ykpiv_rc ykpiv_move_key(ykpiv_state *state, const unsigned char from_slot, const unsigned char to_slot) {
// if(!check_version(state, 5, 7)) {
// DBG("Move key operation available with firmware version 5.7.0 or higher");
// return YKPIV_NOT_SUPPORTED;
// }
ykpiv_rc res = YKPIV_OK;
unsigned char data[256] = {0};
unsigned long recv_len = sizeof(data);
int sw = 0;
unsigned char adpu[] = {0, YKPIV_INS_MOVE_KEY, to_slot, from_slot};
DBG("Moving key from slot %x to slot %x", from_slot, to_slot);

if ((res = _ykpiv_transfer_data(state, adpu, NULL, 0, data, &recv_len, &sw)) != YKPIV_OK) {
return res;
}
res = ykpiv_translate_sw(sw);
if (res != YKPIV_OK) {
DBG("Failed to move key");
} else {
DBG("Key moved from slot %x to %x", from_slot, to_slot);
}

return res;
}
3 changes: 3 additions & 0 deletions lib/ykpiv.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ extern "C"
ykpiv_rc ykpiv_attest(ykpiv_state *state, const unsigned char key, unsigned char *data, size_t *data_len);
ykpiv_rc ykpiv_get_metadata(ykpiv_state *state, const unsigned char key, unsigned char *data, size_t *data_len);

ykpiv_rc ykpiv_move_key(ykpiv_state *state, const unsigned char from_slot, const unsigned char to_slot);

/**
* Return the number of PIN attempts remaining before PIN is locked.
*
Expand Down Expand Up @@ -708,6 +710,7 @@ extern "C"
#define YKPIV_INS_AUTHENTICATE 0x87
#define YKPIV_INS_GET_DATA 0xcb
#define YKPIV_INS_PUT_DATA 0xdb
#define YKPIV_INS_MOVE_KEY 0xf6
#define YKPIV_INS_SELECT_APPLICATION 0xa4
#define YKPIV_INS_GET_RESPONSE_APDU 0xc0

Expand Down
10 changes: 9 additions & 1 deletion tool/cmdline.ggo
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,19 @@ option "action" a "Action to take" values="version","generate","set-mgm-key",
"request-certificate","verify-pin","change-pin","change-puk","unblock-pin",
"selfsign-certificate","delete-certificate","read-certificate","status",
"test-signature","test-decipher","list-readers","set-ccc","write-object",
"read-object","attest" enum multiple
"read-object","attest", "move-key", "delete-key" enum multiple
text "
Multiple actions may be given at once and will be executed in order
for example --action=verify-pin --action=request-certificate\n"
option "slot" s "What key slot to operate on" values="9a","9c","9d","9e","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f","90","91","92","93","94","95","f9" enum optional
text "
9a is for PIV Authentication
9c is for Digital Signature (PIN always checked)
9d is for Key Management
9e is for Card Authentication (PIN never checked)
82-95 is for Retired Key Management
f9 is for Attestation\n"
option "to-slot" - "What slot to move an existing key to" values="9a","9c","9d","9e","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f","90","91","92","93","94","95","f9" enum optional
text "
9a is for PIV Authentication
9c is for Digital Signature (PIN always checked)
Expand Down
41 changes: 41 additions & 0 deletions tool/yubico-piv-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,19 @@ static EVP_PKEY* wrap_public_key(ykpiv_state *state, int algorithm, EVP_PKEY *pu
}
#endif

static bool move_key(ykpiv_state *state, int from_slot, int to_slot) {
bool ret = false;
ykpiv_rc res;

res = ykpiv_move_key(state, (uint8_t) (from_slot & 0xFF), (uint8_t) (to_slot & 0xFF));
if (res != YKPIV_OK) {
fprintf(stderr, "Failed to move key.\n");
} else {
ret = true;
}
return ret;
}

static bool generate_key(ykpiv_state *state, enum enum_slot slot,
enum enum_algorithm algorithm, const char *output_file_name,
enum enum_key_format key_format, enum enum_pin_policy pin_policy,
Expand Down Expand Up @@ -2201,13 +2214,22 @@ int main(int argc, char *argv[]) {
case action_arg_testMINUS_signature:
case action_arg_testMINUS_decipher:
case action_arg_attest:
case action_arg_deleteMINUS_key:
if(args_info.slot_arg == slot__NULL) {
fprintf(stderr, "The '%s' action needs a slot (-s) to operate on.\n",
cmdline_parser_action_values[action]);
cmdline_parser_free(&args_info);
return EXIT_FAILURE;
}
break;
case action_arg_moveMINUS_key:
if(args_info.slot_arg == slot__NULL || args_info.to_slot_arg == to_slot__NULL) {
fprintf(stderr, "The '%s' action needs both a slot (-s) to operate on and a --to-slot to move the key to.\n",
cmdline_parser_action_values[action]);
cmdline_parser_free(&args_info);
return EXIT_FAILURE;
}
break;
case action_arg_pinMINUS_retries:
if(!args_info.pin_retries_given || !args_info.puk_retries_given) {
fprintf(stderr, "The '%s' action needs both --pin-retries and --puk-retries arguments.\n",
Expand Down Expand Up @@ -2296,6 +2318,8 @@ int main(int argc, char *argv[]) {
case action_arg_setMINUS_ccc:
case action_arg_deleteMINUS_certificate:
case action_arg_writeMINUS_object:
case action_arg_moveMINUS_key:
case action_arg_deleteMINUS_key:
if(!authed) {
if(verbosity) {
fprintf(stderr, "Authenticating since action '%s' needs that.\n", cmdline_parser_action_values[action]);
Expand Down Expand Up @@ -2588,6 +2612,23 @@ int main(int argc, char *argv[]) {
ret = EXIT_FAILURE;
}
break;
case action_arg_moveMINUS_key: {
int from_slot = get_slot_hex(args_info.slot_arg);
int to_slot = get_slot_hex((enum enum_slot) args_info.to_slot_arg);
if (move_key(state, from_slot, to_slot) == false) {
ret = EXIT_FAILURE;
} else {
fprintf(stderr, "Successfully moved key.\n");
}
break;
}
dainnilsson marked this conversation as resolved.
Show resolved Hide resolved
case action_arg_deleteMINUS_key:
if(move_key(state, get_slot_hex(args_info.slot_arg), 0xFF) == false) {
ret = EXIT_FAILURE;
} else {
fprintf(stderr, "Successfully deleted key.\n");
}
break;
case action__NULL:
default:
fprintf(stderr, "Wrong action. %d.\n", action);
Expand Down
Loading