From: Pawel Kowalski Date: Mon, 25 Jun 2018 11:38:33 +0000 (+0200) Subject: ODE API negative tests: internal encryption X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bb043095fbd2d11e52670b9395911768b7981a2e;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git ODE API negative tests: internal encryption Change-Id: I4e342049e268bd17ed4367a1e998d38b0aa8b8ba --- diff --git a/packaging/security-tests.spec b/packaging/security-tests.spec index 2d3e3331..af502708 100644 --- a/packaging/security-tests.spec +++ b/packaging/security-tests.spec @@ -49,6 +49,9 @@ cp %{SOURCE1} . export LDFLAGS+="-Wl,--rpath=%{_prefix}/lib" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \ +%if "%{_with_emulator}" == "1" + -DEMULATOR="ON" \ +%endif -DDPL_LOG="ON" \ -DDPL_WITH_DLOG="ON" \ -DVERSION=%{version} \ diff --git a/src/ode/CMakeLists.txt b/src/ode/CMakeLists.txt index cf6aa47a..f7fd4645 100644 --- a/src/ode/CMakeLists.txt +++ b/src/ode/CMakeLists.txt @@ -22,6 +22,11 @@ MESSAGE(STATUS "Generating makefile for the ODE tests...") FILE(GLOB ode_tests_SRCS *.cpp) +OPTION("EMULATOR" ON) +IF(EMULATOR) + ADD_DEFINITIONS("-DEMULATOR") +ENDIF(EMULATOR) + ## Setup target ################################################################ SET(ODE_TESTS "ode-tests") ADD_EXECUTABLE(${ODE_TESTS} ${ode_tests_SRCS}) diff --git a/src/ode/ode-tests-common.cpp b/src/ode/ode-tests-common.cpp index e3b314d7..651ded75 100644 --- a/src/ode/ode-tests-common.cpp +++ b/src/ode/ode-tests-common.cpp @@ -18,8 +18,13 @@ * @brief Tests for the ODE API */ +#include +#include + #include + #include +#include #include "ode-tests-common.h" #define ERRORDESCRIBE(name) case name: return #name @@ -42,6 +47,8 @@ const char* ODEErrorToString(int error) { #undef ERRORDESCRIBE +// helper classes + HelperKeys::HelperKeys(const char* device, const char* password, bool initialize) { dev = device; pass = password; @@ -59,4 +66,20 @@ HelperKeys::HelperKeys(const char* device, const char* password, bool initialize HelperKeys::~HelperKeys() { ode_key_remove_master_key(dev); ode_key_remove(dev, pass); -}; +} + +HelperInternalEncryption::HelperInternalEncryption(const char* password) { + pass = password; + + bool result; + assert_positive(ode_internal_encryption_is_password_initialized, &result); + + if (!result) { + assert_positive(ode_internal_encryption_init_password, pass); + } +} + +HelperInternalEncryption::~HelperInternalEncryption() { + ode_internal_encryption_umount(); + ode_internal_encryption_clean_password(pass); +} diff --git a/src/ode/ode-tests-common.h b/src/ode/ode-tests-common.h index 3b036183..b15440c2 100644 --- a/src/ode/ode-tests-common.h +++ b/src/ode/ode-tests-common.h @@ -23,6 +23,16 @@ #include #include + +#define RUNNER_TEST_DUMMY(Proc, ...) \ + void Proc(std::tuple<__VA_ARGS__> &optionalArgsTuple DPL_UNUSED) + +#ifndef EMULATOR +#define RUNNER_TEST_DEVICE(...) RUNNER_TEST(__VA_ARGS__) +#else +#define RUNNER_TEST_DEVICE(...) RUNNER_TEST_DUMMY(__VA_ARGS__) +#endif + #include const char* ODEErrorToString(int error); @@ -102,3 +112,11 @@ public: HelperKeys(const char* device, const char* password, bool initialize = true); ~HelperKeys(); }; + +class HelperInternalEncryption { + const char* pass; + +public: + HelperInternalEncryption(const char* password); + ~HelperInternalEncryption(); +}; diff --git a/src/ode/ode-tests-internal-encryption.cpp b/src/ode/ode-tests-internal-encryption.cpp index 6d906eb3..61559eda 100644 --- a/src/ode/ode-tests-internal-encryption.cpp +++ b/src/ode/ode-tests-internal-encryption.cpp @@ -18,6 +18,295 @@ * @brief Tests for the ODE API */ -#include "dpl/test/test_runner.h" +#include +#include -RUNNER_TEST_GROUP_INIT(T1000_ODE_API_INTERNAL_ENCRYPTION); \ No newline at end of file +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "ode-tests-common.h" + +namespace OdeTestsInternalEncryption { + +const char * password = "abc123"; +const char * password_new = "def456"; + +RUNNER_TEST_GROUP_INIT(T1000_ODE_API_INTERNAL_ENCRYPTION); + +RUNNER_TEST_DEVICE(T1001_internal_encryption_set_mount_password_1_invalid_parameter) +{ + HelperInternalEncryption helper(password); + + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_set_mount_password, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_set_mount_password, nullptr); +} + +RUNNER_TEST_DEVICE(T1002_internal_encryption_set_mount_password_2_key_rejected) +{ + HelperInternalEncryption helper(password); + + // try to set the mount password different than the init password + assert_key_rejected(ode_internal_encryption_set_mount_password, password_new); +} + +RUNNER_TEST_DEVICE(T1003_internal_encryption_mount_1_no_such_device) +{ + HelperInternalEncryption helper(password); + + // set mount password + assert_positive(ode_internal_encryption_set_mount_password, password); + + assert_no_such_device(ode_internal_encryption_mount); +} + +RUNNER_TEST(T1004_internal_encryption_mount_2_no_data) +{ + assert_no_data(ode_internal_encryption_mount); +} + +RUNNER_TEST_DEVICE(T1005_internal_encryption_umount_1_no_such_device) +{ + HelperInternalEncryption helper(password); + + // set mount password + assert_positive(ode_internal_encryption_set_mount_password, password); + + assert_no_such_device(ode_internal_encryption_umount); +} + +RUNNER_TEST_DEVICE(T1006_internal_encryption_encrypt_1_invalid_parameter) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NONE is returned " + "instead of the ODE_ERROR_INVALID_PARAMETER in case " + "when options are set to NULL. Because no error is " + "returned, the device is encrypted. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_encrypt, "", 0); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_encrypt, nullptr, 0); + + // options set to NULL + assert_invalid_parameter(ode_internal_encryption_encrypt, password, NULL); + /* + * TODO: + * Maybe also value of the options (even if it is uint) should be checked + * and only 0 or 1 should be available. Alternatively options should be bool + * or if more options may be available in the future - enum. Currently, if + * options is set to any value different than 0, fast encryption is enabled. + * Otherwise it is disabled. Needs improvement in ode. + */ +} + +RUNNER_TEST_DEVICE(T1007_internal_encryption_encrypt_2_key_rejected) +{ + HelperInternalEncryption helper(password); + + // try to encrypt using the password different than the init password + assert_key_rejected(ode_internal_encryption_encrypt, password_new, 0); +} + +RUNNER_TEST(T1008_internal_encryption_encrypt_3_no_such_device) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NO_SUCH_FILE is returned " + "instead of the ODE_ERROR_NO_SUCH_DEVICE. " + "Needs improvement in ode module."); + + assert_no_such_device(ode_internal_encryption_encrypt, password, 0); +} + +RUNNER_TEST_DEVICE(T1009_internal_encryption_decrypt_1_invalid_parameter) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NO_SUCH_DEVICE is returned " + "instead of the ODE_ERROR_INVALID_PARAMETER. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_decrypt, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_decrypt, nullptr); +} + +RUNNER_TEST_DEVICE(T1010_internal_encryption_decrypt_2_key_rejected) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NO_SUCH_DEVICE is returned " + "instead of the ODE_ERROR_KEY_REJECTED. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + // try to decrypt using the password different than the init password + assert_key_rejected(ode_internal_encryption_decrypt, password_new); +} + +RUNNER_TEST_DEVICE(T1011_internal_encryption_decrypt_3_no_such_device) +{ + HelperInternalEncryption helper(password); + + assert_no_such_device(ode_internal_encryption_decrypt, password); +} + +RUNNER_TEST_DEVICE(T1012_internal_encryption_recovery_1_no_such_device) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_UNKNOWN is returned " + "instead of the ODE_ERROR_NO_SUCH_DEVICE. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + assert_no_such_device(ode_internal_encryption_recovery); +} + +RUNNER_TEST(T1013_internal_encryption_is_password_initialized_1_invalid_parameter) +{ + // result set to NULL + assert_invalid_parameter(ode_internal_encryption_is_password_initialized, nullptr); +} + +RUNNER_TEST(T1014_internal_encryption_init_password_1_invalid_parameter) +{ + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_init_password, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_init_password, nullptr); +} + +RUNNER_TEST(T1015_internal_encryption_clean_password_1_invalid_parameter) +{ + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_clean_password, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_clean_password, nullptr); +} + +RUNNER_TEST_DEVICE(T1016_internal_encryption_change_password_1_invalid_parameter) +{ + HelperInternalEncryption helper(password); + + // old password set to empty string + assert_invalid_parameter(ode_internal_encryption_change_password, "", password_new); + // old password set to NULL + assert_invalid_parameter(ode_internal_encryption_change_password, nullptr, password_new); + + // new password set to empty string + assert_invalid_parameter(ode_internal_encryption_change_password, password_new, ""); + // new password set to NULL + assert_invalid_parameter(ode_internal_encryption_change_password, password_new, nullptr); +} + +RUNNER_TEST_DEVICE(T1017_internal_encryption_change_password_2_key_rejected) +{ + HelperInternalEncryption helper(password); + + assert_key_rejected(ode_internal_encryption_change_password, password_new, password); +} + +RUNNER_TEST(T1018_internal_encryption_verify_password_1_invalid_parameter) +{ + bool result; + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_verify_password, "", &result); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_verify_password, nullptr, &result); + + // result set to NULL + assert_invalid_parameter(ode_internal_encryption_verify_password, password, nullptr); + assert_invalid_parameter(ode_internal_encryption_verify_password, password_new, nullptr); +} + +RUNNER_TEST(T1019_internal_encryption_get_state_1_invalid_parameter) +{ + // state set to NULL + assert_invalid_parameter(ode_internal_encryption_get_state, nullptr); +} + +RUNNER_TEST(T1020_internal_encryption_connection_refused) +{ + auto sm_start = [](ServiceManager* sm) { + sm->startService(true); + delete sm; + sleep(1); + //TODO: startService should wait until the sm is really started but it does not + // because of that the sleep is needed + }; + std::unique_ptr sm_stop(new ServiceManager("ode.service"), sm_start); + sm_stop->stopService(true); + + unsigned int options = 0; + bool result; + int state; + + assert_connection_refused(ode_internal_encryption_set_mount_password, password); + assert_connection_refused(ode_internal_encryption_mount); + assert_connection_refused(ode_internal_encryption_umount); + assert_connection_refused(ode_internal_encryption_encrypt, password, options); + assert_connection_refused(ode_internal_encryption_decrypt, password); + assert_connection_refused(ode_internal_encryption_recovery); + assert_connection_refused(ode_internal_encryption_is_password_initialized, &result); + assert_connection_refused(ode_internal_encryption_init_password, password); + assert_connection_refused(ode_internal_encryption_clean_password, password); + assert_connection_refused(ode_internal_encryption_change_password, password, password_new); + assert_connection_refused(ode_internal_encryption_verify_password, password, &result); + assert_connection_refused(ode_internal_encryption_get_state, &state); +} + +RUNNER_CHILD_TEST(T1021_internal_encryption_permission_denied) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_UNKNOWN is returned " + "instead of the ODE_ERROR_PERMISSION_DENIED. " + "Needs improvement in ode module."); + + TemporaryTestUser adminUserToSwitch("ode_test_T1021_user", GUM_USERTYPE_ADMIN); + adminUserToSwitch.create(); + + AppInstallHelper appInstallHelper("ode_test_T1021_app_install_helper", + adminUserToSwitch.getUid()); + + ScopedInstaller scopedInstaller(appInstallHelper); + + pid_t pid = fork(); + if (pid != 0) { + waitPid(pid); + } else { //child process + SecurityManagerTest::Api::setProcessLabel(appInstallHelper.getAppId()); + RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUserToSwitch.getUid(), + adminUserToSwitch.getGid()) == 0, + "drop_root_privileges failed"); + + unsigned int options = 0; + bool result; + int state; + + // check if there is access to unprotected function + assert_positive(ode_internal_encryption_is_password_initialized, &result); + assert_positive(ode_internal_encryption_get_state, &state); + + // check if there is no access to protected function + assert_permission_denied(ode_internal_encryption_set_mount_password, password); + assert_permission_denied(ode_internal_encryption_mount); + assert_permission_denied(ode_internal_encryption_umount); + assert_permission_denied(ode_internal_encryption_encrypt, password, options); + assert_permission_denied(ode_internal_encryption_decrypt, password); + assert_permission_denied(ode_internal_encryption_recovery); + assert_permission_denied(ode_internal_encryption_init_password, password); + assert_permission_denied(ode_internal_encryption_clean_password, password); + assert_permission_denied(ode_internal_encryption_change_password, password, password_new); + assert_permission_denied(ode_internal_encryption_verify_password, password, &result); + } +} + +} // namespace OdeTestsInternalEncryption