From e08d179c9689f0d25cfff27faf116674496113db Mon Sep 17 00:00:00 2001 From: yeyuning Date: Wed, 10 Jul 2024 15:40:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8D=E8=A7=A3=E5=8E=8Bso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fundavid --- README.md | 4 +- README_zh.md | 4 +- .../include/code_sign_helper.h | 5 +- .../code_sign_utils/include/code_sign_utils.h | 13 +- .../code_sign_utils/src/code_sign_helper.cpp | 14 +- .../code_sign_utils/src/code_sign_utils.cpp | 20 ++- interfaces/innerkits/common/include/errcode.h | 4 +- test/unittest/code_sign_utils_test.cpp | 162 +++++++++++++++++- utils/include/code_sign_block.h | 21 ++- utils/src/code_sign_block.cpp | 80 +++++++-- 10 files changed, 282 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 3ddba11..e120258 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,9 @@ The code signature component provides the following functions: | **API**| **Description**| | --- | --- | | int32_t EnforceCodeSignForApp(const EntryMap &entryPath, const std::string &signatureFile); | Enforces code signing for HAPs.| -| int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type); | Enforces code signing for HAPs.| +| int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type, uint32_t flag); | Enforces code signing for HAPs.| | int32_t EnforceCodeSignForFile(const std::string &path, const ByteBuffer &signature); | Enforces code signing for files.| -| int32_t EnforceCodeSignForAppWithOwnerId(std::string ownerId, const std::string &path, const EntryMap &entryPathMap, FileType type); | Enforces code signing for HAPs with the owner ID.| +| int32_t EnforceCodeSignForAppWithOwnerId(std::string ownerId, const std::string &path, const EntryMap &entryPathMap, FileType type, uint32_t flag); | Enforces code signing for HAPs with the owner ID.| | int ParseOwnerIdFromSignature(const ByteBuffer &sigbuffer, std::string &ownerID); | Parses the owner ID from the signature.| | int32_t EnableKeyInProfile(const std::string &bundleName, const ByteBuffer &profileBuffer); | Trusts a developer certificate.| | int32_t RemoveKeyInProfile(const std::string &bundleName); | Revokes a trusted developer certificate.| diff --git a/README_zh.md b/README_zh.md index aaa6d98..9cb0302 100644 --- a/README_zh.md +++ b/README_zh.md @@ -42,9 +42,9 @@ | **接口声明** | **接口描述** | | --- | --- | | int32_t EnforceCodeSignForApp(const EntryMap &entryPath, const std::string &signatureFile); | 对hap使能代码签名 | -| int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type); | 对hap使能代码签名 | +| int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type, uint32_t flag); | 对hap使能代码签名 | | int32_t EnforceCodeSignForFile(const std::string &path, const ByteBuffer &signature); | 对文件使能代码签名 | -| int32_t EnforceCodeSignForAppWithOwnerId(std::string ownerId, const std::string &path, const EntryMap &entryPathMap, FileType type); | 对hap使能代码签名和OwnerId校验 | +| int32_t EnforceCodeSignForAppWithOwnerId(std::string ownerId, const std::string &path, const EntryMap &entryPathMap, FileType type, uint32_t flag); | 对hap使能代码签名和OwnerId校验 | | int ParseOwnerIdFromSignature(const ByteBuffer &sigbuffer, std::string &ownerID); | 从签名中解析OwnerId | | int32_t EnableKeyInProfile(const std::string &bundleName, const ByteBuffer &profileBuffer); | 信任开发者证书 | | int32_t RemoveKeyInProfile(const std::string &bundleName); | 撤销已信任的开发者证书 | diff --git a/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h b/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h index 9f9dfd7..1b5754d 100644 --- a/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h @@ -38,11 +38,12 @@ public: * @param ownerId string to abtain owner ID from the signature file * @param path hap real path on disk * @param CallbackFunc enforce code sign callback function address + * @param flag attributes of libs * @return err code, see err_code.h */ - int32_t ProcessMultiTask(const std::string &ownerId, const std::string &path, CallbackFunc &func); + int32_t ProcessMultiTask(const std::string &ownerId, const std::string &path, CallbackFunc &func, uint32_t flag); private: - int32_t ProcessOneFile(); + int32_t ProcessOneFile(uint32_t flag); int32_t ExecuteMultiTask(const std::string &ownerId, const std::string &path, CallbackFunc &func); void ShowCodeSignInfo(const std::string &path, const struct code_sign_enable_arg &arg); private: 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 6f06b68..a34dfa4 100644 --- a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h @@ -39,6 +39,10 @@ typedef enum { FILE_TYPE_MAX, } FileType; +enum CodeSignInfoFlag { + IS_UNCOMPRESSED_NATIVE_LIBS = 0x01 << 0, +}; + class CodeSignUtils { public: /** @@ -55,9 +59,11 @@ public: * @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 flag attributes of libs * @return err code, see err_code.h */ - int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type); + int32_t EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, + FileType type, uint32_t flag = 0); /** * @brief Enforce code signature for a hap with ownerID @@ -65,10 +71,11 @@ public: * @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 flag attributes of libs * @return err code, see err_code.h */ int32_t EnforceCodeSignForAppWithOwnerId(const std::string &ownerId, const std::string &path, - const EntryMap &entryPathMap, FileType type); + const EntryMap &entryPathMap, FileType type, uint32_t flag = 0); /** * @brief Enforce code signature for file with signature @@ -124,7 +131,7 @@ public: static int32_t IsSupportFsVerity(const std::string &path); private: static int32_t EnableCodeSignForFile(const std::string &path, const struct code_sign_enable_arg &arg); - int32_t ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, FileType type); + int32_t ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, FileType type, uint32_t flag); int32_t HandleCodeSignBlockFailure(const std::string &realPath, int32_t ret); private: EntryMap storedEntryMap_; diff --git a/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp b/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp index 0b68ba5..6a6c005 100644 --- a/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp @@ -29,11 +29,12 @@ int32_t CodeSignHelper::ParseCodeSignBlock(const std::string &realPath, return codeSignBlock_.ParseCodeSignBlock(realPath, entryMap, fileType); } -int32_t CodeSignHelper::ProcessMultiTask(const std::string &ownerId, const std::string &path, CallbackFunc &func) +int32_t CodeSignHelper::ProcessMultiTask(const std::string &ownerId, const std::string &path, + CallbackFunc &func, uint32_t flag) { int32_t ret; do { - ret = ProcessOneFile(); + ret = ProcessOneFile(flag); if (ret == CS_SUCCESS_END) { ret = CS_SUCCESS; break; @@ -44,11 +45,11 @@ int32_t CodeSignHelper::ProcessMultiTask(const std::string &ownerId, const std:: return ExecuteMultiTask(ownerId, path, func); } -int32_t CodeSignHelper::ProcessOneFile() +int32_t CodeSignHelper::ProcessOneFile(uint32_t flag) { std::string targetFile; struct code_sign_enable_arg arg = {0}; - int32_t ret = codeSignBlock_.GetOneFileAndCodeSignInfo(targetFile, arg); + int32_t ret = codeSignBlock_.GetOneFileAndCodeSignInfo(targetFile, arg, flag); if (ret != CS_SUCCESS) { return ret; } @@ -84,10 +85,11 @@ void CodeSignHelper::ShowCodeSignInfo(const std::string &path, const struct code "file:%{public}s version:%{public}d hash_algorithm:%{public}d block_size:%{public}d sig_size:%{public}d " "data_size:%{public}lld salt_size:%{public}d salt:[%{public}d, ..., %{public}d, ..., %{public}d] " "flags:%{public}d tree_offset:%{public}lld root_hash:[%{public}d, %{public}d, %{public}d, ..., %{public}d, " - "..., %{public}d] }", + "..., %{public}d] pgtypeinfo_size:%{public}d pgtypeinfo_off:%{public}lld }", path.c_str(), arg.cs_version, arg.hash_algorithm, arg.block_size, arg.sig_size, arg.data_size, arg.salt_size, salt[0], salt[16], salt[31], arg.flags, arg.tree_offset, // 16, 31 data index - rootHashPtr[0], rootHashPtr[1], rootHashPtr[2], rootHashPtr[32], rootHashPtr[63]); // 2, 32, 63 data index + rootHashPtr[0], rootHashPtr[1], rootHashPtr[2], rootHashPtr[32], rootHashPtr[63], // 2, 32, 63 data index + arg.pgtypeinfo_size, arg.pgtypeinfo_off); } } } 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 9a4a331..a9fa7aa 100644 --- a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp @@ -195,10 +195,10 @@ 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 EntryMap &entryPathMap, FileType type, uint32_t flag) { - LOG_INFO("Start to enforce codesign FileType:%{public}d, entryPathMap size:%{public}u, path = %{public}s", - type, static_cast(entryPathMap.size()), path.c_str()); + LOG_INFO("Start to enforce codesign FileType:%{public}u, entryPathMap size:%{public}zu, path = %{public}s, " + "flag = %{public}u", type, entryPathMap.size(), path.c_str(), flag); if (type == FILE_ENTRY_ADD || type == FILE_ENTRY_ONLY || type == FILE_ALL) { { std::lock_guard lock(storedEntryMapLock_); @@ -212,17 +212,18 @@ int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(const std::string &owner return CS_ERR_PARAM_INVALID; } std::lock_guard lock(storedEntryMapLock_); - int ret = ProcessCodeSignBlock(ownerId, path, type); + int ret = ProcessCodeSignBlock(ownerId, path, type, flag); if (ret != CS_SUCCESS) { // retry once to make sure stability - ret = ProcessCodeSignBlock(ownerId, path, type); + ret = ProcessCodeSignBlock(ownerId, path, type, flag); } storedEntryMap_.clear(); LOG_INFO("Enforcing done, ret = %{public}d", ret); return ret; } -int32_t CodeSignUtils::ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, FileType type) +int32_t CodeSignUtils::ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, + FileType type, uint32_t flag) { std::string realPath; if (!OHOS::PathToRealPath(path, realPath)) { @@ -234,7 +235,7 @@ int32_t CodeSignUtils::ProcessCodeSignBlock(const std::string &ownerId, const st if (ret != CS_SUCCESS) { return HandleCodeSignBlockFailure(realPath, ret); } - ret = codeSignHelper.ProcessMultiTask(ownerId, path, EnableCodeSignForFile); + ret = codeSignHelper.ProcessMultiTask(ownerId, path, EnableCodeSignForFile, flag); return ret; } @@ -248,9 +249,10 @@ int32_t CodeSignUtils::HandleCodeSignBlockFailure(const std::string &realPath, i return ret; } -int32_t CodeSignUtils::EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, FileType type) +int32_t CodeSignUtils::EnforceCodeSignForApp(const std::string &path, const EntryMap &entryPathMap, + FileType type, uint32_t flag) { - return EnforceCodeSignForAppWithOwnerId("", path, entryPathMap, type); + return EnforceCodeSignForAppWithOwnerId("", path, entryPathMap, type, flag); } int32_t CodeSignUtils::EnableKeyInProfile(const std::string &bundleName, const ByteBuffer &profileBuffer) diff --git a/interfaces/innerkits/common/include/errcode.h b/interfaces/innerkits/common/include/errcode.h index 73d5f05..541be0e 100644 --- a/interfaces/innerkits/common/include/errcode.h +++ b/interfaces/innerkits/common/include/errcode.h @@ -97,7 +97,9 @@ enum SignBlockErrCode { CS_ERR_SO_SIGN_OFFSET = -0x619, CS_ERR_SO_SIGN_SIZE = -0x620, CS_ERR_SIGN_ADDR_ALIGN = -0x621, - CS_ERR_SIGN_EXTENSION_OFFSET_ALIGN = -0x622, + CS_ERR_INVALID_EXTENSION_OFFSET = -0x622, + CS_ERR_INVALID_PAGE_INFO_EXTENSION = -0x623, + CS_ERR_EXTENSION_SIGN_SIZE = -0x624, }; enum JitCodeSignErrCode { diff --git a/test/unittest/code_sign_utils_test.cpp b/test/unittest/code_sign_utils_test.cpp index aaa675b..148b9fb 100644 --- a/test/unittest/code_sign_utils_test.cpp +++ b/test/unittest/code_sign_utils_test.cpp @@ -387,7 +387,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0014, TestSize.Level0) std::string targetFile; struct code_sign_enable_arg arg = {0}; - ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg); + ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg, 0); EXPECT_EQ(ret, CS_SUCCESS); EXPECT_EQ(arg.version, 1); EXPECT_EQ(arg.cs_version, 1); @@ -399,7 +399,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0014, TestSize.Level0) EXPECT_EQ(arg.flags, 1); EXPECT_EQ(arg.tree_offset, 0x10c000); - ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg); + ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg, 0); EXPECT_EQ(ret, CS_SUCCESS_END); } @@ -428,7 +428,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0015, TestSize.Level0) do { std::string targetFile; struct code_sign_enable_arg arg = {0}; - ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg); + ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg, 0); if (ret != CS_SUCCESS_END) { EXPECT_EQ(ret, CS_SUCCESS); EXPECT_EQ(arg.version, 1); @@ -631,6 +631,162 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0026, TestSize.Level0) ret = utils.EnforceCodeSignForAppWithOwnerId("test-app-identifier", hapRealPath, entryMap, FILE_ALL); EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE); } + +/** + * @tc.name: CodeSignUtilsTest_0027 + * @tc.desc: test Extension address is beyond the end of the block + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0027, TestSize.Level0) +{ + CodeSignBlock codeSignBlock; + uintptr_t block[100] = {0}; + uintptr_t blockAddrEnd = reinterpret_cast(block + sizeof(block)); + uintptr_t extensionAddr = blockAddrEnd + 1; + code_sign_enable_arg arg = {}; + + int32_t ret = codeSignBlock.ProcessExtension(extensionAddr, blockAddrEnd, arg); + EXPECT_EQ(ret, CS_ERR_INVALID_EXTENSION_OFFSET); +} + +/** + * @tc.name: CodeSignUtilsTest_0028 + * @tc.desc: test Extension header size exceeds block boundary + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0028, TestSize.Level0) +{ + CodeSignBlock codeSignBlock; + uintptr_t block[100] = {0}; + uintptr_t blockAddrEnd = reinterpret_cast(block + sizeof(block)); + uintptr_t extensionAddr = blockAddrEnd - sizeof(ExtensionHeader) + 1; + code_sign_enable_arg arg = {}; + + int32_t ret = codeSignBlock.ProcessExtension(extensionAddr, blockAddrEnd, arg); + EXPECT_EQ(ret, CS_ERR_INVALID_EXTENSION_OFFSET); +} + +/** + * @tc.name: CodeSignUtilsTest_0029 + * @tc.desc: test Process Merkle Tree Extension + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0029, TestSize.Level0) +{ + CodeSignBlock codeSignBlock; + struct { + ExtensionHeader header; + MerkleTreeExtension merkleTree; + } block; + block.header.type = CodeSignBlock::CSB_EXTENSION_TYPE_MERKLE_TREE; + block.header.size = sizeof(MerkleTreeExtension); + block.merkleTree.treeOffset = 123; + + uint8_t fakeRootHash[64] = {0xde, 0xad, 0xbe, 0xef}; + std::copy(std::begin(fakeRootHash), std::end(fakeRootHash), std::begin(block.merkleTree.rootHash)); + + uintptr_t blockAddrEnd = reinterpret_cast(&block + 1); + uintptr_t extensionAddr = reinterpret_cast(&block); + code_sign_enable_arg arg = {}; + + int32_t ret = codeSignBlock.ProcessExtension(extensionAddr, blockAddrEnd, arg); + EXPECT_EQ(ret, CS_SUCCESS); + EXPECT_EQ(arg.tree_offset, 123); + EXPECT_EQ(arg.root_hash_ptr, reinterpret_cast(block.merkleTree.rootHash)); + EXPECT_EQ(arg.flags, CodeSignBlock::CSB_SIGN_INFO_MERKLE_TREE); +} + +/** + * @tc.name: CodeSignUtilsTest_0030 + * @tc.desc: test Process Page Info Extension + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0030, TestSize.Level0) +{ + CodeSignBlock codeSignBlock; + struct { + ExtensionHeader header; + PageInfoExtension pageInfo; + } block; + block.header.type = CodeSignBlock::CSB_EXTENSION_TYPE_PAGE_INFO; + block.header.size = sizeof(PageInfoExtension) + 50; + block.pageInfo.sign_size = 30; + block.pageInfo.unitSize = 2; + + uint8_t fakeSignature[64] = {0xde, 0xad, 0xbe, 0xef}; + std::copy(std::begin(fakeSignature), std::begin(fakeSignature) + + block.pageInfo.sign_size, block.pageInfo.signature); + + block.pageInfo.mapSize = 100; + block.pageInfo.mapOffset = 200; + + uintptr_t blockAddrEnd = reinterpret_cast(&block + 1); + uintptr_t extensionAddr = reinterpret_cast(&block); + code_sign_enable_arg arg = {}; + + int32_t ret = codeSignBlock.ProcessExtension(extensionAddr, blockAddrEnd, arg); + EXPECT_EQ(ret, CS_SUCCESS); + EXPECT_EQ(arg.sig_size, 30); + EXPECT_EQ(arg.sig_ptr, reinterpret_cast(block.pageInfo.signature)); + EXPECT_EQ(arg.pgtypeinfo_size, 100); + EXPECT_EQ(arg.pgtypeinfo_off, 200); + EXPECT_EQ(arg.cs_version, CodeSignBlock::CSB_EXTENSION_TYPE_PAGE_INFO_VERSION); + EXPECT_EQ(arg.flags, 2 << 1); +} + +/** + * @tc.name: CodeSignUtilsTest_0031 + * @tc.desc: test Invalid Page Info Extension Sign Size + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0031, TestSize.Level0) +{ + CodeSignBlock codeSignBlock; + struct { + ExtensionHeader header; + PageInfoExtension pageInfo; + } block; + block.header.type = CodeSignBlock::CSB_EXTENSION_TYPE_PAGE_INFO; + block.header.size = sizeof(PageInfoExtension); + block.pageInfo.sign_size = sizeof(PageInfoExtension) + 1; + + uintptr_t blockAddrEnd = reinterpret_cast(&block + 1); + uintptr_t extensionAddr = reinterpret_cast(&block); + code_sign_enable_arg arg = {}; + + int32_t ret = codeSignBlock.ProcessExtension(extensionAddr, blockAddrEnd, arg); + EXPECT_EQ(ret, CS_ERR_EXTENSION_SIGN_SIZE); +} + +/** + * @tc.name: CodeSignUtilsTest_0032 + * @tc.desc: test invalid PageInfoExtension UnitSize + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0032, TestSize.Level0) +{ + CodeSignBlock codeSignBlock; + struct { + ExtensionHeader header; + PageInfoExtension pageInfo; + } block; + block.header.type = CodeSignBlock::CSB_EXTENSION_TYPE_PAGE_INFO; + block.header.size = sizeof(PageInfoExtension); + block.pageInfo.unitSize = CodeSignBlock::CSB_SIGN_INFO_MAX_PAGEINFO_UNITSIZE + 1; + + uintptr_t blockAddrEnd = reinterpret_cast(&block + 1); + uintptr_t extensionAddr = reinterpret_cast(&block); + code_sign_enable_arg arg = {}; + + int32_t ret = codeSignBlock.ProcessExtension(extensionAddr, blockAddrEnd, arg); + EXPECT_EQ(ret, CS_ERR_INVALID_PAGE_INFO_EXTENSION); +} } // namespace CodeSign } // namespace Security } // namespace OHOS diff --git a/utils/include/code_sign_block.h b/utils/include/code_sign_block.h index 98a9bf1..eb41262 100644 --- a/utils/include/code_sign_block.h +++ b/utils/include/code_sign_block.h @@ -62,13 +62,25 @@ typedef struct { } FsVerityInfo; typedef struct { - uint32_t type; // MERKLE_TREE_INCLUDE + uint32_t type; uint32_t size; +} ExtensionHeader; + +typedef struct { uint64_t treeSize; uint64_t treeOffset; uint8_t rootHash[64]; } MerkleTreeExtension; +typedef struct { + uint64_t mapOffset; + uint64_t mapSize; + uint8_t unitSize; + uint8_t reversed[3]; + uint32_t sign_size; + uint8_t signature[0]; +} PageInfoExtension; + typedef struct { uint32_t saltSize; uint32_t signSize; @@ -114,10 +126,15 @@ public: static constexpr uint32_t CSB_HAP_HEADER_MAGIC = 0xC1B5CC66; static constexpr uint32_t CSB_SO_HEADER_MAGIC = 0xED2E720; static constexpr uint32_t CSB_SIGN_INFO_MERKLE_TREE = 0x1; + static constexpr uint32_t CSB_SIGN_INFO_RUNTIME_PAGE = 0x2; static constexpr uint32_t CSB_EXTENSION_TYPE_MERKLE_TREE = 1; + static constexpr uint32_t CSB_EXTENSION_TYPE_PAGE_INFO = 2; + static constexpr uint32_t CSB_SIGN_INFO_MAX_PAGEINFO_UNITSIZE = 7; + static constexpr uint32_t CSB_EXTENSION_TYPE_PAGE_INFO_VERSION = 2; int32_t ParseCodeSignBlock(const std::string &realPath, const EntryMap &entryMap, FileType fileType); - int32_t GetOneFileAndCodeSignInfo(std::string &targetFile, struct code_sign_enable_arg &arg); + int32_t GetOneFileAndCodeSignInfo(std::string &targetFile, struct code_sign_enable_arg &arg, uint32_t flag); + int32_t ProcessExtension(uintptr_t &extensionAddr, const uintptr_t blockAddrEnd, struct code_sign_enable_arg &arg); private: int32_t ParseNativeLibSignInfo(const EntryMap &entryMap); diff --git a/utils/src/code_sign_block.cpp b/utils/src/code_sign_block.cpp index 81c5480..34b22a8 100644 --- a/utils/src/code_sign_block.cpp +++ b/utils/src/code_sign_block.cpp @@ -44,7 +44,58 @@ CodeSignBlock::CodeSignBlock() CodeSignBlock::~CodeSignBlock() { } -int32_t CodeSignBlock::GetOneFileAndCodeSignInfo(std::string &targetFile, struct code_sign_enable_arg &arg) +int32_t CodeSignBlock::ProcessExtension(uintptr_t &extensionAddr, + const uintptr_t blockAddrEnd, struct code_sign_enable_arg &arg) +{ + if (extensionAddr >= blockAddrEnd) { + LOG_ERROR("Extension address is beyond the end of the block"); + return CS_ERR_INVALID_EXTENSION_OFFSET; + } + auto extensionHeader = reinterpret_cast(extensionAddr); + extensionAddr = extensionAddr + sizeof(ExtensionHeader); + if (extensionAddr > blockAddrEnd) { + LOG_ERROR("Extension header size exceeds block boundary. ExtensionHeader size: %{public}zu bytes", + sizeof(ExtensionHeader)); + return CS_ERR_INVALID_EXTENSION_OFFSET; + } + LOG_DEBUG("extensionHeader->type:%{public}d, extensionHeader->size:%{public}d", extensionHeader->type, + extensionHeader->size); + switch (extensionHeader->type) { + case CSB_EXTENSION_TYPE_MERKLE_TREE: { + auto merkleExtension = reinterpret_cast(extensionAddr); + arg.tree_offset = merkleExtension->treeOffset; + arg.root_hash_ptr = reinterpret_cast(merkleExtension->rootHash); + arg.flags |= CSB_SIGN_INFO_MERKLE_TREE; + break; + } + case CSB_EXTENSION_TYPE_PAGE_INFO: { + auto pageInfoExtension = reinterpret_cast(extensionAddr); + arg.sig_size = pageInfoExtension->sign_size; + if (arg.sig_size > extensionHeader->size - sizeof(PageInfoExtension)) { + return CS_ERR_EXTENSION_SIGN_SIZE; + } + if (pageInfoExtension->unitSize > CSB_SIGN_INFO_MAX_PAGEINFO_UNITSIZE) { + return CS_ERR_INVALID_PAGE_INFO_EXTENSION; + } + arg.sig_ptr = reinterpret_cast(pageInfoExtension->signature); + arg.pgtypeinfo_size = pageInfoExtension->mapSize; + arg.pgtypeinfo_off = pageInfoExtension->mapOffset; + arg.cs_version = CSB_EXTENSION_TYPE_PAGE_INFO_VERSION; + arg.flags |= pageInfoExtension->unitSize << 1; + LOG_DEBUG("arg.sig_size:%{public}u, arg.pgtypeinfo_size:%{public}u, " + "arg.pgtypeinfo_off:%{public}llu, unitSize:%{public}u,arg.flags:%{public}u", arg.sig_size, + arg.pgtypeinfo_size, arg.pgtypeinfo_off, pageInfoExtension->unitSize, arg.flags); + break; + } + default: + break; + } + extensionAddr += extensionHeader->size; + return CS_SUCCESS; +} + +int32_t CodeSignBlock::GetOneFileAndCodeSignInfo(std::string &targetFile, + struct code_sign_enable_arg &arg, uint32_t flag) { int32_t ret; uintptr_t signInfoAddr; @@ -67,26 +118,25 @@ int32_t CodeSignBlock::GetOneFileAndCodeSignInfo(std::string &targetFile, struct arg.sig_size = signInfo->signSize; arg.sig_ptr = reinterpret_cast(signInfo->signature); arg.data_size = signInfo->dataSize; - arg.flags = signInfo->flags; - if (!(signInfo->flags & CSB_SIGN_INFO_MERKLE_TREE)) { + if (!signInfo->flags) { return CS_SUCCESS; } uint32_t extensionCount = 0; + uint32_t extensionNum = signInfo->extensionNum; + if ((flag & IS_UNCOMPRESSED_NATIVE_LIBS) == 0) { + extensionNum = std::min(signInfo->extensionNum, 1u); + } + LOG_DEBUG("flag = %{public}u, extensionNum = %{public}u, signInfo->extensionNum = %{public}u", + flag, extensionNum, signInfo->extensionNum); auto extensionAddr = reinterpret_cast(signInfo) + signInfo->extensionOffset; - do { - if (extensionAddr >= blockAddrEnd) { - return CS_ERR_SIGN_EXTENSION_OFFSET_ALIGN; - } - auto extension = reinterpret_cast(extensionAddr); - if (extension->type == CSB_EXTENSION_TYPE_MERKLE_TREE) { - arg.tree_offset = extension->treeOffset; - arg.root_hash_ptr = reinterpret_cast(extension->rootHash); - break; + while (extensionCount < extensionNum) { + ret = ProcessExtension(extensionAddr, blockAddrEnd, arg); + if (ret != CS_SUCCESS) { + return ret; } - extensionAddr += extension->size; extensionCount++; - } while (extensionCount < signInfo->extensionNum); + } return CS_SUCCESS; } @@ -133,7 +183,7 @@ int32_t CodeSignBlock::ParseNativeLibSignInfo(const EntryMap &entryMap) } while (entryInfo < entryInfoEnd); if (entryMap.size() != signMap_.size() - signMapPreSize) { - LOG_DEBUG("signMap_ size:%{public}u, signMapPreSize:%{public}u", + LOG_ERROR("Libs signature not found: signMap_ size:%{public}u, signMapPreSize:%{public}u", static_cast(signMap_.size()), static_cast(signMapPreSize)); return CS_ERR_NO_SIGNATURE; } -- Gitee