From 4200af146a17398dc7050c92e1f861f2066debec Mon Sep 17 00:00:00 2001 From: Amit Aronovitch Date: Wed, 2 Oct 2019 00:01:48 +0300 Subject: Identify Librem Key, behaving like Nitrokey Pro device --- NitrokeyManager.cc | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 6c26a43..d874dca 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -217,7 +217,12 @@ using nitrokey::misc::strcpyT; } } - auto info_ptr = hid_enumerate(NITROKEY_VID, 0); + auto vendor_id = NITROKEY_VID; + auto info_ptr = hid_enumerate(vendor_id, 0); + if (!info_ptr) { + vendor_id = PURISM_VID; + info_ptr = hid_enumerate(vendor_id, 0); + } auto first_info_ptr = info_ptr; if (!info_ptr) return false; @@ -225,7 +230,7 @@ using nitrokey::misc::strcpyT; misc::Option model; while (info_ptr && !model.has_value()) { if (path == std::string(info_ptr->path)) { - model = product_id_to_model(info_ptr->product_id); + model = product_id_to_model(vendor_id, info_ptr->product_id); } info_ptr = info_ptr->next; } @@ -254,7 +259,8 @@ using nitrokey::misc::strcpyT; bool NitrokeyManager::connect() { std::lock_guard lock(mex_dev_com_manager); - vector< shared_ptr > devices = { make_shared(), make_shared() }; + vector< shared_ptr > devices = { make_shared(), make_shared(), + make_shared() }; bool connected = false; for( auto & d : devices ){ if (d->connect()){ @@ -290,6 +296,9 @@ using nitrokey::misc::strcpyT; case 'S': device = make_shared(); break; + case 'L': + device = make_shared(); + break; default: throw std::runtime_error("Unknown model"); } @@ -305,6 +314,9 @@ using nitrokey::misc::strcpyT; case device::DeviceModel::STORAGE: model_string = "S"; break; + case device::DeviceModel::LIBREM: + model_string = "L"; + break; default: throw std::runtime_error("Unknown model"); } @@ -382,6 +394,7 @@ using nitrokey::misc::strcpyT; string NitrokeyManager::get_serial_number() { if (device == nullptr) { return ""; }; switch (device->get_device_model()) { + case DeviceModel::LIBREM: case DeviceModel::PRO: { auto response = GetStatus::CommandTransaction::run(device); return nitrokey::misc::toHex(response.data().card_serial_u32); @@ -552,6 +565,7 @@ using nitrokey::misc::strcpyT; strcpyT(payload.slot_name, slot_name); strcpyT(payload.slot_token_id, token_ID); switch (device->get_device_model() ){ + case DeviceModel::LIBREM: case DeviceModel::PRO: { payload.slot_counter = hotp_counter; break; @@ -713,6 +727,7 @@ using nitrokey::misc::strcpyT; template void NitrokeyManager::change_PIN_general(const char *current_PIN, const char *new_PIN) { switch (device->get_device_model()){ + case DeviceModel::LIBREM: case DeviceModel::PRO: { auto p = get_payload(); @@ -834,6 +849,7 @@ using nitrokey::misc::strcpyT; void NitrokeyManager::build_aes_key(const char *admin_password) { switch (device->get_device_model()) { + case DeviceModel::LIBREM: case DeviceModel::PRO: { auto p = get_payload(); strcpyT(p.admin_password, admin_password); @@ -858,6 +874,7 @@ using nitrokey::misc::strcpyT; void NitrokeyManager::unlock_user_password(const char *admin_password, const char *new_user_password) { switch (device->get_device_model()){ + case DeviceModel::LIBREM: case DeviceModel::PRO: { auto p = get_payload(); strcpyT(p.admin_password, admin_password); @@ -907,6 +924,7 @@ using nitrokey::misc::strcpyT; //authorization command is supported for versions equal or below: auto m = std::unordered_map({ {DeviceModel::PRO, 7}, + {DeviceModel::LIBREM, 7}, {DeviceModel::STORAGE, 53}, }); return get_minor_firmware_version() <= m[device->get_device_model()]; @@ -916,6 +934,7 @@ using nitrokey::misc::strcpyT; // 320 bit OTP secret is supported by version bigger or equal to: auto m = std::unordered_map({ {DeviceModel::PRO, 8}, + {DeviceModel::LIBREM, 8}, {DeviceModel::STORAGE, 54}, }); return get_minor_firmware_version() >= m[device->get_device_model()]; @@ -940,6 +959,7 @@ using nitrokey::misc::strcpyT; uint8_t NitrokeyManager::get_minor_firmware_version(){ switch(device->get_device_model()){ + case DeviceModel::LIBREM: case DeviceModel::PRO:{ auto status_p = GetStatus::CommandTransaction::run(device); return status_p.data().firmware_version_st.minor; //7 or 8 @@ -956,6 +976,7 @@ using nitrokey::misc::strcpyT; } uint8_t NitrokeyManager::get_major_firmware_version(){ switch(device->get_device_model()){ + case DeviceModel::LIBREM: case DeviceModel::PRO:{ auto status_p = GetStatus::CommandTransaction::run(device); return status_p.data().firmware_version_st.major; //0 -- cgit v1.2.1 From 67b14773cf4ab1812af85d3aaf99bdc6119c5a8a Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 2 Apr 2020 15:02:36 +0200 Subject: NitrokeyManager: Also return serial number as u32 This patch adds the get_serial_number_as_u32 method to NitrokeyManager. It returns the serial number as a 32-bit unsigned integer. Previously, we only returned it as a string generated from the integer value, get_serial_number. While get_serial_number returns an empty string if no device is connected and "NA" if an unknown model is connected, the new method throws a DeviceNotConnected exception in the first case and returns zero in the second case as we cannot express the three states in one integer return value. --- NitrokeyManager.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 6c26a43..496496e 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -398,6 +398,25 @@ using nitrokey::misc::strcpyT; return "NA"; } + uint32_t NitrokeyManager::get_serial_number_as_u32() { + if (device == nullptr) { throw DeviceNotConnected("device not connected"); } + switch (device->get_device_model()) { + case DeviceModel::PRO: { + auto response = GetStatus::CommandTransaction::run(device); + return response.data().card_serial_u32; + } + break; + + case DeviceModel::STORAGE: + { + auto response = stick20::GetDeviceStatus::CommandTransaction::run(device); + return response.data().ActiveSmartCardID_u32; + } + break; + } + return 0; + } + stick10::GetStatus::ResponsePayload NitrokeyManager::get_status(){ try{ auto response = GetStatus::CommandTransaction::run(device); -- cgit v1.2.1 From 02f19713c155457e8cc7d80d581bdac35cb1716d Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Thu, 2 Apr 2020 15:14:11 +0200 Subject: NitrokeyManager: Refactor get_serial_number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid duplicate code, this patch refactors the get_serial_number method to use get_serial_number_as_u32 internally. It does not change get_serial_number’s behavior. --- NitrokeyManager.cc | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 496496e..b6a076a 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -380,22 +380,16 @@ using nitrokey::misc::strcpyT; string NitrokeyManager::get_serial_number() { - if (device == nullptr) { return ""; }; - switch (device->get_device_model()) { - case DeviceModel::PRO: { - auto response = GetStatus::CommandTransaction::run(device); - return nitrokey::misc::toHex(response.data().card_serial_u32); - } - break; - - case DeviceModel::STORAGE: - { - auto response = stick20::GetDeviceStatus::CommandTransaction::run(device); - return nitrokey::misc::toHex(response.data().ActiveSmartCardID_u32); + try { + auto serial_number = this->get_serial_number_as_u32(); + if (serial_number == 0) { + return "NA"; + } else { + return nitrokey::misc::toHex(serial_number); } - break; + } catch (DeviceNotConnected& e) { + return ""; } - return "NA"; } uint32_t NitrokeyManager::get_serial_number_as_u32() { -- cgit v1.2.1 From 444a6cb764fbcea3c91ae936b1c76a190f935b10 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Sat, 13 Jun 2020 12:21:44 +0200 Subject: Revert API change Remove the change to keep binary compatibility. Use the vendor_id field from the dev description. --- NitrokeyManager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index d874dca..71d156f 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -230,7 +230,7 @@ using nitrokey::misc::strcpyT; misc::Option model; while (info_ptr && !model.has_value()) { if (path == std::string(info_ptr->path)) { - model = product_id_to_model(vendor_id, info_ptr->product_id); + model = product_id_to_model(info_ptr->vendor_id, info_ptr->product_id); } info_ptr = info_ptr->next; } -- cgit v1.2.1