|
| 1 | +From de355ed93ba50280bf377772082b76b7a2285185 Mon Sep 17 00:00:00 2001 |
| 2 | +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= <sosthene@nitrokey.com> |
| 3 | +Date: Mon, 25 Nov 2024 17:04:47 +0100 |
| 4 | +Subject: [PATCH 1/3] Add reset command for nitrokey 3 |
| 5 | + |
| 6 | +--- |
| 7 | + src/main.c | 10 ++++++++-- |
| 8 | + src/operations_ccid.c | 41 +++++++++++++++++++++++++++++++++++++++++ |
| 9 | + src/operations_ccid.h | 1 + |
| 10 | + 3 files changed, 50 insertions(+), 2 deletions(-) |
| 11 | + |
| 12 | +diff --git a/src/main.c b/src/main.c |
| 13 | +index 059069e..b80b71d 100644 |
| 14 | +--- a/src/main.c |
| 15 | ++++ b/src/main.c |
| 16 | +@@ -21,6 +21,7 @@ |
| 17 | + |
| 18 | + #include "ccid.h" |
| 19 | + #include "operations.h" |
| 20 | ++#include "operations_ccid.h" |
| 21 | + #include "return_codes.h" |
| 22 | + #include "utils.h" |
| 23 | + #include "version.h" |
| 24 | +@@ -134,8 +135,13 @@ int parse_cmd_and_run(int argc, char *const *argv) { |
| 25 | + } |
| 26 | + break; |
| 27 | + case 'r': |
| 28 | +- if (argc != 3) break; |
| 29 | +- res = regenerate_AES_key(&dev, argv[2]); |
| 30 | ++ if (strncmp(argv[1], "reset", 15) == 0) { |
| 31 | ++ if (argc != 2) break; |
| 32 | ++ res = nk3_reset(&dev); |
| 33 | ++ } else if (strncmp(argv[1], "regenerate", 15) == 0) { |
| 34 | ++ if (argc != 3) break; |
| 35 | ++ res = regenerate_AES_key(&dev, argv[2]); |
| 36 | ++ } |
| 37 | + break; |
| 38 | + default: |
| 39 | + break; |
| 40 | +diff --git a/src/operations_ccid.c b/src/operations_ccid.c |
| 41 | +index eb46124..574155d 100644 |
| 42 | +--- a/src/operations_ccid.c |
| 43 | ++++ b/src/operations_ccid.c |
| 44 | +@@ -32,6 +32,47 @@ |
| 45 | + #include <string.h> |
| 46 | + |
| 47 | + |
| 48 | ++ |
| 49 | ++int nk3_reset(struct Device *dev) { |
| 50 | ++ libusb_device *usb_dev; |
| 51 | ++ struct libusb_device_descriptor usb_desc; |
| 52 | ++ usb_dev = libusb_get_device(dev->mp_devhandle_ccid); |
| 53 | ++ |
| 54 | ++ int r = libusb_get_device_descriptor(usb_dev, &usb_desc); |
| 55 | ++ |
| 56 | ++ if (r < 0) { |
| 57 | ++ return r; |
| 58 | ++ } |
| 59 | ++ |
| 60 | ++ |
| 61 | ++ if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { |
| 62 | ++ return 0; |
| 63 | ++ } |
| 64 | ++ |
| 65 | ++ |
| 66 | ++ uint8_t buf[10]; |
| 67 | ++ // encode |
| 68 | ++ uint32_t icc_actual_length = iso7816_compose(buf, sizeof buf, Ins_Reset, 0xDE, 0xAD, 0, 0, NULL, 0); |
| 69 | ++ |
| 70 | ++ // encode ccid wrapper |
| 71 | ++ icc_actual_length = icc_compose(dev->ccid_buffer_out, sizeof dev->ccid_buffer_out, |
| 72 | ++ 0x6F, icc_actual_length, |
| 73 | ++ 0, 0, 0, buf); |
| 74 | ++ // send |
| 75 | ++ IccResult iccResult; |
| 76 | ++ r = ccid_process_single(dev->mp_devhandle_ccid, dev->ccid_buffer_in, sizeof dev->ccid_buffer_in, |
| 77 | ++ dev->ccid_buffer_out, icc_actual_length, &iccResult); |
| 78 | ++ if (r != 0) { |
| 79 | ++ return r; |
| 80 | ++ } |
| 81 | ++ // check status code |
| 82 | ++ if (iccResult.data_status_code != 0x9000) { |
| 83 | ++ return 1; |
| 84 | ++ } |
| 85 | ++ |
| 86 | ++ return RET_NO_ERROR; |
| 87 | ++} |
| 88 | ++ |
| 89 | + int set_pin_ccid(struct Device *dev, const char *admin_PIN) { |
| 90 | + TLV tlvs[] = { |
| 91 | + { |
| 92 | +diff --git a/src/operations_ccid.h b/src/operations_ccid.h |
| 93 | +index b26b3c7..ec0070c 100644 |
| 94 | +--- a/src/operations_ccid.h |
| 95 | ++++ b/src/operations_ccid.h |
| 96 | +@@ -11,6 +11,7 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); |
| 97 | + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); |
| 98 | + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); |
| 99 | + int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); |
| 100 | ++int nk3_reset(struct Device *dev); |
| 101 | + |
| 102 | + |
| 103 | + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H |
| 104 | + |
| 105 | +From 8425e8c622138aef9ab207119e14f7cbedd40175 Mon Sep 17 00:00:00 2001 |
| 106 | +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= <sosthene@nitrokey.com> |
| 107 | +Date: Mon, 2 Dec 2024 10:29:59 +0100 |
| 108 | +Subject: [PATCH 2/3] Add optional new pin when resetting |
| 109 | + |
| 110 | +--- |
| 111 | + src/main.c | 9 +++++---- |
| 112 | + src/operations_ccid.c | 6 +++++- |
| 113 | + src/operations_ccid.h | 5 ++++- |
| 114 | + 3 files changed, 14 insertions(+), 6 deletions(-) |
| 115 | + |
| 116 | +diff --git a/src/main.c b/src/main.c |
| 117 | +index b80b71d..3f4a1cc 100644 |
| 118 | +--- a/src/main.c |
| 119 | ++++ b/src/main.c |
| 120 | +@@ -38,9 +38,10 @@ void print_help(char *app_name) { |
| 121 | + "\t%s info\n" |
| 122 | + "\t%s version\n" |
| 123 | + "\t%s check <HOTP CODE>\n" |
| 124 | +- "\t%s regenerate <ADMIN PIN>\n" |
| 125 | ++ "\t%s reset [ADMIN PIN]\n" |
| 126 | ++ "\t%s regenerate\n" |
| 127 | + "\t%s set <BASE32 HOTP SECRET> <ADMIN PIN> [COUNTER]\n", |
| 128 | +- app_name, app_name, app_name, app_name, app_name, app_name); |
| 129 | ++ app_name, app_name, app_name, app_name, app_name, app_name, app_name); |
| 130 | + } |
| 131 | + |
| 132 | + |
| 133 | +@@ -136,8 +137,8 @@ int parse_cmd_and_run(int argc, char *const *argv) { |
| 134 | + break; |
| 135 | + case 'r': |
| 136 | + if (strncmp(argv[1], "reset", 15) == 0) { |
| 137 | +- if (argc != 2) break; |
| 138 | +- res = nk3_reset(&dev); |
| 139 | ++ if (argc != 2 && argc != 3) break; |
| 140 | ++ res = nk3_reset(&dev, argc == 3 ? argv[2]: NULL); |
| 141 | + } else if (strncmp(argv[1], "regenerate", 15) == 0) { |
| 142 | + if (argc != 3) break; |
| 143 | + res = regenerate_AES_key(&dev, argv[2]); |
| 144 | +diff --git a/src/operations_ccid.c b/src/operations_ccid.c |
| 145 | +index 574155d..07834ce 100644 |
| 146 | +--- a/src/operations_ccid.c |
| 147 | ++++ b/src/operations_ccid.c |
| 148 | +@@ -33,7 +33,7 @@ |
| 149 | + |
| 150 | + |
| 151 | + |
| 152 | +-int nk3_reset(struct Device *dev) { |
| 153 | ++int nk3_reset(struct Device *dev, const char * new_pin) { |
| 154 | + libusb_device *usb_dev; |
| 155 | + struct libusb_device_descriptor usb_desc; |
| 156 | + usb_dev = libusb_get_device(dev->mp_devhandle_ccid); |
| 157 | +@@ -70,6 +70,10 @@ int nk3_reset(struct Device *dev) { |
| 158 | + return 1; |
| 159 | + } |
| 160 | + |
| 161 | ++ if (new_pin != NULL) { |
| 162 | ++ set_pin_ccid(dev, new_pin); |
| 163 | ++ } |
| 164 | ++ |
| 165 | + return RET_NO_ERROR; |
| 166 | + } |
| 167 | + |
| 168 | +diff --git a/src/operations_ccid.h b/src/operations_ccid.h |
| 169 | +index ec0070c..61cad72 100644 |
| 170 | +--- a/src/operations_ccid.h |
| 171 | ++++ b/src/operations_ccid.h |
| 172 | +@@ -11,7 +11,10 @@ int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN); |
| 173 | + int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter); |
| 174 | + int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify); |
| 175 | + int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number); |
| 176 | +-int nk3_reset(struct Device *dev); |
| 177 | ++// new_pin can be `null` |
| 178 | ++// |
| 179 | ++// If it is, no new pin will be set |
| 180 | ++int nk3_reset(struct Device *dev, const char * new_pin); |
| 181 | + |
| 182 | + |
| 183 | + #endif//NITROKEY_HOTP_VERIFICATION_OPERATIONS_CCID_H |
| 184 | + |
| 185 | +From 596f701985682adf6bfab06c78cbe132cbcb2aae Mon Sep 17 00:00:00 2001 |
| 186 | +From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= <sosthene@nitrokey.com> |
| 187 | +Date: Tue, 3 Dec 2024 10:48:27 +0100 |
| 188 | +Subject: [PATCH 3/3] Fix null pointer bug on non nk3 |
| 189 | + |
| 190 | +--- |
| 191 | + src/operations_ccid.c | 8 +++++++- |
| 192 | + 1 file changed, 7 insertions(+), 1 deletion(-) |
| 193 | + |
| 194 | +diff --git a/src/operations_ccid.c b/src/operations_ccid.c |
| 195 | +index 07834ce..538d434 100644 |
| 196 | +--- a/src/operations_ccid.c |
| 197 | ++++ b/src/operations_ccid.c |
| 198 | +@@ -36,6 +36,12 @@ |
| 199 | + int nk3_reset(struct Device *dev, const char * new_pin) { |
| 200 | + libusb_device *usb_dev; |
| 201 | + struct libusb_device_descriptor usb_desc; |
| 202 | ++ |
| 203 | ++ if (!dev->mp_devhandle_ccid) { |
| 204 | ++ // Not an NK3 |
| 205 | ++ return RET_NO_ERROR; |
| 206 | ++ } |
| 207 | ++ |
| 208 | + usb_dev = libusb_get_device(dev->mp_devhandle_ccid); |
| 209 | + |
| 210 | + int r = libusb_get_device_descriptor(usb_dev, &usb_desc); |
| 211 | +@@ -46,7 +52,7 @@ int nk3_reset(struct Device *dev, const char * new_pin) { |
| 212 | + |
| 213 | + |
| 214 | + if (usb_desc.idVendor != NITROKEY_USB_VID || usb_desc.idProduct != NITROKEY_3_USB_PID) { |
| 215 | +- return 0; |
| 216 | ++ return RET_NO_ERROR; |
| 217 | + } |
| 218 | + |
| 219 | + |
0 commit comments