diff --git a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h index 90d51b11dc80b35b2116311bad306def5790be8d..822aef7b2fc6dfb9a4660719bc628ef9805f5b68 100644 --- a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -42,7 +42,7 @@ typedef enum { class CodeSignUtils { public: /** - * @brief Enforce code signature for app + * @brief Enforce code signature for a hap * @param entryPath map from entryname in hap to real path on disk * @param signatureFile signature file path * @return err code, see err_code.h @@ -50,27 +50,25 @@ public: static int32_t EnforceCodeSignForApp(const EntryMap &entryPath, const std::string &signatureFile); /** - * @brief Enforce code signature for app + * @brief Enforce code signature for a hap with its native files. + * Multiple instances should be created to enable code signing for a multi-hap app. * @param path hap real path on disk * @param entryPath map from entryname in hap to real path on disk * @param type signature file type - * @param moduleName hap module name * @return err code, see err_code.h */ - int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, - FileType type, const std::string &moduleName); + int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type); /** - * @brief Enforce code signature for app with ownerID + * @brief Enforce code signature for a hap with ownerID * @param ownerId app-identifier of the signature * @param path hap real path on disk * @param entryPath map from entryname in hap to real path on disk * @param type signature file type - * @param moduleName hap module name * @return err code, see err_code.h */ int32_t EnforceCodeSignForAppWithOwnerId(const std::string &ownerId, const std::string &path, - const EntryMap &entryPathMap, FileType type, const std::string &moduleName); + const EntryMap &entryPathMap, FileType type); /** * @brief Enforce code signature for file with signature @@ -118,11 +116,6 @@ public: * @return return ture if in permissive mode */ static bool InPermissiveMode(); - /** - * @brief Check if code signing is completed - * @return return ture if Completed - */ - bool IsCodeSignEnableCompleted(); /** * @brief Check if the file path support FsVerity * @param path file path @@ -132,14 +125,10 @@ public: private: static int32_t IsFsVerityEnabled(int fd); static int32_t EnableCodeSignForFile(const std::string &path, const struct code_sign_enable_arg &arg); - void StoredEntryMapInsert(const std::string &moduleName, const EntryMap &entryPathMap); - void StoredEntryMapDelete(const std::string &moduleName); - void StoredEntryMapSearch(const std::string &moduleName, EntryMap &entryPathMap); - int32_t ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, - FileType type, const std::string &moduleName); + int32_t ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, FileType type); int32_t HandleCodeSignBlockFailure(const std::string &realPath, int32_t ret); private: - std::unordered_map storedEntryMap_; + EntryMap storedEntryMap_; std::mutex storedEntryMapLock_; }; } diff --git a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp index 2a3a6c5b306e139ecf4da2538049f747ad1059ee..72e9bbe7955c94d4c6d0334deab2678a90392098 100644 --- a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -210,12 +210,15 @@ int32_t CodeSignUtils::EnforceCodeSignForFile(const std::string &path, const uin } int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(const std::string &ownerId, const std::string &path, - const EntryMap &entryPathMap, FileType type, const std::string &moduleName) + const EntryMap &entryPathMap, FileType type) { LOG_INFO(LABEL, "Start to enforce codesign FileType:%{public}d, entryPathMap size:%{public}u, path = %{public}s", type, static_cast(entryPathMap.size()), path.c_str()); if (type == FILE_ENTRY_ADD || type == FILE_ENTRY_ONLY || type == FILE_ALL) { - StoredEntryMapInsert(moduleName, entryPathMap); + { + std::lock_guard lock(storedEntryMapLock_); + storedEntryMap_.insert(entryPathMap.begin(), entryPathMap.end()); + } if (type == FILE_ENTRY_ADD) { LOG_DEBUG(LABEL, "Add entryPathMap complete"); return CS_SUCCESS; @@ -223,24 +226,21 @@ int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(const std::string &owner } else if (type >= FILE_TYPE_MAX) { return CS_ERR_PARAM_INVALID; } - return ProcessCodeSignBlock(ownerId, path, type, moduleName); + return ProcessCodeSignBlock(ownerId, path, type); } -int32_t CodeSignUtils::ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, - FileType type, const std::string &moduleName) +int32_t CodeSignUtils::ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, FileType type) { std::string realPath; if (!OHOS::PathToRealPath(path, realPath)) { return CS_ERR_FILE_PATH; } int32_t ret; - EntryMap entryMap; CodeSignHelper codeSignHelper; { std::lock_guard lock(storedEntryMapLock_); - StoredEntryMapSearch(moduleName, entryMap); - ret = codeSignHelper.ParseCodeSignBlock(realPath, entryMap, type); - StoredEntryMapDelete(moduleName); + ret = codeSignHelper.ParseCodeSignBlock(realPath, storedEntryMap_, type); + storedEntryMap_.clear(); } if (ret != CS_SUCCESS) { return HandleCodeSignBlockFailure(realPath, ret); @@ -258,10 +258,9 @@ int32_t CodeSignUtils::HandleCodeSignBlockFailure(const std::string &realPath, i return ret; } -int32_t CodeSignUtils::EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, - FileType type, const std::string &moduleName) +int32_t CodeSignUtils::EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type) { - return EnforceCodeSignForAppWithOwnerId("", path, entryPathMap, type, moduleName); + return EnforceCodeSignForAppWithOwnerId("", path, entryPathMap, type); } int32_t CodeSignUtils::EnableKeyInProfile(const std::string &bundleName, const ByteBuffer &profileBuffer) @@ -317,40 +316,6 @@ bool CodeSignUtils::IsSupportOHCodeSign() return false; #endif } - -bool CodeSignUtils::IsCodeSignEnableCompleted() -{ - std::lock_guard lock(storedEntryMapLock_); - if (!storedEntryMap_.empty()) { - storedEntryMap_.clear(); - return false; - } - return true; -} - -void CodeSignUtils::StoredEntryMapInsert(const std::string &moduleName, const EntryMap &entryPathMap) -{ - std::lock_guard lock(storedEntryMapLock_); - auto iter = storedEntryMap_.find(moduleName); - if (iter != storedEntryMap_.end()) { - iter->second.insert(entryPathMap.begin(), entryPathMap.end()); - return; - } - storedEntryMap_.emplace(moduleName, entryPathMap); -} - -void CodeSignUtils::StoredEntryMapDelete(const std::string &moduleName) -{ - storedEntryMap_.erase(moduleName); -} - -void CodeSignUtils::StoredEntryMapSearch(const std::string &moduleName, EntryMap &entryPathMap) -{ - auto iter = storedEntryMap_.find(moduleName); - if (iter != storedEntryMap_.end()) { - entryPathMap = iter->second; - } -} } } } diff --git a/test/unittest/code_sign_utils_test.cpp b/test/unittest/code_sign_utils_test.cpp index 2ab611e9232d1fc8ebb9221f5554f0f208e6258c..c1e431ab58a679ee9df16674720599af04f9a786 100644 --- a/test/unittest/code_sign_utils_test.cpp +++ b/test/unittest/code_sign_utils_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -472,10 +472,9 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0015, TestSize.Level0) HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0016, TestSize.Level0) { std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap"; - std::string moduleName = "EntryAbility"; EntryMap entryMap; CodeSignUtils utils; - int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF, moduleName); + int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_SUCCESS); std::string filePath1("libs/arm64-v8a/libc++_shared.so"); @@ -485,10 +484,10 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0016, TestSize.Level0) std::string targetPath2 = TEST_APP_DTAT_DIR + "libs/arm64/libentry.so"; entryMap.emplace(filePath2, targetPath2); - ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD, moduleName); + ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD); EXPECT_EQ(ret, CS_SUCCESS); - ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL, moduleName); + ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL); EXPECT_EQ(ret, CS_ERR_FILE_PATH); } @@ -504,7 +503,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0017, TestSize.Level0) EntryMap entryMap; CodeSignUtils utils; int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("DEBUG_LIB_ID", - hapRealPath, entryMap, FILE_SELF, "EntryAbility"); + hapRealPath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_SUCCESS); } @@ -520,7 +519,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0018, TestSize.Level0) EntryMap entryMap; CodeSignUtils utils; int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("test-app-identifier", - hapRealPath, entryMap, FILE_SELF, "EntryAbility"); + hapRealPath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_SUCCESS); } @@ -536,7 +535,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0019, TestSize.Level0) EntryMap entryMap; CodeSignUtils utils; int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("INVALID_ID", - hapRealPath, entryMap, FILE_SELF, "EntryAbility"); + hapRealPath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_ERR_INVALID_OWNER_ID); } @@ -552,7 +551,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0020, TestSize.Level0) EntryMap entryMap; CodeSignUtils utils; int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("INVALID_ID", - hapRealPath, entryMap, FILE_SELF, "EntryAbility"); + hapRealPath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_ERR_INVALID_OWNER_ID); } @@ -576,7 +575,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0021, TestSize.Level0) EntryMap entryMap; CodeSignUtils utils; - ret = utils.EnforceCodeSignForApp(hapEnablePath, entryMap, FILE_SELF, "EntryAbility"); + ret = utils.EnforceCodeSignForApp(hapEnablePath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_SUCCESS); } @@ -616,7 +615,6 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0022, TestSize.Level0) HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0023, TestSize.Level0) { std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap"; - std::string moduleName = "EntryAbility"; EntryMap entryMap; std::string filePath1("libs/arm64-v8a/libc++_shared.so"); @@ -624,18 +622,18 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0023, TestSize.Level0) entryMap.emplace(filePath1, targetPath1); CodeSignUtils utils; - int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ONLY, moduleName); + int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ONLY); EXPECT_EQ(ret, CS_SUCCESS); std::string filePath2("libs/arm64-v8a/libentry.so"); std::string targetPath2 = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/code_sign_block/libentry.so"; entryMap.emplace(filePath2, targetPath2); - ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD, moduleName); + ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD); EXPECT_EQ(ret, CS_SUCCESS); entryMap.clear(); - ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL, moduleName); + ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL); EXPECT_EQ(ret, CS_SUCCESS); } @@ -653,7 +651,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0024, TestSize.Level0) EntryMap entryMap; CodeSignUtils utils; std::string hapRealPath = APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"; - int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF, "EntryAbility"); + int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_SUCCESS); SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, ENFORCE_MODE); } @@ -672,13 +670,13 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0025, TestSize.Level0) std::string hapRealPath = APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"; EntryMap entryMap; CodeSignUtils utils; - int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF, "EntryAbility"); + int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF); EXPECT_EQ(ret, CS_CODE_SIGN_NOT_EXISTS); } /** * @tc.name: CodeSignUtilsTest_0026 - * @tc.desc: enable code signature in multiple Hap Scenarios + * @tc.desc: hap so mismatch scenarios * @tc.type: Func * @tc.require: */ @@ -686,34 +684,21 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0026, TestSize.Level0) { EntryMap entryMap; CodeSignUtils utils; - std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap"; - std::string hapRealPath2 = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-release.hap"; - std::string hapRealPath3 = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-debug.hap"; + std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-release.hap"; - std::string filePath1("libs/arm64-v8a/libc++_shared.so"); + std::string filePath1("libs/arm64-v8a/code_sign_block/libc++_shared.so"); std::string targetPath1 = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/code_sign_block/libc++_shared.so"; entryMap.emplace(filePath1, targetPath1); - std::string filePath2("libs/arm64-v8a/libentry.so"); + std::string filePath2("libs/arm64-v8a/code_sign_block/libentry.so"); std::string targetPath2 = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/code_sign_block/libentry.so"; entryMap.emplace(filePath2, targetPath2); - int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD, "EntryAbility"); + int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD); EXPECT_EQ(ret, CS_SUCCESS); entryMap.clear(); - ret = utils.EnforceCodeSignForAppWithOwnerId("test-app-identifier", - hapRealPath2, entryMap, FILE_ALL, "EntryAbility2"); - EXPECT_EQ(ret, CS_SUCCESS); - - ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL, "EntryAbility"); - EXPECT_EQ(ret, CS_SUCCESS); - - ret = utils.EnforceCodeSignForAppWithOwnerId("DEBUG_LIB_ID", - hapRealPath3, entryMap, FILE_ALL, "EntryAbility3"); - EXPECT_EQ(ret, CS_SUCCESS); - - ret = utils.IsCodeSignEnableCompleted(); - EXPECT_EQ(ret, true); + ret = utils.EnforceCodeSignForAppWithOwnerId("test-app-identifier", hapRealPath, entryMap, FILE_ALL); + EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE); } } // namespace CodeSign } // namespace Security diff --git a/utils/src/code_sign_block.cpp b/utils/src/code_sign_block.cpp index 0525f04188a4a94de35298f69777423d32fb3242..fce154866f7bea947ed25297400ac5056e3c2013 100644 --- a/utils/src/code_sign_block.cpp +++ b/utils/src/code_sign_block.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -101,6 +101,7 @@ int32_t CodeSignBlock::ParseNativeLibSignInfo(const EntryMap &entryMap) return CS_ERR_NO_SIGNATURE; } + size_t signMapPreSize = signMap_.size(); auto entryInfo = soInfo->info; auto entryInfoEnd = soInfo->info + soInfo->sectionNum; auto dataInfo = CONST_STATIC_CAST(char, soInfo); @@ -130,6 +131,12 @@ int32_t CodeSignBlock::ParseNativeLibSignInfo(const EntryMap &entryMap) entryInfo++; } while (entryInfo < entryInfoEnd); + if (entryMap.size() != signMap_.size() - signMapPreSize) { + LOG_DEBUG(LABEL, "signMap_ size:%{public}u, signMapPreSize:%{public}u", + static_cast(signMap_.size()), static_cast(signMapPreSize)); + return CS_ERR_NO_SIGNATURE; + } + return CS_SUCCESS; }