summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-04-02 16:29:27 +0200
committerRobin Krahl <robin.krahl@ireas.org>2020-04-02 16:29:27 +0200
commit0270a9b3de4b45fcfcb83f8e20a78702811d4192 (patch)
tree4135cf93dd87ca81b2e6f534603dfb6f7ca2b1d4
parent6100df4127eca5f9733cd5fa51acd32c8febd754 (diff)
downloadlibnitrokey-0270a9b3de4b45fcfcb83f8e20a78702811d4192.tar.gz
libnitrokey-0270a9b3de4b45fcfcb83f8e20a78702811d4192.tar.bz2
Add NK_config struct and read/write functions
This patch adds the NK_config struct to the C API that stores the general configuration of a Nitrokey device. It also adds the NK_read_config_struct and NK_write_config_struct functions to make the API easier to use. While NK_write_config_struct is only a convenience method, NK_read_config_struct makes the API more safe as the user no longer has to read the data from a pointer to an array. This patch also extends the test_read_write_config test case with the two new functions.
-rw-r--r--NK_C_API.cc21
-rw-r--r--NK_C_API.h43
-rw-r--r--unittest/test_pro.py26
3 files changed, 89 insertions, 1 deletions
diff --git a/NK_C_API.cc b/NK_C_API.cc
index 1d3fa3a..d993671 100644
--- a/NK_C_API.cc
+++ b/NK_C_API.cc
@@ -217,6 +217,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 +232,21 @@ extern "C" {
});
}
+ 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();
diff --git a/NK_C_API.h b/NK_C_API.h
index d5c54a3..6aab7ca 100644
--- a/NK_C_API.h
+++ b/NK_C_API.h
@@ -265,6 +265,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];
@@ -450,6 +476,14 @@ 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
* @see NK_write_config
* @return uint8_t general_config[5]:
@@ -462,6 +496,15 @@ extern "C" {
*/
NK_C_API uint8_t* NK_read_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
/**
diff --git a/unittest/test_pro.py b/unittest/test_pro.py
index 99d7b1f..e61d8bf 100644
--- a/unittest/test_pro.py
+++ b/unittest/test_pro.py
@@ -647,6 +647,30 @@ def test_read_write_config(C):
config = cast_pointer_to_tuple(config_raw_data, 'uint8_t', 5)
assert config == (0, 1, 2, True, False)
+ # use structs: read I
+ config_st = ffi.new('struct NK_config *')
+ if not config_st:
+ raise Exception("Could not allocate config")
+ assert C.NK_read_config_struct(config_st) == DeviceErrorCode.STATUS_OK
+ assert config_st.numlock == 0
+ assert config_st.capslock == 1
+ assert config_st.scrolllock == 2
+ assert config_st.enable_user_password
+ assert not config_st.disable_user_password
+
+ # use structs: write
+ config_st.numlock = 3
+ assert C.NK_write_config_struct(config_st[0], DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
+
+ # use structs: read II
+ err = C.NK_read_config_struct(config_st)
+ assert err == 0
+ assert config_st.numlock == 3
+ assert config_st.capslock == 1
+ assert config_st.scrolllock == 2
+ assert config_st.enable_user_password
+ assert not config_st.disable_user_password
+
# restore defaults and check
assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
@@ -1038,4 +1062,4 @@ def test_OTP_all_rw(C):
this_loop_codes.append(('H', i, code))
all_codes.append(this_loop_codes)
from pprint import pprint
- pprint(all_codes) \ No newline at end of file
+ pprint(all_codes)