SET(BUILD_CYNARA ON)
SET(BUILD_WEB ON)
SET(BUILD_YACA ON)
+ SET(BUILD_ODE ON)
ENDIF(BUILD_ALL_TESTS)
# If supported for the target machine, emit position-independent code,suitable
security-manager-tests
cynara
cynara-test
+ode
+ ode-tests
There are also inner-tests for testing complex security-tests framework
mechanisms with binary:
BuildRequires: key-manager-initial-values
BuildRequires: util-linux
BuildRequires: pkgconfig(yaca)
+BuildRequires: pkgconfig(ode)
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(dbus-1)
export LDFLAGS+="-Wl,--rpath=%{_prefix}/lib"
cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+%if "%{_with_emulator}" == "1"
+ -DEMULATOR="ON" \
+%endif
%if %{tz_backend_enabled} == ON
-DTZ_BACKEND="ON" \
%endif
%caps(cap_mac_admin=ep) /usr/bin/ckm-privileged-tests
%caps(cap_mac_admin=ep) /usr/bin/ckm-integration-tests
/usr/bin/yaca-test
+/usr/bin/ode-tests
%{ckm_test_dir}/*
/etc/security-tests
/usr/lib/security-tests/cynara-tests/plugins/single-policy/*
IF(BUILD_YACA)
ADD_SUBDIRECTORY(yaca)
ENDIF(BUILD_YACA)
+
+IF(BUILD_ODE)
+ ADD_SUBDIRECTORY(ode)
+ENDIF(BUILD_ODE)
\ No newline at end of file
--- /dev/null
+#
+# Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+# @file CMakeLists.txt
+# @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+#
+
+MESSAGE(STATUS "")
+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})
+
+## Link libraries ##############################################################
+PKG_CHECK_MODULES(ODE_TESTS_DEPS REQUIRED
+ ode
+ security-manager
+ dbus-1
+ libgum
+)
+
+INCLUDE_DIRECTORIES(SYSTEM
+ ${ODE_TESTS_DEPS_INCLUDE_DIRS}
+ ${PROJECT_SOURCE_DIR}/src/common/
+)
+
+TARGET_LINK_LIBRARIES(
+ ${ODE_TESTS}
+ ${ODE_TESTS_DEPS_LIBRARIES}
+ dpl-test-framework
+ tests-common
+)
+
+## Install #####################################################################
+INSTALL(TARGETS ${ODE_TESTS} DESTINATION bin)
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-tests-common.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @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
+
+const char* ODEErrorToString(int error) {
+ switch(error) {
+ ERRORDESCRIBE(ODE_ERROR_NONE);
+ ERRORDESCRIBE(ODE_ERROR_INVALID_PARAMETER);
+ ERRORDESCRIBE(ODE_ERROR_CONNECTION_REFUSED);
+ ERRORDESCRIBE(ODE_ERROR_PERMISSION_DENIED);
+ ERRORDESCRIBE(ODE_ERROR_NO_SUCH_FILE);
+ ERRORDESCRIBE(ODE_ERROR_NO_SUCH_DEVICE);
+ ERRORDESCRIBE(ODE_ERROR_KEY_REJECTED);
+ ERRORDESCRIBE(ODE_ERROR_NO_DATA);
+ ERRORDESCRIBE(ODE_ERROR_RESOURCE_BUSY);
+ ERRORDESCRIBE(ODE_ERROR_UNKNOWN);
+ default: return "Error not defined";
+ }
+}
+
+#undef ERRORDESCRIBE
+
+// helper classes
+
+HelperKeys::HelperKeys(const char* device, const char* password, bool initialize) {
+ dev = device;
+ pass = password;
+
+ if (initialize) {
+ bool result;
+ assert_positive(ode_key_is_initialized, dev, &result);
+
+ if (!result) {
+ assert_positive(ode_key_init, dev, pass, ODE_KEY_DEFAULT_256BIT);
+ }
+ }
+}
+
+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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-tests-common.h
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @brief Tests for the ODE API
+ */
+
+#pragma once
+
+#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);
+
+// RUNNER_ASSERT wrappers
+
+template <typename F, typename... Args>
+void assert_result(int expected, F&& func, Args... args)
+{
+ int ret = func(args...);
+ RUNNER_ASSERT_MSG(ret == expected,
+ "Expected: " << ODEErrorToString(expected) << "(" << expected << ")"
+ " got: " << ODEErrorToString(ret) << "(" << ret << ")");
+}
+
+template <typename F, typename... Args>
+void assert_positive(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_NONE, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_invalid_parameter(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_INVALID_PARAMETER, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_connection_refused(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_CONNECTION_REFUSED, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_permission_denied(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_PERMISSION_DENIED, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_no_such_file(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_NO_SUCH_FILE, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_no_such_device(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_NO_SUCH_DEVICE, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_key_rejected(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_KEY_REJECTED, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_no_data(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_NO_DATA, std::move(func), args...);
+}
+
+template <typename F, typename... Args>
+void assert_resource_busy(F&& func, Args... args)
+{
+ assert_result(ODE_ERROR_RESOURCE_BUSY, std::move(func), args...);
+}
+
+// helper classes
+
+class HelperKeys {
+ const char* dev;
+ const char* pass;
+
+public:
+ HelperKeys(const char* device, const char* password, bool initialize = true);
+ ~HelperKeys();
+};
+
+class HelperInternalEncryption {
+ const char* pass;
+
+public:
+ HelperInternalEncryption(const char* password);
+ ~HelperInternalEncryption();
+};
--- /dev/null
+/*
+ * Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-tests-external-encryption.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @brief Tests for the ODE API
+ */
+
+#include "dpl/test/test_runner.h"
+
+RUNNER_TEST_GROUP_INIT(T0000_ODE_API_EXTERNAL_ENCRYPTION);
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-tests-internal-encryption.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @brief Tests for the ODE API
+ */
+
+#include <memory>
+#include <string>
+
+#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
--- /dev/null
+/*
+ * Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-tests-keys.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @brief Tests for the ODE API
+ */
+
+#include <memory>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.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/keys.h>
+#include "ode-tests-common.h"
+
+namespace OdeTestsKeys {
+
+const std::string PRIVILEGE_INTERNAL_USERMANAGEMENT =
+ "http://tizen.org/privilege/internal/usermanagement";
+const std::string PRIVILEGE_INTERNAL_DEFAULT_PLATFORM =
+ "http://tizen.org/privilege/internal/default/platform";
+
+const char* device1 = "/dev/vda1";
+const char* device2 = "/dev/vda2";
+
+const char* password = "abc123";
+const char* password_new = "def456";
+
+// TODO: obtain existing block devices from /proc/mounts
+
+RUNNER_TEST_GROUP_INIT(T2000_ODE_API_KEYS);
+
+/*
+ * If at least one of the parameters in invalid, then the INVALID_PARAM error
+ * is returned.
+ */
+RUNNER_TEST(T2001_ode_key_is_initialized_1_invalid_parameter)
+{
+ bool result;
+
+ // device set to empty string
+ assert_invalid_parameter(ode_key_is_initialized, "", &result);
+ // device set to NULL
+ assert_invalid_parameter(ode_key_is_initialized, nullptr, &result);
+
+ // result set to NULL
+ assert_invalid_parameter(ode_key_is_initialized, device1, nullptr);
+}
+
+/*
+ * The third argument of the ode_key_init function is the type of key
+ * initialization method used. It may be ODE_KEY_DEFAULT_256BIT (1) or
+ * ODE_KEY_DEFAULT_512BIT (2). So if value different than 1 or 2 is passed,
+ * invalid parameter error is returned by the function.
+ * Invalid parameter error is returned also if empty strings or null pointers
+ * are passed as the arguments of the function.
+ */
+RUNNER_TEST(T2002_ode_key_init_1_invalid_parameter)
+{
+ // device set to empty string
+ assert_invalid_parameter(ode_key_init, "", password, ODE_KEY_DEFAULT_256BIT);
+ // device set to NULL
+ assert_invalid_parameter(ode_key_init, nullptr, password, ODE_KEY_DEFAULT_256BIT);
+
+ // password set to empty string
+ assert_invalid_parameter(ode_key_init, device1, "", ODE_KEY_DEFAULT_256BIT);
+ // password set to NULL
+ assert_invalid_parameter(ode_key_init, device1, nullptr, ODE_KEY_DEFAULT_256BIT);
+
+ // if the key will be initialized, the helper will remove it after the test execution
+ HelperKeys helper(device1, password, false);
+ // invalid type of key
+ assert_invalid_parameter(ode_key_init, device1, password, static_cast<ode_key_gen_params_e>(0));
+ assert_invalid_parameter(ode_key_init, device1, password, static_cast<ode_key_gen_params_e>(3));
+}
+
+/*
+ * TODO: ode_key_init should return invalid param in case of double init
+ *
+ * Calling ode_key_init() second time for given device should fail (now it just
+ * overwrites the existing key).
+ */
+RUNNER_TEST(T2003_ode_key_init_2_invalid_parameter_double_init)
+{
+ RUNNER_IGNORED_MSG("Test ignored because no error is returned in case of "
+ "the double init, while the ODE_ERROR_INVALID_PARAMETER "
+ "should be returned.");
+
+ HelperKeys helper(device1, password);
+
+ assert_invalid_parameter(ode_key_init, device1, password, ODE_KEY_DEFAULT_256BIT);
+}
+
+/*
+ * Invalid parameter error is returned if empty strings or null pointers
+ * are passed as the arguments of the function.
+ */
+RUNNER_TEST(T2004_ode_key_remove_1_invalid_parameter)
+{
+ HelperKeys helper(device1, password);
+
+ // device set to empty string
+ assert_invalid_parameter(ode_key_remove, "", password);
+ // device set to NULL
+ assert_invalid_parameter(ode_key_remove, nullptr, password);
+
+ // password set to empty string
+ assert_invalid_parameter(ode_key_remove, device1, "");
+ // password set to NULL
+ assert_invalid_parameter(ode_key_remove, device1, nullptr);
+}
+
+/*
+ * If the password is wrong, then the key cannot be removed and the error
+ * should be returned by the ode_key_remove function.
+ */
+RUNNER_TEST(T2005_ode_key_remove_2_rejected)
+{
+ const char* password_wrong = "abc321";
+
+ HelperKeys helper(device1, password);
+
+ assert_key_rejected(ode_key_remove, device1, password_wrong);
+}
+
+/*
+ * If no key exists for the given device, then the error should be returned by
+ * the ode_key_remove function.
+ */
+RUNNER_TEST(T2006_ode_key_remove_3_no_such_file)
+{
+ assert_no_such_file(ode_key_remove, device1, password);
+ assert_no_such_file(ode_key_remove, device2, password);
+}
+
+/*
+ * Invalid parameter error is returned if empty strings or null pointers
+ * are passed as the arguments of the function.
+ */
+RUNNER_TEST(T2007_ode_key_change_password_1_invalid_parameter)
+{
+ HelperKeys helper(device1, password);
+
+ // device set to empty string
+ assert_invalid_parameter(ode_key_change_password, "", password, password_new);
+ // device set to NULL
+ assert_invalid_parameter(ode_key_change_password, nullptr, password, password_new);
+
+ // old password set to empty string
+ assert_invalid_parameter(ode_key_change_password, device1, "", password_new);
+ // old password set to NULL
+ assert_invalid_parameter(ode_key_change_password, device1, nullptr, password_new);
+
+ // new password set to empty string
+ assert_invalid_parameter(ode_key_change_password, device1, password, "");
+ // new password set to NULL
+ assert_invalid_parameter(ode_key_change_password, device1, password, nullptr);
+}
+
+/*
+ * If the current password is wrong (for example the developer mistook the
+ * string with the current password with the new one), then the password cannot
+ * be changed and the error is returned by the ode_key_change_password
+ * function.
+ */
+RUNNER_TEST(T2008_ode_key_change_password_2_key_rejected)
+{
+ HelperKeys helper(device1, password);
+
+ assert_key_rejected(ode_key_change_password, device1, password_new, password);
+}
+
+/*
+ * If no key exists for the given device, then the password cannot be changed
+ * and the error is returned by the ode_key_change_password function.
+ */
+RUNNER_TEST(T2009_ode_key_change_password_3_no_such_file)
+{
+ assert_no_such_file(ode_key_change_password, device1, password, password_new);
+ assert_no_such_file(ode_key_change_password, device2, password, password_new);
+}
+
+/*
+ * Invalid parameter error is returned if empty strings or null pointers
+ * are passed as the arguments of the function.
+ */
+RUNNER_TEST(T2010_ode_key_verify_password_1_invalid_parameter)
+{
+ HelperKeys helper(device1, password);
+
+ bool result;
+
+ // device set to empty string
+ assert_invalid_parameter(ode_key_verify_password, "", password, &result);
+ // device set to NULL
+ assert_invalid_parameter(ode_key_verify_password, nullptr, password, &result);
+
+ // password set to empty string
+ assert_invalid_parameter(ode_key_verify_password, device1, "", &result);
+ // password set to NULL
+ assert_invalid_parameter(ode_key_verify_password, device1, nullptr, &result);
+
+ // result set to NULL
+ assert_invalid_parameter(ode_key_verify_password, device1, password, nullptr);
+}
+
+RUNNER_TEST(T2011_ode_key_verify_password_2_no_such_file)
+{
+ bool result;
+
+ assert_no_such_file(ode_key_verify_password, device1, password, &result);
+ assert_no_such_file(ode_key_verify_password, device2, password, &result);
+}
+
+/*
+ * Invalid parameter error is returned if empty strings or null pointers
+ * are passed as the arguments of the function.
+ */
+RUNNER_TEST(T2012_ode_key_store_master_key_1_invalid_parameter)
+{
+ HelperKeys helper(device1, password);
+
+ // device set to empty string
+ assert_invalid_parameter(ode_key_store_master_key, "", password);
+ // device set to NULL
+ assert_invalid_parameter(ode_key_store_master_key, nullptr, password);
+
+ // password set to empty string
+ assert_invalid_parameter(ode_key_store_master_key, device1, "");
+ // password set to NULL
+ assert_invalid_parameter(ode_key_store_master_key, device1, nullptr);
+}
+
+/*
+ * If the password passed into the ode_key_store_master_key function is wrong,
+ * then the key cannot be stored and ODE_ERROR_KEY_REJECTED should be returned
+ * by the storing function.
+ */
+RUNNER_TEST(T2013_ode_key_store_master_key_2_key_rejected)
+{
+ HelperKeys helper(device1, password);
+
+ assert_key_rejected(ode_key_store_master_key, device1, password_new);
+}
+
+RUNNER_TEST(T2014_ode_key_store_master_key_3_no_such_file)
+{
+ assert_no_such_file(ode_key_store_master_key, device1, password);
+ assert_no_such_file(ode_key_store_master_key, device2, password);
+}
+
+/*
+ * Invalid parameter error is returned if empty strings or null pointers
+ * are passed as the arguments of the function.
+ */
+RUNNER_TEST(T2015_ode_key_remove_master_key_1_invalid_parameter)
+{
+ HelperKeys helper(device1, password);
+
+ assert_positive(ode_key_store_master_key, device1, password);
+
+ // device set to empty string
+ assert_invalid_parameter(ode_key_remove_master_key, "");
+ // device set to NULL
+ assert_invalid_parameter(ode_key_remove_master_key, nullptr);
+}
+
+/*
+ * If the ode service is not active during the try of using the API functions,
+ * then the connection should be refused and the error should be returned by
+ * the API function.
+ */
+RUNNER_TEST(T2016_ode_keys_connection_refused)
+{
+ HelperKeys helper(device1, password);
+
+ auto sm_start = [](ServiceManager* sm) {
+ sm->startService(true);
+ delete sm;
+ };
+ std::unique_ptr<ServiceManager, decltype(sm_start)> sm_stop(new ServiceManager("ode.service"), sm_start);
+ sm_stop->stopService(true);
+
+ bool result;
+
+ assert_connection_refused(ode_key_is_initialized, device1, &result);
+ assert_connection_refused(ode_key_init, device1, password, ODE_KEY_DEFAULT_256BIT);
+ assert_connection_refused(ode_key_remove, device1, password);
+ assert_connection_refused(ode_key_change_password, device1, password, password_new);
+ assert_connection_refused(ode_key_verify_password, device1, password, &result);
+ assert_connection_refused(ode_key_store_master_key, device1, password);
+ assert_connection_refused(ode_key_remove_master_key, device1);
+}
+
+/*
+ * When the unprivileged process (without the privilege internal/default/platform)
+ * tries to use protected API functions, then the PERMISSION_DENIED error is
+ * returned.
+ *
+ * TODO: permission denied should be returned instead of unknown error
+ */
+RUNNER_CHILD_TEST(T2017_ode_keys_permission_denied)
+{
+ RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_UNKNOWN is returned "
+ "instead of the ODE_ERROR_PERMISSION_DENIED.");
+
+ TemporaryTestUser adminUserToSwitch("ode_test_T2016_user", GUM_USERTYPE_ADMIN);
+ adminUserToSwitch.create();
+
+ AppInstallHelper appInstallHelper("ode_test_T2016_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");
+
+ bool result;
+
+ // check if there is access to unprotected function
+ assert_positive(ode_key_is_initialized, device1, &result);
+
+ // check if there is no access to protected function
+ assert_permission_denied(ode_key_init, device1, password, ODE_KEY_DEFAULT_256BIT);
+ assert_permission_denied(ode_key_remove, device1, password);
+ assert_permission_denied(ode_key_change_password, device1, password, password_new);
+ assert_permission_denied(ode_key_verify_password, device1, password, &result);
+ assert_permission_denied(ode_key_store_master_key, device1, password);
+ assert_permission_denied(ode_key_remove_master_key, device1);
+ }
+}
+
+} // namespace OdeTestsKeys
--- /dev/null
+/*
+ * Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-tests-luks.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @brief Tests for the ODE API
+ */
+
+#include "dpl/test/test_runner.h"
+
+RUNNER_TEST_GROUP_INIT(T3000_ODE_API_LUKS);
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-tests-secure-erase.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @brief Tests for the ODE API
+ */
+
+#include "dpl/test/test_runner.h"
+
+RUNNER_TEST_GROUP_INIT(T4000_ODE_API_SECURE_ERASE);
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file ode-test.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ * @brief Tests for the ODE API
+ */
+
+#include <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+
+int main (int argc, char *argv[])
+{
+ DPL::Log::LogSystemSingleton::Instance().SetTag("SECURITY_TESTS_ODE");
+ int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+ return status;
+}