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 global device reset #516

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
26 changes: 26 additions & 0 deletions lib/ykpiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2371,3 +2371,29 @@ ykpiv_rc ykpiv_auth_get_verified(ykpiv_state* state) {
ykpiv_rc ykpiv_auth_verify(ykpiv_state* state, uint8_t* pin, size_t* p_pin_len, int *tries, bool force_select, bool bio, bool verify_spin) {
return _ykpiv_verify_select(state, pin, p_pin_len, tries, force_select, bio, verify_spin);
}

ykpiv_rc ykpiv_global_reset(ykpiv_state *state) {
ykpiv_rc res = YKPIV_OK;
unsigned char mgm_templ[] = {0x00, YKPIV_INS_SELECT_APPLICATION, 0x04, 0x00};
unsigned char recv[256] = {0};
unsigned long recv_len = sizeof(recv);
int sw = 0;
if ((res = _ykpiv_transfer_data(state, mgm_templ, mgmt_aid, sizeof(mgmt_aid), recv, &recv_len, &sw)) < YKPIV_OK) {
return res;
}
res = ykpiv_translate_sw_ex(__FUNCTION__, sw);
if (res != YKPIV_OK) {
DBG("Failed selecting mgmt/yk application");
return res;
}

unsigned char reset_templ[] = {0, MGM_INS_GLOBAL_RESET, 0, 0};
recv_len = 0;
sw = 0;
res = ykpiv_transfer_data(state, reset_templ, NULL, 0, NULL, &recv_len, &sw);
if(res != YKPIV_OK) {
return res;
}
return ykpiv_translate_sw_ex(__FUNCTION__, sw);

}
3 changes: 3 additions & 0 deletions lib/ykpiv.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ extern "C"

bool is_version_compatible(ykpiv_state *state, uint8_t major, uint8_t minor, uint8_t patch);
ykpiv_rc ykpiv_move_key(ykpiv_state *state, const unsigned char from_slot, const unsigned char to_slot);
ykpiv_rc ykpiv_global_reset(ykpiv_state *state);

/**
* Return the number of PIN attempts remaining before PIN is locked.
Expand Down Expand Up @@ -745,6 +746,8 @@ extern "C"
#define YKPIV_INS_GET_SERIAL 0xf8
#define YKPIV_INS_GET_METADATA 0xf7

#define MGM_INS_GLOBAL_RESET 0x1f

#define YKPIV_PINPOLICY_TAG 0xaa
#define YKPIV_PINPOLICY_DEFAULT 0
#define YKPIV_PINPOLICY_NEVER 1
Expand Down
1 change: 1 addition & 0 deletions tool/cmdline.ggo
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ option "input" i "Filename to use as input, - for stdin" string optional default
option "output" o "Filename to use as output, - for stdout" string optional default="-"
option "key-format" K "Format of the key being read/written" values="PEM","PKCS12","GZIP","DER","SSH" enum optional default="PEM"
option "compress" - "Compress a large certificate using GZIP before import" flag off
option "global" - "Reset the whole device over all protocols" flag off
option "password" p "Password for decryption of private key file, if omitted password will be asked for" string optional
option "subject" S "The subject to use for certificate request" string optional
text "
Expand Down
33 changes: 27 additions & 6 deletions tool/yubico-piv-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,32 @@ static bool generate_key(ykpiv_state *state, enum enum_slot slot,
return ret;
}

static bool reset(ykpiv_state *state) {
return ykpiv_util_reset(state) == YKPIV_OK;
static bool reset(ykpiv_state *state, bool global) {
if(!global) {
if(ykpiv_util_reset(state) != YKPIV_OK) {
fprintf(stderr, "Reset failed, are pincodes blocked?\n");
return false;
}
} else {
fprintf(stderr, "ALL of the data, including PIV data, in the YubiKey will be deleted. The action cannot be reversed!\n\nType 'y' to proceed: ");
char resp = fgetc(stdin);
if(resp == 'y') {
ykpiv_rc rc = ykpiv_global_reset(state);
if(rc != YKPIV_OK) {
if(rc == YKPIV_NOT_SUPPORTED) {
fprintf(stderr, "Global reset not supported on this YubiKey. Please refer to reset commands for specific applications instead\n");
} else {
fprintf(stderr, "Reset failed\n");
}
return false;
}
} else {
fprintf(stderr, "Global reset operation aborted\n");
return true;
}
}
fprintf(stderr, "Successfully reset the application.\n");
return true;
}

static bool set_pin_retries(ykpiv_state *state, int pin_retries, int puk_retries, int verbose) {
Expand Down Expand Up @@ -2687,11 +2711,8 @@ int main(int argc, char *argv[]) {
}
break;
case action_arg_reset:
if(reset(state) == false) {
fprintf(stderr, "Reset failed, are pincodes blocked?\n");
if(!reset(state, args_info.global_given)) {
ret = EXIT_FAILURE;
} else {
fprintf(stderr, "Successfully reset the application.\n");
}
break;
case action_arg_pinMINUS_retries:
Expand Down
Loading