aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-09-19 23:05:35 +0200
committerRobin Krahl <robin.krahl@ireas.org>2020-09-20 11:59:36 +0200
commit56eb89dcf5f7d2c3b4ea92490a3b4df6f85713c0 (patch)
treed07b62514704b71b89bd176ea438c84641bff9b1
parent655b823d13acbb71bb1496df29a9008e1b0ee9a2 (diff)
downloadnitrokey-sys-rs-56eb89dcf5f7d2c3b4ea92490a3b4df6f85713c0.tar.gz
nitrokey-sys-rs-56eb89dcf5f7d2c3b4ea92490a3b4df6f85713c0.tar.bz2
Update to libnitrokey v3.6
This patch updates libnitrokey from version 3.5 to version 3.6, causing these changes: - New constants: - `NK_device_model_NK_LIBREM` (`NK_device_model` enum) - New structures: - `NK_config` - New functions: - `NK_device_serial_number_as_u32` - `NK_write_config_struct` - `NK_free_config` - `NK_read_config_struct` - `NK_free_password_safe_slot_status` - Deprecated functions: - `NK_set_unencrypted_read_only` - `NK_set_unencrypted_read_write`
-rw-r--r--CHANGELOG.md14
-rw-r--r--build.rs2
-rw-r--r--libnitrokey-v3.6/DeviceCommunicationExceptions.cpp (renamed from libnitrokey-v3.5/DeviceCommunicationExceptions.cpp)0
-rw-r--r--libnitrokey-v3.6/LICENSE (renamed from libnitrokey-v3.5/LICENSE)0
-rw-r--r--libnitrokey-v3.6/NK_C_API.cc (renamed from libnitrokey-v3.5/NK_C_API.cc)51
-rw-r--r--libnitrokey-v3.6/NK_C_API.h (renamed from libnitrokey-v3.5/NK_C_API.h)84
-rw-r--r--libnitrokey-v3.6/NitrokeyManager.cc (renamed from libnitrokey-v3.5/NitrokeyManager.cc)48
-rw-r--r--libnitrokey-v3.6/README.md (renamed from libnitrokey-v3.5/README.md)83
-rw-r--r--libnitrokey-v3.6/command_id.cc (renamed from libnitrokey-v3.5/command_id.cc)3
-rw-r--r--libnitrokey-v3.6/device.cc (renamed from libnitrokey-v3.5/device.cc)84
-rw-r--r--libnitrokey-v3.6/libnitrokey/CommandFailedException.h (renamed from libnitrokey-v3.5/libnitrokey/CommandFailedException.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/DeviceCommunicationExceptions.h (renamed from libnitrokey-v3.5/libnitrokey/DeviceCommunicationExceptions.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/LibraryException.h (renamed from libnitrokey-v3.5/libnitrokey/LibraryException.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/LongOperationInProgressException.h (renamed from libnitrokey-v3.5/libnitrokey/LongOperationInProgressException.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/NitrokeyManager.h (renamed from libnitrokey-v3.5/libnitrokey/NitrokeyManager.h)3
-rw-r--r--libnitrokey-v3.6/libnitrokey/command.h (renamed from libnitrokey-v3.5/libnitrokey/command.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/command_id.h (renamed from libnitrokey-v3.5/libnitrokey/command_id.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/cxx_semantics.h (renamed from libnitrokey-v3.5/libnitrokey/cxx_semantics.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/deprecated.h (renamed from libnitrokey-v3.5/libnitrokey/deprecated.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/device.h (renamed from libnitrokey-v3.5/libnitrokey/device.h)18
-rw-r--r--libnitrokey-v3.6/libnitrokey/device_proto.h (renamed from libnitrokey-v3.5/libnitrokey/device_proto.h)2
-rw-r--r--libnitrokey-v3.6/libnitrokey/dissect.h (renamed from libnitrokey-v3.5/libnitrokey/dissect.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/hidapi/hidapi.h (renamed from libnitrokey-v3.5/libnitrokey/hidapi/hidapi.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/log.h (renamed from libnitrokey-v3.5/libnitrokey/log.h)1
-rw-r--r--libnitrokey-v3.6/libnitrokey/misc.h (renamed from libnitrokey-v3.5/libnitrokey/misc.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/stick10_commands.h (renamed from libnitrokey-v3.5/libnitrokey/stick10_commands.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/stick10_commands_0.8.h (renamed from libnitrokey-v3.5/libnitrokey/stick10_commands_0.8.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/stick20_commands.h (renamed from libnitrokey-v3.5/libnitrokey/stick20_commands.h)0
-rw-r--r--libnitrokey-v3.6/libnitrokey/version.h (renamed from libnitrokey-v3.5/libnitrokey/version.h)0
-rw-r--r--libnitrokey-v3.6/log.cc (renamed from libnitrokey-v3.5/log.cc)0
-rw-r--r--libnitrokey-v3.6/misc.cc (renamed from libnitrokey-v3.5/misc.cc)0
-rw-r--r--libnitrokey-v3.6/version.cc (renamed from libnitrokey-v3.5/version.cc)0
-rw-r--r--libnitrokey-v3.6/version.cc.in (renamed from libnitrokey-v3.5/version.cc.in)0
-rw-r--r--patches/deprecated.diff20
-rw-r--r--src/ffi.rs122
35 files changed, 498 insertions, 37 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6480c5f..af7fb18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,20 @@
- Derive `Debug` for all structs generated by `bindgen`.
- Implement `std::fmt::Display` instead of `std::string::ToString` for the
`Version` enum in `build.rs`.
+- Update to libnitrokey 3.6, causing all following changes.
+- New constants:
+ - `NK_device_model_NK_LIBREM` (`NK_device_model` enum)
+- New structures:
+ - `NK_config`
+- New functions:
+ - `NK_device_serial_number_as_u32`
+ - `NK_write_config_struct`
+ - `NK_free_config`
+ - `NK_read_config_struct`
+ - `NK_free_password_safe_slot_status`
+- Deprecated functions:
+ - `NK_set_unencrypted_read_only`
+ - `NK_set_unencrypted_read_write`
# v3.5.0 (2019-07-04)
- Mark deprecated functions using the `deprecated` attribute.
diff --git a/build.rs b/build.rs
index 24fdf0a..a6ae9fc 100644
--- a/build.rs
+++ b/build.rs
@@ -26,7 +26,7 @@ impl fmt::Display for Version {
const LIBNITROKEY_VERSION: Version = Version {
major: 3,
- minor: 5,
+ minor: 6,
patch: None,
};
diff --git a/libnitrokey-v3.5/DeviceCommunicationExceptions.cpp b/libnitrokey-v3.6/DeviceCommunicationExceptions.cpp
index 4d62aad..4d62aad 100644
--- a/libnitrokey-v3.5/DeviceCommunicationExceptions.cpp
+++ b/libnitrokey-v3.6/DeviceCommunicationExceptions.cpp
diff --git a/libnitrokey-v3.5/LICENSE b/libnitrokey-v3.6/LICENSE
index 341c30b..341c30b 100644
--- a/libnitrokey-v3.5/LICENSE
+++ b/libnitrokey-v3.6/LICENSE
diff --git a/libnitrokey-v3.5/NK_C_API.cc b/libnitrokey-v3.6/NK_C_API.cc
index 1d3fa3a..c84e402 100644
--- a/libnitrokey-v3.5/NK_C_API.cc
+++ b/libnitrokey-v3.6/NK_C_API.cc
@@ -158,6 +158,9 @@ extern "C" {
case NK_STORAGE:
model_string = "S";
break;
+ case NK_LIBREM:
+ model_string = "L";
+ break;
case NK_DISCONNECTED:
default:
/* no such enum value -- return error code */
@@ -217,6 +220,12 @@ extern "C" {
});
}
+ NK_C_API int NK_write_config_struct(struct NK_config config,
+ const char *admin_temporary_password) {
+ return NK_write_config(config.numlock, config.capslock, config.scrolllock, config.enable_user_password,
+ config.disable_user_password, admin_temporary_password);
+ }
+
NK_C_API uint8_t* NK_read_config() {
auto m = NitrokeyManager::instance();
@@ -226,6 +235,25 @@ extern "C" {
});
}
+ NK_C_API void NK_free_config(uint8_t* config) {
+ delete[] config;
+ }
+
+ NK_C_API int NK_read_config_struct(struct NK_config* out) {
+ if (out == nullptr) {
+ return -1;
+ }
+ auto m = NitrokeyManager::instance();
+ return get_without_result([&]() {
+ auto v = m->read_config();
+ out->numlock = v[0];
+ out->capslock = v[1];
+ out->scrolllock = v[2];
+ out->enable_user_password = v[3];
+ out->disable_user_password = v[4];
+ });
+ }
+
NK_C_API enum NK_device_model NK_get_device_model() {
auto m = NitrokeyManager::instance();
@@ -236,6 +264,8 @@ extern "C" {
return NK_PRO;
case DeviceModel::STORAGE:
return NK_STORAGE;
+ case DeviceModel::LIBREM:
+ return NK_LIBREM;
default:
/* unknown or not connected device */
return NK_device_model::NK_DISCONNECTED;
@@ -299,6 +329,13 @@ extern "C" {
});
}
+ NK_C_API uint32_t NK_device_serial_number_as_u32() {
+ auto m = NitrokeyManager::instance();
+ return get_with_result([&]() {
+ return m->get_serial_number_as_u32();
+ });
+ }
+
NK_C_API char * NK_get_hotp_code(uint8_t slot_number) {
return NK_get_hotp_code_PIN(slot_number, "");
}
@@ -448,6 +485,10 @@ extern "C" {
}
+ NK_C_API void NK_free_password_safe_slot_status(uint8_t* status) {
+ delete[] status;
+ }
+
NK_C_API uint8_t NK_get_user_retry_count() {
auto m = NitrokeyManager::instance();
return get_with_result([&]() {
@@ -563,6 +604,9 @@ extern "C" {
});
}
+ // deprecated, noop on v0.51 and older (excl. v0.49)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
NK_C_API int NK_set_unencrypted_read_only(const char *user_pin) {
auto m = NitrokeyManager::instance();
return get_without_result([&]() {
@@ -570,12 +614,14 @@ extern "C" {
});
}
- NK_C_API int NK_set_unencrypted_read_write(const char *user_pin) {
+ // deprecated, noop on v0.51 and older (excl. v0.49)
+ NK_C_API int NK_set_unencrypted_read_write(const char *user_pin) {
auto m = NitrokeyManager::instance();
return get_without_result([&]() {
m->set_unencrypted_read_write(user_pin);
});
}
+#pragma GCC diagnostic pop
NK_C_API int NK_set_unencrypted_read_only_admin(const char *admin_pin) {
auto m = NitrokeyManager::instance();
@@ -791,6 +837,9 @@ NK_C_API char* NK_get_SD_usage_data_as_string() {
case DeviceModel::STORAGE:
target->model = NK_STORAGE;
break;
+ case DeviceModel::LIBREM:
+ target->model = NK_LIBREM;
+ break;
default:
return false;
}
diff --git a/libnitrokey-v3.5/NK_C_API.h b/libnitrokey-v3.6/NK_C_API.h
index d5c54a3..68fb56c 100644
--- a/libnitrokey-v3.5/NK_C_API.h
+++ b/libnitrokey-v3.6/NK_C_API.h
@@ -67,6 +67,9 @@
* case NK_STORAGE:
* printf("a Nitrokey Storage");
* break;
+ * case NK_LIBREM:
+ * printf("a Librem Key");
+ * break;
* default:
* printf("an unsupported Nitrokey");
* break;
@@ -111,7 +114,11 @@ extern "C" {
/**
* Nitrokey Storage.
*/
- NK_STORAGE = 2
+ NK_STORAGE = 2,
+ /**
+ * Librem Key.
+ */
+ NK_LIBREM = 3
};
/**
@@ -265,6 +272,32 @@ extern "C" {
uint8_t write_level_max;
};
+ /**
+ * The general configuration of a Nitrokey device.
+ */
+ struct NK_config {
+ /**
+ * value in range [0-1] to send HOTP code from slot 'numlock' after double pressing numlock
+ * or outside the range to disable this function
+ */
+ uint8_t numlock;
+ /**
+ * similar to numlock but with capslock
+ */
+ uint8_t capslock;
+ /**
+ * similar to numlock but with scrolllock
+ */
+ uint8_t scrolllock;
+ /**
+ * True to enable OTP PIN protection (require PIN each OTP code request)
+ */
+ bool enable_user_password;
+ /**
+ * Unused.
+ */
+ bool disable_user_password;
+ };
struct NK_storage_ProductionTest{
uint8_t FirmwareVersion_au8[2];
@@ -327,7 +360,7 @@ extern "C" {
/**
* Connect to device of given model. Currently library can be connected only to one device at once.
- * @param device_model NK_device_model: NK_PRO: Nitrokey Pro, NK_STORAGE: Nitrokey Storage
+ * @param device_model NK_device_model: NK_PRO: Nitrokey Pro, NK_STORAGE: Nitrokey Storage, NK_LIBREM: Librem Key
* @return 1 if connected, 0 if wrong model or cannot connect
*/
NK_C_API int NK_login_enum(enum NK_device_model device_model);
@@ -386,6 +419,14 @@ extern "C" {
NK_C_API char * NK_device_serial_number();
/**
+ * Return the device's serial number string as an integer. Use
+ * NK_last_command_status to check for an error if this function
+ * returns zero.
+ * @return device's serial number as an integer
+ */
+ NK_C_API uint32_t NK_device_serial_number_as_u32();
+
+ /**
* Get last command processing status. Useful for commands which returns the results of their own and could not return
* an error code.
* @return previous command processing error code
@@ -450,7 +491,16 @@ extern "C" {
bool enable_user_password, bool delete_user_password, const char *admin_temporary_password);
/**
+ * Write general config to the device
+ * @param config the configuration data
+ * @param admin_temporary_password current admin temporary password
+ * @return command processing error code
+ */
+ NK_C_API int NK_write_config_struct(struct NK_config config, const char *admin_temporary_password);
+
+ /**
* Get currently set config - status of function Numlock/Capslock/Scrollock OTP sending and is enabled PIN protected OTP
+ * The return value must be freed using NK_free_config.
* @see NK_write_config
* @return uint8_t general_config[5]:
* uint8_t numlock;
@@ -462,6 +512,21 @@ extern "C" {
*/
NK_C_API uint8_t* NK_read_config();
+ /**
+ * Free a value returned by NK_read_config. May be called with a NULL
+ * argument.
+ */
+ NK_C_API void NK_free_config(uint8_t* config);
+
+ /**
+ * Get currently set config and write it to the given pointer.
+ * @see NK_read_config
+ * @see NK_write_config_struct
+ * @param out a pointer to the struct that should be written to
+ * @return command processing error code
+ */
+ NK_C_API int NK_read_config_struct(struct NK_config* out);
+
//OTP
/**
@@ -634,10 +699,17 @@ extern "C" {
/**
* Get password safe slots' status
+ * The return value must be freed using NK_free_password_safe_slot_status.
* @return uint8_t[16] slot statuses - each byte represents one slot with 0 (not programmed) and 1 (programmed)
*/
NK_C_API uint8_t * NK_get_password_safe_slot_status();
+ /**
+ * Free a value returned by NK_get_password_safe_slot_status. May be
+ * called with a NULL argument.
+ */
+ NK_C_API void NK_free_password_safe_slot_status(uint8_t* status);
+
/**
* Get password safe slot name
* @param slot_number password safe slot number, slot_number<16
@@ -765,7 +837,9 @@ extern "C" {
* @param user_pin 20 characters User PIN
* @return command processing error code
*/
- NK_C_API int NK_set_unencrypted_read_only(const char *user_pin);
+ //[[deprecated("Use NK_set_unencrypted_read_only_admin instead")]]
+ DEPRECATED
+ NK_C_API int NK_set_unencrypted_read_only(const char *user_pin);
/**
* Make unencrypted volume read-write.
@@ -777,7 +851,9 @@ extern "C" {
* @param user_pin 20 characters User PIN
* @return command processing error code
*/
- NK_C_API int NK_set_unencrypted_read_write(const char *user_pin);
+ //[[deprecated("Use NK_set_unencrypted_read_write_admin instead")]]
+ DEPRECATED
+ NK_C_API int NK_set_unencrypted_read_write(const char *user_pin);
/**
* Make unencrypted volume read-only.
diff --git a/libnitrokey-v3.5/NitrokeyManager.cc b/libnitrokey-v3.6/NitrokeyManager.cc
index 6c26a43..329d155 100644
--- a/libnitrokey-v3.5/NitrokeyManager.cc
+++ b/libnitrokey-v3.6/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<DeviceModel> 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(info_ptr->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<std::mutex> lock(mex_dev_com_manager);
- vector< shared_ptr<Device> > devices = { make_shared<Stick10>(), make_shared<Stick20>() };
+ vector< shared_ptr<Device> > devices = { make_shared<Stick10>(), make_shared<Stick20>(),
+ make_shared<LibremKey>() };
bool connected = false;
for( auto & d : devices ){
if (d->connect()){
@@ -290,6 +296,9 @@ using nitrokey::misc::strcpyT;
case 'S':
device = make_shared<Stick20>();
break;
+ case 'L':
+ device = make_shared<LibremKey>();
+ 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");
}
@@ -380,22 +392,36 @@ using nitrokey::misc::strcpyT;
string NitrokeyManager::get_serial_number() {
- if (device == nullptr) { return ""; };
+ try {
+ auto serial_number = this->get_serial_number_as_u32();
+ if (serial_number == 0) {
+ return "NA";
+ } else {
+ return nitrokey::misc::toHex(serial_number);
+ }
+ } catch (DeviceNotConnected& e) {
+ return "";
+ }
+ }
+
+ uint32_t NitrokeyManager::get_serial_number_as_u32() {
+ if (device == nullptr) { throw DeviceNotConnected("device not connected"); }
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);
+ return response.data().card_serial_u32;
}
break;
case DeviceModel::STORAGE:
{
auto response = stick20::GetDeviceStatus::CommandTransaction::run(device);
- return nitrokey::misc::toHex(response.data().ActiveSmartCardID_u32);
+ return response.data().ActiveSmartCardID_u32;
}
break;
}
- return "NA";
+ return 0;
}
stick10::GetStatus::ResponsePayload NitrokeyManager::get_status(){
@@ -552,6 +578,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 +740,7 @@ using nitrokey::misc::strcpyT;
template <typename ProCommand, PasswordKind StoKind>
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<ProCommand>();
@@ -834,6 +862,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<BuildAESKey>();
strcpyT(p.admin_password, admin_password);
@@ -858,6 +887,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<stick10::UnlockUserPassword>();
strcpyT(p.admin_password, admin_password);
@@ -907,6 +937,7 @@ using nitrokey::misc::strcpyT;
//authorization command is supported for versions equal or below:
auto m = std::unordered_map<DeviceModel , int, EnumClassHash>({
{DeviceModel::PRO, 7},
+ {DeviceModel::LIBREM, 7},
{DeviceModel::STORAGE, 53},
});
return get_minor_firmware_version() <= m[device->get_device_model()];
@@ -916,6 +947,7 @@ using nitrokey::misc::strcpyT;
// 320 bit OTP secret is supported by version bigger or equal to:
auto m = std::unordered_map<DeviceModel , int, EnumClassHash>({
{DeviceModel::PRO, 8},
+ {DeviceModel::LIBREM, 8},
{DeviceModel::STORAGE, 54},
});
return get_minor_firmware_version() >= m[device->get_device_model()];
@@ -940,6 +972,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 +989,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
diff --git a/libnitrokey-v3.5/README.md b/libnitrokey-v3.6/README.md
index a3683c0..aa5ca1a 100644
--- a/libnitrokey-v3.5/README.md
+++ b/libnitrokey-v3.6/README.md
@@ -91,6 +91,7 @@ To use libnitrokey with Python a [CFFI](http://cffi.readthedocs.io/en/latest/ove
pip install --user cffi # for python 2.x
pip3 install cffi # for python 3.x
```
+## Python2
Just import it, read the C API header and it is done! You have access to the library. Here is an example (in Python 2) printing HOTP code for Pro or Storage device, assuming it is run in root directory [(full example)](python_bindings_example.py):
```python
#!/usr/bin/env python2
@@ -158,6 +159,88 @@ print('Getting HOTP code from Nitrokey device: ')
print(hotp_slot_code)
libnitrokey.NK_logout() # disconnect device
```
+In case no devices are connected, a friendly message will be printed.
+All available functions for C and Python are listed in [NK_C_API.h](NK_C_API.h). Please check `Documentation` section below.
+
+## Python3
+Just import it, read the C API header and it is done! You have access to the library. Here is an example (in Python 3) printing HOTP code for Pro or Storage device, assuming it is run in root directory [(full example)](python3_bindings_example.py):
+```python
+#!/usr/bin/env python3
+import cffi
+
+ffi = cffi.FFI()
+get_string = ffi.string
+
+def get_library():
+ fp = 'NK_C_API.h' # path to C API header
+
+ declarations = []
+ with open(fp, 'r') as f:
+ declarations = f.readlines()
+
+ cnt = 0
+ a = iter(declarations)
+ for declaration in a:
+ if declaration.strip().startswith('NK_C_API'):
+ declaration = declaration.replace('NK_C_API', '').strip()
+ while ';' not in declaration:
+ declaration += (next(a)).strip()
+ # print(declaration)
+ ffi.cdef(declaration, override=True)
+ cnt +=1
+ print('Imported {} declarations'.format(cnt))
+
+
+ C = None
+ import os, sys
+ path_build = os.path.join(".", "build")
+ paths = [
+ os.environ.get('LIBNK_PATH', None),
+ os.path.join(path_build,"libnitrokey.so"),
+ os.path.join(path_build,"libnitrokey.dylib"),
+ os.path.join(path_build,"libnitrokey.dll"),
+ os.path.join(path_build,"nitrokey.dll"),
+ ]
+ for p in paths:
+ if not p: continue
+ print("Trying " +p)
+ p = os.path.abspath(p)
+ if os.path.exists(p):
+ print("Found: "+p)
+ C = ffi.dlopen(p)
+ break
+ else:
+ print("File does not exist: " + p)
+ if not C:
+ print("No library file found")
+ sys.exit(1)
+
+ return C
+
+
+def get_hotp_code(lib, i):
+ return lib.NK_get_hotp_code(i)
+
+def connect_device(lib):
+ # lib.NK_login('S'.encode('ascii')) # connect only to Nitrokey Storage device
+ # lib.NK_login('P'.encode('ascii')) # connect only to Nitrokey Pro device
+ device_connected = lib.NK_login_auto() # connect to any Nitrokey Stick
+ if device_connected:
+ print('Connected to Nitrokey device!')
+ else:
+ print('Could not connect to Nitrokey device!')
+ exit()
+
+libnitrokey = get_library()
+libnitrokey.NK_set_debug(False) # do not show debug messages (log library only)
+
+connect_device(libnitrokey)
+
+hotp_slot_code = get_hotp_code(libnitrokey, 1)
+print('Getting HOTP code from Nitrokey device: ')
+print(ffi.string(hotp_slot_code).decode('ascii'))
+libnitrokey.NK_logout() # disconnect device
+```
In case no devices are connected, a friendly message will be printed.
All available functions for C and Python are listed in [NK_C_API.h](NK_C_API.h). Please check `Documentation` section below.
diff --git a/libnitrokey-v3.5/command_id.cc b/libnitrokey-v3.6/command_id.cc
index 9a329bc..90f300f 100644
--- a/libnitrokey-v3.5/command_id.cc
+++ b/libnitrokey-v3.6/command_id.cc
@@ -26,6 +26,9 @@ namespace nitrokey {
namespace proto {
const char *commandid_to_string(CommandID id) {
+#ifdef NO_LOG
+ return "";
+#endif
switch (id) {
case CommandID::GET_STATUS:
return "GET_STATUS";
diff --git a/libnitrokey-v3.5/device.cc b/libnitrokey-v3.6/device.cc
index bc42965..1204c1e 100644
--- a/libnitrokey-v3.5/device.cc
+++ b/libnitrokey-v3.6/device.cc
@@ -45,14 +45,33 @@ const uint16_t nitrokey::device::NITROKEY_VID = 0x20a0;
const uint16_t nitrokey::device::NITROKEY_PRO_PID = 0x4108;
const uint16_t nitrokey::device::NITROKEY_STORAGE_PID = 0x4109;
+const uint16_t nitrokey::device::PURISM_VID = 0x316d;
+const uint16_t nitrokey::device::LIBREM_KEY_PID = 0x4c4b;
+
Option<DeviceModel> nitrokey::device::product_id_to_model(uint16_t product_id) {
- switch (product_id) {
+ return product_id_to_model(NITROKEY_VID, product_id);
+}
+
+Option<DeviceModel> nitrokey::device::product_id_to_model(uint16_t vendor_id, uint16_t product_id) {
+ switch (vendor_id) {
+ case NITROKEY_VID:
+ switch (product_id) {
case NITROKEY_PRO_PID:
return DeviceModel::PRO;
case NITROKEY_STORAGE_PID:
return DeviceModel::STORAGE;
default:
return {};
+ }
+ case PURISM_VID:
+ switch (product_id) {
+ case LIBREM_KEY_PID:
+ return DeviceModel::LIBREM;
+ default:
+ return {};
+ }
+ default:
+ return {};
}
}
@@ -67,6 +86,9 @@ std::ostream& nitrokey::device::operator<<(std::ostream& stream, DeviceModel mod
case DeviceModel::STORAGE:
stream << "Storage";
break;
+ case DeviceModel::LIBREM:
+ stream << "Librem";
+ break;
default:
stream << "Unknown";
break;
@@ -99,7 +121,9 @@ bool Device::disconnect() {
}
bool Device::_disconnect() {
- LOG(std::string(__FUNCTION__) + std::string(m_model == DeviceModel::PRO ? "PRO" : "STORAGE"), Loglevel::DEBUG_L2);
+ LOG(std::string(__FUNCTION__) +
+ std::string(m_model == DeviceModel::PRO ? "PRO" : (m_model == DeviceModel::STORAGE ? "STORAGE" : "LIBREM")),
+ Loglevel::DEBUG_L2);
LOG(std::string(__FUNCTION__) + std::string(" *IN* "), Loglevel::DEBUG_L2);
if(mp_devhandle == nullptr) {
@@ -204,27 +228,36 @@ int Device::recv(void *packet) {
return status;
}
-std::vector<DeviceInfo> Device::enumerate(){
- auto pInfo = hid_enumerate(NITROKEY_VID, 0);
- auto pInfo_ = pInfo;
- std::vector<DeviceInfo> res;
- while (pInfo != nullptr){
- auto deviceModel = product_id_to_model(pInfo->product_id);
- if (deviceModel.has_value()) {
- std::string path(pInfo->path);
- std::wstring serialNumberW(pInfo->serial_number);
- std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
- std::string serialNumber = converter.to_bytes(serialNumberW);
- DeviceInfo info = { deviceModel.value(), path, serialNumber };
- res.push_back(info);
+namespace {
+ void add_vendor_devices(std::vector<DeviceInfo>& res, uint16_t vendor_id){
+ auto pInfo = hid_enumerate(vendor_id, 0);
+ auto pInfo_ = pInfo;
+ while (pInfo != nullptr){
+ if (pInfo->path == nullptr || pInfo->serial_number == nullptr) {
+ continue;
+ }
+ auto deviceModel = product_id_to_model(vendor_id, pInfo->product_id);
+ if (deviceModel.has_value()) {
+ std::string path(pInfo->path);
+ std::wstring serialNumberW(pInfo->serial_number);
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
+ std::string serialNumber = converter.to_bytes(serialNumberW);
+ DeviceInfo info = { deviceModel.value(), path, serialNumber };
+ res.push_back(info);
+ }
+ pInfo = pInfo->next;
}
- pInfo = pInfo->next;
- }
- if (pInfo_ != nullptr){
- hid_free_enumeration(pInfo_);
+ if (pInfo_ != nullptr){
+ hid_free_enumeration(pInfo_);
+ }
}
+}
+std::vector<DeviceInfo> Device::enumerate(){
+ std::vector<DeviceInfo> res;
+ ::add_vendor_devices(res, NITROKEY_VID);
+ ::add_vendor_devices(res, PURISM_VID);
return res;
}
@@ -234,6 +267,8 @@ std::shared_ptr<Device> Device::create(DeviceModel model) {
return std::make_shared<Stick10>();
case DeviceModel::STORAGE:
return std::make_shared<Stick20>();
+ case DeviceModel::LIBREM:
+ return std::make_shared<LibremKey>();
default:
return {};
}
@@ -305,9 +340,20 @@ Stick20::Stick20():
setDefaultDelay();
}
+
+LibremKey::LibremKey():
+ Device(PURISM_VID, LIBREM_KEY_PID, DeviceModel::LIBREM, 100ms, 5, 100ms)
+ {
+ setDefaultDelay();
+ }
+
#include <sstream>
#define p(x) ss << #x << " " << x << ", ";
std::string Device::ErrorCounters::get_as_string() {
+#ifdef NO_LOG
+ return "";
+#endif
+
std::stringstream ss;
p(total_comm_runs);
p(communication_successful);
diff --git a/libnitrokey-v3.5/libnitrokey/CommandFailedException.h b/libnitrokey-v3.6/libnitrokey/CommandFailedException.h
index 32bd6b7..32bd6b7 100644
--- a/libnitrokey-v3.5/libnitrokey/CommandFailedException.h
+++ b/libnitrokey-v3.6/libnitrokey/CommandFailedException.h
diff --git a/libnitrokey-v3.5/libnitrokey/DeviceCommunicationExceptions.h b/libnitrokey-v3.6/libnitrokey/DeviceCommunicationExceptions.h
index f710d0b..f710d0b 100644
--- a/libnitrokey-v3.5/libnitrokey/DeviceCommunicationExceptions.h
+++ b/libnitrokey-v3.6/libnitrokey/DeviceCommunicationExceptions.h
diff --git a/libnitrokey-v3.5/libnitrokey/LibraryException.h b/libnitrokey-v3.6/libnitrokey/LibraryException.h
index 3b9d177..3b9d177 100644
--- a/libnitrokey-v3.5/libnitrokey/LibraryException.h
+++ b/libnitrokey-v3.6/libnitrokey/LibraryException.h
diff --git a/libnitrokey-v3.5/libnitrokey/LongOperationInProgressException.h b/libnitrokey-v3.6/libnitrokey/LongOperationInProgressException.h
index 865d6b5..865d6b5 100644
--- a/libnitrokey-v3.5/libnitrokey/LongOperationInProgressException.h
+++ b/libnitrokey-v3.6/libnitrokey/LongOperationInProgressException.h
diff --git a/libnitrokey-v3.5/libnitrokey/NitrokeyManager.h b/libnitrokey-v3.6/libnitrokey/NitrokeyManager.h
index 33ede1b..cb7cfce 100644
--- a/libnitrokey-v3.5/libnitrokey/NitrokeyManager.h
+++ b/libnitrokey-v3.6/libnitrokey/NitrokeyManager.h
@@ -104,6 +104,7 @@ char * strndup(const char* str, size_t maxlen);
stick10::GetStatus::ResponsePayload get_status();
string get_status_as_string();
string get_serial_number();
+ uint32_t get_serial_number_as_u32();
char * get_totp_slot_name(uint8_t slot_number);
char * get_hotp_slot_name(uint8_t slot_number);
@@ -157,6 +158,7 @@ char * strndup(const char* str, size_t maxlen);
* Does nothing otherwise.
* @param user_pin User PIN
*/
+ [[deprecated("Use set_unencrypted_read_only_admin instead.")]]
void set_unencrypted_read_only(const char *user_pin);
/**
@@ -173,6 +175,7 @@ char * strndup(const char* str, size_t maxlen);
* Does nothing otherwise.
* @param user_pin User PIN
*/
+ [[deprecated("Use set_unencrypted_read_write_admin instead")]]
void set_unencrypted_read_write(const char *user_pin);
/**
diff --git a/libnitrokey-v3.5/libnitrokey/command.h b/libnitrokey-v3.6/libnitrokey/command.h
index 6852bf0..6852bf0 100644
--- a/libnitrokey-v3.5/libnitrokey/command.h
+++ b/libnitrokey-v3.6/libnitrokey/command.h
diff --git a/libnitrokey-v3.5/libnitrokey/command_id.h b/libnitrokey-v3.6/libnitrokey/command_id.h
index ee6726c..ee6726c 100644
--- a/libnitrokey-v3.5/libnitrokey/command_id.h
+++ b/libnitrokey-v3.6/libnitrokey/command_id.h
diff --git a/libnitrokey-v3.5/libnitrokey/cxx_semantics.h b/libnitrokey-v3.6/libnitrokey/cxx_semantics.h
index 36ed142..36ed142 100644
--- a/libnitrokey-v3.5/libnitrokey/cxx_semantics.h
+++ b/libnitrokey-v3.6/libnitrokey/cxx_semantics.h
diff --git a/libnitrokey-v3.5/libnitrokey/deprecated.h b/libnitrokey-v3.6/libnitrokey/deprecated.h
index 5a83288..5a83288 100644
--- a/libnitrokey-v3.5/libnitrokey/deprecated.h
+++ b/libnitrokey-v3.6/libnitrokey/deprecated.h
diff --git a/libnitrokey-v3.5/libnitrokey/device.h b/libnitrokey-v3.6/libnitrokey/device.h
index d50080d..917e0d0 100644
--- a/libnitrokey-v3.5/libnitrokey/device.h
+++ b/libnitrokey-v3.6/libnitrokey/device.h
@@ -50,7 +50,8 @@ namespace device {
enum class DeviceModel{
PRO,
- STORAGE
+ STORAGE,
+ LIBREM
};
std::ostream& operator<<(std::ostream& stream, DeviceModel model);
@@ -67,12 +68,21 @@ extern const uint16_t NITROKEY_PRO_PID;
* The USB product ID for the Nitrokey Storage.
*/
extern const uint16_t NITROKEY_STORAGE_PID;
+/**
+ * The USB vendor ID for Purism devices.
+ */
+extern const uint16_t PURISM_VID;
+/**
+ * The USB product ID for the Librem Key.
+ */
+extern const uint16_t LIBREM_KEY_PID;
/**
* Convert the given USB product ID to a Nitrokey model. If there is no model
* with that ID, return an absent value.
*/
misc::Option<DeviceModel> product_id_to_model(uint16_t product_id);
+misc::Option<DeviceModel> product_id_to_model(uint16_t vendor_id, uint16_t product_id);
/**
* Information about a connected device.
@@ -219,6 +229,12 @@ class Stick20 : public Device {
public:
Stick20();
};
+
+class LibremKey : public Device {
+ public:
+ LibremKey();
+};
+
}
}
#endif
diff --git a/libnitrokey-v3.5/libnitrokey/device_proto.h b/libnitrokey-v3.6/libnitrokey/device_proto.h
index 45a6c16..6ffe5fb 100644
--- a/libnitrokey-v3.5/libnitrokey/device_proto.h
+++ b/libnitrokey-v3.6/libnitrokey/device_proto.h
@@ -249,7 +249,7 @@ namespace nitrokey {
}
dev->m_counters.total_comm_runs++;
- int status;
+ int status = 0;
OutgoingPacket outp;
ResponsePacket resp;
diff --git a/libnitrokey-v3.5/libnitrokey/dissect.h b/libnitrokey-v3.6/libnitrokey/dissect.h
index 690b5b7..690b5b7 100644
--- a/libnitrokey-v3.5/libnitrokey/dissect.h
+++ b/libnitrokey-v3.6/libnitrokey/dissect.h
diff --git a/libnitrokey-v3.5/libnitrokey/hidapi/hidapi.h b/libnitrokey-v3.6/libnitrokey/hidapi/hidapi.h
index e5bc2dc..e5bc2dc 100644
--- a/libnitrokey-v3.5/libnitrokey/hidapi/hidapi.h
+++ b/libnitrokey-v3.6/libnitrokey/hidapi/hidapi.h
diff --git a/libnitrokey-v3.5/libnitrokey/log.h b/libnitrokey-v3.6/libnitrokey/log.h
index 278b49c..eade68f 100644
--- a/libnitrokey-v3.5/libnitrokey/log.h
+++ b/libnitrokey-v3.6/libnitrokey/log.h
@@ -100,6 +100,7 @@ namespace nitrokey {
#ifdef NO_LOG
#define LOG(string, level) while(false){}
#define LOGD(string) while(false){}
+#define LOGD1(string) while(false){}
#else
#define LOG(string, level) nitrokey::log::Log::instance()((string), (level))
#define LOGD1(string) nitrokey::log::Log::instance()((string), (nitrokey::log::Loglevel::DEBUG_L1))
diff --git a/libnitrokey-v3.5/libnitrokey/misc.h b/libnitrokey-v3.6/libnitrokey/misc.h
index a9c4672..a9c4672 100644
--- a/libnitrokey-v3.5/libnitrokey/misc.h
+++ b/libnitrokey-v3.6/libnitrokey/misc.h
diff --git a/libnitrokey-v3.5/libnitrokey/stick10_commands.h b/libnitrokey-v3.6/libnitrokey/stick10_commands.h
index 5e8a5aa..5e8a5aa 100644
--- a/libnitrokey-v3.5/libnitrokey/stick10_commands.h
+++ b/libnitrokey-v3.6/libnitrokey/stick10_commands.h
diff --git a/libnitrokey-v3.5/libnitrokey/stick10_commands_0.8.h b/libnitrokey-v3.6/libnitrokey/stick10_commands_0.8.h
index 9477890..9477890 100644
--- a/libnitrokey-v3.5/libnitrokey/stick10_commands_0.8.h
+++ b/libnitrokey-v3.6/libnitrokey/stick10_commands_0.8.h
diff --git a/libnitrokey-v3.5/libnitrokey/stick20_commands.h b/libnitrokey-v3.6/libnitrokey/stick20_commands.h
index 7efa1b6..7efa1b6 100644
--- a/libnitrokey-v3.5/libnitrokey/stick20_commands.h
+++ b/libnitrokey-v3.6/libnitrokey/stick20_commands.h
diff --git a/libnitrokey-v3.5/libnitrokey/version.h b/libnitrokey-v3.6/libnitrokey/version.h
index 6547af0..6547af0 100644
--- a/libnitrokey-v3.5/libnitrokey/version.h
+++ b/libnitrokey-v3.6/libnitrokey/version.h
diff --git a/libnitrokey-v3.5/log.cc b/libnitrokey-v3.6/log.cc
index 06acee7..06acee7 100644
--- a/libnitrokey-v3.5/log.cc
+++ b/libnitrokey-v3.6/log.cc
diff --git a/libnitrokey-v3.5/misc.cc b/libnitrokey-v3.6/misc.cc
index 59185f3..59185f3 100644
--- a/libnitrokey-v3.5/misc.cc
+++ b/libnitrokey-v3.6/misc.cc
diff --git a/libnitrokey-v3.5/version.cc b/libnitrokey-v3.6/version.cc
index dfdc802..dfdc802 100644
--- a/libnitrokey-v3.5/version.cc
+++ b/libnitrokey-v3.6/version.cc
diff --git a/libnitrokey-v3.5/version.cc.in b/libnitrokey-v3.6/version.cc.in
index 0eae647..0eae647 100644
--- a/libnitrokey-v3.5/version.cc.in
+++ b/libnitrokey-v3.6/version.cc.in
diff --git a/patches/deprecated.diff b/patches/deprecated.diff
index c814812..79fe5ba 100644
--- a/patches/deprecated.diff
+++ b/patches/deprecated.diff
@@ -6,7 +6,7 @@ Index: nitrokey-sys-rs/src/ffi.rs
===================================================================
--- nitrokey-sys-rs.orig/src/ffi.rs
+++ nitrokey-sys-rs/src/ffi.rs
-@@ -767,6 +767,7 @@ extern "C" {
+@@ -848,6 +848,7 @@ extern "C" {
#[doc = " deprecated in favor of NK_get_status_as_string."]
#[doc = " @return string representation of the status or an empty string"]
#[doc = " if the command failed"]
@@ -14,7 +14,7 @@ Index: nitrokey-sys-rs/src/ffi.rs
pub fn NK_status() -> *mut ::std::os::raw::c_char;
}
extern "C" {
-@@ -1022,6 +1023,7 @@ extern "C" {
+@@ -1134,6 +1135,7 @@ extern "C" {
pub fn NK_totp_set_time_soft(time: u64) -> ::std::os::raw::c_int;
}
extern "C" {
@@ -22,3 +22,19 @@ Index: nitrokey-sys-rs/src/ffi.rs
pub fn NK_totp_get_time() -> ::std::os::raw::c_int;
}
extern "C" {
+@@ -1309,6 +1311,7 @@ extern "C" {
+ #[doc = " Storage only"]
+ #[doc = " @param user_pin 20 characters User PIN"]
+ #[doc = " @return command processing error code"]
++ #[deprecated(since = "3.6.0", note = "use `set_unencrypted_read_only_admin` instead")]
+ pub fn NK_set_unencrypted_read_only(
+ user_pin: *const ::std::os::raw::c_char,
+ ) -> ::std::os::raw::c_int;
+@@ -1322,6 +1325,7 @@ extern "C" {
+ #[doc = " Storage only"]
+ #[doc = " @param user_pin 20 characters User PIN"]
+ #[doc = " @return command processing error code"]
++ #[deprecated(since = "3.6.0", note = "use `set_unencrypted_read_write_admin` instead")]
+ pub fn NK_set_unencrypted_read_write(
+ user_pin: *const ::std::os::raw::c_char,
+ ) -> ::std::os::raw::c_int;
diff --git a/src/ffi.rs b/src/ffi.rs
index f81982e..d335280 100644
--- a/src/ffi.rs
+++ b/src/ffi.rs
@@ -10,6 +10,8 @@ pub const NK_device_model_NK_DISCONNECTED: NK_device_model = 0;
pub const NK_device_model_NK_PRO: NK_device_model = 1;
#[doc = " Nitrokey Storage."]
pub const NK_device_model_NK_STORAGE: NK_device_model = 2;
+#[doc = " Librem Key."]
+pub const NK_device_model_NK_LIBREM: NK_device_model = 3;
#[doc = " The Nitrokey device models supported by the API."]
pub type NK_device_model = ::std::os::raw::c_uint;
#[doc = " The connection info for a Nitrokey device as a linked list."]
@@ -498,6 +500,85 @@ fn bindgen_test_layout_NK_SD_usage_data() {
)
);
}
+#[doc = " The general configuration of a Nitrokey device."]
+#[repr(C)]
+#[derive(Debug, Default, Copy, Clone)]
+pub struct NK_config {
+ #[doc = " value in range [0-1] to send HOTP code from slot 'numlock' after double pressing numlock"]
+ #[doc = " or outside the range to disable this function"]
+ pub numlock: u8,
+ #[doc = " similar to numlock but with capslock"]
+ pub capslock: u8,
+ #[doc = " similar to numlock but with scrolllock"]
+ pub scrolllock: u8,
+ #[doc = " True to enable OTP PIN protection (require PIN each OTP code request)"]
+ pub enable_user_password: bool,
+ #[doc = " Unused."]
+ pub disable_user_password: bool,
+}
+#[test]
+fn bindgen_test_layout_NK_config() {
+ assert_eq!(
+ ::std::mem::size_of::<NK_config>(),
+ 5usize,
+ concat!("Size of: ", stringify!(NK_config))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<NK_config>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(NK_config))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<NK_config>())).numlock as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(NK_config),
+ "::",
+ stringify!(numlock)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<NK_config>())).capslock as *const _ as usize },
+ 1usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(NK_config),
+ "::",
+ stringify!(capslock)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<NK_config>())).scrolllock as *const _ as usize },
+ 2usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(NK_config),
+ "::",
+ stringify!(scrolllock)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<NK_config>())).enable_user_password as *const _ as usize },
+ 3usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(NK_config),
+ "::",
+ stringify!(enable_user_password)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<NK_config>())).disable_user_password as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(NK_config),
+ "::",
+ stringify!(disable_user_password)
+ )
+ );
+}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct NK_storage_ProductionTest {
@@ -737,7 +818,7 @@ extern "C" {
}
extern "C" {
#[doc = " Connect to device of given model. Currently library can be connected only to one device at once."]
- #[doc = " @param device_model NK_device_model: NK_PRO: Nitrokey Pro, NK_STORAGE: Nitrokey Storage"]
+ #[doc = " @param device_model NK_device_model: NK_PRO: Nitrokey Pro, NK_STORAGE: Nitrokey Storage, NK_LIBREM: Librem Key"]
#[doc = " @return 1 if connected, 0 if wrong model or cannot connect"]
pub fn NK_login_enum(device_model: NK_device_model) -> ::std::os::raw::c_int;
}
@@ -788,6 +869,13 @@ extern "C" {
pub fn NK_device_serial_number() -> *mut ::std::os::raw::c_char;
}
extern "C" {
+ #[doc = " Return the device's serial number string as an integer. Use"]
+ #[doc = " NK_last_command_status to check for an error if this function"]
+ #[doc = " returns zero."]
+ #[doc = " @return device's serial number as an integer"]
+ pub fn NK_device_serial_number_as_u32() -> u32;
+}
+extern "C" {
#[doc = " Get last command processing status. Useful for commands which returns the results of their own and could not return"]
#[doc = " an error code."]
#[doc = " @return previous command processing error code"]
@@ -861,7 +949,18 @@ extern "C" {
) -> ::std::os::raw::c_int;
}
extern "C" {
+ #[doc = " Write general config to the device"]
+ #[doc = " @param config the configuration data"]
+ #[doc = " @param admin_temporary_password current admin temporary password"]
+ #[doc = " @return command processing error code"]
+ pub fn NK_write_config_struct(
+ config: NK_config,
+ admin_temporary_password: *const ::std::os::raw::c_char,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
#[doc = " Get currently set config - status of function Numlock/Capslock/Scrollock OTP sending and is enabled PIN protected OTP"]
+ #[doc = " The return value must be freed using NK_free_config."]
#[doc = " @see NK_write_config"]
#[doc = " @return uint8_t general_config[5]:"]
#[doc = " uint8_t numlock;"]
@@ -873,6 +972,19 @@ extern "C" {
pub fn NK_read_config() -> *mut u8;
}
extern "C" {
+ #[doc = " Free a value returned by NK_read_config. May be called with a NULL"]
+ #[doc = " argument."]
+ pub fn NK_free_config(config: *mut u8);
+}
+extern "C" {
+ #[doc = " Get currently set config and write it to the given pointer."]
+ #[doc = " @see NK_read_config"]
+ #[doc = " @see NK_write_config_struct"]
+ #[doc = " @param out a pointer to the struct that should be written to"]
+ #[doc = " @return command processing error code"]
+ pub fn NK_read_config_struct(out: *mut NK_config) -> ::std::os::raw::c_int;
+}
+extern "C" {
#[doc = " Get name of given TOTP slot"]
#[doc = " @param slot_number TOTP slot number, slot_number<15"]
#[doc = " @return char[20] the name of the slot"]
@@ -1062,10 +1174,16 @@ extern "C" {
}
extern "C" {
#[doc = " Get password safe slots' status"]
+ #[doc = " The return value must be freed using NK_free_password_safe_slot_status."]
#[doc = " @return uint8_t[16] slot statuses - each byte represents one slot with 0 (not programmed) and 1 (programmed)"]
pub fn NK_get_password_safe_slot_status() -> *mut u8;
}
extern "C" {
+ #[doc = " Free a value returned by NK_get_password_safe_slot_status. May be"]
+ #[doc = " called with a NULL argument."]
+ pub fn NK_free_password_safe_slot_status(status: *mut u8);
+}
+extern "C" {
#[doc = " Get password safe slot name"]
#[doc = " @param slot_number password safe slot number, slot_number<16"]
#[doc = " @return slot name"]
@@ -1189,6 +1307,7 @@ extern "C" {
#[doc = " Storage only"]
#[doc = " @param user_pin 20 characters User PIN"]
#[doc = " @return command processing error code"]
+ #[deprecated(since = "3.6.0", note = "use `set_unencrypted_read_only_admin` instead")]
pub fn NK_set_unencrypted_read_only(
user_pin: *const ::std::os::raw::c_char,
) -> ::std::os::raw::c_int;
@@ -1202,6 +1321,7 @@ extern "C" {
#[doc = " Storage only"]
#[doc = " @param user_pin 20 characters User PIN"]
#[doc = " @return command processing error code"]
+ #[deprecated(since = "3.6.0", note = "use `set_unencrypted_read_write_admin` instead")]
pub fn NK_set_unencrypted_read_write(
user_pin: *const ::std::os::raw::c_char,
) -> ::std::os::raw::c_int;