--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#include <system_info.h>
+#include <gtest/gtest.h>
+#include <string.h>
+
+#include "hal-security-certs.h"
+
+int check_feature(void)
+{
+ bool is_supported;
+ if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool(
+ "http://tizen.org/feature/security.device_certificate", &is_supported))
+ return -1; // error
+ else if (is_supported)
+ return 1; // supported
+ else
+ return 0; // not supported
+}
+
+class SECURITY_CERTS : public testing::Test
+{
+protected:
+ void SetUp() override {
+ int ret;
+ status = check_feature();
+ switch (status) {
+ case 1:
+ ret = hal_security_certs_get_backend();
+ ASSERT_EQ(ret, 0) << "Failed to get security certs backend (" << ret << ")";
+ break;
+ case 0:
+ GTEST_SKIP() << "Device certificate feature not supported, test skipped.";
+ break;
+ case -1:
+ GTEST_FAIL() << "Checking platform feature failed.";
+ break;
+ }
+ };
+
+ void TearDown() override {
+ if (status == 1) {
+ int ret = hal_security_certs_put_backend();
+ EXPECT_EQ(ret, 0) << "Failed to put security certs backend (" << ret << ")";
+ }
+ };
+
+ int status;
+};
+
+TEST_F(SECURITY_CERTS, CreateAndFreeKeyContextPositive)
+{
+ int ret;
+
+ hal_security_certs_context_s context;
+ std::string correct_key_type = "RSA";
+ hal_security_certs_data_s correct_key_type_data_s =
+ {
+ const_cast<char*>(correct_key_type.c_str()),
+ correct_key_type.size()
+ };
+
+ ret = hal_security_certs_create_key_context(&context, correct_key_type_data_s);
+ EXPECT_EQ(ret, 0) << "Failed to create key context (" << ret << ")";
+
+ ret = hal_security_certs_free_key_context(&context);
+ EXPECT_EQ(ret, 0) << "Failed to free key context (" << ret << ")";
+}
+
+TEST_F(SECURITY_CERTS, CreateKeyContextNegative)
+{
+ int ret;
+
+ hal_security_certs_context_s context;
+ std::string wrong_key_type = "error";
+ hal_security_certs_data_s wrong_key_type_data_s =
+ {
+ const_cast<char*>(wrong_key_type.c_str()),
+ wrong_key_type.size()
+ };
+
+ ret = hal_security_certs_create_key_context(&context, wrong_key_type_data_s);
+ EXPECT_EQ(ret, -ENODATA) << "Created wrong key context (" << ret << ")";
+}
+
+TEST_F(SECURITY_CERTS, RequestCertificateChainContextPositive)
+{
+ int ret;
+
+ hal_security_certs_context_s context;
+
+ for (std::string key_type : {"RSA", "ECDSA"})
+ {
+ hal_security_certs_data_s key_type_data_s =
+ {
+ const_cast<char*>(key_type.c_str()),
+ key_type.size()
+ };
+
+ ret = hal_security_certs_create_key_context(&context, key_type_data_s);
+ EXPECT_EQ(ret, 0) << "Failed to create key context (" << ret << ")";
+
+ hal_security_certs_data_s chain;
+ ret = hal_security_certs_request_certificate_chain(&context, &chain);
+ EXPECT_EQ(ret, 0) << "Failed to request certificate chain (" << ret << ")";
+ EXPECT_TRUE(chain.length > 0) << "Certificate chain length is zero";
+ free(chain.buffer);
+
+ ret = hal_security_certs_free_key_context(&context);
+ EXPECT_EQ(ret, 0) << "Failed to free key context (" << ret << ")";
+ }
+}
+
+TEST_F(SECURITY_CERTS, SignCryptoDataPositive)
+{
+ int ret;
+
+ hal_security_certs_context_s context;
+ std::map<hal_security_certs_digest_type_e, int> digest_length_map =
+ {
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_MD2, 128/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_MD4, 128/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_MD5, 128/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_SHA1, 160/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_SHA224, 224/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_SHA256, 256/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_SHA384, 384/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_SHA512, 512/8},
+ {HAL_SECURITY_CERTS_DIGEST_TYPE_RIPEMD160, 160/8}
+ };
+
+ for (std::string key_type : {"RSA", "ECDSA"})
+ {
+
+ hal_security_certs_data_s key_type_data_s =
+ {
+ const_cast<char*>(key_type.c_str()),
+ key_type.size()
+ };
+
+ ret = hal_security_certs_create_key_context(&context, key_type_data_s);
+ EXPECT_EQ(ret, 0) << "Failed to create key context (" << ret << ")";
+
+ for (auto digest : digest_length_map) {
+ char data[digest.second] = {0,};
+ hal_security_certs_data_s message_data_s =
+ {
+ data,
+ sizeof(data)
+ };
+
+ hal_security_certs_data_s signature;
+ hal_security_certs_digest_type_e digest_type = static_cast<hal_security_certs_digest_type_e>(digest.first);
+ ret = hal_security_certs_sign_crypto_data(&context, digest_type, message_data_s, &signature);
+ EXPECT_EQ(ret, 0) << "Failed to sign crypto data (" << ret << ")";
+ EXPECT_TRUE(signature.length > 0) << "Signature length is zero";
+ free(signature.buffer);
+ }
+
+ ret = hal_security_certs_free_key_context(&context);
+ EXPECT_EQ(ret, 0) << "Failed to free key context (" << ret << ")";
+ }
+}
+
+TEST_F(SECURITY_CERTS, SignCryptoDataNegative)
+{
+ int ret;
+
+ hal_security_certs_context_s context;
+ std::string key_type = "RSA";
+ hal_security_certs_data_s key_type_data_s =
+ {
+ const_cast<char*>(key_type.c_str()),
+ key_type.size()
+ };
+
+ ret = hal_security_certs_create_key_context(&context, key_type_data_s);
+ EXPECT_EQ(ret, 0) << "Failed to create key context (" << ret << ")";
+
+ char data[20] = {0,};
+ hal_security_certs_data_s message_data_s =
+ {
+ data,
+ sizeof(data)
+ };
+
+ hal_security_certs_data_s signature;
+ ret = hal_security_certs_sign_crypto_data(
+ &context, HAL_SECURITY_CERTS_DIGEST_TYPE_SHA256, message_data_s, &signature);
+ EXPECT_EQ(ret, -EINVAL) << "Succeded with wrong size of crypto data to sign (" << ret << ")";
+
+ hal_security_certs_digest_type_e wrong_digest_type = static_cast<hal_security_certs_digest_type_e>(-1);
+ ret = hal_security_certs_sign_crypto_data(&context, wrong_digest_type, message_data_s, &signature);
+ EXPECT_EQ(ret, -EINVAL) << "Succeded with wrong digest type to sign crypto data (" << ret << ")";
+
+ ret = hal_security_certs_free_key_context(&context);
+ EXPECT_EQ(ret, 0) << "Failed to free key context (" << ret << ")";
+}
+
+TEST_F(SECURITY_CERTS, GetKeyTypeAndLengthPositive)
+{
+ int ret;
+
+ std::map<std::string, std::pair<hal_security_certs_crypto_key_type_e, unsigned int>> key_map =
+ {
+ {"RSA", {HAL_SECURITY_CERTS_KEY_TYPE_RSA, 1024}},
+ {"ECDSA", {HAL_SECURITY_CERTS_KEY_TYPE_ECDSA, 521}},
+ };
+
+ for (auto key : key_map)
+ {
+ std::string key_type = key.first;
+ hal_security_certs_crypto_key_type_e ret_key_type_enum;
+ unsigned int key_bit_length = key.second.second;
+ hal_security_certs_crypto_key_type_e key_type_enum = key.second.first;
+
+ hal_security_certs_data_s key_type_data_s =
+ {
+ const_cast<char*>(key_type.c_str()),
+ key_type.size()
+ };
+
+ hal_security_certs_context_s context;
+ ret = hal_security_certs_create_key_context(&context, key_type_data_s);
+ EXPECT_EQ(ret, 0) << "Failed to create key context (" << ret << ")";
+
+ ret = hal_security_certs_get_key_type(&context, &ret_key_type_enum);
+ EXPECT_EQ(ret, 0) << "Failed to get key type (" << ret << ")";
+ EXPECT_EQ(ret_key_type_enum, key_type_enum) << "Incorrect key type (" << ret_key_type_enum << ")";
+
+ unsigned int key_length = 0;
+ ret = hal_security_certs_get_key_bit_length(&context, &key_length);
+ EXPECT_EQ(ret, 0) << "Failed to get key bit length (" << ret << ")";
+ EXPECT_EQ(key_length, key_bit_length) << "Incorrect key bit length (" << key_length << ")";
+
+ ret = hal_security_certs_free_key_context(&context);
+ EXPECT_EQ(ret, 0) << "Failed to free key context (" << ret << ")";
+ }
+}
+
+TEST_F(SECURITY_CERTS, ExtCallApiNegative)
+{
+ int ret;
+
+ std::string method_name = "test-method-name";
+ hal_security_certs_data_s method_name_data_s =
+ {
+ const_cast<char*>(method_name.c_str()),
+ method_name.size()
+ };
+
+ hal_security_certs_data_s input_data_s;
+ hal_security_certs_data_s output_data_s;
+
+ ret = hal_security_certs_ext_call_api(method_name_data_s, input_data_s, &output_data_s);
+ EXPECT_EQ(ret, -EINVAL) << "Executesd not exisitng external call api method (" << ret << ")";
+}
+
+TEST_F(SECURITY_CERTS, ExtGetApiPrivilegeNegative)
+{
+ int ret;
+
+ std::string method_name = "test-method-name";
+ hal_security_certs_data_s method_name_data_s =
+ {
+ const_cast<char*>(method_name.c_str()),
+ method_name.size()
+ };
+
+ hal_security_certs_data_s privilege;
+
+ ret = hal_security_certs_ext_get_api_privilege(method_name_data_s, &privilege);
+ EXPECT_EQ(ret, -EINVAL) << "Executesd not exisitng external call api method (" << ret << ")";
+}