ODE API negative tests: internal encryption 14/182614/5
authorPawel Kowalski <p.kowalski2@partner.samsung.com>
Mon, 25 Jun 2018 11:38:33 +0000 (13:38 +0200)
committerPawel Kowalski <p.kowalski2@partner.samsung.com>
Thu, 27 Sep 2018 09:39:05 +0000 (11:39 +0200)
Change-Id: I4e342049e268bd17ed4367a1e998d38b0aa8b8ba

packaging/security-tests.spec
src/ode/CMakeLists.txt
src/ode/ode-tests-common.cpp
src/ode/ode-tests-common.h
src/ode/ode-tests-internal-encryption.cpp

index 2d3e333..af50270 100644 (file)
@@ -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}              \
index cf6aa47..f7fd464 100644 (file)
@@ -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})
index e3b314d..651ded7 100644 (file)
  *  @brief  Tests for the ODE API
  */
 
+#include <iostream>
+#include <string>
+
 #include <dpl/log/log.h>
+
 #include <ode/keys.h>
+#include <ode/internal-encryption.h>
 #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);
+}
index 3b03618..b15440c 100644 (file)
 #include <utility>
 
 #include <dpl/test/test_runner.h>
+
+#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 <ode/common.h>
 
 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();
+};
index 6d906eb..61559ed 100644 (file)
  *  @brief  Tests for the ODE API
  */
 
-#include "dpl/test/test_runner.h"
+#include <memory>
+#include <string>
 
-RUNNER_TEST_GROUP_INIT(T1000_ODE_API_INTERNAL_ENCRYPTION);
\ No newline at end of file
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <dpl/log/log.h>
+#include <temp_test_user.h>
+#include <app_install_helper.h>
+#include <tests_common.h>
+#include <scoped_installer.h>
+#include <service_manager.h>
+
+#include <ode/internal-encryption.h>
+#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<ServiceManager, decltype(sm_start)> 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