From 2fccc0f5c96cd16efb50c6691a7ae8b53b426557 Mon Sep 17 00:00:00 2001 From: lihehe Date: Tue, 20 Aug 2024 22:10:12 +0800 Subject: [PATCH] parse code sign block Signed-off-by: lihehe Change-Id: I3f652b76033e8fae7ffb8ccd040c26543a660902 --- .../appverify/include/interfaces/hap_verify.h | 1 + .../include/util/hap_signing_block_utils.h | 8 +++ .../appverify/include/verify/hap_verify_v2.h | 1 + .../appverify/src/interfaces/hap_verify.cpp | 6 +++ .../src/util/hap_signing_block_utils.cpp | 51 +++++++++++++++++++ .../appverify/src/verify/hap_verify_v2.cpp | 25 +++++++++ .../src/hap_signing_block_utils_test.cpp | 41 +++++++++++++++ 7 files changed, 133 insertions(+) diff --git a/interfaces/innerkits/appverify/include/interfaces/hap_verify.h b/interfaces/innerkits/appverify/include/interfaces/hap_verify.h index 4cc9461..d6ddd68 100644 --- a/interfaces/innerkits/appverify/include/interfaces/hap_verify.h +++ b/interfaces/innerkits/appverify/include/interfaces/hap_verify.h @@ -29,6 +29,7 @@ DLL_EXPORT void DisableDebugMode(); DLL_EXPORT int32_t HapVerify(const std::string& filePath, HapVerifyResult& hapVerifyResult); DLL_EXPORT int32_t ParseHapProfile(const std::string& filePath, HapVerifyResult& hapVerifyV1Result); DLL_EXPORT int32_t ParseHapSignatureInfo(const std::string& filePath, SignatureInfo &hapSignInfo); +DLL_EXPORT int32_t ParseCodeSignatureInfo(const std::string& filePath, HapByteBuffer &codeSignBlock); DLL_EXPORT void SetDevMode(DevMode devMode); } // namespace Verify } // namespace Security diff --git a/interfaces/innerkits/appverify/include/util/hap_signing_block_utils.h b/interfaces/innerkits/appverify/include/util/hap_signing_block_utils.h index 53959ec..2c2a605 100644 --- a/interfaces/innerkits/appverify/include/util/hap_signing_block_utils.h +++ b/interfaces/innerkits/appverify/include/util/hap_signing_block_utils.h @@ -39,6 +39,10 @@ enum HapBlobType { PROPERTY_BLOB = 0x20000003, }; +enum PropertyBlobType { + CODE_SIGNATURE_BLOCK = 0x30000001, +}; + struct HapSignBlockHead { int32_t version = 0; int32_t blockCount = 0; @@ -59,6 +63,8 @@ public: DLL_EXPORT static bool GetOptionalBlockIndex(std::vector& optionBlocks, int32_t type, int& index); DLL_EXPORT static bool VerifyHapIntegrity(Pkcs7Context& digestInfo, RandomAccessFile& hapFile, SignatureInfo& signInfo); + DLL_EXPORT static bool FindPropertyBlockByType(RandomAccessFile &hapFile, SignatureInfo &hapSignInfo, + uint32_t type, HapByteBuffer &subBlock); private: DLL_EXPORT static const long long HAP_SIG_BLOCK_MAGIC_HIGH_OLD; @@ -109,6 +115,8 @@ private: static bool ParseSignBlockHead(HapSignBlockHead& hapSignBlockHead, HapByteBuffer& hapBlockHead); static bool ParseSubSignBlockHead(HapSubSignBlockHead& subSignBlockHead, HapByteBuffer& hapBlockHead); static bool CheckSignBlockHead(const HapSignBlockHead& hapSignBlockHead); + static bool ParsePropertyBlock(RandomAccessFile &hapFile, SignatureInfo &hapSignInfo, + const HapSubSignBlockHead *subBlockHeader, HapByteBuffer &subBlock); }; } // namespace Verify } // namespace Security diff --git a/interfaces/innerkits/appverify/include/verify/hap_verify_v2.h b/interfaces/innerkits/appverify/include/verify/hap_verify_v2.h index f5983b6..feb5746 100644 --- a/interfaces/innerkits/appverify/include/verify/hap_verify_v2.h +++ b/interfaces/innerkits/appverify/include/verify/hap_verify_v2.h @@ -32,6 +32,7 @@ public: int32_t Verify(const std::string& filePath, HapVerifyResult& hapVerifyV1Result); int32_t ParseHapProfile(const std::string& filePath, HapVerifyResult& hapVerifyV1Result); int32_t ParseHapSignatureInfo(const std::string& filePath, SignatureInfo &hapSignInfo); + int32_t ParseCodeSignatureInfo(const std::string& filePath, HapByteBuffer &codeSignBlock); private: int32_t Verify(RandomAccessFile& hapFile, HapVerifyResult& hapVerifyV1Result); diff --git a/interfaces/innerkits/appverify/src/interfaces/hap_verify.cpp b/interfaces/innerkits/appverify/src/interfaces/hap_verify.cpp index 316cfc5..acdb578 100644 --- a/interfaces/innerkits/appverify/src/interfaces/hap_verify.cpp +++ b/interfaces/innerkits/appverify/src/interfaces/hap_verify.cpp @@ -104,6 +104,12 @@ int32_t ParseHapSignatureInfo(const std::string& filePath, SignatureInfo &hapSig return hapVerifyV2.ParseHapSignatureInfo(filePath, hapSignInfo); } +int32_t ParseCodeSignatureInfo(const std::string& filePath, HapByteBuffer &codeSignBlock) +{ + HapVerifyV2 hapVerifyV2; + return hapVerifyV2.ParseCodeSignatureInfo(filePath, codeSignBlock); +} + } // namespace Verify } // namespace Security } // namespace OHOS diff --git a/interfaces/innerkits/appverify/src/util/hap_signing_block_utils.cpp b/interfaces/innerkits/appverify/src/util/hap_signing_block_utils.cpp index b8b4d8b..a699045 100644 --- a/interfaces/innerkits/appverify/src/util/hap_signing_block_utils.cpp +++ b/interfaces/innerkits/appverify/src/util/hap_signing_block_utils.cpp @@ -583,6 +583,57 @@ bool HapSigningBlockUtils::InitDigestPrefix(const DigestParameter& digestParam, } return true; } + +bool HapSigningBlockUtils::ParsePropertyBlock(RandomAccessFile &hapFile, SignatureInfo &hapSignInfo, + const HapSubSignBlockHead *subBlockHeader, HapByteBuffer &subBlock) +{ + long long blockOffset = static_cast(subBlockHeader->offset); + uint32_t blockSize = subBlockHeader->length; + if (blockOffset > hapSignInfo.hapCentralDirOffset || + blockOffset < hapSignInfo.hapSigningBlockOffset) { + HAPVERIFY_LOG_ERROR("Invalid offset = %{public}lld, CentralDirOffset = %{public}lld, " \ + "SigningBlockOffset = %{public}lld", blockOffset, hapSignInfo.hapCentralDirOffset, + hapSignInfo.hapSigningBlockOffset); + return false; + } + subBlock.SetCapacity(blockSize); + long long readLen = hapFile.ReadFileFullyFromOffset(subBlock, blockOffset); + if (readLen != static_cast(blockSize)) { + HAPVERIFY_LOG_ERROR("Read property block failed."); + return false; + } + return true; +} + +bool HapSigningBlockUtils::FindPropertyBlockByType(RandomAccessFile &hapFile, SignatureInfo &hapSignInfo, + uint32_t type, HapByteBuffer &subBlock) +{ + int32_t propertyIndex = 0; + if (!GetOptionalBlockIndex(hapSignInfo.optionBlocks, PROPERTY_BLOB, propertyIndex)) { + HAPVERIFY_LOG_INFO("Property block not found"); + return false; + } + auto propertyBlob = hapSignInfo.optionBlocks[propertyIndex].optionalBlockValue; + auto* propertyBlobBuffer = propertyBlob.GetBufferPtr(); + uint32_t propertyBlobLen = static_cast(propertyBlob.GetCapacity()); + bool ret = false; + uint32_t offset = 0; + do { + const auto blobHeader = reinterpret_cast(propertyBlobBuffer + offset); + if (blobHeader->type == type) { + if (!ParsePropertyBlock(hapFile, hapSignInfo, blobHeader, subBlock)) { + break; + } + ret = true; + break; + } + offset += sizeof(HapSubSignBlockHead); + } while (offset < propertyBlobLen); + if (!ret) { + HAPVERIFY_LOG_INFO("Block not found, type = %{public}u", type); + } + return ret; +} } // namespace Verify } // namespace Security } // namespace OHOS diff --git a/interfaces/innerkits/appverify/src/verify/hap_verify_v2.cpp b/interfaces/innerkits/appverify/src/verify/hap_verify_v2.cpp index e0bcaa5..00b2c8d 100644 --- a/interfaces/innerkits/appverify/src/verify/hap_verify_v2.cpp +++ b/interfaces/innerkits/appverify/src/verify/hap_verify_v2.cpp @@ -488,6 +488,31 @@ int32_t HapVerifyV2::ParseHapSignatureInfo(const std::string& filePath, Signatur return VERIFY_SUCCESS; } +int32_t HapVerifyV2::ParseCodeSignatureInfo(const std::string& filePath, HapByteBuffer &codeSignBlock) +{ + HAPVERIFY_LOG_INFO("start to ParseCodeSignatureInfo"); + std::string standardFilePath; + if (!CheckFilePath(filePath, standardFilePath)) { + return FILE_PATH_INVALID; + } + + RandomAccessFile hapFile; + if (!hapFile.Init(standardFilePath)) { + HAPVERIFY_LOG_ERROR("open standard file failed"); + return OPEN_FILE_ERROR; + } + + SignatureInfo hapSignInfo; + if (!HapSigningBlockUtils::FindHapSignature(hapFile, hapSignInfo)) { + return SIGNATURE_NOT_FOUND; + } + + if (!HapSigningBlockUtils::FindPropertyBlockByType(hapFile, hapSignInfo, CODE_SIGNATURE_BLOCK, codeSignBlock)) { + return SIGNATURE_NOT_FOUND; + } + return VERIFY_SUCCESS; +} + void HapVerifyV2::SetOrganization(ProvisionInfo& provisionInfo) { std::string& certInProfile = provisionInfo.bundleInfo.distributionCertificate; diff --git a/interfaces/innerkits/appverify/test/unittest/src/hap_signing_block_utils_test.cpp b/interfaces/innerkits/appverify/test/unittest/src/hap_signing_block_utils_test.cpp index 2efd921..6df3617 100644 --- a/interfaces/innerkits/appverify/test/unittest/src/hap_signing_block_utils_test.cpp +++ b/interfaces/innerkits/appverify/test/unittest/src/hap_signing_block_utils_test.cpp @@ -348,4 +348,45 @@ HWTEST_F(HapSigningBlockUtilsTest, GetSumOfChunkDigestLenTest001, TestSize.Level TEST_ZIP_BLOCKS_NUM_NEED_DIGEST, INT_MAX, chunkCount, sumOfChunkDigestLen); ASSERT_FALSE(ret); } + +/** + * @tc.name: Test FindPropertyBlockByType function + * @tc.desc: Test FindPropertyBlockByType success + * @tc.type: FUNC + */ +HWTEST_F(HapSigningBlockUtilsTest, FindPropertyBlockByType001, TestSize.Level1) +{ + /* + * @tc.steps: step1. create a test file with invalid length. + */ + std::string pathFile = "./codesignparse.hap"; + std::ofstream hapFile; + hapFile.open(pathFile.c_str(), std::ios::binary | std::ios::out | std::ios::trunc); + ASSERT_TRUE(hapFile.is_open()); + char buf[TEST_FILE_BLOCK_LENGTH]; + hapFile.write(buf, TEST_FILE_BLOCK_LENGTH); + hapFile.close(); + /* + * @tc.steps: step2. run function with input of code signautre block + * @tc.expected: step2. parse code signature block success. + */ + RandomAccessFile hapTestFile; + ASSERT_TRUE(hapTestFile.Init(pathFile)); + SignatureInfo signInfo; + signInfo.hapCentralDirOffset = TEST_FILE_BLOCK_LENGTH; + signInfo.hapSigningBlockOffset = 0; + HapByteBuffer subBlock; + uint32_t type = PROPERTY_BLOB; + HapSigningBlockUtils hapSignBlockUtils; + HapSubSignBlockHead codeSignBlockHeader; + codeSignBlockHeader.type = CODE_SIGNATURE_BLOCK; + codeSignBlockHeader.length = TEST_HAPBYTEBUFFER_LENGTH; + codeSignBlockHeader.offset = sizeof(HapSubSignBlockHead); + subBlock.SetCapacity(sizeof(HapSubSignBlockHead)); + subBlock.PutData(0, reinterpret_cast(&codeSignBlockHeader), sizeof(HapSubSignBlockHead)); + hapSignBlockUtils.ClassifyHapSubSigningBlock(signInfo, subBlock, type); + HapByteBuffer codeSignBlock; + ASSERT_TRUE(hapSignBlockUtils.FindPropertyBlockByType(hapTestFile, signInfo, CODE_SIGNATURE_BLOCK, codeSignBlock)); + ASSERT_EQ(codeSignBlock.GetCapacity(), TEST_HAPBYTEBUFFER_LENGTH); +} } -- Gitee