diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index b8eb872799d82387dc4840cbb57f544087ecf37e..d03d9720cbfbe7658a9b0c2a4edb5535d04366ac 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -162,6 +162,34 @@ ohos_unittest("local_code_sign_utils_unittest") { ] } +ohos_unittest("local_code_sign_utils_mock_unittest") { + module_out_path = "security/code_signature" + resource_config_file = "resources/ohos_test.xml" + sources = [ + "${code_signature_root_dir}/services/local_code_sign/src/local_sign_key.cpp", + "${code_signature_root_dir}/utils/src/cert_utils.cpp", + "local_code_sign_utils_mock_test.cpp", + "mock/src/hks_api_mock_helper.cpp", + "mock/src/hks_api_mock_test.cpp", + ] + deps = [ "${code_signature_root_dir}/interfaces/innerkits/code_sign_utils:libcode_sign_utils" ] + + include_dirs = [ + "mock/include", + "utils/include", + "${code_signature_root_dir}/services/local_code_sign/include", + ] + + configs = [ "${code_signature_root_dir}:common_utils_config" ] + external_deps = [ + "c_utils:utils", + "fsverity-utils:libfsverity_utils", + "hilog:libhilog", + "huks:libhukssdk", + "openssl:libcrypto_shared", + ] +} + ohos_unittest("sign_and_enforce_unittest") { module_out_path = "security/code_signature" resource_config_file = "resources/ohos_test.xml" @@ -329,6 +357,7 @@ group("unittest_group") { ":code_sign_utils_unittest", ":enable_verity_ioctl_unittest", ":local_code_sign_unittest", + ":local_code_sign_utils_mock_unittest", ":local_code_sign_utils_unittest", ":multi_thread_local_sign_unittest", ":sign_and_enforce_unittest", diff --git a/test/unittest/local_code_sign_test.cpp b/test/unittest/local_code_sign_test.cpp index cb1879be5dd24a7dd47f2f8c3257c21463b3f049..57c3af8481f4f5545a3b8ab82e37304e42c9faf1 100644 --- a/test/unittest/local_code_sign_test.cpp +++ b/test/unittest/local_code_sign_test.cpp @@ -266,6 +266,31 @@ HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0014, TestSize.Level0) NativeTokenReset(selfTokenId); EXPECT_EQ(ret, CS_ERR_INVALID_OWNER_ID); } + +/** + * @tc.name: LocalCodeSignTest_0015 + * @tc.desc: sign local code failed with ownerID exceed 128 bytes + * @tc.type: Func + * @tc.require: issueI8FCGF + */ +HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0015, TestSize.Level0) +{ + ByteBuffer sig; + uint64_t selfTokenId = NativeTokenSet("compiler_service"); + std::string ownerID = "AppName123"; + + int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig); + + NativeTokenSet("local_code_sign"); + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + EXPECT_NE(samgr, nullptr); + + ret = samgr->UnloadSystemAbility(LOCAL_CODE_SIGN_SA_ID); + EXPECT_NE(ret, ERR_OK); + NativeTokenSet("compiler_service"); + LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig); + NativeTokenReset(selfTokenId); +} } // namespace CodeSign } // namespace Security } // namespace OHOS diff --git a/test/unittest/local_code_sign_utils_mock_test.cpp b/test/unittest/local_code_sign_utils_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d46a10046425db3e37130e825ba4efc0fa80149a --- /dev/null +++ b/test/unittest/local_code_sign_utils_mock_test.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2024 Huawei Device 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 +#include +#include + +#include "cert_utils.h" +#include "directory_ex.h" +#include "fsverity_utils_helper.h" +#include "local_sign_key.h" +#include "log.h" +#include "pkcs7_generator.h" +#include "hks_api.h" + +using namespace OHOS::Security::CodeSign; +using namespace testing::ext; +using namespace std; + +namespace OHOS { +namespace Security { +namespace CodeSign { +static const std::string AN_BASE_PATH = "/data/local/ark-cache/tmp/"; +static const std::string DEMO_AN_PATH2 = AN_BASE_PATH + "demo2.an"; +static const std::string DEFAULT_HASH_ALGORITHM = "sha256"; + +class LocalCodeSignUtilsMockTest : public testing::Test { +public: + LocalCodeSignUtilsMockTest() {}; + virtual ~LocalCodeSignUtilsMockTest() {}; + static void SetUpTestCase() {}; + static void TearDownTestCase() {}; + void SetUp() {}; + void TearDown() {}; +}; + +/** + * @tc.name: LocalCodeSignUtilsMockTest_0001 + * @tc.desc: Sign local code successfully, owner ID is empty, and set g_count. + * @tc.type: Func + * @tc.require: issueI8FCGF + */ +HWTEST_F(LocalCodeSignUtilsMockTest, LocalCodeSignUtilsMockTest_0001, TestSize.Level0) +{ + ByteBuffer digest; + std::string realPath; + std::string ownerID = ""; + bool bRet = OHOS::PathToRealPath(DEMO_AN_PATH2, realPath); + EXPECT_EQ(bRet, true); + bRet = FsverityUtilsHelper::GetInstance().GenerateFormattedDigest(realPath.c_str(), digest); + EXPECT_EQ(bRet, true); + + ByteBuffer signature; + g_count = ATTESTKEY; + int ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); + + g_count = INIT; + ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); + + g_count = UPDATE; + ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); + + g_count = FINISH; + ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); +} + +/** + * @tc.name: LocalCodeSignUtilsMockTest_0002 + * @tc.desc: Sign local code with owner ID successfully, and set g_count. + * @tc.type: Func + * @tc.require: issueI88PPA + */ +HWTEST_F(LocalCodeSignUtilsMockTest, LocalCodeSignUtilsMockTest_0002, TestSize.Level0) +{ + ByteBuffer digest; + std::string realPath; + std::string ownerID = "AppName123"; + bool bRet = OHOS::PathToRealPath(DEMO_AN_PATH2, realPath); + EXPECT_EQ(bRet, true); + bRet = FsverityUtilsHelper::GetInstance().GenerateFormattedDigest(realPath.c_str(), digest); + EXPECT_EQ(bRet, true); + + ByteBuffer signature; + g_count = ATTESTKEY; + int ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); + + g_count = INIT; + ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); + + g_count = UPDATE; + ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); + + g_count = FINISH; + ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); +} + +/** + * @tc.name: LocalCodeSignUtilsMockTest_0003 + * @tc.desc: Generate formatted digest failed with wrong path + * @tc.type: Func + * @tc.require: issueI8FCGF + */ +HWTEST_F(LocalCodeSignUtilsMockTest, LocalCodeSignUtilsMockTest_0003, TestSize.Level0) +{ + std::unique_ptr challenge = GetRandomChallenge(); + LocalSignKey &key = LocalSignKey::GetInstance(); + key.SetChallenge(*challenge); + bool bRet = key.InitKey(); + EXPECT_EQ(bRet, false); + + g_count = ERROR; + bRet = key.InitKey(); + EXPECT_EQ(bRet, false); + + g_count = KEYEXIST; + bRet = key.InitKey(); + EXPECT_EQ(bRet, false); + + int32_t iRet = key.GetFormattedCertChain(*challenge); + EXPECT_EQ(iRet, 0); +} +} // namespace CodeSign +} // namespace Security +} // namespace OHOS diff --git a/test/unittest/mock/include/hks_api.h b/test/unittest/mock/include/hks_api.h index fa509f16e7dbaf829d9090d7032b4869d8a9c0ec..a783ee3628ef06e0b4e1bcf99b8e659d94d391ad 100644 --- a/test/unittest/mock/include/hks_api.h +++ b/test/unittest/mock/include/hks_api.h @@ -21,6 +21,16 @@ namespace OHOS { namespace Security { namespace CodeSign { +extern int g_count; +enum HksType { + KEYEXIST = 1, + ATTESTKEY = 2, + GENERATEKEY = 3, + INIT = 4, + UPDATE = 5, + FINISH = 6, + ERROR = 7, +}; int32_t HksKeyExist(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet); int32_t HksAttestKey(const struct HksBlob *keyAlias, diff --git a/test/unittest/mock/src/hks_api_mock_test.cpp b/test/unittest/mock/src/hks_api_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01bf6be1e76b9be3aca96112dd956b834635df8d --- /dev/null +++ b/test/unittest/mock/src/hks_api_mock_test.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024 Huawei Device 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 "hks_api.h" + +#include "hks_api_mock_helper.h" + +namespace OHOS { +namespace Security { +namespace CodeSign { +int g_count = 0; +int32_t HksKeyExist(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet) +{ + LOG_INFO("Mock HksKeyExist"); + if (g_count == KEYEXIST) { + return -1; + } + if (g_count == ERROR) { + return HKS_ERROR_NOT_EXIST; + } + return HKS_SUCCESS; +} + +int32_t HksAttestKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, + struct HksCertChain *certChain) +{ + LOG_INFO("Mock HksAttestKey"); + if (g_count == ATTESTKEY) { + return -1; + } + + bool ret = GetCertInDer(certChain->certs[0].data, certChain->certs[0].size); + if (!ret) { + LOG_ERROR("Failed to convert PEM to DER.\n"); + return HKS_FAILURE; + } + return HKS_SUCCESS; +} + +int32_t HksGenerateKey(const struct HksBlob *keyAlias, + const struct HksParamSet *paramSetIn, struct HksParamSet *paramSetOut) +{ + LOG_INFO("Mock HksGenerateKey"); + if (g_count == GENERATEKEY) { + return -1; + } + return HKS_SUCCESS; +} + +int32_t HksInit(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, + struct HksBlob *handle, struct HksBlob *token) +{ + LOG_INFO("Mock HksInit"); + if (g_count == INIT) { + return -1; + } + return HKS_SUCCESS; +} + + +int32_t HksUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData) +{ + LOG_INFO("Mock HksUpdate"); + if (g_count == UPDATE) { + return -1; + } + return HKS_SUCCESS; +} + +int32_t HksFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData) +{ + LOG_INFO("Mock HksFinish"); + if (g_count == FINISH) { + return -1; + } + return HKS_SUCCESS; +} +} +} +} \ No newline at end of file