diff options
author | Szczepan Zalega <szczepan@nitrokey.com> | 2016-08-09 15:15:17 +0200 |
---|---|---|
committer | Szczepan Zalega <szczepan@nitrokey.com> | 2016-08-09 18:34:00 +0200 |
commit | 9d6e045a3143f8eb31c5033c9c4be59cc2f73336 (patch) | |
tree | cdda7d8d8866ae2c63aba812cbb2efe2f2b657b0 | |
parent | 0f2965f5808386f9dd89209d754fd827ef2b27bd (diff) | |
download | libnitrokey-9d6e045a3143f8eb31c5033c9c4be59cc2f73336.tar.gz libnitrokey-9d6e045a3143f8eb31c5033c9c4be59cc2f73336.tar.bz2 |
Return error for too long string
Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | CommandFailedException.cpp | 5 | ||||
-rw-r--r-- | InvalidSlotException.h | 27 | ||||
-rw-r--r-- | NK_C_API.cc | 21 | ||||
-rw-r--r-- | NitrokeyManager.cc | 9 | ||||
-rw-r--r-- | TooLongStringException.cpp | 5 | ||||
-rw-r--r-- | include/CommandFailedException.cpp | 5 | ||||
-rw-r--r-- | include/TooLongStringException.h | 32 | ||||
-rw-r--r-- | unittest/test_bindings.py | 27 |
9 files changed, 119 insertions, 14 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 37fac0f..3abcb0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,6 @@ set(SOURCE_FILES log.cc misc.cc NitrokeyManager.cc - NK_C_API.cc include/CommandFailedException.cpp include/CommandFailedException.h) + NK_C_API.cc CommandFailedException.cpp include/CommandFailedException.h TooLongStringException.cpp include/TooLongStringException.h InvalidSlotException.h) add_executable(libnitrokey ${SOURCE_FILES})
\ No newline at end of file diff --git a/CommandFailedException.cpp b/CommandFailedException.cpp new file mode 100644 index 0000000..ccc780c --- /dev/null +++ b/CommandFailedException.cpp @@ -0,0 +1,5 @@ +// +// Created by sz on 23.07.16. +// + +#include "include/CommandFailedException.h" diff --git a/InvalidSlotException.h b/InvalidSlotException.h new file mode 100644 index 0000000..741d53e --- /dev/null +++ b/InvalidSlotException.h @@ -0,0 +1,27 @@ +// +// Created by sz on 09.08.16. +// + +#ifndef LIBNITROKEY_INVALIDSLOTEXCEPTION_H +#define LIBNITROKEY_INVALIDSLOTEXCEPTION_H + + +#include <cstdint> +#include <string> +#include <exception> + +class InvalidSlotException : public std::exception { +public: + static const std::uint8_t exception_id = 201; + + uint8_t slot_selected; + + InvalidSlotException(uint8_t slot_selected) : slot_selected(slot_selected) {} + + virtual const char *what() const throw() { + return "Wrong slot selected"; + } + +}; + +#endif //LIBNITROKEY_INVALIDSLOTEXCEPTION_H diff --git a/NK_C_API.cc b/NK_C_API.cc index 577f2d6..4ba29ab 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -1,5 +1,7 @@ #include <cstring> #include "NK_C_API.h" +#include "include/TooLongStringException.h" + using namespace nitrokey; static uint8_t NK_last_command_status = 0; @@ -20,8 +22,11 @@ uint8_t * get_with_array_result(T func){ } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; - return nullptr; } + catch (TooLongStringException & longStringException){ + NK_last_command_status = TooLongStringException::exception_id; + } + return nullptr; } template <typename T> @@ -32,8 +37,11 @@ const char* get_with_string_result(T func){ } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; - return ""; } + catch (TooLongStringException & longStringException){ + NK_last_command_status = TooLongStringException::exception_id; + } + return ""; } template <typename T> @@ -44,8 +52,11 @@ auto get_with_result(T func){ } catch (CommandFailedException & commandFailedException){ NK_last_command_status = commandFailedException.last_command_status; - return static_cast<decltype(func())>(0); } + catch (TooLongStringException & longStringException){ + NK_last_command_status = TooLongStringException::exception_id; + } + return static_cast<decltype(func())>(0); } template <typename T> @@ -59,6 +70,10 @@ uint8_t get_without_result(T func){ NK_last_command_status = commandFailedException.last_command_status; return commandFailedException.last_command_status; } + catch (TooLongStringException & longStringException){ + NK_last_command_status = TooLongStringException::exception_id; + return NK_last_command_status; + } } extern "C" diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 5baf7bd..c27de2b 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -2,15 +2,18 @@ #include <cstring> #include <iostream> #include "include/NitrokeyManager.h" +#include "include/TooLongStringException.h" namespace nitrokey{ template <typename T> void strcpyT(T& dest, const char* src){ assert(src != nullptr); - const size_t s = sizeof dest; - assert(strlen(src) <= s); // FIXME should throw an exception to abort when too long string appears - strncpy((char*) &dest, src, s); + const size_t s_dest = sizeof dest; + if (strlen(src) > s_dest){ + throw TooLongStringException(strlen(src), s_dest, src); + } + strncpy((char*) &dest, src, s_dest); } template <typename T> diff --git a/TooLongStringException.cpp b/TooLongStringException.cpp new file mode 100644 index 0000000..96c5132 --- /dev/null +++ b/TooLongStringException.cpp @@ -0,0 +1,5 @@ +// +// Created by sz on 09.08.16. +// + +#include "include/TooLongStringException.h" diff --git a/include/CommandFailedException.cpp b/include/CommandFailedException.cpp deleted file mode 100644 index 5ba4b0b..0000000 --- a/include/CommandFailedException.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by sz on 23.07.16. -// - -#include "CommandFailedException.h" diff --git a/include/TooLongStringException.h b/include/TooLongStringException.h new file mode 100644 index 0000000..3a9244b --- /dev/null +++ b/include/TooLongStringException.h @@ -0,0 +1,32 @@ +// +// Created by sz on 09.08.16. +// + +#ifndef LIBNITROKEY_TOOLONGSTRINGEXCEPTION_H +#define LIBNITROKEY_TOOLONGSTRINGEXCEPTION_H + + +#include <cstdint> +#include <string> +#include <exception> + +class TooLongStringException : public std::exception { +public: + static const std::uint8_t exception_id = 200; + + std::size_t size_source; + std::size_t size_destination; + std::string message; + + TooLongStringException(size_t size_source, size_t size_destination, const std::string &message = "") : size_source( + size_source), size_destination(size_destination), message(message) {} + + virtual const char *what() const throw() { + //TODO add sizes and message data to final message + return "Too long string has been supplied as an argument"; + } + +}; + + +#endif //LIBNITROKEY_TOOLONGSTRINGEXCEPTION_H diff --git a/unittest/test_bindings.py b/unittest/test_bindings.py index d072bfc..9eebcb3 100644 --- a/unittest/test_bindings.py +++ b/unittest/test_bindings.py @@ -23,6 +23,11 @@ class DeviceErrorCode(Enum): STATUS_AES_DEC_FAILED = 0xa +class LibraryErrors(Enum): + TOO_LONG_STRING = 200 + INVALID_SLOT = 201 + + @pytest.fixture(scope="module") def C(request): fp = '../NK_C_API.h' @@ -187,9 +192,27 @@ def test_user_PIN_change(C): assert C.NK_change_user_PIN(new_password, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK -def test_too_long_PIN(C): +def test_too_long_strings(C): new_password = '123123123' - assert C.NK_change_user_PIN('a' * 100, new_password) == DeviceErrorCode.WRONG_PASSWORD + long_string = 'a' * 100 + assert C.NK_change_user_PIN(long_string, new_password) == LibraryErrors.TOO_LONG_STRING + assert C.NK_change_user_PIN(new_password, long_string) == LibraryErrors.TOO_LONG_STRING + assert C.NK_change_admin_PIN(long_string, new_password) == LibraryErrors.TOO_LONG_STRING + assert C.NK_change_admin_PIN(new_password, long_string) == LibraryErrors.TOO_LONG_STRING + assert C.NK_first_authenticate(long_string, DefaultPasswords.ADMIN_TEMP) == LibraryErrors.TOO_LONG_STRING + assert C.NK_erase_totp_slot(0, long_string) == LibraryErrors.TOO_LONG_STRING + digits = False + assert C.NK_write_hotp_slot(1, long_string, RFC_SECRET, 0, digits, False, False, "", + DefaultPasswords.ADMIN_TEMP) == LibraryErrors.TOO_LONG_STRING + assert C.NK_write_hotp_slot(1, 'long_test', RFC_SECRET, 0, digits, False, False, "", + long_string) == LibraryErrors.TOO_LONG_STRING + assert C.NK_get_hotp_code_PIN(0, long_string) == 0 + assert C.NK_get_last_command_status() == LibraryErrors.TOO_LONG_STRING + + +# def test_invalid_slot(C): +# invalid_slot = 255 +# assert C.NK_erase_totp_slot(invalid_slot, 'some password') == LibraryErrors.INVALID_SLOT def test_admin_retry_counts(C): |