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 "verify_bin.h"
1754aa6d63Sopenharmony_ci#include "verify_hap.h"
1854aa6d63Sopenharmony_ci#include "constant.h"
1954aa6d63Sopenharmony_ci
2054aa6d63Sopenharmony_cinamespace OHOS {
2154aa6d63Sopenharmony_cinamespace SignatureTools {
2254aa6d63Sopenharmony_ci
2354aa6d63Sopenharmony_cibool VerifyBin::Verify(Options* options)
2454aa6d63Sopenharmony_ci{
2554aa6d63Sopenharmony_ci    // check param
2654aa6d63Sopenharmony_ci    if (options == nullptr) {
2754aa6d63Sopenharmony_ci        PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "Param options is null.");
2854aa6d63Sopenharmony_ci        return false;
2954aa6d63Sopenharmony_ci    }
3054aa6d63Sopenharmony_ci    if (!VerifyElf::CheckParams(options)) {
3154aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("verify bin check params failed!");
3254aa6d63Sopenharmony_ci        return false;
3354aa6d63Sopenharmony_ci    }
3454aa6d63Sopenharmony_ci    std::string filePath = options->GetString(Options::IN_FILE);
3554aa6d63Sopenharmony_ci    bool checkSignFileFlag = VerifyElf::CheckSignFile(filePath);
3654aa6d63Sopenharmony_ci    if (!checkSignFileFlag) {
3754aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("check input bin file %s failed!", filePath.c_str());
3854aa6d63Sopenharmony_ci        return false;
3954aa6d63Sopenharmony_ci    }
4054aa6d63Sopenharmony_ci    // verify bin
4154aa6d63Sopenharmony_ci    std::vector<int8_t> profileVec;
4254aa6d63Sopenharmony_ci    Pkcs7Context pkcs7Context;
4354aa6d63Sopenharmony_ci    bool verifyBinFileFLag = VerifyBinFile(filePath, profileVec, options, pkcs7Context);
4454aa6d63Sopenharmony_ci    if (!verifyBinFileFLag) {
4554aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("verify bin file %s failed!", filePath.c_str());
4654aa6d63Sopenharmony_ci        return false;
4754aa6d63Sopenharmony_ci    }
4854aa6d63Sopenharmony_ci    // write certificate and p7b file
4954aa6d63Sopenharmony_ci    VerifyHap hapVerify(false);
5054aa6d63Sopenharmony_ci    int32_t writeFlag = hapVerify.WriteVerifyOutput(pkcs7Context, profileVec, options);
5154aa6d63Sopenharmony_ci    if (writeFlag != RET_OK) {
5254aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("write elf output failed on verify bin!");
5354aa6d63Sopenharmony_ci        return false;
5454aa6d63Sopenharmony_ci    }
5554aa6d63Sopenharmony_ci    return true;
5654aa6d63Sopenharmony_ci}
5754aa6d63Sopenharmony_ci
5854aa6d63Sopenharmony_cibool VerifyBin::VerifyBinFile(const std::string& binFile, std::vector<int8_t>& profileVec,
5954aa6d63Sopenharmony_ci                              Options* options, Pkcs7Context& pkcs7Context)
6054aa6d63Sopenharmony_ci{
6154aa6d63Sopenharmony_ci    SignBlockInfo signBlockInfo(true);
6254aa6d63Sopenharmony_ci    bool getSignBlockInfoFlag = VerifyElf::GetSignBlockInfo(binFile, signBlockInfo, BIN);
6354aa6d63Sopenharmony_ci    if (!getSignBlockInfoFlag) {
6454aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("get signBlockInfo failed on verify bin %s", binFile.c_str());
6554aa6d63Sopenharmony_ci        return false;
6654aa6d63Sopenharmony_ci    }
6754aa6d63Sopenharmony_ci    // verify profile
6854aa6d63Sopenharmony_ci    std::string profileJson;
6954aa6d63Sopenharmony_ci    bool verifyP7bFlag = VerifyElf::VerifyP7b(signBlockInfo.GetSignBlockMap(), options, pkcs7Context,
7054aa6d63Sopenharmony_ci        profileVec, profileJson);
7154aa6d63Sopenharmony_ci    if (!verifyP7bFlag) {
7254aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("verify profile failed on verify bin %s", binFile.c_str());
7354aa6d63Sopenharmony_ci        return false;
7454aa6d63Sopenharmony_ci    }
7554aa6d63Sopenharmony_ci    // verify signed data
7654aa6d63Sopenharmony_ci    bool verifyBinDigestFlag = VerifyBinDigest(signBlockInfo);
7754aa6d63Sopenharmony_ci    if (!verifyBinDigestFlag) {
7854aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("verify digest failed on verify bin %s", binFile.c_str());
7954aa6d63Sopenharmony_ci        return false;
8054aa6d63Sopenharmony_ci    }
8154aa6d63Sopenharmony_ci    return true;
8254aa6d63Sopenharmony_ci}
8354aa6d63Sopenharmony_ci
8454aa6d63Sopenharmony_cibool VerifyBin::VerifyBinDigest(SignBlockInfo& signBlockInfo)
8554aa6d63Sopenharmony_ci{
8654aa6d63Sopenharmony_ci    std::vector<int8_t>& rawDigest = signBlockInfo.GetRawDigest();
8754aa6d63Sopenharmony_ci    std::vector<int8_t>& generatedDig = signBlockInfo.GetFileDigest();
8854aa6d63Sopenharmony_ci    bool isEqual = rawDigest.empty() || generatedDig.empty() ||
8954aa6d63Sopenharmony_ci        !std::equal(rawDigest.begin(), rawDigest.end(), generatedDig.begin());
9054aa6d63Sopenharmony_ci    if (isEqual) {
9154aa6d63Sopenharmony_ci        PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "compare bin file raw digest and generated digest failed!");
9254aa6d63Sopenharmony_ci        return false;
9354aa6d63Sopenharmony_ci    }
9454aa6d63Sopenharmony_ci    return true;
9554aa6d63Sopenharmony_ci}
9654aa6d63Sopenharmony_ci
9754aa6d63Sopenharmony_ci} // namespace SignatureTools
9854aa6d63Sopenharmony_ci} // namespace OHOS