154aa6d63Sopenharmony_ci/* 254aa6d63Sopenharmony_ci * Copyright (c) 2024-2024 Huawei Device Co., Ltd. 354aa6d63Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 454aa6d63Sopenharmony_ci * you may not use this file except in compliance with the License. 554aa6d63Sopenharmony_ci * You may obtain a copy of the License at 654aa6d63Sopenharmony_ci * 754aa6d63Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 854aa6d63Sopenharmony_ci * 954aa6d63Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1054aa6d63Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1154aa6d63Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1254aa6d63Sopenharmony_ci * See the License for the specific language governing permissions and 1354aa6d63Sopenharmony_ci * limitations under the License. 1454aa6d63Sopenharmony_ci */ 1554aa6d63Sopenharmony_ci 1654aa6d63Sopenharmony_ci#include <fstream> 1754aa6d63Sopenharmony_ci#include <filesystem> 1854aa6d63Sopenharmony_ci 1954aa6d63Sopenharmony_ci#include "constant.h" 2054aa6d63Sopenharmony_ci#include "file_utils.h" 2154aa6d63Sopenharmony_ci#include "sign_head.h" 2254aa6d63Sopenharmony_ci#include "block_head.h" 2354aa6d63Sopenharmony_ci#include "verify_hap.h" 2454aa6d63Sopenharmony_ci#include "verify_code_signature.h" 2554aa6d63Sopenharmony_ci#include "hash_utils.h" 2654aa6d63Sopenharmony_ci#include "sign_content_info.h" 2754aa6d63Sopenharmony_ci#include "signature_block_tags.h" 2854aa6d63Sopenharmony_ci#include "verify_elf.h" 2954aa6d63Sopenharmony_ci 3054aa6d63Sopenharmony_cinamespace OHOS { 3154aa6d63Sopenharmony_cinamespace SignatureTools { 3254aa6d63Sopenharmony_ci 3354aa6d63Sopenharmony_ciconst int8_t VerifyElf::SIGNATURE_BLOCK = 0; 3454aa6d63Sopenharmony_ciconst int8_t VerifyElf::PROFILE_NOSIGNED_BLOCK = 1; 3554aa6d63Sopenharmony_ciconst int8_t VerifyElf::PROFILE_SIGNED_BLOCK = 2; 3654aa6d63Sopenharmony_ciconst int8_t VerifyElf::KEY_ROTATION_BLOCK = 3; 3754aa6d63Sopenharmony_ciconst int8_t VerifyElf::CODESIGNING_BLOCK_TYPE = 3; 3854aa6d63Sopenharmony_ci 3954aa6d63Sopenharmony_cibool VerifyElf::Verify(Options* options) 4054aa6d63Sopenharmony_ci{ 4154aa6d63Sopenharmony_ci // check param 4254aa6d63Sopenharmony_ci if (options == nullptr) { 4354aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "Param options is null."); 4454aa6d63Sopenharmony_ci return false; 4554aa6d63Sopenharmony_ci } 4654aa6d63Sopenharmony_ci if (!CheckParams(options)) { 4754aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("verify elf check params failed!"); 4854aa6d63Sopenharmony_ci return false; 4954aa6d63Sopenharmony_ci } 5054aa6d63Sopenharmony_ci std::string filePath = options->GetString(Options::IN_FILE); 5154aa6d63Sopenharmony_ci bool checkSignFileFlag = CheckSignFile(filePath); 5254aa6d63Sopenharmony_ci if (!checkSignFileFlag) { 5354aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("check input elf file %s failed!", filePath.c_str()); 5454aa6d63Sopenharmony_ci return false; 5554aa6d63Sopenharmony_ci } 5654aa6d63Sopenharmony_ci // verify elf 5754aa6d63Sopenharmony_ci std::vector<int8_t> profileVec; 5854aa6d63Sopenharmony_ci Pkcs7Context pkcs7Context; 5954aa6d63Sopenharmony_ci bool verifyElfFileFlag = VerifyElfFile(filePath, profileVec, options, pkcs7Context); 6054aa6d63Sopenharmony_ci if (!verifyElfFileFlag) { 6154aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("verify elf file %s failed!", filePath.c_str()); 6254aa6d63Sopenharmony_ci return false; 6354aa6d63Sopenharmony_ci } 6454aa6d63Sopenharmony_ci // write certificate and p7b file 6554aa6d63Sopenharmony_ci VerifyHap hapVerify(false); 6654aa6d63Sopenharmony_ci int32_t writeVerifyOutputFlag = hapVerify.WriteVerifyOutput(pkcs7Context, profileVec, options); 6754aa6d63Sopenharmony_ci if (writeVerifyOutputFlag != RET_OK) { 6854aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("write elf output failed on verify elf!"); 6954aa6d63Sopenharmony_ci return false; 7054aa6d63Sopenharmony_ci } 7154aa6d63Sopenharmony_ci return true; 7254aa6d63Sopenharmony_ci} 7354aa6d63Sopenharmony_ci 7454aa6d63Sopenharmony_cibool VerifyElf::VerifyElfFile(const std::string& elfFile, std::vector<int8_t>& profileVec, 7554aa6d63Sopenharmony_ci Options* options, Pkcs7Context& pkcs7Context) 7654aa6d63Sopenharmony_ci{ 7754aa6d63Sopenharmony_ci SignBlockInfo signBlockInfo(false); 7854aa6d63Sopenharmony_ci bool getSignBlockInfoFlag = GetSignBlockInfo(elfFile, signBlockInfo, ELF); 7954aa6d63Sopenharmony_ci if (!getSignBlockInfoFlag) { 8054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("get signBlockInfo failed on verify elf %s", elfFile.c_str()); 8154aa6d63Sopenharmony_ci return false; 8254aa6d63Sopenharmony_ci } 8354aa6d63Sopenharmony_ci // verify profile 8454aa6d63Sopenharmony_ci std::string profileJson; 8554aa6d63Sopenharmony_ci bool verifyP7b = VerifyP7b(signBlockInfo.GetSignBlockMap(), options, pkcs7Context, profileVec, profileJson); 8654aa6d63Sopenharmony_ci if (!verifyP7b) { 8754aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("verify profile failed on verify elf %s", elfFile.c_str()); 8854aa6d63Sopenharmony_ci return false; 8954aa6d63Sopenharmony_ci } 9054aa6d63Sopenharmony_ci // verify code sign 9154aa6d63Sopenharmony_ci bool findFlag = 9254aa6d63Sopenharmony_ci signBlockInfo.GetSignBlockMap().find(CODESIGNING_BLOCK_TYPE) != signBlockInfo.GetSignBlockMap().end(); 9354aa6d63Sopenharmony_ci if (findFlag) { 9454aa6d63Sopenharmony_ci SigningBlock codesign = signBlockInfo.GetSignBlockMap().find(CODESIGNING_BLOCK_TYPE)->second; 9554aa6d63Sopenharmony_ci bool verifyElfFlag = VerifyCodeSignature::VerifyElf(elfFile, codesign.GetOffset(), codesign.GetLength(), 9654aa6d63Sopenharmony_ci ELF, profileJson); 9754aa6d63Sopenharmony_ci if (!verifyElfFlag) { 9854aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("code signing failed on verify elf %s", elfFile.c_str()); 9954aa6d63Sopenharmony_ci return false; 10054aa6d63Sopenharmony_ci } 10154aa6d63Sopenharmony_ci } 10254aa6d63Sopenharmony_ci return true; 10354aa6d63Sopenharmony_ci} 10454aa6d63Sopenharmony_ci 10554aa6d63Sopenharmony_cibool VerifyElf::VerifyP7b(std::unordered_map<int8_t, SigningBlock>& signBlockMap, 10654aa6d63Sopenharmony_ci Options* options, Pkcs7Context& pkcs7Context, 10754aa6d63Sopenharmony_ci std::vector<int8_t>& profileVec, std::string& profileJson) 10854aa6d63Sopenharmony_ci{ 10954aa6d63Sopenharmony_ci if (signBlockMap.find(PROFILE_NOSIGNED_BLOCK) != signBlockMap.end()) { 11054aa6d63Sopenharmony_ci // verify unsigned profile 11154aa6d63Sopenharmony_ci const std::vector<int8_t>& profileByte = signBlockMap.find(PROFILE_NOSIGNED_BLOCK)->second.GetValue(); 11254aa6d63Sopenharmony_ci std::string fromByteStr(profileByte.begin(), profileByte.end()); 11354aa6d63Sopenharmony_ci profileJson = fromByteStr; 11454aa6d63Sopenharmony_ci profileVec = profileByte; 11554aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGW("profile is not signed."); 11654aa6d63Sopenharmony_ci } else if (signBlockMap.find(PROFILE_SIGNED_BLOCK) != signBlockMap.end()) { 11754aa6d63Sopenharmony_ci // verify signed profile 11854aa6d63Sopenharmony_ci SigningBlock profileSign = signBlockMap.find(PROFILE_SIGNED_BLOCK)->second; 11954aa6d63Sopenharmony_ci const std::vector<int8_t>& profileByte = profileSign.GetValue(); 12054aa6d63Sopenharmony_ci bool getRawContentFlag = GetRawContent(profileByte, profileJson); 12154aa6d63Sopenharmony_ci if (!getRawContentFlag) { 12254aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("get profile content failed on verify elf!"); 12354aa6d63Sopenharmony_ci return false; 12454aa6d63Sopenharmony_ci } 12554aa6d63Sopenharmony_ci VerifyHap hapVerify(false); 12654aa6d63Sopenharmony_ci std::unique_ptr<ByteBuffer> profileBuffer = 12754aa6d63Sopenharmony_ci std::make_unique<ByteBuffer>((char*)profileByte.data(), profileByte.size()); 12854aa6d63Sopenharmony_ci bool resultFlag = hapVerify.VerifyAppPkcs7(pkcs7Context, *profileBuffer); 12954aa6d63Sopenharmony_ci if (!resultFlag) { 13054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("verify elf profile failed on verify elf!"); 13154aa6d63Sopenharmony_ci return false; 13254aa6d63Sopenharmony_ci } 13354aa6d63Sopenharmony_ci profileVec = profileByte; 13454aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGI("verify profile success."); 13554aa6d63Sopenharmony_ci } else { 13654aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGW("can not found profile sign block."); 13754aa6d63Sopenharmony_ci } 13854aa6d63Sopenharmony_ci return true; 13954aa6d63Sopenharmony_ci} 14054aa6d63Sopenharmony_ci 14154aa6d63Sopenharmony_cibool VerifyElf::GetSignBlockInfo(const std::string& file, SignBlockInfo& signBlockInfo, 14254aa6d63Sopenharmony_ci const std::string fileType) 14354aa6d63Sopenharmony_ci{ 14454aa6d63Sopenharmony_ci // read file 14554aa6d63Sopenharmony_ci std::uintmax_t fileSize = std::filesystem::file_size(file); 14654aa6d63Sopenharmony_ci std::ifstream fileStream(file, std::ios::binary); 14754aa6d63Sopenharmony_ci if (!fileStream.is_open()) { 14854aa6d63Sopenharmony_ci PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "open file: " + file + "failed"); 14954aa6d63Sopenharmony_ci return false; 15054aa6d63Sopenharmony_ci } 15154aa6d63Sopenharmony_ci std::vector<char>* fileBytes = new std::vector<char>(fileSize, 0); 15254aa6d63Sopenharmony_ci fileStream.read(fileBytes->data(), fileBytes->size()); 15354aa6d63Sopenharmony_ci if (fileStream.fail() && !fileStream.eof()) { 15454aa6d63Sopenharmony_ci PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "Error occurred while reading data"); 15554aa6d63Sopenharmony_ci fileStream.close(); 15654aa6d63Sopenharmony_ci delete fileBytes; 15754aa6d63Sopenharmony_ci return false; 15854aa6d63Sopenharmony_ci } 15954aa6d63Sopenharmony_ci fileStream.close(); 16054aa6d63Sopenharmony_ci // get BlockData 16154aa6d63Sopenharmony_ci BlockData blockData(0, 0); 16254aa6d63Sopenharmony_ci bool getSignBlockData = GetSignBlockData(*((std::vector<int8_t>*)fileBytes), blockData, fileType); 16354aa6d63Sopenharmony_ci if (!getSignBlockData) { 16454aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("get signBlockData failed on verify elf/bin file %s", file.c_str()); 16554aa6d63Sopenharmony_ci delete fileBytes; 16654aa6d63Sopenharmony_ci return false; 16754aa6d63Sopenharmony_ci } 16854aa6d63Sopenharmony_ci // get SignBlockMap 16954aa6d63Sopenharmony_ci if (fileType == ELF) { 17054aa6d63Sopenharmony_ci GetElfSignBlock(*((std::vector<int8_t>*)fileBytes), blockData, signBlockInfo.GetSignBlockMap()); 17154aa6d63Sopenharmony_ci } else { 17254aa6d63Sopenharmony_ci GetBinSignBlock(*((std::vector<int8_t>*)fileBytes), blockData, signBlockInfo.GetSignBlockMap()); 17354aa6d63Sopenharmony_ci } 17454aa6d63Sopenharmony_ci // get bin file digest 17554aa6d63Sopenharmony_ci bool needGenerateDigest = signBlockInfo.GetNeedGenerateDigest(); 17654aa6d63Sopenharmony_ci if (needGenerateDigest) { 17754aa6d63Sopenharmony_ci const std::vector<int8_t>& signatrue = signBlockInfo.GetSignBlockMap().find(0)->second.GetValue(); 17854aa6d63Sopenharmony_ci bool getFileDigest = GetFileDigest(*((std::vector<int8_t>*)fileBytes), signatrue, signBlockInfo); 17954aa6d63Sopenharmony_ci if (!getFileDigest) { 18054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("getFileDigest failed on verify bin file %s", file.c_str()); 18154aa6d63Sopenharmony_ci delete fileBytes; 18254aa6d63Sopenharmony_ci return false; 18354aa6d63Sopenharmony_ci } 18454aa6d63Sopenharmony_ci } 18554aa6d63Sopenharmony_ci delete fileBytes; 18654aa6d63Sopenharmony_ci return true; 18754aa6d63Sopenharmony_ci} 18854aa6d63Sopenharmony_ci 18954aa6d63Sopenharmony_cibool VerifyElf::GetFileDigest(std::vector<int8_t>& fileBytes, const std::vector<int8_t>& signatrue, 19054aa6d63Sopenharmony_ci SignBlockInfo& signBlockInfo) 19154aa6d63Sopenharmony_ci{ 19254aa6d63Sopenharmony_ci std::string binDigest; 19354aa6d63Sopenharmony_ci bool getRawContentFlag = GetRawContent(signatrue, binDigest); 19454aa6d63Sopenharmony_ci if (!getRawContentFlag) { 19554aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("getBinDigest failed on verify bin digest!"); 19654aa6d63Sopenharmony_ci return false; 19754aa6d63Sopenharmony_ci } 19854aa6d63Sopenharmony_ci std::vector<int8_t> rawDigest(binDigest.begin(), binDigest.end()); 19954aa6d63Sopenharmony_ci signBlockInfo.SetRawDigest(rawDigest); 20054aa6d63Sopenharmony_ci GenerateFileDigest(fileBytes, signBlockInfo); 20154aa6d63Sopenharmony_ci return true; 20254aa6d63Sopenharmony_ci} 20354aa6d63Sopenharmony_ci 20454aa6d63Sopenharmony_cibool VerifyElf::GenerateFileDigest(std::vector<int8_t>& fileBytes, SignBlockInfo& signBlockInfo) 20554aa6d63Sopenharmony_ci{ 20654aa6d63Sopenharmony_ci // get algId 20754aa6d63Sopenharmony_ci std::vector<int8_t>& rawDigest = signBlockInfo.GetRawDigest(); 20854aa6d63Sopenharmony_ci std::unique_ptr<ByteBuffer> digBuffer = std::make_unique<ByteBuffer>(rawDigest.size()); 20954aa6d63Sopenharmony_ci digBuffer->PutData(rawDigest.data(), rawDigest.size()); 21054aa6d63Sopenharmony_ci digBuffer->Flip(); 21154aa6d63Sopenharmony_ci int32_t algOffset = 10; 21254aa6d63Sopenharmony_ci int16_t algId = 0; 21354aa6d63Sopenharmony_ci const char* bufferPtr = digBuffer->GetBufferPtr(); 21454aa6d63Sopenharmony_ci algId = static_cast<int16_t>(be16toh(*reinterpret_cast<const int16_t*>(bufferPtr + algOffset))); 21554aa6d63Sopenharmony_ci // generate digest 21654aa6d63Sopenharmony_ci int32_t fileLength = signBlockInfo.GetSignBlockMap().find(0)->second.GetOffset(); 21754aa6d63Sopenharmony_ci std::string digAlg = HashUtils::GetHashAlgName(algId); 21854aa6d63Sopenharmony_ci std::vector<int8_t> generatedDig = HashUtils::GetDigestFromBytes(fileBytes, fileLength, digAlg); 21954aa6d63Sopenharmony_ci if (generatedDig.empty()) { 22054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("generate bin file digest failed on verify bin"); 22154aa6d63Sopenharmony_ci return false; 22254aa6d63Sopenharmony_ci } 22354aa6d63Sopenharmony_ci SignContentInfo contentInfo; 22454aa6d63Sopenharmony_ci contentInfo.AddContentHashData(0, SignatureBlockTags::HASH_ROOT_4K, algId, generatedDig.size(), generatedDig); 22554aa6d63Sopenharmony_ci std::vector<int8_t> dig = contentInfo.GetByteContent(); 22654aa6d63Sopenharmony_ci if (dig.empty()) { 22754aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("generate file digest is null on verify bin"); 22854aa6d63Sopenharmony_ci return false; 22954aa6d63Sopenharmony_ci } 23054aa6d63Sopenharmony_ci signBlockInfo.SetFileDigest(dig); 23154aa6d63Sopenharmony_ci return true; 23254aa6d63Sopenharmony_ci} 23354aa6d63Sopenharmony_ci 23454aa6d63Sopenharmony_cibool VerifyElf::GetSignBlockData(std::vector<int8_t>& bytes, BlockData& blockData, 23554aa6d63Sopenharmony_ci const std::string fileType) 23654aa6d63Sopenharmony_ci{ 23754aa6d63Sopenharmony_ci int64_t offset = 0; 23854aa6d63Sopenharmony_ci bool checkMagicAndVersionFlag = CheckMagicAndVersion(bytes, offset, fileType); 23954aa6d63Sopenharmony_ci if (!checkMagicAndVersionFlag) { 24054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("check magic and version failed, file type: %s", fileType.c_str()); 24154aa6d63Sopenharmony_ci return false; 24254aa6d63Sopenharmony_ci } 24354aa6d63Sopenharmony_ci int32_t intByteLength = 4; 24454aa6d63Sopenharmony_ci std::vector<int8_t> blockSizeByte(bytes.begin() + offset, bytes.begin() + offset + intByteLength); 24554aa6d63Sopenharmony_ci offset += intByteLength; 24654aa6d63Sopenharmony_ci std::vector<int8_t> blockNumByte(bytes.begin() + offset, bytes.begin() + offset + intByteLength); 24754aa6d63Sopenharmony_ci if (fileType == BIN) { 24854aa6d63Sopenharmony_ci std::reverse(blockSizeByte.begin(), blockSizeByte.end()); 24954aa6d63Sopenharmony_ci std::reverse(blockNumByte.begin(), blockNumByte.end()); 25054aa6d63Sopenharmony_ci } 25154aa6d63Sopenharmony_ci std::unique_ptr<ByteBuffer> blockNumBf = std::make_unique<ByteBuffer>(blockNumByte.size()); 25254aa6d63Sopenharmony_ci blockNumBf->PutData(blockNumByte.data(), blockNumByte.size()); 25354aa6d63Sopenharmony_ci blockNumBf->Flip(); 25454aa6d63Sopenharmony_ci int32_t blockNum = 0; 25554aa6d63Sopenharmony_ci blockNumBf->GetInt32(blockNum); 25654aa6d63Sopenharmony_ci std::unique_ptr<ByteBuffer> blockSizeBf = std::make_unique<ByteBuffer>(blockSizeByte.size()); 25754aa6d63Sopenharmony_ci blockSizeBf->PutData(blockSizeByte.data(), blockSizeByte.size()); 25854aa6d63Sopenharmony_ci blockSizeBf->Flip(); 25954aa6d63Sopenharmony_ci int32_t blockSize = 0; 26054aa6d63Sopenharmony_ci blockSizeBf->GetInt32(blockSize); 26154aa6d63Sopenharmony_ci int64_t blockStart = 0; 26254aa6d63Sopenharmony_ci if (fileType == BIN) { 26354aa6d63Sopenharmony_ci blockStart = bytes.size() - blockSize; 26454aa6d63Sopenharmony_ci } else { 26554aa6d63Sopenharmony_ci blockStart = bytes.size() - SignHead::SIGN_HEAD_LEN - blockSize; 26654aa6d63Sopenharmony_ci } 26754aa6d63Sopenharmony_ci blockData.SetBlockNum(blockNum); 26854aa6d63Sopenharmony_ci blockData.SetBlockStart(blockStart); 26954aa6d63Sopenharmony_ci return true; 27054aa6d63Sopenharmony_ci} 27154aa6d63Sopenharmony_ci 27254aa6d63Sopenharmony_cibool VerifyElf::CheckMagicAndVersion(std::vector<int8_t>& bytes, int64_t& offset, const std::string fileType) 27354aa6d63Sopenharmony_ci{ 27454aa6d63Sopenharmony_ci std::string magicStr = (fileType == ELF ? SignHead::ELF_MAGIC : SignHead::MAGIC); 27554aa6d63Sopenharmony_ci offset = bytes.size() - SignHead::SIGN_HEAD_LEN; 27654aa6d63Sopenharmony_ci std::vector<int8_t> magicByte(bytes.begin() + offset, bytes.begin() + offset + magicStr.size()); 27754aa6d63Sopenharmony_ci offset += magicStr.size(); 27854aa6d63Sopenharmony_ci std::vector<int8_t> versionByte(bytes.begin() + offset, bytes.begin() + offset + SignHead::VERSION.size()); 27954aa6d63Sopenharmony_ci offset += SignHead::VERSION.size(); 28054aa6d63Sopenharmony_ci std::vector<int8_t> magicVec(magicStr.begin(), magicStr.end()); 28154aa6d63Sopenharmony_ci for (int i = 0; i < magicStr.size(); i++) { 28254aa6d63Sopenharmony_ci if (magicVec[i] != magicByte[i]) { 28354aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "magic verify failed!"); 28454aa6d63Sopenharmony_ci return false; 28554aa6d63Sopenharmony_ci } 28654aa6d63Sopenharmony_ci } 28754aa6d63Sopenharmony_ci std::vector<int8_t> versionVec(SignHead::VERSION.begin(), SignHead::VERSION.end()); 28854aa6d63Sopenharmony_ci for (int i = 0; i < SignHead::VERSION.size(); i++) { 28954aa6d63Sopenharmony_ci if (versionVec[i] != versionByte[i]) { 29054aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "sign version verify failed!"); 29154aa6d63Sopenharmony_ci return false; 29254aa6d63Sopenharmony_ci } 29354aa6d63Sopenharmony_ci } 29454aa6d63Sopenharmony_ci return true; 29554aa6d63Sopenharmony_ci} 29654aa6d63Sopenharmony_ci 29754aa6d63Sopenharmony_civoid VerifyElf::GetElfSignBlock(std::vector<int8_t>& bytes, BlockData& blockData, 29854aa6d63Sopenharmony_ci std::unordered_map<int8_t, SigningBlock>& signBlockMap) 29954aa6d63Sopenharmony_ci{ 30054aa6d63Sopenharmony_ci int32_t headBlockLen = SignHead::ELF_BLOCK_LEN; 30154aa6d63Sopenharmony_ci int64_t offset = blockData.GetBlockStart(); 30254aa6d63Sopenharmony_ci for (int i = 0; i < blockData.GetBlockNum(); i++) { 30354aa6d63Sopenharmony_ci std::vector<int8_t> blockByte(bytes.begin() + offset, bytes.begin() + offset + headBlockLen); 30454aa6d63Sopenharmony_ci std::unique_ptr<ByteBuffer> blockBuffer = std::make_unique<ByteBuffer>(blockByte.size()); 30554aa6d63Sopenharmony_ci blockBuffer->PutData(blockByte.data(), blockByte.size()); 30654aa6d63Sopenharmony_ci blockBuffer->Flip(); 30754aa6d63Sopenharmony_ci int8_t type = 0; 30854aa6d63Sopenharmony_ci int8_t tag = 0; 30954aa6d63Sopenharmony_ci int16_t empValue = 0; 31054aa6d63Sopenharmony_ci int32_t length = 0; 31154aa6d63Sopenharmony_ci int32_t blockOffset = 0; 31254aa6d63Sopenharmony_ci blockBuffer->GetByte((int8_t*)&type, sizeof(int8_t)); 31354aa6d63Sopenharmony_ci blockBuffer->GetByte((int8_t*)&tag, sizeof(int8_t)); 31454aa6d63Sopenharmony_ci blockBuffer->GetInt16(empValue); 31554aa6d63Sopenharmony_ci blockBuffer->GetInt32(length); 31654aa6d63Sopenharmony_ci blockBuffer->GetInt32(blockOffset); 31754aa6d63Sopenharmony_ci std::vector<int8_t> value(bytes.begin() + blockData.GetBlockStart() + blockOffset, 31854aa6d63Sopenharmony_ci bytes.begin() + blockData.GetBlockStart() + blockOffset + length); 31954aa6d63Sopenharmony_ci SigningBlock signingBlock(type, value, blockData.GetBlockStart() + blockOffset); 32054aa6d63Sopenharmony_ci signBlockMap.insert(std::make_pair(type, signingBlock)); 32154aa6d63Sopenharmony_ci offset += headBlockLen; 32254aa6d63Sopenharmony_ci } 32354aa6d63Sopenharmony_ci} 32454aa6d63Sopenharmony_ci 32554aa6d63Sopenharmony_civoid VerifyElf::GetBinSignBlock(std::vector<int8_t>& bytes, BlockData& blockData, 32654aa6d63Sopenharmony_ci std::unordered_map<int8_t, SigningBlock>& signBlockMap) 32754aa6d63Sopenharmony_ci{ 32854aa6d63Sopenharmony_ci int32_t headBlockLen = SignHead::BIN_BLOCK_LEN; 32954aa6d63Sopenharmony_ci int32_t offset = blockData.GetBlockStart(); 33054aa6d63Sopenharmony_ci for (int i = 0; i < blockData.GetBlockNum(); i++) { 33154aa6d63Sopenharmony_ci std::vector<int8_t> blockByte(bytes.begin() + offset, bytes.begin() + offset + headBlockLen); 33254aa6d63Sopenharmony_ci std::unique_ptr<ByteBuffer> blockBuffer = std::make_unique<ByteBuffer>(blockByte.size()); 33354aa6d63Sopenharmony_ci blockBuffer->PutData(blockByte.data(), blockByte.size()); 33454aa6d63Sopenharmony_ci blockBuffer->Flip(); 33554aa6d63Sopenharmony_ci int8_t type = 0; 33654aa6d63Sopenharmony_ci int8_t tag = 0; 33754aa6d63Sopenharmony_ci int16_t length = 0; 33854aa6d63Sopenharmony_ci int32_t blockOffset = 0; 33954aa6d63Sopenharmony_ci blockBuffer->GetByte((int8_t*)&type, sizeof(int8_t)); 34054aa6d63Sopenharmony_ci blockBuffer->GetByte((int8_t*)&tag, sizeof(int8_t)); 34154aa6d63Sopenharmony_ci const char* bufferPtr = blockBuffer->GetBufferPtr(); 34254aa6d63Sopenharmony_ci int bfLengthIdx = 2; 34354aa6d63Sopenharmony_ci int bfBlockIdx = 4; 34454aa6d63Sopenharmony_ci length = static_cast<int16_t>(be16toh(*reinterpret_cast<const int16_t*>(bufferPtr + bfLengthIdx))); 34554aa6d63Sopenharmony_ci blockOffset = static_cast<int32_t>(be32toh(*reinterpret_cast<const int32_t*>(bufferPtr + bfBlockIdx))); 34654aa6d63Sopenharmony_ci if (length == 0) { 34754aa6d63Sopenharmony_ci length = bytes.size() - SignHead::SIGN_HEAD_LEN - blockOffset; 34854aa6d63Sopenharmony_ci } 34954aa6d63Sopenharmony_ci std::vector<int8_t> value(bytes.begin() + blockOffset, bytes.begin() + blockOffset + length); 35054aa6d63Sopenharmony_ci SigningBlock signingBlock(type, value, blockOffset); 35154aa6d63Sopenharmony_ci signBlockMap.insert(std::make_pair(type, signingBlock)); 35254aa6d63Sopenharmony_ci offset += headBlockLen; 35354aa6d63Sopenharmony_ci } 35454aa6d63Sopenharmony_ci} 35554aa6d63Sopenharmony_ci 35654aa6d63Sopenharmony_cibool VerifyElf::CheckParams(Options* options) 35754aa6d63Sopenharmony_ci{ 35854aa6d63Sopenharmony_ci bool certEmpty = options->GetString(Options::OUT_CERT_CHAIN).empty(); 35954aa6d63Sopenharmony_ci if (certEmpty) { 36054aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "Missing parameter: " + Options::OUT_CERT_CHAIN + "s."); 36154aa6d63Sopenharmony_ci return false; 36254aa6d63Sopenharmony_ci } 36354aa6d63Sopenharmony_ci bool profileEmpty = options->GetString(Options::OUT_PROFILE).empty(); 36454aa6d63Sopenharmony_ci if (profileEmpty) { 36554aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "Missing parameter: " + Options::OUT_PROFILE + "s."); 36654aa6d63Sopenharmony_ci return false; 36754aa6d63Sopenharmony_ci } 36854aa6d63Sopenharmony_ci bool proofEmpty = options->GetString(Options::PROOF_FILE).empty(); 36954aa6d63Sopenharmony_ci if (proofEmpty) { 37054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGW("Missing parameter: %s.", 37154aa6d63Sopenharmony_ci Options::PROOF_FILE.c_str()); 37254aa6d63Sopenharmony_ci } 37354aa6d63Sopenharmony_ci return true; 37454aa6d63Sopenharmony_ci} 37554aa6d63Sopenharmony_ci 37654aa6d63Sopenharmony_cibool VerifyElf::CheckSignFile(const std::string& signedFile) 37754aa6d63Sopenharmony_ci{ 37854aa6d63Sopenharmony_ci if (signedFile.empty()) { 37954aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "Not found verify file path " + signedFile); 38054aa6d63Sopenharmony_ci return false; 38154aa6d63Sopenharmony_ci } 38254aa6d63Sopenharmony_ci bool validFlag = FileUtils::IsValidFile(signedFile); 38354aa6d63Sopenharmony_ci if (!validFlag) { 38454aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("signed file is invalid."); 38554aa6d63Sopenharmony_ci return false; 38654aa6d63Sopenharmony_ci } 38754aa6d63Sopenharmony_ci return true; 38854aa6d63Sopenharmony_ci} 38954aa6d63Sopenharmony_ci 39054aa6d63Sopenharmony_cibool VerifyElf::GetRawContent(const std::vector<int8_t>& contentVec, std::string& rawContent) 39154aa6d63Sopenharmony_ci{ 39254aa6d63Sopenharmony_ci PKCS7Data p7Data; 39354aa6d63Sopenharmony_ci int parseFlag = p7Data.Parse(contentVec); 39454aa6d63Sopenharmony_ci if (parseFlag < 0) { 39554aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("parse content failed!"); 39654aa6d63Sopenharmony_ci return false; 39754aa6d63Sopenharmony_ci } 39854aa6d63Sopenharmony_ci int verifyFlag = p7Data.Verify(); 39954aa6d63Sopenharmony_ci if (verifyFlag < 0) { 40054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("verify content failed!"); 40154aa6d63Sopenharmony_ci return false; 40254aa6d63Sopenharmony_ci } 40354aa6d63Sopenharmony_ci int getContentFlag = p7Data.GetContent(rawContent); 40454aa6d63Sopenharmony_ci if (getContentFlag < 0) { 40554aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("get p7Data raw content failed!"); 40654aa6d63Sopenharmony_ci return false; 40754aa6d63Sopenharmony_ci } 40854aa6d63Sopenharmony_ci return true; 40954aa6d63Sopenharmony_ci} 41054aa6d63Sopenharmony_ci 41154aa6d63Sopenharmony_ci} // namespace SignatureTools 41254aa6d63Sopenharmony_ci} // namespace OHOS