diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | NK_C_API.cc | 28 | ||||
| -rw-r--r-- | NK_C_API.h | 64 | ||||
| -rw-r--r-- | unittest/test_multiple_devices.cc | 2 | ||||
| -rw-r--r-- | unittest/test_pro.py | 18 | ||||
| -rw-r--r-- | unittest/test_safe.cpp | 2 | ||||
| -rw-r--r-- | unittest/test_strdup.cpp | 4 | 
7 files changed, 111 insertions, 8 deletions
| @@ -2,6 +2,7 @@  *.log  *.o  unittest/build/ +unittest/.pytest_cache/  *.pyc  core  .cache/ diff --git a/NK_C_API.cc b/NK_C_API.cc index eae35d5..e560c3f 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -252,6 +252,10 @@ extern "C" {  	NK_C_API char * NK_status() { +		return NK_get_status_as_string(); +	} + +	NK_C_API char * NK_get_status_as_string() {  		auto m = NitrokeyManager::instance();  		return get_with_string_result([&]() {  			string && s = m->get_status_as_string(); @@ -261,6 +265,30 @@ extern "C" {  		});  	} +	NK_C_API int NK_get_status(struct NK_status* out) { +		if (out == nullptr) { +			return -1; +		} +		auto m = NitrokeyManager::instance(); +		auto result = get_with_status([&]() { +			return m->get_status(); +		}, proto::stick10::GetStatus::ResponsePayload()); +		auto error_code = std::get<0>(result); +		if (error_code != 0) { +			return error_code; +		} + +		auto status = std::get<1>(result); +		out->firmware_version_major = status.firmware_version_st.major; +		out->firmware_version_minor = status.firmware_version_st.minor; +		out->serial_number_smart_card = status.card_serial_u32; +		out->config_numlock = status.numlock; +		out->config_capslock = status.capslock; +		out->config_scrolllock = status.scrolllock; +		out->otp_user_password = status.enable_user_password != 0; +		return 0; +	} +  	NK_C_API char * NK_device_serial_number() {  		auto m = NitrokeyManager::instance();  		return get_with_string_result([&]() { @@ -138,6 +138,47 @@ extern "C" {  	};  	/** +	 * Stores the common device status for all Nitrokey devices. +	 */ +	struct NK_status { +		/** +		 * 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; +		/** +		 * The serial number of the smart card. +		 */ +		uint32_t serial_number_smart_card; +		/** +		 * The HOTP slot to generate a password from if the numlock +		 * key is pressed twice (slot 0-1, or any other value to +		 * disable the function). +		 */ +		uint8_t config_numlock; +		/** +		 * The HOTP slot to generate a password from if the capslock +		 * key is pressed twice (slot 0-1, or any other value to +		 * disable the function). +		 */ +		uint8_t config_capslock; +		/** +		 * The HOTP slot to generate a password from if the scrolllock +		 * key is pressed twice (slot 0-1, or any other value to +		 * disable the function). +		 */ +		uint8_t config_scrolllock; +		/** +		 * Indicates whether the user password is required to generate +		 * an OTP value. +		 */ +		bool otp_user_password; +	}; + +	/**  	 * Stores the status of a Storage device.  	 */          struct NK_storage_status { @@ -312,10 +353,31 @@ extern "C" {  	NK_C_API enum NK_device_model NK_get_device_model();  	/** +	 * Return the debug status string. Debug purposes.  This function is +	 * deprecated in favor of NK_get_status_as_string. +	 * @return string representation of the status or an empty string +	 *         if the command failed +	 */ +	DEPRECATED +	NK_C_API char * NK_status(); + +	/**  	 * Return the debug status string. Debug purposes. +	 * @return string representation of the status or an empty string +	 *         if the command failed +	 */ +	NK_C_API char * NK_get_status_as_string(); + +	/** +	 * Get the stick status common to all Nitrokey devices 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 status  	 * @return command processing error code  	 */ -	NK_C_API char * NK_status(); +	NK_C_API int NK_get_status(struct NK_status* out);  	/**  	 * Return the device's serial number string in hex. diff --git a/unittest/test_multiple_devices.cc b/unittest/test_multiple_devices.cc index 4b1e2c1..7e10a42 100644 --- a/unittest/test_multiple_devices.cc +++ b/unittest/test_multiple_devices.cc @@ -117,7 +117,7 @@ TEST_CASE("Use C API", "[BASIC]") {      while (ptr) {        std::cout << "Connect with: " << ptr->model << " " << ptr->path << " "          << ptr->serial_number << " | " << NK_connect_with_path(ptr->path) << " | "; -      auto status = NK_status(); +      auto status = NK_get_status_as_string();        std::cout << status << std::endl;        free(status);        ptr = ptr->next; diff --git a/unittest/test_pro.py b/unittest/test_pro.py index afa9505..6ab7c1d 100644 --- a/unittest/test_pro.py +++ b/unittest/test_pro.py @@ -674,11 +674,23 @@ def test_factory_reset(C):  @pytest.mark.status -def test_get_status(C): -    status = C.NK_status() +def test_get_status_as_string(C): +    status = C.NK_get_status_as_string()      s = gs(status)      assert len(s) > 0 + +@pytest.mark.status +def test_get_status(C): +    status_st = ffi.new('struct NK_status *') +    if not status_st: +        raise Exception("Could not allocate status") +    err = C.NK_get_status(status_st) +    assert err == 0 +    assert status_st.firmware_version_major == 0 +    assert status_st.firmware_version_minor != 0 + +  @pytest.mark.status  def test_get_serial_number(C):      sn = C.NK_device_serial_number() @@ -926,4 +938,4 @@ def test_TOTP_codes_from_nitrokeyapp(secret, C):  def test_get_device_model(C):      assert C.NK_get_device_model() != 0 -    # assert C.NK_get_device_model() != C.NK_DISCONNECTED
\ No newline at end of file +    # assert C.NK_get_device_model() != C.NK_DISCONNECTED diff --git a/unittest/test_safe.cpp b/unittest/test_safe.cpp index d6f8b63..a244027 100644 --- a/unittest/test_safe.cpp +++ b/unittest/test_safe.cpp @@ -60,7 +60,7 @@ TEST_CASE("Status command for Pro or Storage", "[BASIC]") {      auto const m = NK_get_device_model();      REQUIRE(m != NK_DISCONNECTED);      if (m == NK_PRO) -        s = NK_status(); +        s = NK_get_status_as_string();      else if (m == NK_STORAGE){          s = NK_get_status_storage_as_string();      } diff --git a/unittest/test_strdup.cpp b/unittest/test_strdup.cpp index 4f77b7f..c7f4ea8 100644 --- a/unittest/test_strdup.cpp +++ b/unittest/test_strdup.cpp @@ -34,7 +34,7 @@ static const int SHORT_STRING_LENGTH = 10;  TEST_CASE("Test strdup memory free error", "[BASIC]")  {    NK_set_debug(false); -  char *c = NK_status(); /* error --> string literal */ +  char *c = NK_get_status_as_string(); /* error --> string literal */    REQUIRE(c != nullptr);    REQUIRE(strnlen(c, SHORT_STRING_LENGTH) == 0);    puts(c); @@ -48,7 +48,7 @@ TEST_CASE("Test strdup memory leak", "[BASIC]")    if (!connected) return;    REQUIRE(connected); -  char *c = NK_status();  /* no error --> dynamically allocated */ +  char *c = NK_get_status_as_string();  /* no error --> dynamically allocated */    REQUIRE(c != nullptr);    REQUIRE(strnlen(c, SHORT_STRING_LENGTH) > 0);    puts(c); | 
