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