/* * Copyright (c) 2023-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 #include #include "access_token_setter.h" #include "byte_buffer.h" #include "code_sign_utils.h" #include "local_code_sign_kit.h" #include "local_key_helper.h" #include "log.h" using namespace OHOS::Security::CodeSign; using namespace std; using namespace testing::ext; using namespace testing::mt; namespace OHOS { namespace Security { namespace CodeSign { static constexpr uint32_t MULTI_THREAD_NUM = 10; static constexpr int64_t BUFFER_SIZE = 1024; static const std::string AN_BASE_PATH = "/data/local/ark-cache/tmp/multi_thread/"; static const std::string ORIGIN_AN_FILE = AN_BASE_PATH + "demo.an"; static const std::string DEMO_WITHOWNER_ID = AN_BASE_PATH + "demoWithownerID.an"; static const char *VALID_CALLER = "compiler_service"; uint64_t GetFileSize(int32_t fd) { struct stat st; if (fstat(fd, &st) != 0) { LOG_ERROR("Stat file failed, errno = <%{public}d, %{public}s>", errno, strerror(errno)); return 0; } return st.st_size; } static bool DupFile(const std::string &path) { int32_t fin = open(ORIGIN_AN_FILE.c_str(), O_RDONLY); if (fin < 0) { return false; } uint32_t fileSize = GetFileSize(fin); int32_t fout = open(path.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0777); if (fout < 0) { close(fin); return false; } ssize_t curSize = 0; char buffer[BUFFER_SIZE]; bool ret = true; while (curSize < fileSize) { ssize_t len = read(fin, buffer, BUFFER_SIZE); if (len <= 0) { break; } curSize += len; write(fout, buffer, len); } close(fin); close(fout); return ret; } void LocalCodeSignAndEnforce() { ByteBuffer sig; uint64_t selfTokenId = NativeTokenSet(VALID_CALLER); int ret = LocalCodeSignKit::SignLocalCode(ORIGIN_AN_FILE, sig); std::thread::id thisId = std::this_thread::get_id(); std::ostringstream oss; oss << thisId; std::string thisIdStr = oss.str(); std::string tmpFileName = AN_BASE_PATH + thisIdStr + ".an"; EXPECT_EQ(DupFile(tmpFileName), true); NativeTokenReset(selfTokenId); EXPECT_EQ(ret, CS_SUCCESS); ret = CodeSignUtils::EnforceCodeSignForFile(tmpFileName, sig); EXPECT_EQ(ret, GetEnforceFileResult()); } void LocalCodeSignAndEnforceWithOwnerID() { ByteBuffer sig; uint64_t selfTokenId = NativeTokenSet(VALID_CALLER); std::string ownerID = "AppName123"; int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_WITHOWNER_ID, sig); std::thread::id thisId = std::this_thread::get_id(); std::ostringstream oss; oss << thisId; std::string thisIdStr = oss.str(); std::string tmpFileName = AN_BASE_PATH + thisIdStr + "demoWithownerID.an"; EXPECT_EQ(DupFile(tmpFileName), true); NativeTokenReset(selfTokenId); EXPECT_EQ(ret, CS_SUCCESS); ret = CodeSignUtils::EnforceCodeSignForFile(tmpFileName, sig); EXPECT_EQ(ret, GetEnforceFileResult()); } class MultiThreadLocalSignTest : public testing::Test { public: MultiThreadLocalSignTest() {}; virtual ~MultiThreadLocalSignTest() {}; static void SetUpTestCase() {}; static void TearDownTestCase() {}; void SetUp() {}; void TearDown() {}; }; /** * @tc.name: MultiThreadLocalSignTest_0001 * @tc.desc: sign AN files and enforce using multi threads * @tc.type: Func * @tc.require: */ HWMTEST_F(MultiThreadLocalSignTest, MultiThreadLocalSignTest_0001, TestSize.Level1, MULTI_THREAD_NUM) { LocalCodeSignAndEnforce(); } /** * @tc.name: MultiThreadLocalSignTest_0002 * @tc.desc: sign AN files with owner ID and enforce using multi threads * @tc.type: Func * @tc.require: */ HWMTEST_F(MultiThreadLocalSignTest, MultiThreadLocalSignTest_0002, TestSize.Level1, MULTI_THREAD_NUM) { LocalCodeSignAndEnforceWithOwnerID(); } } // namespace CodeSign } // namespace Security } // namespace OHOS