diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2018-12-10 12:42:48 +0000 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2018-12-10 13:46:42 +0100 |
commit | 4615f5ecf96ef4637d814a4dfeab9c404b4a3667 (patch) | |
tree | 5bd65c78c1c913d44e8917c29e91895a9de450f6 | |
parent | b126c5ba1e5a9f00859868d75900043d02a0031c (diff) | |
download | nitrokey-sys-rs-9e5080c4cf4dd358b76b1a9c04f6b7ed4cd1c663.tar.gz nitrokey-sys-rs-9e5080c4cf4dd358b76b1a9c04f6b7ed4cd1c663.tar.bz2 |
Update to libnitrokey v3.4v3.4.0
Besides the changes listed in the changelog, this patch also changes the
build system to be able to generate the version.cc file containing the
library version.
-rw-r--r-- | CHANGELOG.md | 24 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | build.rs | 34 | ||||
-rw-r--r-- | libnitrokey-v3.4/DeviceCommunicationExceptions.cpp (renamed from libnitrokey-v3.3/DeviceCommunicationExceptions.cpp) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/LICENSE (renamed from libnitrokey-v3.3/LICENSE) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/NK_C_API.cc (renamed from libnitrokey-v3.3/NK_C_API.cc) | 199 | ||||
-rw-r--r-- | libnitrokey-v3.4/NK_C_API.h (renamed from libnitrokey-v3.3/NK_C_API.h) | 268 | ||||
-rw-r--r-- | libnitrokey-v3.4/NitrokeyManager.cc (renamed from libnitrokey-v3.3/NitrokeyManager.cc) | 34 | ||||
-rw-r--r-- | libnitrokey-v3.4/README.md (renamed from libnitrokey-v3.3/README.md) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/command_id.cc (renamed from libnitrokey-v3.3/command_id.cc) | 4 | ||||
-rw-r--r-- | libnitrokey-v3.4/device.cc (renamed from libnitrokey-v3.3/device.cc) | 6 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/CommandFailedException.h (renamed from libnitrokey-v3.3/libnitrokey/CommandFailedException.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/DeviceCommunicationExceptions.h (renamed from libnitrokey-v3.3/libnitrokey/DeviceCommunicationExceptions.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/LibraryException.h (renamed from libnitrokey-v3.3/libnitrokey/LibraryException.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/LongOperationInProgressException.h (renamed from libnitrokey-v3.3/libnitrokey/LongOperationInProgressException.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/NitrokeyManager.h (renamed from libnitrokey-v3.3/libnitrokey/NitrokeyManager.h) | 35 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/command.h (renamed from libnitrokey-v3.3/libnitrokey/command.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/command_id.h (renamed from libnitrokey-v3.3/libnitrokey/command_id.h) | 2 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/cxx_semantics.h (renamed from libnitrokey-v3.3/libnitrokey/cxx_semantics.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/deprecated.h | 35 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/device.h (renamed from libnitrokey-v3.3/libnitrokey/device.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/device_proto.h (renamed from libnitrokey-v3.3/libnitrokey/device_proto.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/dissect.h (renamed from libnitrokey-v3.3/libnitrokey/dissect.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/hidapi/hidapi.h (renamed from libnitrokey-v3.3/libnitrokey/hidapi/hidapi.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/log.h (renamed from libnitrokey-v3.3/libnitrokey/log.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/misc.h (renamed from libnitrokey-v3.3/libnitrokey/misc.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/stick10_commands.h (renamed from libnitrokey-v3.3/libnitrokey/stick10_commands.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/stick10_commands_0.8.h (renamed from libnitrokey-v3.3/libnitrokey/stick10_commands_0.8.h) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/stick20_commands.h (renamed from libnitrokey-v3.3/libnitrokey/stick20_commands.h) | 6 | ||||
-rw-r--r-- | libnitrokey-v3.4/libnitrokey/version.h | 33 | ||||
-rw-r--r-- | libnitrokey-v3.4/log.cc (renamed from libnitrokey-v3.3/log.cc) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/misc.cc (renamed from libnitrokey-v3.3/misc.cc) | 0 | ||||
-rw-r--r-- | libnitrokey-v3.4/version.cc.in | 37 | ||||
-rw-r--r-- | src/ffi.rs | 607 |
35 files changed, 1149 insertions, 179 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a6f6fc..113b342 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ +# v3.4.0 (2018-12-10) + +- Update to libnitrokey 3.4, causing all following changes. +- New constant `NK_device_model_NK_DISCONNECTED` in the `NK_device_model` + enumeration. +- New structures: + - `NK_storage_ProductionTest` + - `NK_storage_status` +- New functions: + - `NK_get_device_model` + - `NK_get_library_version` + - `NK_get_major_library_version` + - `NK_get_minor_libray_version` + - `NK_get_status_storage` + - `NK_get_storage_production_info` + - `NK_totp_set_time_soft` + - `NK_wink` +- The function `NK_totp_get_time` is now deprecated. If applicable, + `NK_totp_set_time_soft` should be used instead. See the [upstream pull + request #114][] for details. +- Strings are now returned as mutable instead of constant pointers. + # v3.3.0 (2018-05-21) - Change the crate license to LGPL 3.0. @@ -10,3 +32,5 @@ # v0.1.0 (2018-05-19) - Initial release. + +[upstream pull request #114]: https://github.com/Nitrokey/libnitrokey/pull/114 @@ -1,6 +1,6 @@ [package] name = "nitrokey-sys" -version = "3.3.0" +version = "3.4.0" authors = ["Robin Krahl <robin.krahl@ireas.org>"] homepage = "https://code.ireas.org/nitrokey-rs/" repository = "https://git.ireas.org/nitrokey-sys-rs/" @@ -5,7 +5,7 @@ devices. ```toml [dependencies] -nitrokey-sys = "3.3.0" +nitrokey-sys = "3.4.0" ``` The version of this crate corresponds to the wrapped `libnitrokey` version. @@ -1,6 +1,9 @@ extern crate cc; use std::env; +use std::io; +use std::io::{Read, Write}; +use std::fs; use std::path; struct Version { @@ -41,7 +44,34 @@ fn get_version() -> Result<Version, String> { }) } +fn prepare_version_source( + version: &Version, + out_path: &path::Path, + library_path: &path::Path +) -> io::Result<path::PathBuf> { + let out = out_path.join("version.cc"); + let template = library_path.join("version.cc.in"); + + let mut file = fs::File::open(template)?; + let mut data = String::new(); + file.read_to_string(&mut data)?; + drop(file); + + let data = data + .replace("@PROJECT_VERSION_MAJOR@", &version.major) + .replace("@PROJECT_VERSION_MINOR@", &version.minor) + .replace("@PROJECT_VERSION_GIT@", &version.git); + + let mut file = fs::File::create(&out)?; + file.write_all(data.as_bytes())?; + + Ok(out) +} + fn main() { + let out_dir = env::var("OUT_DIR").expect("Environment variable OUT_DIR is not set"); + let out_path = path::PathBuf::from(out_dir); + let version = get_version().expect("Could not extract library version"); let sources = [ @@ -56,10 +86,14 @@ fn main() { let library_dir = format!("libnitrokey-{}", version.git); let library_path = path::Path::new(&library_dir); + let version_source = prepare_version_source(&version, &out_path, &library_path) + .expect("Could not prepare the version source file"); + cc::Build::new() .cpp(true) .include(library_path.join("libnitrokey")) .files(sources.iter().map(|s| library_path.join(s))) + .file(version_source) .compile("libnitrokey.a"); println!("cargo:rustc-link-lib=hidapi-libusb"); diff --git a/libnitrokey-v3.3/DeviceCommunicationExceptions.cpp b/libnitrokey-v3.4/DeviceCommunicationExceptions.cpp index 4d62aad..4d62aad 100644 --- a/libnitrokey-v3.3/DeviceCommunicationExceptions.cpp +++ b/libnitrokey-v3.4/DeviceCommunicationExceptions.cpp diff --git a/libnitrokey-v3.3/LICENSE b/libnitrokey-v3.4/LICENSE index 341c30b..341c30b 100644 --- a/libnitrokey-v3.3/LICENSE +++ b/libnitrokey-v3.4/LICENSE diff --git a/libnitrokey-v3.3/NK_C_API.cc b/libnitrokey-v3.4/NK_C_API.cc index b245940..7d0a10e 100644 --- a/libnitrokey-v3.3/NK_C_API.cc +++ b/libnitrokey-v3.4/NK_C_API.cc @@ -21,10 +21,13 @@ #include "NK_C_API.h" #include <iostream> +#include <tuple> #include "libnitrokey/NitrokeyManager.h" #include <cstring> #include "libnitrokey/LibraryException.h" #include "libnitrokey/cxx_semantics.h" +#include "libnitrokey/stick20_commands.h" +#include "version.h" #ifdef _MSC_VER #ifdef _WIN32 @@ -52,11 +55,11 @@ T* duplicate_vector_and_clear(std::vector<T> &v){ return d; } -template <typename T> -uint8_t * get_with_array_result(T func){ +template <typename R, typename T> +std::tuple<int, R> get_with_status(T func, R fallback) { NK_last_command_status = 0; try { - return func(); + return std::make_tuple(0, func()); } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; @@ -67,43 +70,26 @@ uint8_t * get_with_array_result(T func){ catch (const DeviceCommunicationException &deviceException){ NK_last_command_status = 256-deviceException.getType(); } - return nullptr; + return std::make_tuple(NK_last_command_status, fallback); } template <typename T> -const char* get_with_string_result(T func){ - NK_last_command_status = 0; - try { - return func(); - } - catch (CommandFailedException & commandFailedException){ - NK_last_command_status = commandFailedException.last_command_status; - } - catch (LibraryException & libraryException){ - NK_last_command_status = libraryException.exception_id(); - } - catch (const DeviceCommunicationException &deviceException){ - NK_last_command_status = 256-deviceException.getType(); +uint8_t * get_with_array_result(T func){ + return std::get<1>(get_with_status<uint8_t*>(func, nullptr)); +} + +template <typename T> +char* get_with_string_result(T func){ + auto result = std::get<1>(get_with_status<char*>(func, nullptr)); + if (result == nullptr) { + return strndup("", MAXIMUM_STR_REPLY_LENGTH); } - return ""; + return result; } template <typename T> auto get_with_result(T func){ - NK_last_command_status = 0; - try { - return func(); - } - catch (CommandFailedException & commandFailedException){ - NK_last_command_status = commandFailedException.last_command_status; - } - catch (LibraryException & libraryException){ - NK_last_command_status = libraryException.exception_id(); - } - catch (const DeviceCommunicationException &deviceException){ - NK_last_command_status = 256-deviceException.getType(); - } - return static_cast<decltype(func())>(0); + return std::get<1>(get_with_status(func, static_cast<decltype(func())>(0))); } template <typename T> @@ -170,6 +156,7 @@ extern "C" { case NK_STORAGE: model_string = "S"; break; + case NK_DISCONNECTED: default: /* no such enum value -- return error code */ return 0; @@ -238,22 +225,41 @@ extern "C" { } + NK_C_API enum NK_device_model NK_get_device_model() { + auto m = NitrokeyManager::instance(); + try { + auto model = m->get_connected_device_model(); + switch (model) { + case DeviceModel::PRO: + return NK_PRO; + case DeviceModel::STORAGE: + return NK_STORAGE; + default: + /* unknown or not connected device */ + return NK_device_model::NK_DISCONNECTED; + } + } catch (const DeviceNotConnected& e) { + return NK_device_model::NK_DISCONNECTED; + } +} + + void clear_string(std::string &s) { std::fill(s.begin(), s.end(), ' '); } - NK_C_API const char * NK_status() { + NK_C_API char * NK_status() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { string && s = m->get_status_as_string(); - char * rs = strndup(s.c_str(), max_string_field_length); + char * rs = strndup(s.c_str(), MAXIMUM_STR_REPLY_LENGTH); clear_string(s); return rs; }); } - NK_C_API const char * NK_device_serial_number() { + NK_C_API char * NK_device_serial_number() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { string && s = m->get_serial_number(); @@ -263,11 +269,11 @@ extern "C" { }); } - NK_C_API const char * NK_get_hotp_code(uint8_t slot_number) { + NK_C_API char * NK_get_hotp_code(uint8_t slot_number) { return NK_get_hotp_code_PIN(slot_number, ""); } - NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password) { + NK_C_API char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { string && s = m->get_HOTP_code(slot_number, user_temporary_password); @@ -277,12 +283,12 @@ extern "C" { }); } - NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, + NK_C_API char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval) { return NK_get_totp_code_PIN(slot_number, challenge, last_totp_time, last_interval, ""); } - NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, + NK_C_API char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char *user_temporary_password) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { @@ -327,14 +333,14 @@ extern "C" { }); } - NK_C_API const char* NK_get_totp_slot_name(uint8_t slot_number) { + NK_C_API char* NK_get_totp_slot_name(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { const auto slot_name = m->get_totp_slot_name(slot_number); return slot_name; }); } - NK_C_API const char* NK_get_hotp_slot_name(uint8_t slot_number) { + NK_C_API char* NK_get_hotp_slot_name(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { const auto slot_name = m->get_hotp_slot_name(slot_number); @@ -353,6 +359,18 @@ extern "C" { m->set_loglevel(level); } + NK_C_API unsigned int NK_get_major_library_version() { + return get_major_library_version(); + } + + NK_C_API unsigned int NK_get_minor_library_version() { + return get_minor_library_version(); + } + + NK_C_API const char* NK_get_library_version() { + return get_library_version(); + } + NK_C_API int NK_totp_set_time(uint64_t time) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { @@ -360,11 +378,15 @@ extern "C" { }); } - NK_C_API int NK_totp_get_time() { + NK_C_API int NK_totp_set_time_soft(uint64_t time) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { - m->get_time(0); // FIXME check how that should work + m->set_time_soft(time); }); + } + + NK_C_API int NK_totp_get_time() { + return 0; } NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN) { @@ -417,20 +439,20 @@ extern "C" { }); } - NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number) { + NK_C_API char *NK_get_password_safe_slot_name(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_password_safe_slot_name(slot_number); }); } - NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number) { + NK_C_API char *NK_get_password_safe_slot_login(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_password_safe_slot_login(slot_number); }); } - NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number) { + NK_C_API char *NK_get_password_safe_slot_password(uint8_t slot_number) { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_password_safe_slot_password(slot_number); @@ -589,14 +611,84 @@ extern "C" { }); } - NK_C_API const char* NK_get_status_storage_as_string() { + NK_C_API char* NK_get_status_storage_as_string() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_status_storage_as_string(); }); } - NK_C_API const char* NK_get_SD_usage_data_as_string() { + NK_C_API int NK_get_status_storage(NK_storage_status* out) { + if (out == nullptr) { + return -1; + } + auto m = NitrokeyManager::instance(); + auto result = get_with_status([&]() { + return m->get_status_storage(); + }, proto::stick20::DeviceConfigurationResponsePacket::ResponsePayload()); + auto error_code = std::get<0>(result); + if (error_code != 0) { + return error_code; + } + + auto status = std::get<1>(result); + out->unencrypted_volume_read_only = status.ReadWriteFlagUncryptedVolume_u8 != 0; + out->unencrypted_volume_active = status.VolumeActiceFlag_st.unencrypted; + out->encrypted_volume_read_only = status.ReadWriteFlagCryptedVolume_u8 != 0; + out->encrypted_volume_active = status.VolumeActiceFlag_st.encrypted; + out->hidden_volume_read_only = status.ReadWriteFlagHiddenVolume_u8 != 0; + out->hidden_volume_active = status.VolumeActiceFlag_st.hidden; + out->firmware_version_major = status.versionInfo.major; + out->firmware_version_minor = status.versionInfo.minor; + out->firmware_locked = status.FirmwareLocked_u8 != 0; + out->serial_number_sd_card = status.ActiveSD_CardID_u32; + out->serial_number_smart_card = status.ActiveSmartCardID_u32; + out->user_retry_count = status.UserPwRetryCount; + out->admin_retry_count = status.AdminPwRetryCount; + out->new_sd_card_found = status.NewSDCardFound_st.NewCard; + out->filled_with_random = (status.SDFillWithRandomChars_u8 & 0x01) != 0; + out->stick_initialized = status.StickKeysNotInitiated == 0; + return 0; + } + + NK_C_API int NK_get_storage_production_info(NK_storage_ProductionTest * out){ + if (out == nullptr) { + return -1; + } + auto m = NitrokeyManager::instance(); + auto result = get_with_status([&]() { + return m->production_info(); + }, proto::stick20::ProductionTest::ResponsePayload()); + + auto error_code = std::get<0>(result); + if (error_code != 0) { + return error_code; + } + + stick20::ProductionTest::ResponsePayload status = std::get<1>(result); + // Cannot use memcpy without declaring C API struct packed + // (which is not parsed by Python's CFFI apparently), hence the manual way. +#define a(x) out->x = status.x; + a(FirmwareVersion_au8[0]); + a(FirmwareVersion_au8[1]); + a(FirmwareVersionInternal_u8); + a(SD_Card_Size_u8); + a(CPU_CardID_u32); + a(SmartCardID_u32); + a(SD_CardID_u32); + a(SC_UserPwRetryCount); + a(SC_AdminPwRetryCount); + a(SD_Card_ManufacturingYear_u8); + a(SD_Card_ManufacturingMonth_u8); + a(SD_Card_OEM_u16); + a(SD_WriteSpeed_u16); + a(SD_Card_Manufacturer_u8); +#undef a + return 0; + } + + +NK_C_API char* NK_get_SD_usage_data_as_string() { auto m = NitrokeyManager::instance(); return get_with_string_result([&]() { return m->get_SD_usage_data_as_string(); @@ -631,7 +723,7 @@ extern "C" { }); } - NK_C_API const char* NK_list_devices_by_cpuID() { + NK_C_API char* NK_list_devices_by_cpuID() { auto nm = NitrokeyManager::instance(); return get_with_string_result([&]() { auto v = nm->list_devices_by_cpuID(); @@ -640,7 +732,7 @@ extern "C" { res += a+";"; } if (res.size()>0) res.pop_back(); // remove last delimiter char - return strndup(res.c_str(), 8192); //this buffer size sets limit to over 200 devices ID's + return strndup(res.c_str(), MAXIMUM_STR_REPLY_LENGTH); }); } @@ -651,7 +743,12 @@ extern "C" { }); } - + NK_C_API int NK_wink() { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + return m->wink(); + }); + } #ifdef __cplusplus } diff --git a/libnitrokey-v3.3/NK_C_API.h b/libnitrokey-v3.4/NK_C_API.h index 96a1950..b1bdf1e 100644 --- a/libnitrokey-v3.3/NK_C_API.h +++ b/libnitrokey-v3.4/NK_C_API.h @@ -25,41 +25,160 @@ #include <stdbool.h> #include <stdint.h> +#include "deprecated.h" + #ifdef _MSC_VER #define NK_C_API __declspec(dllexport) #else -#define NK_C_API +#define NK_C_API #endif #ifdef __cplusplus extern "C" { #endif + static const int MAXIMUM_STR_REPLY_LENGTH = 8192; + /** * The Nitrokey device models supported by the API. */ enum NK_device_model { + /** + * Use, if no supported device is connected + */ + NK_DISCONNECTED = 0, /** * Nitrokey Pro. */ - NK_PRO, + NK_PRO = 1, /** * Nitrokey Storage. */ - NK_STORAGE + NK_STORAGE = 2 }; /** - * Set debug level of messages written on stderr - * @param state state=True - most messages, state=False - only errors level - */ + * Stores the status of a Storage device. + */ + struct NK_storage_status { + /** + * Indicates whether the unencrypted volume is read-only. + */ + bool unencrypted_volume_read_only; + /** + * Indicates whether the unencrypted volume is active. + */ + bool unencrypted_volume_active; + /** + * Indicates whether the encrypted volume is read-only. + */ + bool encrypted_volume_read_only; + /** + * Indicates whether the encrypted volume is active. + */ + bool encrypted_volume_active; + /** + * Indicates whether the hidden volume is read-only. + */ + bool hidden_volume_read_only; + /** + * Indicates whether the hidden volume is active. + */ + bool hidden_volume_active; + /** + * The major firmware version, e. g. 0 in v0.40. + */ + uint8_t firmware_version_major; + /** + * The minor firmware version, e. g. 40 in v0.40. + */ + uint8_t firmware_version_minor; + /** + * Indicates whether the firmware is locked. + */ + bool firmware_locked; + /** + * The serial number of the SD card in the Storage stick. + */ + uint32_t serial_number_sd_card; + /** + * The serial number of the smart card in the Storage stick. + */ + uint32_t serial_number_smart_card; + /** + * The number of remaining login attempts for the user PIN. + */ + uint8_t user_retry_count; + /** + * The number of remaining login attempts for the admin PIN. + */ + uint8_t admin_retry_count; + /** + * Indicates whether a new SD card was found. + */ + bool new_sd_card_found; + /** + * Indicates whether the SD card is filled with random characters. + */ + bool filled_with_random; + /** + * Indicates whether the stick has been initialized by generating + * the AES keys. + */ + bool stick_initialized; + }; + + struct NK_storage_ProductionTest{ + uint8_t FirmwareVersion_au8[2]; + uint8_t FirmwareVersionInternal_u8; + uint8_t SD_Card_Size_u8; + uint32_t CPU_CardID_u32; + uint32_t SmartCardID_u32; + uint32_t SD_CardID_u32; + uint8_t SC_UserPwRetryCount; + uint8_t SC_AdminPwRetryCount; + uint8_t SD_Card_ManufacturingYear_u8; + uint8_t SD_Card_ManufacturingMonth_u8; + uint16_t SD_Card_OEM_u16; + uint16_t SD_WriteSpeed_u16; + uint8_t SD_Card_Manufacturer_u8; + }; + + NK_C_API int NK_get_storage_production_info(struct NK_storage_ProductionTest * out); + + +/** + * Set debug level of messages written on stderr + * @param state state=True - most messages, state=False - only errors level + */ NK_C_API void NK_set_debug(bool state); /** * Set debug level of messages written on stderr * @param level (int) 0-lowest verbosity, 5-highest verbosity */ - NK_C_API void NK_set_debug_level(const int level); + NK_C_API void NK_set_debug_level(const int level); + + /** + * Get the major library version, e. g. the 3 in v3.2. + * @return the major library version + */ + NK_C_API unsigned int NK_get_major_library_version(); + + /** + * Get the minor library version, e. g. the 2 in v3.2. + * @return the minor library version + */ + NK_C_API unsigned int NK_get_minor_library_version(); + + /** + * Get the library version as a string. This is the output of + * `git describe --always` at compile time, for example "v3.3" or + * "v3.3-19-gaee920b". + * The return value is a string literal and must not be freed. + * @return the library version as a string + */ + NK_C_API const char* NK_get_library_version(); /** * Connect to device of given model. Currently library can be connected only to one device at once. @@ -88,16 +207,24 @@ extern "C" { NK_C_API int NK_logout(); /** + * Query the model of the connected device. + * Returns the model of the connected device or NK_DISCONNECTED. + * + * @return true if a device is connected and the out argument has been set + */ + NK_C_API enum NK_device_model NK_get_device_model(); + + /** * Return the debug status string. Debug purposes. * @return command processing error code */ - NK_C_API const char * NK_status(); + NK_C_API char * NK_status(); /** * Return the device's serial number string in hex. * @return string device's serial number in hex */ - NK_C_API const char * NK_device_serial_number(); + NK_C_API char * NK_device_serial_number(); /** * Get last command processing status. Useful for commands which returns the results of their own and could not return @@ -114,37 +241,37 @@ extern "C" { /** * Authenticates the user on USER privilages with user_password and sets user's temporary password on device to user_temporary_password. - * @param user_password char[25](Pro) current user password - * @param user_temporary_password char[25](Pro) user temporary password to be set on device for further communication (authentication command) + * @param user_password char[25] current user password + * @param user_temporary_password char[25] user temporary password to be set on device for further communication (authentication command) * @return command processing error code */ NK_C_API int NK_user_authenticate(const char* user_password, const char* user_temporary_password); /** * Authenticates the user on ADMIN privilages with admin_password and sets user's temporary password on device to admin_temporary_password. - * @param admin_password char[25](Pro) current administrator PIN - * @param admin_temporary_password char[25](Pro) admin temporary password to be set on device for further communication (authentication command) + * @param admin_password char[25] current administrator PIN + * @param admin_temporary_password char[25] admin temporary password to be set on device for further communication (authentication command) * @return command processing error code */ NK_C_API int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password); /** * Execute a factory reset. - * @param admin_password char[20](Pro) current administrator PIN + * @param admin_password char[20] current administrator PIN * @return command processing error code */ NK_C_API int NK_factory_reset(const char* admin_password); /** * Generates AES key on the device - * @param admin_password char[20](Pro) current administrator PIN + * @param admin_password char[20] current administrator PIN * @return command processing error code */ NK_C_API int NK_build_aes_key(const char* admin_password); /** * Unlock user PIN locked after 3 incorrect codes tries. - * @param admin_password char[20](Pro) current administrator PIN + * @param admin_password char[20] current administrator PIN * @return command processing error code */ NK_C_API int NK_unlock_user_password(const char *admin_password, const char *new_user_password); @@ -181,16 +308,16 @@ extern "C" { /** * Get name of given TOTP slot * @param slot_number TOTP slot number, slot_number<15 - * @return char[20](Pro) the name of the slot + * @return char[20] the name of the slot */ - NK_C_API const char * NK_get_totp_slot_name(uint8_t slot_number); + NK_C_API char * NK_get_totp_slot_name(uint8_t slot_number); /** * * @param slot_number HOTP slot number, slot_number<3 - * @return char[20](Pro) the name of the slot + * @return char[20] the name of the slot */ - NK_C_API const char * NK_get_hotp_slot_name(uint8_t slot_number); + NK_C_API char * NK_get_hotp_slot_name(uint8_t slot_number); /** * Erase HOTP slot data from the device @@ -210,15 +337,16 @@ extern "C" { /** * Write HOTP slot data to the device - * @param slot_number HOTP slot number, slot_number<3 - * @param slot_name char[15](Pro) desired slot name - * @param secret char[20](Pro) 160-bit secret + * @param slot_number HOTP slot number, slot_number<3, 0-numbered + * @param slot_name char[15] desired slot name. C string (requires ending '\0'; 16 bytes). + * @param secret char[40] 160-bit or 320-bit (currently Pro v0.8 only) secret as a hex string. C string (requires ending '\0'; 41 bytes). + * See NitrokeyManager::is_320_OTP_secret_supported. * @param hotp_counter uint32_t starting value of HOTP counter * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock * @param use_tokenID @see token_ID * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section - * @param temporary_password char[25](Pro) admin temporary password + * @param temporary_password char[25] admin temporary password * @return command processing error code */ NK_C_API int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, @@ -227,15 +355,16 @@ extern "C" { /** * Write TOTP slot data to the device - * @param slot_number TOTP slot number, slot_number<15 - * @param slot_name char[15](Pro) desired slot name - * @param secret char[20](Pro) 160-bit secret + * @param slot_number TOTP slot number, slot_number<15, 0-numbered + * @param slot_name char[15] desired slot name. C string (requires ending '\0'; 16 bytes). + * @param secret char[40] 160-bit or 320-bit (currently Pro v0.8 only) secret as a hex string. C string (requires ending '\0'; 41 bytes). + * See NitrokeyManager::is_320_OTP_secret_supported. * @param time_window uint16_t time window for this TOTP * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock * @param use_tokenID @see token_ID * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section - * @param temporary_password char[20](Pro) admin temporary password + * @param temporary_password char[20] admin temporary password * @return command processing error code */ NK_C_API int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, @@ -247,39 +376,39 @@ extern "C" { * @param slot_number HOTP slot number, slot_number<3 * @return HOTP code */ - NK_C_API const char * NK_get_hotp_code(uint8_t slot_number); + NK_C_API char * NK_get_hotp_code(uint8_t slot_number); /** * Get HOTP code from the device (PIN protected) * @param slot_number HOTP slot number, slot_number<3 - * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, + * @param user_temporary_password char[25] user temporary password if PIN protected OTP codes are enabled, * otherwise should be set to empty string - '' * @return HOTP code */ - NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password); + NK_C_API char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password); /** * Get TOTP code from the device * @param slot_number TOTP slot number, slot_number<15 - * @param challenge TOTP challenge - * @param last_totp_time last time - * @param last_interval last interval + * @param challenge TOTP challenge -- unused + * @param last_totp_time last time -- unused + * @param last_interval last interval --unused * @return TOTP code */ - NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, + NK_C_API char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval); /** * Get TOTP code from the device (PIN protected) * @param slot_number TOTP slot number, slot_number<15 - * @param challenge TOTP challenge - * @param last_totp_time last time - * @param last_interval last interval - * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, + * @param challenge TOTP challenge -- unused + * @param last_totp_time last time -- unused + * @param last_interval last interval -- unused + * @param user_temporary_password char[25] user temporary password if PIN protected OTP codes are enabled, * otherwise should be set to empty string - '' * @return TOTP code */ - NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, + NK_C_API char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char *user_temporary_password); @@ -290,21 +419,35 @@ extern "C" { */ NK_C_API int NK_totp_set_time(uint64_t time); + /** + * Set the device time used for TOTP to the given time. Contrary to + * {@code set_time(uint64_t)}, this command fails if {@code old_time} + * > {@code time} or if {@code old_time} is zero (where {@code + * old_time} is the current time on the device). + * + * @param time new device time as Unix timestamp (seconds since + * 1970-01-01) + * @return command processing error code + */ + NK_C_API int NK_totp_set_time_soft(uint64_t time); + + // NK_totp_get_time is deprecated -- use NK_totp_set_time_soft instead + DEPRECATED NK_C_API int NK_totp_get_time(); //passwords /** * Change administrator PIN - * @param current_PIN char[25](Pro) current PIN - * @param new_PIN char[25](Pro) new PIN + * @param current_PIN char[25] current PIN + * @param new_PIN char[25] new PIN * @return command processing error code */ NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN); /** * Change user PIN - * @param current_PIN char[25](Pro) current PIN - * @param new_PIN char[25](Pro) new PIN + * @param current_PIN char[25] current PIN + * @param new_PIN char[25] new PIN * @return command processing error code */ NK_C_API int NK_change_user_PIN(const char *current_PIN, const char *new_PIN); @@ -325,7 +468,7 @@ extern "C" { /** * Enable password safe access - * @param user_pin char[30](Pro) current user PIN + * @param user_pin char[30] current user PIN * @return command processing error code */ NK_C_API int NK_enable_password_safe(const char *user_pin); @@ -341,28 +484,28 @@ extern "C" { * @param slot_number password safe slot number, slot_number<16 * @return slot name */ - NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number); + NK_C_API char *NK_get_password_safe_slot_name(uint8_t slot_number); /** * Get password safe slot login * @param slot_number password safe slot number, slot_number<16 * @return login from the PWS slot */ - NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number); + NK_C_API char *NK_get_password_safe_slot_login(uint8_t slot_number); /** * Get the password safe slot password * @param slot_number password safe slot number, slot_number<16 * @return password from the PWS slot */ - NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number); + NK_C_API char *NK_get_password_safe_slot_password(uint8_t slot_number); /** * Write password safe data to the slot * @param slot_number password safe slot number, slot_number<16 - * @param slot_name char[11](Pro) name of the slot - * @param slot_login char[32](Pro) login string - * @param slot_password char[20](Pro) password string + * @param slot_name char[11] name of the slot + * @param slot_login char[32] login string + * @param slot_password char[20] password string * @return command processing error code */ NK_C_API int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, @@ -580,7 +723,18 @@ extern "C" { * Storage only * @return string with devices attributes */ - NK_C_API const char* NK_get_status_storage_as_string(); + NK_C_API char* NK_get_status_storage_as_string(); + + /** + * Get the Storage stick status and return the command processing + * error code. If the code is zero, i. e. the command was successful, + * the storage status is written to the output pointer's target. + * The output pointer must not be null. + * + * @param out the output pointer for the storage status + * @return command processing error code + */ + NK_C_API int NK_get_status_storage(struct NK_storage_status* out); /** * Get SD card usage attributes as string. @@ -588,7 +742,7 @@ extern "C" { * Storage only * @return string with SD card usage attributes */ - NK_C_API const char* NK_get_SD_usage_data_as_string(); + NK_C_API char* NK_get_SD_usage_data_as_string(); /** * Get progress value of current long operation. @@ -612,7 +766,7 @@ extern "C" { * @example Example of returned data: '00005d19:dacc2cb4_p_0001:0010:02;000037c7:4cf12445_p_0001:000f:02;0001:000c:02' * @return string delimited id's of connected devices */ - NK_C_API const char* NK_list_devices_by_cpuID(); + NK_C_API char* NK_list_devices_by_cpuID(); /** @@ -625,7 +779,11 @@ extern "C" { */ NK_C_API int NK_connect_with_ID(const char* id); - + /** + * Blink red and green LED alternatively and infinitely (until device is reconnected). + * @return command processing error code + */ + NK_C_API int NK_wink(); #ifdef __cplusplus } diff --git a/libnitrokey-v3.3/NitrokeyManager.cc b/libnitrokey-v3.4/NitrokeyManager.cc index 2ca183c..a950e4b 100644 --- a/libnitrokey-v3.3/NitrokeyManager.cc +++ b/libnitrokey-v3.4/NitrokeyManager.cc @@ -234,12 +234,14 @@ using nitrokey::misc::strcpyT; bool NitrokeyManager::connect() { std::lock_guard<std::mutex> lock(mex_dev_com_manager); vector< shared_ptr<Device> > devices = { make_shared<Stick10>(), make_shared<Stick20>() }; + bool connected = false; for( auto & d : devices ){ if (d->connect()){ device = std::shared_ptr<Device>(d); + connected = true; } } - return device != nullptr; + return connected; } @@ -630,12 +632,12 @@ using nitrokey::misc::strcpyT; auto resp = WriteToTOTPSlot::CommandTransaction::run(device, payload); } - const char * NitrokeyManager::get_totp_slot_name(uint8_t slot_number) { + char * NitrokeyManager::get_totp_slot_name(uint8_t slot_number) { if (!is_valid_totp_slot_number(slot_number)) throw InvalidSlotException(slot_number); slot_number = get_internal_slot_number_for_totp(slot_number); return get_slot_name(slot_number); } - const char * NitrokeyManager::get_hotp_slot_name(uint8_t slot_number) { + char * NitrokeyManager::get_hotp_slot_name(uint8_t slot_number) { if (!is_valid_hotp_slot_number(slot_number)) throw InvalidSlotException(slot_number); slot_number = get_internal_slot_number_for_hotp(slot_number); return get_slot_name(slot_number); @@ -643,7 +645,7 @@ using nitrokey::misc::strcpyT; static const int max_string_field_length = 2*1024; //storage's status string is ~1k - const char * NitrokeyManager::get_slot_name(uint8_t slot_number) { + char * NitrokeyManager::get_slot_name(uint8_t slot_number) { auto payload = get_payload<GetSlotName>(); payload.slot_number = slot_number; auto resp = GetSlotName::CommandTransaction::run(device, payload); @@ -666,11 +668,15 @@ using nitrokey::misc::strcpyT; return false; } - bool NitrokeyManager::get_time(uint64_t time) { + void NitrokeyManager::set_time_soft(uint64_t time) { auto p = get_payload<SetTime>(); p.reset = 0; p.time = time; SetTime::CommandTransaction::run(device, p); + } + + bool NitrokeyManager::get_time(uint64_t time) { + set_time_soft(time); return true; } @@ -749,7 +755,7 @@ using nitrokey::misc::strcpyT; LockDevice::CommandTransaction::run(device); } - const char *NitrokeyManager::get_password_safe_slot_name(uint8_t slot_number) { + char * NitrokeyManager::get_password_safe_slot_name(uint8_t slot_number) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload<GetPasswordSafeSlotName>(); p.slot_number = slot_number; @@ -759,7 +765,7 @@ using nitrokey::misc::strcpyT; bool NitrokeyManager::is_valid_password_safe_slot_number(uint8_t slot_number) const { return slot_number < 16; } - const char *NitrokeyManager::get_password_safe_slot_login(uint8_t slot_number) { + char * NitrokeyManager::get_password_safe_slot_login(uint8_t slot_number) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload<GetPasswordSafeSlotLogin>(); p.slot_number = slot_number; @@ -767,7 +773,7 @@ using nitrokey::misc::strcpyT; return strndup((const char *) response.data().slot_login, max_string_field_length); } - const char *NitrokeyManager::get_password_safe_slot_password(uint8_t slot_number) { + char * NitrokeyManager::get_password_safe_slot_password(uint8_t slot_number) { if (!is_valid_password_safe_slot_number(slot_number)) throw InvalidSlotException(slot_number); auto p = get_payload<GetPasswordSafeSlotPassword>(); p.slot_number = slot_number; @@ -1059,7 +1065,7 @@ using nitrokey::misc::strcpyT; stick20::ChangeUpdatePassword::CommandTransaction::run(device, p); } - const char * NitrokeyManager::get_status_storage_as_string(){ + char * NitrokeyManager::get_status_storage_as_string(){ auto p = stick20::GetDeviceStatus::CommandTransaction::run(device); return strndup(p.data().dissect().c_str(), max_string_field_length); } @@ -1069,7 +1075,7 @@ using nitrokey::misc::strcpyT; return p.data(); } - const char * NitrokeyManager::get_SD_usage_data_as_string(){ + char * NitrokeyManager::get_SD_usage_data_as_string(){ auto p = stick20::GetSDCardOccupancy::CommandTransaction::run(device); return strndup(p.data().dissect().c_str(), max_string_field_length); } @@ -1131,5 +1137,13 @@ using nitrokey::misc::strcpyT; return current_device_id; } + void NitrokeyManager::wink(){ + stick20::Wink::CommandTransaction::run(device); + }; + + stick20::ProductionTest::ResponsePayload NitrokeyManager::production_info(){ + auto data = stick20::ProductionTest::CommandTransaction::run(device); + return data.data(); + }; } diff --git a/libnitrokey-v3.3/README.md b/libnitrokey-v3.4/README.md index 81b367a..81b367a 100644 --- a/libnitrokey-v3.3/README.md +++ b/libnitrokey-v3.4/README.md diff --git a/libnitrokey-v3.3/command_id.cc b/libnitrokey-v3.4/command_id.cc index d81d487..a6c2a28 100644 --- a/libnitrokey-v3.3/command_id.cc +++ b/libnitrokey-v3.4/command_id.cc @@ -173,10 +173,10 @@ const char *commandid_to_string(CommandID id) { return "NEW_AES_KEY"; case CommandID::WRITE_TO_SLOT_2: return "WRITE_TO_SLOT_2"; - break; case CommandID::SEND_OTP_DATA: return "SEND_OTP_DATA"; - break; + case CommandID::WINK: + return "WINK"; } return "UNKNOWN"; } diff --git a/libnitrokey-v3.3/device.cc b/libnitrokey-v3.4/device.cc index da54e33..80e4b38 100644 --- a/libnitrokey-v3.3/device.cc +++ b/libnitrokey-v3.4/device.cc @@ -69,8 +69,10 @@ bool Device::_disconnect() { LOG(std::string(__FUNCTION__) + std::string(m_model == DeviceModel::PRO ? "PRO" : "STORAGE"), Loglevel::DEBUG_L2); LOG(std::string(__FUNCTION__) + std::string(" *IN* "), Loglevel::DEBUG_L2); - LOG(std::string("Disconnection: handle already freed: ") + std::to_string(mp_devhandle == nullptr) + " ("+m_path+")", Loglevel::DEBUG_L1); - if(mp_devhandle == nullptr) return false; + if(mp_devhandle == nullptr) { + LOG(std::string("Disconnection: handle already freed: ") + std::to_string(mp_devhandle == nullptr) + " ("+m_path+")", Loglevel::DEBUG_L1); + return false; + } hid_close(mp_devhandle); mp_devhandle = nullptr; diff --git a/libnitrokey-v3.3/libnitrokey/CommandFailedException.h b/libnitrokey-v3.4/libnitrokey/CommandFailedException.h index 32bd6b7..32bd6b7 100644 --- a/libnitrokey-v3.3/libnitrokey/CommandFailedException.h +++ b/libnitrokey-v3.4/libnitrokey/CommandFailedException.h diff --git a/libnitrokey-v3.3/libnitrokey/DeviceCommunicationExceptions.h b/libnitrokey-v3.4/libnitrokey/DeviceCommunicationExceptions.h index f710d0b..f710d0b 100644 --- a/libnitrokey-v3.3/libnitrokey/DeviceCommunicationExceptions.h +++ b/libnitrokey-v3.4/libnitrokey/DeviceCommunicationExceptions.h diff --git a/libnitrokey-v3.3/libnitrokey/LibraryException.h b/libnitrokey-v3.4/libnitrokey/LibraryException.h index 3b9d177..3b9d177 100644 --- a/libnitrokey-v3.3/libnitrokey/LibraryException.h +++ b/libnitrokey-v3.4/libnitrokey/LibraryException.h diff --git a/libnitrokey-v3.3/libnitrokey/LongOperationInProgressException.h b/libnitrokey-v3.4/libnitrokey/LongOperationInProgressException.h index 865d6b5..865d6b5 100644 --- a/libnitrokey-v3.3/libnitrokey/LongOperationInProgressException.h +++ b/libnitrokey-v3.4/libnitrokey/LongOperationInProgressException.h diff --git a/libnitrokey-v3.3/libnitrokey/NitrokeyManager.h b/libnitrokey-v3.4/libnitrokey/NitrokeyManager.h index 1f4cec4..d6e5df4 100644 --- a/libnitrokey-v3.3/libnitrokey/NitrokeyManager.h +++ b/libnitrokey-v3.4/libnitrokey/NitrokeyManager.h @@ -65,6 +65,18 @@ char * strndup(const char* str, size_t maxlen); stick10::ReadSlot::ResponsePayload get_HOTP_slot_data(const uint8_t slot_number); bool set_time(uint64_t time); + /** + * Set the device time used for TOTP to the given time. Contrary to + * {@code set_time(uint64_t)}, this command fails if {@code old_time} + * > {@code time} or if {@code old_time} is zero (where {@code + * old_time} is the current time on the device). + * + * @param time new device time as Unix timestamp (seconds since + * 1970-01-01) + */ + void set_time_soft(uint64_t time); + + [[deprecated("get_time is deprecated -- use set_time_soft instead")]] bool get_time(uint64_t time = 0); bool erase_totp_slot(uint8_t slot_number, const char *temporary_password); bool erase_hotp_slot(uint8_t slot_number, const char *temporary_password); @@ -93,8 +105,8 @@ char * strndup(const char* str, size_t maxlen); string get_status_as_string(); string get_serial_number(); - const char * get_totp_slot_name(uint8_t slot_number); - const char * get_hotp_slot_name(uint8_t slot_number); + char * get_totp_slot_name(uint8_t slot_number); + char * get_hotp_slot_name(uint8_t slot_number); void change_user_PIN(const char *current_PIN, const char *new_PIN); void change_admin_PIN(const char *current_PIN, const char *new_PIN); @@ -108,9 +120,9 @@ char * strndup(const char* str, size_t maxlen); void lock_device(); - const char *get_password_safe_slot_name(uint8_t slot_number); - const char *get_password_safe_slot_password(uint8_t slot_number); - const char *get_password_safe_slot_login(uint8_t slot_number); + char * get_password_safe_slot_name(uint8_t slot_number); + char * get_password_safe_slot_password(uint8_t slot_number); + char * get_password_safe_slot_login(uint8_t slot_number); void write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, @@ -187,10 +199,10 @@ char * strndup(const char* str, size_t maxlen); void send_startup(uint64_t seconds_from_epoch); - const char * get_status_storage_as_string(); + char * get_status_storage_as_string(); stick20::DeviceConfigurationResponsePacket::ResponsePayload get_status_storage(); - const char *get_SD_usage_data_as_string(); + char * get_SD_usage_data_as_string(); std::pair<uint8_t,uint8_t> get_SD_usage_data(); @@ -227,7 +239,7 @@ char * strndup(const char* str, size_t maxlen); uint8_t get_internal_slot_number_for_hotp(uint8_t slot_number) const; uint8_t get_internal_slot_number_for_totp(uint8_t slot_number) const; bool erase_slot(uint8_t slot_number, const char *temporary_password); - const char * get_slot_name(uint8_t slot_number); + char * get_slot_name(uint8_t slot_number); template <typename ProCommand, PasswordKind StoKind> void change_PIN_general(const char *current_PIN, const char *new_PIN); @@ -276,6 +288,13 @@ char * strndup(const char* str, size_t maxlen); * @return Returns true, if set unencrypted volume ro/rw pin type is User, false otherwise. */ bool set_unencrypted_volume_rorw_pin_type_user(); + + /** + * Blink red and green LED alternatively and infinitely (until device is reconnected). + */ + void wink(); + + stick20::ProductionTest::ResponsePayload production_info(); }; } diff --git a/libnitrokey-v3.3/libnitrokey/command.h b/libnitrokey-v3.4/libnitrokey/command.h index 6852bf0..6852bf0 100644 --- a/libnitrokey-v3.3/libnitrokey/command.h +++ b/libnitrokey-v3.4/libnitrokey/command.h diff --git a/libnitrokey-v3.3/libnitrokey/command_id.h b/libnitrokey-v3.4/libnitrokey/command_id.h index 1092ea9..eb0d450 100644 --- a/libnitrokey-v3.3/libnitrokey/command_id.h +++ b/libnitrokey-v3.4/libnitrokey/command_id.h @@ -130,6 +130,8 @@ enum class CommandID : uint8_t { ENABLE_ADMIN_READONLY_ENCRYPTED_LUN = 0x20 + 30, ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN = 0x20 + 31, CHECK_SMARTCARD_USAGE = 0x20 + 32, + //v0.52+ + WINK = 0x20 + 33, GET_PW_SAFE_SLOT_STATUS = 0x60, GET_PW_SAFE_SLOT_NAME = 0x61, diff --git a/libnitrokey-v3.3/libnitrokey/cxx_semantics.h b/libnitrokey-v3.4/libnitrokey/cxx_semantics.h index 36ed142..36ed142 100644 --- a/libnitrokey-v3.3/libnitrokey/cxx_semantics.h +++ b/libnitrokey-v3.4/libnitrokey/cxx_semantics.h diff --git a/libnitrokey-v3.4/libnitrokey/deprecated.h b/libnitrokey-v3.4/libnitrokey/deprecated.h new file mode 100644 index 0000000..5a83288 --- /dev/null +++ b/libnitrokey-v3.4/libnitrokey/deprecated.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018 Nitrokey UG + * + * This file is part of libnitrokey. + * + * libnitrokey is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * libnitrokey is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGPL-3.0 + */ + + +#ifndef LIBNITROKEY_DEPRECATED_H +#define LIBNITROKEY_DEPRECATED_H + +#if defined(__GNUC__) || defined(__clang__) +#define DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: DEPRECATED macro is not defined for this compiler") +#define DEPRECATED +#endif + +#endif //LIBNITROKEY_DEPRECATED_H diff --git a/libnitrokey-v3.3/libnitrokey/device.h b/libnitrokey-v3.4/libnitrokey/device.h index f6d2380..f6d2380 100644 --- a/libnitrokey-v3.3/libnitrokey/device.h +++ b/libnitrokey-v3.4/libnitrokey/device.h diff --git a/libnitrokey-v3.3/libnitrokey/device_proto.h b/libnitrokey-v3.4/libnitrokey/device_proto.h index 45a6c16..45a6c16 100644 --- a/libnitrokey-v3.3/libnitrokey/device_proto.h +++ b/libnitrokey-v3.4/libnitrokey/device_proto.h diff --git a/libnitrokey-v3.3/libnitrokey/dissect.h b/libnitrokey-v3.4/libnitrokey/dissect.h index 690b5b7..690b5b7 100644 --- a/libnitrokey-v3.3/libnitrokey/dissect.h +++ b/libnitrokey-v3.4/libnitrokey/dissect.h diff --git a/libnitrokey-v3.3/libnitrokey/hidapi/hidapi.h b/libnitrokey-v3.4/libnitrokey/hidapi/hidapi.h index e5bc2dc..e5bc2dc 100644 --- a/libnitrokey-v3.3/libnitrokey/hidapi/hidapi.h +++ b/libnitrokey-v3.4/libnitrokey/hidapi/hidapi.h diff --git a/libnitrokey-v3.3/libnitrokey/log.h b/libnitrokey-v3.4/libnitrokey/log.h index 2a64bef..2a64bef 100644 --- a/libnitrokey-v3.3/libnitrokey/log.h +++ b/libnitrokey-v3.4/libnitrokey/log.h diff --git a/libnitrokey-v3.3/libnitrokey/misc.h b/libnitrokey-v3.4/libnitrokey/misc.h index 88254dd..88254dd 100644 --- a/libnitrokey-v3.3/libnitrokey/misc.h +++ b/libnitrokey-v3.4/libnitrokey/misc.h diff --git a/libnitrokey-v3.3/libnitrokey/stick10_commands.h b/libnitrokey-v3.4/libnitrokey/stick10_commands.h index f2ffba2..f2ffba2 100644 --- a/libnitrokey-v3.3/libnitrokey/stick10_commands.h +++ b/libnitrokey-v3.4/libnitrokey/stick10_commands.h diff --git a/libnitrokey-v3.3/libnitrokey/stick10_commands_0.8.h b/libnitrokey-v3.4/libnitrokey/stick10_commands_0.8.h index 9477890..9477890 100644 --- a/libnitrokey-v3.3/libnitrokey/stick10_commands_0.8.h +++ b/libnitrokey-v3.4/libnitrokey/stick10_commands_0.8.h diff --git a/libnitrokey-v3.3/libnitrokey/stick20_commands.h b/libnitrokey-v3.4/libnitrokey/stick20_commands.h index 4b75e6a..7efa1b6 100644 --- a/libnitrokey-v3.3/libnitrokey/stick20_commands.h +++ b/libnitrokey-v3.4/libnitrokey/stick20_commands.h @@ -275,6 +275,12 @@ namespace nitrokey { CommandTransaction; }; + class Wink : Command<CommandID::WINK> { + public: + typedef Transaction<command_id(), struct EmptyPayload, struct EmptyPayload> + CommandTransaction; + }; + class CheckSmartcardUsage : Command<CommandID::CHECK_SMARTCARD_USAGE> { public: typedef Transaction<command_id(), struct EmptyPayload, EmptyPayload> diff --git a/libnitrokey-v3.4/libnitrokey/version.h b/libnitrokey-v3.4/libnitrokey/version.h new file mode 100644 index 0000000..6547af0 --- /dev/null +++ b/libnitrokey-v3.4/libnitrokey/version.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018 Nitrokey UG + * + * This file is part of libnitrokey. + * + * libnitrokey is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * libnitrokey is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGPL-3.0 + */ + +#ifndef LIBNITROKEY_VERSION_H +#define LIBNITROKEY_VERSION_H + +namespace nitrokey { + unsigned int get_major_library_version(); + + unsigned int get_minor_library_version(); + + const char* get_library_version(); +} + +#endif diff --git a/libnitrokey-v3.3/log.cc b/libnitrokey-v3.4/log.cc index 06acee7..06acee7 100644 --- a/libnitrokey-v3.3/log.cc +++ b/libnitrokey-v3.4/log.cc diff --git a/libnitrokey-v3.3/misc.cc b/libnitrokey-v3.4/misc.cc index 59185f3..59185f3 100644 --- a/libnitrokey-v3.3/misc.cc +++ b/libnitrokey-v3.4/misc.cc diff --git a/libnitrokey-v3.4/version.cc.in b/libnitrokey-v3.4/version.cc.in new file mode 100644 index 0000000..0eae647 --- /dev/null +++ b/libnitrokey-v3.4/version.cc.in @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018 Nitrokey UG + * + * This file is part of libnitrokey. + * + * libnitrokey is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * libnitrokey is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libnitrokey. If not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGPL-3.0 + */ + +#include "version.h" + +namespace nitrokey { + unsigned int get_major_library_version() { + return @PROJECT_VERSION_MAJOR@; + } + + unsigned int get_minor_library_version() { + return @PROJECT_VERSION_MINOR@; + } + + const char* get_library_version() { + return "@PROJECT_VERSION_GIT@"; + } +} + @@ -1,11 +1,467 @@ /* automatically generated by rust-bindgen, manually modified */ +/// Use, if no supported device is connected +pub const NK_device_model_NK_DISCONNECTED: NK_device_model = 0; /// Nitrokey Pro. -pub const NK_device_model_NK_PRO: NK_device_model = 0; +pub const NK_device_model_NK_PRO: NK_device_model = 1; /// Nitrokey Storage. -pub const NK_device_model_NK_STORAGE: NK_device_model = 1; +pub const NK_device_model_NK_STORAGE: NK_device_model = 2; /// The Nitrokey device models supported by the API. pub type NK_device_model = u32; +/// Stores the status of a Storage device. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct NK_storage_status { + /// Indicates whether the unencrypted volume is read-only. + pub unencrypted_volume_read_only: bool, + /// Indicates whether the unencrypted volume is active. + pub unencrypted_volume_active: bool, + /// Indicates whether the encrypted volume is read-only. + pub encrypted_volume_read_only: bool, + /// Indicates whether the encrypted volume is active. + pub encrypted_volume_active: bool, + /// Indicates whether the hidden volume is read-only. + pub hidden_volume_read_only: bool, + /// Indicates whether the hidden volume is active. + pub hidden_volume_active: bool, + /// The major firmware version, e. g. 0 in v0.40. + pub firmware_version_major: u8, + /// The minor firmware version, e. g. 40 in v0.40. + pub firmware_version_minor: u8, + /// Indicates whether the firmware is locked. + pub firmware_locked: bool, + /// The serial number of the SD card in the Storage stick. + pub serial_number_sd_card: u32, + /// The serial number of the smart card in the Storage stick. + pub serial_number_smart_card: u32, + /// The number of remaining login attempts for the user PIN. + pub user_retry_count: u8, + /// The number of remaining login attempts for the admin PIN. + pub admin_retry_count: u8, + /// Indicates whether a new SD card was found. + pub new_sd_card_found: bool, + /// Indicates whether the SD card is filled with random characters. + pub filled_with_random: bool, + /// Indicates whether the stick has been initialized by generating + /// the AES keys. + pub stick_initialized: bool, +} +#[test] +fn bindgen_test_layout_NK_storage_status() { + assert_eq!( + ::std::mem::size_of::<NK_storage_status>(), + 28usize, + concat!("Size of: ", stringify!(NK_storage_status)) + ); + assert_eq!( + ::std::mem::align_of::<NK_storage_status>(), + 4usize, + concat!("Alignment of ", stringify!(NK_storage_status)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).unencrypted_volume_read_only as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(unencrypted_volume_read_only) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).unencrypted_volume_active as *const _ + as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(unencrypted_volume_active) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).encrypted_volume_read_only as *const _ + as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(encrypted_volume_read_only) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).encrypted_volume_active as *const _ + as usize + }, + 3usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(encrypted_volume_active) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).hidden_volume_read_only as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(hidden_volume_read_only) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).hidden_volume_active as *const _ as usize + }, + 5usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(hidden_volume_active) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).firmware_version_major as *const _ + as usize + }, + 6usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(firmware_version_major) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).firmware_version_minor as *const _ + as usize + }, + 7usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(firmware_version_minor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).firmware_locked as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(firmware_locked) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).serial_number_sd_card as *const _ as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(serial_number_sd_card) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).serial_number_smart_card as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(serial_number_smart_card) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).user_retry_count as *const _ as usize + }, + 20usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(user_retry_count) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).admin_retry_count as *const _ as usize + }, + 21usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(admin_retry_count) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).new_sd_card_found as *const _ as usize + }, + 22usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(new_sd_card_found) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).filled_with_random as *const _ as usize + }, + 23usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(filled_with_random) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_status>())).stick_initialized as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_status), + "::", + stringify!(stick_initialized) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct NK_storage_ProductionTest { + pub FirmwareVersion_au8: [u8; 2usize], + pub FirmwareVersionInternal_u8: u8, + pub SD_Card_Size_u8: u8, + pub CPU_CardID_u32: u32, + pub SmartCardID_u32: u32, + pub SD_CardID_u32: u32, + pub SC_UserPwRetryCount: u8, + pub SC_AdminPwRetryCount: u8, + pub SD_Card_ManufacturingYear_u8: u8, + pub SD_Card_ManufacturingMonth_u8: u8, + pub SD_Card_OEM_u16: u16, + pub SD_WriteSpeed_u16: u16, + pub SD_Card_Manufacturer_u8: u8, +} +#[test] +fn bindgen_test_layout_NK_storage_ProductionTest() { + assert_eq!( + ::std::mem::size_of::<NK_storage_ProductionTest>(), + 28usize, + concat!("Size of: ", stringify!(NK_storage_ProductionTest)) + ); + assert_eq!( + ::std::mem::align_of::<NK_storage_ProductionTest>(), + 4usize, + concat!("Alignment of ", stringify!(NK_storage_ProductionTest)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).FirmwareVersion_au8 as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(FirmwareVersion_au8) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).FirmwareVersionInternal_u8 + as *const _ as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(FirmwareVersionInternal_u8) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SD_Card_Size_u8 as *const _ + as usize + }, + 3usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SD_Card_Size_u8) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).CPU_CardID_u32 as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(CPU_CardID_u32) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SmartCardID_u32 as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SmartCardID_u32) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SD_CardID_u32 as *const _ as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SD_CardID_u32) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SC_UserPwRetryCount as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SC_UserPwRetryCount) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SC_AdminPwRetryCount as *const _ + as usize + }, + 17usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SC_AdminPwRetryCount) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SD_Card_ManufacturingYear_u8 + as *const _ as usize + }, + 18usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SD_Card_ManufacturingYear_u8) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SD_Card_ManufacturingMonth_u8 + as *const _ as usize + }, + 19usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SD_Card_ManufacturingMonth_u8) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SD_Card_OEM_u16 as *const _ + as usize + }, + 20usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SD_Card_OEM_u16) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SD_WriteSpeed_u16 as *const _ + as usize + }, + 22usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SD_WriteSpeed_u16) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::<NK_storage_ProductionTest>())).SD_Card_Manufacturer_u8 + as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(NK_storage_ProductionTest), + "::", + stringify!(SD_Card_Manufacturer_u8) + ) + ); +} +extern "C" { + pub fn NK_get_storage_production_info( + out: *mut NK_storage_ProductionTest, + ) -> ::std::os::raw::c_int; +} extern "C" { /// Set debug level of messages written on stderr /// @param state state=True - most messages, state=False - only errors level @@ -17,6 +473,24 @@ extern "C" { pub fn NK_set_debug_level(level: ::std::os::raw::c_int); } extern "C" { + /// Get the major library version, e. g. the 3 in v3.2. + /// @return the major library version + pub fn NK_get_major_library_version() -> ::std::os::raw::c_uint; +} +extern "C" { + /// Get the minor library version, e. g. the 2 in v3.2. + /// @return the minor library version + pub fn NK_get_minor_library_version() -> ::std::os::raw::c_uint; +} +extern "C" { + /// Get the library version as a string. This is the output of + /// `git describe --always` at compile time, for example "v3.3" or + /// "v3.3-19-gaee920b". + /// The return value is a string literal and must not be freed. + /// @return the library version as a string + pub fn NK_get_library_version() -> *const ::std::os::raw::c_char; +} +extern "C" { /// Connect to device of given model. Currently library can be connected only to one device at once. /// @param device_model char 'S': Nitrokey Storage, 'P': Nitrokey Pro /// @return 1 if connected, 0 if wrong model or cannot connect @@ -39,14 +513,21 @@ extern "C" { pub fn NK_logout() -> ::std::os::raw::c_int; } extern "C" { + /// Query the model of the connected device. + /// Returns the model of the connected device or NK_DISCONNECTED. + /// + /// @return true if a device is connected and the out argument has been set + pub fn NK_get_device_model() -> NK_device_model; +} +extern "C" { /// Return the debug status string. Debug purposes. /// @return command processing error code - pub fn NK_status() -> *const ::std::os::raw::c_char; + pub fn NK_status() -> *mut ::std::os::raw::c_char; } extern "C" { /// Return the device's serial number string in hex. /// @return string device's serial number in hex - pub fn NK_device_serial_number() -> *const ::std::os::raw::c_char; + pub fn NK_device_serial_number() -> *mut ::std::os::raw::c_char; } extern "C" { /// Get last command processing status. Useful for commands which returns the results of their own and could not return @@ -61,8 +542,8 @@ extern "C" { } extern "C" { /// Authenticates the user on USER privilages with user_password and sets user's temporary password on device to user_temporary_password. - /// @param user_password char[25](Pro) current user password - /// @param user_temporary_password char[25](Pro) user temporary password to be set on device for further communication (authentication command) + /// @param user_password char[25] current user password + /// @param user_temporary_password char[25] user temporary password to be set on device for further communication (authentication command) /// @return command processing error code pub fn NK_user_authenticate( user_password: *const ::std::os::raw::c_char, @@ -71,8 +552,8 @@ extern "C" { } extern "C" { /// Authenticates the user on ADMIN privilages with admin_password and sets user's temporary password on device to admin_temporary_password. - /// @param admin_password char[25](Pro) current administrator PIN - /// @param admin_temporary_password char[25](Pro) admin temporary password to be set on device for further communication (authentication command) + /// @param admin_password char[25] current administrator PIN + /// @param admin_temporary_password char[25] admin temporary password to be set on device for further communication (authentication command) /// @return command processing error code pub fn NK_first_authenticate( admin_password: *const ::std::os::raw::c_char, @@ -81,21 +562,21 @@ extern "C" { } extern "C" { /// Execute a factory reset. - /// @param admin_password char[20](Pro) current administrator PIN + /// @param admin_password char[20] current administrator PIN /// @return command processing error code pub fn NK_factory_reset(admin_password: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } extern "C" { /// Generates AES key on the device - /// @param admin_password char[20](Pro) current administrator PIN + /// @param admin_password char[20] current administrator PIN /// @return command processing error code pub fn NK_build_aes_key(admin_password: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } extern "C" { /// Unlock user PIN locked after 3 incorrect codes tries. - /// @param admin_password char[20](Pro) current administrator PIN + /// @param admin_password char[20] current administrator PIN /// @return command processing error code pub fn NK_unlock_user_password( admin_password: *const ::std::os::raw::c_char, @@ -135,13 +616,13 @@ extern "C" { extern "C" { /// Get name of given TOTP slot /// @param slot_number TOTP slot number, slot_number<15 - /// @return char[20](Pro) the name of the slot - pub fn NK_get_totp_slot_name(slot_number: u8) -> *const ::std::os::raw::c_char; + /// @return char[20] the name of the slot + pub fn NK_get_totp_slot_name(slot_number: u8) -> *mut ::std::os::raw::c_char; } extern "C" { /// @param slot_number HOTP slot number, slot_number<3 - /// @return char[20](Pro) the name of the slot - pub fn NK_get_hotp_slot_name(slot_number: u8) -> *const ::std::os::raw::c_char; + /// @return char[20] the name of the slot + pub fn NK_get_hotp_slot_name(slot_number: u8) -> *mut ::std::os::raw::c_char; } extern "C" { /// Erase HOTP slot data from the device @@ -165,15 +646,16 @@ extern "C" { } extern "C" { /// Write HOTP slot data to the device - /// @param slot_number HOTP slot number, slot_number<3 - /// @param slot_name char[15](Pro) desired slot name - /// @param secret char[20](Pro) 160-bit secret + /// @param slot_number HOTP slot number, slot_number<3, 0-numbered + /// @param slot_name char[15] desired slot name. C string (requires ending '\0'; 16 bytes). + /// @param secret char[40] 160-bit or 320-bit (currently Pro v0.8 only) secret as a hex string. C string (requires ending '\0'; 41 bytes). + /// See NitrokeyManager::is_320_OTP_secret_supported. /// @param hotp_counter uint32_t starting value of HOTP counter /// @param use_8_digits should returned codes be 6 (false) or 8 digits (true) /// @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock /// @param use_tokenID @see token_ID /// @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section - /// @param temporary_password char[25](Pro) admin temporary password + /// @param temporary_password char[25] admin temporary password /// @return command processing error code pub fn NK_write_hotp_slot( slot_number: u8, @@ -189,15 +671,16 @@ extern "C" { } extern "C" { /// Write TOTP slot data to the device - /// @param slot_number TOTP slot number, slot_number<15 - /// @param slot_name char[15](Pro) desired slot name - /// @param secret char[20](Pro) 160-bit secret + /// @param slot_number TOTP slot number, slot_number<15, 0-numbered + /// @param slot_name char[15] desired slot name. C string (requires ending '\0'; 16 bytes). + /// @param secret char[40] 160-bit or 320-bit (currently Pro v0.8 only) secret as a hex string. C string (requires ending '\0'; 41 bytes). + /// See NitrokeyManager::is_320_OTP_secret_supported. /// @param time_window uint16_t time window for this TOTP /// @param use_8_digits should returned codes be 6 (false) or 8 digits (true) /// @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock /// @param use_tokenID @see token_ID /// @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section - /// @param temporary_password char[20](Pro) admin temporary password + /// @param temporary_password char[20] admin temporary password /// @return command processing error code pub fn NK_write_totp_slot( slot_number: u8, @@ -215,40 +698,40 @@ extern "C" { /// Get HOTP code from the device /// @param slot_number HOTP slot number, slot_number<3 /// @return HOTP code - pub fn NK_get_hotp_code(slot_number: u8) -> *const ::std::os::raw::c_char; + pub fn NK_get_hotp_code(slot_number: u8) -> *mut ::std::os::raw::c_char; } extern "C" { /// Get HOTP code from the device (PIN protected) /// @param slot_number HOTP slot number, slot_number<3 - /// @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, + /// @param user_temporary_password char[25] user temporary password if PIN protected OTP codes are enabled, /// otherwise should be set to empty string - '' /// @return HOTP code pub fn NK_get_hotp_code_PIN( slot_number: u8, user_temporary_password: *const ::std::os::raw::c_char, - ) -> *const ::std::os::raw::c_char; + ) -> *mut ::std::os::raw::c_char; } extern "C" { /// Get TOTP code from the device /// @param slot_number TOTP slot number, slot_number<15 - /// @param challenge TOTP challenge - /// @param last_totp_time last time - /// @param last_interval last interval + /// @param challenge TOTP challenge -- unused + /// @param last_totp_time last time -- unused + /// @param last_interval last interval --unused /// @return TOTP code pub fn NK_get_totp_code( slot_number: u8, challenge: u64, last_totp_time: u64, last_interval: u8, - ) -> *const ::std::os::raw::c_char; + ) -> *mut ::std::os::raw::c_char; } extern "C" { /// Get TOTP code from the device (PIN protected) /// @param slot_number TOTP slot number, slot_number<15 - /// @param challenge TOTP challenge - /// @param last_totp_time last time - /// @param last_interval last interval - /// @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, + /// @param challenge TOTP challenge -- unused + /// @param last_totp_time last time -- unused + /// @param last_interval last interval -- unused + /// @param user_temporary_password char[25] user temporary password if PIN protected OTP codes are enabled, /// otherwise should be set to empty string - '' /// @return TOTP code pub fn NK_get_totp_code_PIN( @@ -257,7 +740,7 @@ extern "C" { last_totp_time: u64, last_interval: u8, user_temporary_password: *const ::std::os::raw::c_char, - ) -> *const ::std::os::raw::c_char; + ) -> *mut ::std::os::raw::c_char; } extern "C" { /// Set time on the device (for TOTP requests) @@ -266,12 +749,23 @@ extern "C" { pub fn NK_totp_set_time(time: u64) -> ::std::os::raw::c_int; } extern "C" { + /// Set the device time used for TOTP to the given time. Contrary to + /// {@code set_time(uint64_t)}, this command fails if {@code old_time} + /// > {@code time} or if {@code old_time} is zero (where {@code + /// old_time} is the current time on the device). + /// + /// @param time new device time as Unix timestamp (seconds since + /// 1970-01-01) + /// @return command processing error code + pub fn NK_totp_set_time_soft(time: u64) -> ::std::os::raw::c_int; +} +extern "C" { pub fn NK_totp_get_time() -> ::std::os::raw::c_int; } extern "C" { /// Change administrator PIN - /// @param current_PIN char[25](Pro) current PIN - /// @param new_PIN char[25](Pro) new PIN + /// @param current_PIN char[25] current PIN + /// @param new_PIN char[25] new PIN /// @return command processing error code pub fn NK_change_admin_PIN( current_PIN: *const ::std::os::raw::c_char, @@ -280,8 +774,8 @@ extern "C" { } extern "C" { /// Change user PIN - /// @param current_PIN char[25](Pro) current PIN - /// @param new_PIN char[25](Pro) new PIN + /// @param current_PIN char[25] current PIN + /// @param new_PIN char[25] new PIN /// @return command processing error code pub fn NK_change_user_PIN( current_PIN: *const ::std::os::raw::c_char, @@ -300,7 +794,7 @@ extern "C" { } extern "C" { /// Enable password safe access - /// @param user_pin char[30](Pro) current user PIN + /// @param user_pin char[30] current user PIN /// @return command processing error code pub fn NK_enable_password_safe( user_pin: *const ::std::os::raw::c_char, @@ -315,26 +809,26 @@ extern "C" { /// Get password safe slot name /// @param slot_number password safe slot number, slot_number<16 /// @return slot name - pub fn NK_get_password_safe_slot_name(slot_number: u8) -> *const ::std::os::raw::c_char; + pub fn NK_get_password_safe_slot_name(slot_number: u8) -> *mut ::std::os::raw::c_char; } extern "C" { /// Get password safe slot login /// @param slot_number password safe slot number, slot_number<16 /// @return login from the PWS slot - pub fn NK_get_password_safe_slot_login(slot_number: u8) -> *const ::std::os::raw::c_char; + pub fn NK_get_password_safe_slot_login(slot_number: u8) -> *mut ::std::os::raw::c_char; } extern "C" { /// Get the password safe slot password /// @param slot_number password safe slot number, slot_number<16 /// @return password from the PWS slot - pub fn NK_get_password_safe_slot_password(slot_number: u8) -> *const ::std::os::raw::c_char; + pub fn NK_get_password_safe_slot_password(slot_number: u8) -> *mut ::std::os::raw::c_char; } extern "C" { /// Write password safe data to the slot /// @param slot_number password safe slot number, slot_number<16 - /// @param slot_name char[11](Pro) name of the slot - /// @param slot_login char[32](Pro) login string - /// @param slot_password char[20](Pro) password string + /// @param slot_name char[11] name of the slot + /// @param slot_login char[32] login string + /// @param slot_password char[20] password string /// @return command processing error code pub fn NK_write_password_safe_slot( slot_number: u8, @@ -561,14 +1055,24 @@ extern "C" { /// Get Storage stick status as string. /// Storage only /// @return string with devices attributes - pub fn NK_get_status_storage_as_string() -> *const ::std::os::raw::c_char; + pub fn NK_get_status_storage_as_string() -> *mut ::std::os::raw::c_char; +} +extern "C" { + /// Get the Storage stick status and return the command processing + /// error code. If the code is zero, i. e. the command was successful, + /// the storage status is written to the output pointer's target. + /// The output pointer must not be null. + /// + /// @param out the output pointer for the storage status + /// @return command processing error code + pub fn NK_get_status_storage(out: *mut NK_storage_status) -> ::std::os::raw::c_int; } extern "C" { /// Get SD card usage attributes as string. /// Usable during hidden volumes creation. /// Storage only /// @return string with SD card usage attributes - pub fn NK_get_SD_usage_data_as_string() -> *const ::std::os::raw::c_char; + pub fn NK_get_SD_usage_data_as_string() -> *mut ::std::os::raw::c_char; } extern "C" { /// Get progress value of current long operation. @@ -590,7 +1094,7 @@ extern "C" { /// Storage only /// @example Example of returned data: '00005d19:dacc2cb4_p_0001:0010:02;000037c7:4cf12445_p_0001:000f:02;0001:000c:02' /// @return string delimited id's of connected devices - pub fn NK_list_devices_by_cpuID() -> *const ::std::os::raw::c_char; + pub fn NK_list_devices_by_cpuID() -> *mut ::std::os::raw::c_char; } extern "C" { /// Connects to the device with given ID. ID's list could be created with NK_list_devices_by_cpuID. @@ -601,3 +1105,8 @@ extern "C" { /// @return 1 on successful connection, 0 otherwise pub fn NK_connect_with_ID(id: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } +extern "C" { + /// Blink red and green LED alternatively and infinitely (until device is reconnected). + /// @return command processing error code + pub fn NK_wink() -> ::std::os::raw::c_int; +} |