* @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