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