diff --git a/src/main.c b/src/main.c index ed26932..84c0afe 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,7 @@ #include "ccid.h" #include "operations.h" +#include "operations_ccid.h" #include "return_codes.h" #include "utils.h" #include "operations_ccid.h" @@ -40,8 +41,11 @@ void print_help(char *app_name) { "\t%s check \n" "\t%s regenerate \n" "\t%s set [COUNTER]\n" - "\t%s nk3-change-pin \n", - app_name, app_name, app_name, app_name, app_name, app_name, app_name); + "\t%s nk3-change-pin \n" + "\t%s reset [ADMIN PIN]\n" + "\t%s regenerate\n" + "\t%s set [COUNTER]\n", + app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name, app_name); } @@ -161,8 +165,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { } break; case 'r': - if (argc != 3) break; - res = regenerate_AES_key(&dev, argv[2]); + if (strncmp(argv[1], "reset", 15) == 0) { + if (argc != 2 && argc != 3) break; + res = nk3_reset(&dev, argc == 3 ? argv[2]: NULL); + } else if (strncmp(argv[1], "regenerate", 15) == 0) { + if (argc != 3) break; + res = regenerate_AES_key(&dev, argv[2]); + } break; default: break; diff --git a/src/operations_ccid.c b/src/operations_ccid.c index 1ca6f54..356a1b4 100644 --- a/src/operations_ccid.c +++ b/src/operations_ccid.c @@ -32,6 +32,59 @@ #include + +int nk3_reset(struct Device *dev, const char * new_pin) { + libusb_device *usb_dev; + struct libusb_device_descriptor usb_desc; + + if (!dev->mp_devhandle_ccid) { + // Not an NK3 + printf("No Nitrokey 3 found. No operation performed\n"); + return RET_NO_ERROR; + } + + usb_dev = libusb_get_device(dev->mp_devhandle_ccid); + + int r = libusb_get_device_descriptor(usb_dev, &usb_desc); + + if (r < 0) { + return r; + } + + + if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { + printf("No Nitrokey 3 found. No operation performed\n"); + return RET_NO_ERROR; + } + + + uint8_t buf[10]; + // encode + uint32_t icc_actual_length = iso7816_compose(buf, sizeof buf, Ins_Reset, 0xDE, 0xAD, 0, 0, NULL, 0); + + // encode ccid wrapper + icc_actual_length = icc_compose(dev->ccid_buffer_out, sizeof dev->ccid_buffer_out, + 0x6F, icc_actual_length, + 0, 0, 0, buf); + // send + IccResult iccResult; + r = ccid_process_single(dev->mp_devhandle_ccid, dev->ccid_buffer_in, sizeof dev->ccid_buffer_in, + dev->ccid_buffer_out, icc_actual_length, &iccResult); + if (r != 0) { + return r; + } + // check status code + if (iccResult.data_status_code != 0x9000) { + return 1; + } + + if (new_pin != NULL) { + set_pin_ccid(dev, new_pin); + } + + return RET_NO_ERROR; +} + int set_pin_ccid(struct Device *dev, const char *admin_PIN) { TLV tlvs[] = { { diff --git a/src/operations_ccid.h b/src/operations_ccid.h index 77a6fdc..4d55ad8 100644 --- a/src/operations_ccid.h +++ b/src/operations_ccid.h @@ -12,6 +12,10 @@ int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const c int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); int status_ccid(libusb_device_handle *handle, struct FullResponseStatus *full_response); int nk3_change_pin(struct Device *dev, const char *old_pin, const char*new_pin); +// new_pin can be `null` +// +// If it is, no new pin will be set +int nk3_reset(struct Device *dev, const char * new_pin); #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H