1/*
2 * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <algorithm>
17
18#include "elf_sign_block.h"
19#include "fs_verity_descriptor.h"
20#include "fs_verity_descriptor_with_sign.h"
21#include "verify_code_signature.h"
22#include "code_signing.h"
23#include "signer_factory.h"
24#include "localization_adapter.h"
25
26namespace OHOS {
27namespace SignatureTools {
28const int BUFFER_SIZE = 16 * 1024;
29const int FILE_NAME_SIZE = 512;
30const std::vector<std::string> CodeSigning::SUPPORT_FILE_FORM = { "hap", "hsp", "hqf" };
31const std::string CodeSigning::HAP_SIGNATURE_ENTRY_NAME = "Hap";
32const std::string CodeSigning::ENABLE_SIGN_CODE_VALUE = "1";
33const std::string CodeSigning::LIBS_PATH_PREFIX = "libs/";
34
35const FsVerityHashAlgorithm FS_SHA256(1, "SHA-256", 256 / 8);
36const FsVerityHashAlgorithm FS_SHA512(2, "SHA-512", 512 / 8);
37const int8_t LOG_2_OF_FSVERITY_HASH_PAGE_SIZE = 12;
38
39CodeSigning::CodeSigning(SignerConfig* signConfig) : mPools(new Uscript::ThreadPool(POOL_SIZE))
40{
41    m_signConfig = signConfig;
42}
43
44CodeSigning::CodeSigning() : mPools(new Uscript::ThreadPool(POOL_SIZE))
45{
46}
47
48bool CodeSigning::GetCodeSignBlock(const std::string &input, int64_t offset,
49                                   const std::string &inForm, const std::string &profileContent,
50                                   ZipSigner& zip, std::vector<int8_t>& ret)
51{
52    SIGNATURE_TOOLS_LOGI("Start to sign code.");
53    bool formatFlag = std::find(SUPPORT_FILE_FORM.begin(), SUPPORT_FILE_FORM.end(), inForm)
54        == SUPPORT_FILE_FORM.end();
55    if (formatFlag) {
56        SIGNATURE_TOOLS_LOGE("only support format is [hap, hqf, hsp, app]");
57        return false;
58    }
59    uint32_t dataSize = ComputeDataSize(zip);
60    if (dataSize < 0) {
61        return false;
62    }
63    m_timestamp = GetTimestamp();
64    int64_t fsvTreeOffset = m_codeSignBlock.ComputeMerkleTreeOffset(offset);
65    std::unique_ptr<FsVerityInfoSegment> fsVerityInfoSegment =
66        std::make_unique<FsVerityInfoSegment>((int8_t)FsVerityDescriptor::VERSION,
67                                              (int8_t)FsVerityGenerator::GetFsVerityHashAlgorithm(),
68                                              (int8_t)FsVerityGenerator::GetLog2BlockSize());
69    m_codeSignBlock.SetFsVerityInfoSegment(*(fsVerityInfoSegment.get()));
70    SIGNATURE_TOOLS_LOGI("Sign hap.");
71    std::string ownerID = HapUtils::GetAppIdentifier(profileContent);
72    std::ifstream inputStream;
73    inputStream.open(input, std::ios::binary);
74    if (!inputStream.is_open()) {
75        PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "open file: " + input + "failed");
76        inputStream.close();
77        return false;
78    }
79    std::pair<SignInfo, std::vector<int8_t>> hapSignInfoAndMerkleTreeBytesPair;
80    bool signFileFlag = SignFile(inputStream, dataSize, true, fsvTreeOffset, ownerID,
81                                 hapSignInfoAndMerkleTreeBytesPair);
82    if (!signFileFlag) {
83        SIGNATURE_TOOLS_LOGE("SignFile Failed");
84        inputStream.close();
85        return false;
86    }
87    inputStream.close();
88    m_codeSignBlock.GetHapInfoSegment().SetSignInfo(hapSignInfoAndMerkleTreeBytesPair.first);
89    m_codeSignBlock.AddOneMerkleTree(HAP_SIGNATURE_ENTRY_NAME,
90                                     hapSignInfoAndMerkleTreeBytesPair.second);
91    if (!SignNativeLibs(input, ownerID)) {
92        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "Failed to sign the contents in the compressed file.");
93        return false;
94    }
95    UpdateCodeSignBlock();
96    m_codeSignBlock.GenerateCodeSignBlockByte(fsvTreeOffset, ret);
97    SIGNATURE_TOOLS_LOGI("Sign successfully.");
98    return true;
99}
100
101uint32_t CodeSigning::ComputeDataSize(ZipSigner& zip)
102{
103    uint32_t dataSize = 0L;
104    for (const auto& entry : zip.GetZipEntries()) {
105        ZipEntryHeader* zipEntryHeader = entry->GetZipEntryData()->GetZipEntryHeader();
106        bool runnableFileFlag = FileUtils::IsRunnableFile(zipEntryHeader->GetFileName())
107            && zipEntryHeader->GetMethod() == ZipSigner::FILE_UNCOMPRESS_METHOD_FLAG;
108        if (runnableFileFlag) {
109            continue;
110        }
111        // if the first file is not uncompressed abc or so, set dataSize to zero
112        if (entry->GetCentralDirectory()->GetOffset() == 0) {
113            break;
114        }
115        // the first entry which is not abc/so/an is found, return its data offset
116        dataSize = entry->GetCentralDirectory()->GetOffset() + ZipEntryHeader::HEADER_LENGTH
117            + zipEntryHeader->GetFileNameLength() + zipEntryHeader->GetExtraLength();
118        break;
119    }
120    if ((dataSize % CodeSignBlock::PAGE_SIZE_4K) != 0) {
121        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR,
122                            "Invalid dataSize, the dataSize must be an integer multiple of 4096");
123        return -1;
124    }
125    return dataSize;
126}
127
128int64_t CodeSigning::GetTimestamp()
129{
130    auto now = std::chrono::system_clock::now();
131    auto nowSeconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
132    return nowSeconds.time_since_epoch().count();
133}
134
135bool CodeSigning::SignFile(std::istream& inputStream, int64_t fileSize, bool storeTree,
136                           int64_t fsvTreeOffset, const std::string &ownerID,
137                           std::pair<SignInfo, std::vector<int8_t>>& ret)
138{
139    std::unique_ptr<FsVerityGenerator> fsVerityGenerator =
140        std::make_unique<FsVerityGenerator>();
141    if (!fsVerityGenerator->GenerateFsVerityDigest(inputStream, fileSize, fsvTreeOffset)) {
142        SIGNATURE_TOOLS_LOGE("SignFile GenerateFsVerityDigest Fail");
143        return false;
144    }
145    std::vector<int8_t> fsVerityDigest = fsVerityGenerator->GetFsVerityDigest();
146    std::vector<int8_t> signature;
147    bool generateSignatureFlag = GenerateSignature(fsVerityDigest, ownerID, signature);
148    if (!generateSignatureFlag) {
149        SIGNATURE_TOOLS_LOGE("SignFile GenerateSignature Fail");
150        return false;
151    }
152    int flags = 0;
153    if (storeTree) {
154        flags = SignInfo::FLAG_MERKLE_TREE_INCLUDED;
155    }
156    int saltSize = fsVerityGenerator->GetSaltSize();
157    std::vector<int8_t> salt = fsVerityGenerator->GetSalt();
158    SignInfo signInfo(saltSize, flags, fileSize, salt, signature);
159    // if store merkle tree in sign info
160    if (storeTree) {
161        int merkleTreeSize = fsVerityGenerator->GetTreeBytes().empty() ? 0
162            : fsVerityGenerator->GetTreeBytes().size();
163        MerkleTreeExtension* merkleTreeExtension = new MerkleTreeExtension(merkleTreeSize,
164                                                                           fsvTreeOffset,
165                                                                           fsVerityGenerator->GetRootHash());
166        if (merkleTreeExtension == nullptr) {
167            PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "system failed to allocate memory for MerkleTreeExtension");
168            return false;
169        }
170        signInfo.AddExtension(merkleTreeExtension);
171    }
172    ret = std::make_pair(signInfo, fsVerityGenerator->GetTreeBytes());
173    return true;
174}
175
176bool CodeSigning::GetElfCodeSignBlock(const std::string &input, int64_t offset,
177                                      const std::string &inForm, const std::string &profileContent,
178                                      std::vector<int8_t>& codesignData)
179{
180    SIGNATURE_TOOLS_LOGI("Start to sign elf code.");
181    int paddingSize = ElfSignBlock::ComputeMerkleTreePaddingLength(offset);
182    int64_t fsvTreeOffset = offset + FsVerityDescriptorWithSign::INTEGER_BYTES * 2 + paddingSize;
183    std::ifstream inputstream(input, std::ios::binary | std::ios::ate);
184    if (!inputstream.is_open()) {
185        PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "open file: " + input + "failed");
186        return false;
187    }
188    std::streamsize fileSize = inputstream.tellg();
189    inputstream.seekg(0, std::ios::beg);
190    std::unique_ptr<FsVerityGenerator> fsVerityGenerator = std::make_unique<FsVerityGenerator>();
191    fsVerityGenerator->GenerateFsVerityDigest(inputstream, fileSize, fsvTreeOffset);
192    std::vector<int8_t> fsVerityDigest = fsVerityGenerator->GetFsVerityDigest();
193    std::string ownerID = profileContent.empty() ? "DEBUF_LIB_ID" : HapUtils::GetAppIdentifier(profileContent);
194    std::vector<int8_t> signature;
195    bool generateSignatureFlag = GenerateSignature(fsVerityDigest, ownerID, signature);
196    if (!generateSignatureFlag) {
197        SIGNATURE_TOOLS_LOGE("[SignElf] generate elf signature failed");
198        return false;
199    }
200
201    FsVerityDescriptor::Builder fsdbuilder;
202    fsdbuilder.SetFileSize(fileSize)
203              .SetHashAlgorithm(FS_SHA256.GetId())
204              .SetLog2BlockSize(LOG_2_OF_FSVERITY_HASH_PAGE_SIZE)
205              .SetSaltSize(fsVerityGenerator->GetSaltSize())
206              .SetSignSize(signature.size())
207              .SetFileSize(fileSize)
208              .SetSalt(fsVerityGenerator->Getsalt())
209              .SetRawRootHash(fsVerityGenerator->GetRootHash())
210              .SetFlags(FsVerityDescriptor::FLAG_STORE_MERKLE_TREE_OFFSET)
211              .SetMerkleTreeOffset(fsvTreeOffset)
212              .SetCsVersion(FsVerityDescriptor::CODE_SIGN_VERSION);
213
214    FsVerityDescriptorWithSign fsVerityDescriptorWithSign =
215        FsVerityDescriptorWithSign(FsVerityDescriptor(fsdbuilder), signature);
216    std::vector<int8_t> treeBytes = fsVerityGenerator->GetTreeBytes();
217    ElfSignBlock signBlock = ElfSignBlock(paddingSize, treeBytes, fsVerityDescriptorWithSign);
218    signBlock.ToByteArray(codesignData);
219    return true;
220}
221
222bool CodeSigning::SignNativeLibs(const std::string &input, std::string &ownerID)
223{
224    // sign native files
225    std::vector<std::pair<std::string, SignInfo>> ret;
226    UnzipHandleParam param(ret, ownerID, true);
227    bool nativeLibflag = GetNativeEntriesFromHap(input, param);
228    if (!nativeLibflag) {
229        SIGNATURE_TOOLS_LOGE("%s native libs handle failed", input.c_str());
230        return false;
231    }
232    std::vector<std::pair<std::string, SignInfo>>& nativeLibInfoList = param.GetRet();
233    if (nativeLibInfoList.empty()) {
234        SIGNATURE_TOOLS_LOGI("No native libs.");
235        return true;
236    }
237    m_codeSignBlock.GetSoInfoSegment().SetSoInfoList(nativeLibInfoList);
238    return true;
239}
240
241void CodeSigning::UpdateCodeSignBlock()
242{
243    // construct segment header list
244    m_codeSignBlock.SetSegmentHeaders();
245    // Compute and set segment number
246    m_codeSignBlock.SetSegmentNum();
247    // update code sign block header flag
248    m_codeSignBlock.SetCodeSignBlockFlag();
249    // compute segment offset
250    m_codeSignBlock.ComputeSegmentOffset();
251}
252
253bool CodeSigning::GetNativeEntriesFromHap(const std::string& packageName, UnzipHandleParam& param)
254{
255    unzFile zFile = unzOpen(packageName.c_str());
256    if (zFile == NULL) {
257        PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "zlib open file: " + packageName + " failed.");
258        return false;
259    }
260    // get zipFile all paramets
261    unz_global_info zGlobalInfo;
262    int getRet = unzGetGlobalInfo(zFile, &zGlobalInfo);
263    if (getRet != UNZ_OK) {
264        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "zlib get global info failed.");
265        unzClose(zFile);
266        return false;
267    }
268    // search each file
269    bool handleFlag = HandleZipGlobalInfo(packageName, zFile, zGlobalInfo, param);
270    if (!handleFlag) {
271        unzClose(zFile);
272        return false;
273    }
274
275    unzClose(zFile);
276    return true;
277}
278
279bool CodeSigning::GetSingleFileStreamFromZip(unzFile &zFile, char fileName[],
280                                             unz_file_info &zFileInfo,
281                                             int &readFileSize, std::stringbuf &sb)
282{
283    char szReadBuffer[BUFFER_SIZE] = { 0 };
284
285    long fileLength = zFileInfo.uncompressed_size;
286    int nReadFileSize;
287    do {
288        nReadFileSize = 0;
289        if (memset_s(szReadBuffer, BUFFER_SIZE, 0, BUFFER_SIZE) != EOK) {
290            SIGNATURE_TOOLS_LOGE("memset_s failed");
291            unzClose(zFile);
292            return false;
293        }
294        nReadFileSize = unzReadCurrentFile(zFile, szReadBuffer, BUFFER_SIZE);
295        if (nReadFileSize > 0) {
296            sb.sputn(szReadBuffer, nReadFileSize);
297        }
298        fileLength -= nReadFileSize;
299        readFileSize += nReadFileSize;
300    } while (fileLength > 0 && nReadFileSize > 0);
301    if (fileLength) {
302        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "zlib read stream from "
303                            + std::string(fileName) + " failed.");
304        unzClose(zFile);
305        return false;
306    }
307
308    unzCloseCurrentFile(zFile);
309    unzClose(zFile);
310    return true;
311}
312
313bool CodeSigning::RunParseZipInfo(const std::string& packageName, UnzipHandleParam& param, uLong index)
314{
315    unzFile zFile = unzOpen(packageName.c_str());
316    if (zFile == NULL) {
317        PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "zlib open file: " + packageName + " failed.");
318        return false;
319    }
320    // get zipFile all paramets
321    unz_global_info zGlobalInfo;
322    int getRet = unzGetGlobalInfo(zFile, &zGlobalInfo);
323    if (getRet != UNZ_OK) {
324        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "zlib get global info failed.");
325        unzClose(zFile);
326        return false;
327    }
328    for (uLong i = 0; i < index; ++i) {
329        int ret = unzGoToNextFile(zFile);
330        if (ret != UNZ_OK) {
331            unzClose(zFile);
332            return false;
333        }
334    }
335    unz_file_info zFileInfo;
336    char fileName[FILE_NAME_SIZE];
337    int readFileSize = 0;
338    std::stringbuf sb;
339    if (memset_s(fileName, FILE_NAME_SIZE, 0, FILE_NAME_SIZE) != 0) {
340        unzClose(zFile);
341        return false;
342    }
343    size_t nameLen = 0;
344    if (!CheckUnzParam(zFile, zFileInfo, fileName, &nameLen)) {
345        unzClose(zFile);
346        return false;
347    }
348    if (!CheckFileName(zFile, fileName, &nameLen)) {
349        unzClose(zFile);
350        return true;
351    }
352    bool flag = GetSingleFileStreamFromZip(zFile, fileName, zFileInfo, readFileSize, sb);
353    if (!flag) {
354        return false;
355    }
356    bool handleFlag = DoNativeLibSignOrVerify(std::string(fileName), sb, param, readFileSize);
357    if (!handleFlag) {
358        SIGNATURE_TOOLS_LOGE("%s native libs handle failed", fileName);
359        return false;
360    }
361    return true;
362}
363
364bool CodeSigning::HandleZipGlobalInfo(const std::string& packageName, unzFile& zFile,
365                                      unz_global_info& zGlobalInfo, UnzipHandleParam& param)
366{
367    std::vector<std::future<bool>> thread_results;
368    SIGNATURE_TOOLS_LOGI("zGlobalInfo.number_entry = %lu", zGlobalInfo.number_entry);
369    for (uLong i = 0; i < zGlobalInfo.number_entry; ++i) {
370        thread_results.push_back(mPools->Enqueue(&CodeSigning::RunParseZipInfo, this,
371            std::ref(packageName), std::ref(param), i));
372    }
373
374    bool result = true;
375    for (auto& thread_result : thread_results) {
376        if (!thread_result.get())
377            result = false;
378    }
379    if (!result) {
380        return false;
381    }
382    return true;
383}
384
385bool CodeSigning::DoNativeLibVerify(std::string fileName, std::stringbuf& sb,
386                                    UnzipHandleParam& param, int readFileSize)
387{
388    std::istream input(&sb);
389    CodeSignBlock csb = param.GetCodeSignBlock();
390    std::vector<std::string>& fileNames = csb.GetSoInfoSegment().GetFileNameList();
391    bool isContainFileName = std::find(fileNames.begin(), fileNames.end(), fileName) != fileNames.end();
392    if (!isContainFileName) {
393        PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
394                            "verify signed file position failed, file: " + fileName);
395        return false;
396    }
397    for (int j = 0; j < csb.GetSoInfoSegment().GetSectionNum(); j++) {
398        SignInfo signInfo = csb.GetSoInfoSegment().GetSignInfoList()[j];
399        std::string entryName = csb.GetSoInfoSegment().GetFileNameList()[j];
400        std::vector<int8_t> entrySig = signInfo.GetSignature();
401        std::string entrySigStr(entrySig.begin(), entrySig.end());
402        if (fileName != entryName) {
403            continue;
404        }
405        if (readFileSize != signInfo.GetDataSize()) {
406            PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "Invalid dataSize of native lib");
407            return false;
408        }
409        bool verifyFlag = VerifyCodeSignature::VerifySingleFile(input, readFileSize, entrySig, 0,
410                                                                std::vector<int8_t>());
411        if (!verifyFlag) {
412            return false;
413        }
414        std::ifstream* inputFile = (std::ifstream*)(&input);
415        inputFile->close();
416        std::pair<std::string, std::string> pairResult = param.GetPairResult();
417        bool checkOwnerIDFlag = CmsUtils::CheckOwnerID(entrySigStr, pairResult.first, pairResult.second);
418        if (!checkOwnerIDFlag) {
419            return false;
420        }
421    }
422    return true;
423}
424
425bool CodeSigning::DoNativeLibSignOrVerify(std::string fileName, std::stringbuf& sb,
426                                          UnzipHandleParam& param, int readFileSize)
427{
428    bool isSign = param.IsSign();
429    if (isSign) {
430        std::istream input(&sb);
431        std::string ownerID = param.GetOwnerID();
432        std::pair<SignInfo, std::vector<int8_t>> pairSignInfoAndMerkleTreeBytes;
433        bool signFileFlag = SignFile(input, readFileSize, false, 0, ownerID, pairSignInfoAndMerkleTreeBytes);
434        if (!signFileFlag) {
435            return false;
436        }
437        m_mutex.lock();
438        std::vector<std::pair<std::string, SignInfo>> &ret = param.GetRet();
439        ret.push_back(std::make_pair(fileName, pairSignInfoAndMerkleTreeBytes.first));
440        m_mutex.unlock();
441    } else {
442        bool flag = DoNativeLibVerify(fileName, sb, param, readFileSize);
443        if (!flag) {
444            return false;
445        }
446    }
447    return true;
448}
449
450bool CodeSigning::CheckUnzParam(unzFile& zFile, unz_file_info& zFileInfo,
451                                char fileName[], size_t* nameLen)
452{
453    if (UNZ_OK != unzGetCurrentFileInfo(zFile, &zFileInfo, fileName,
454        FILE_NAME_SIZE, NULL, 0, NULL, 0)) {
455        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR,
456                            "unzip get file: " + std::string(fileName) + "info failed!");
457        return false;
458    }
459    SIGNATURE_TOOLS_LOGI("Open zipFile filename is : %s", fileName);
460    if ((*nameLen = strlen(fileName)) == 0U) {
461        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "Open zipFile fileName is null");
462        return false;
463    }
464    if (UNZ_OK != unzOpenCurrentFile(zFile)) {
465        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR,
466                            "unzOpenCurrentFile zipFile error");
467        return false;
468    }
469    return true;
470}
471
472bool CodeSigning::CheckFileName(unzFile& zFile, char fileName[], size_t* nameLen)
473{
474    if (fileName[*nameLen - 1] == '/') {
475        SIGNATURE_TOOLS_LOGI("It is dictionary.");
476        unzCloseCurrentFile(zFile);
477        unzGoToNextFile(zFile);
478        return false;
479    }
480    std::string str(fileName);
481    bool nativeFileFlag = IsNativeFile(str);
482    if (!nativeFileFlag) {
483        SIGNATURE_TOOLS_LOGI("Suffix mismatched.");
484        unzCloseCurrentFile(zFile);
485        unzGoToNextFile(zFile);
486        return false;
487    }
488    return true;
489}
490
491bool CodeSigning::IsNativeFile(const std::string& input)
492{
493    size_t dotPos = input.rfind('.');
494    if (dotPos == std::string::npos) {
495        return false;
496    }
497    std::string suffix = input.substr(dotPos + 1);
498    if (suffix == "an") {
499        return true;
500    }
501    std::string libDir = input.substr(0, LIBS_PATH_PREFIX.size());
502    int ret = LIBS_PATH_PREFIX.compare(libDir);
503    if (ret == 0) {
504        return true;
505    }
506    return false;
507}
508
509bool CodeSigning::GenerateSignature(const std::vector<int8_t>& signedData, const std::string& ownerID,
510                                    std::vector<int8_t>& ret)
511{
512    Options* options = m_signConfig->GetOptions();
513    SignerFactory factory;
514    LocalizationAdapter adapter(options);
515    std::shared_ptr<Signer> signer(factory.GetSigner(adapter));
516    if (signer != nullptr) {
517        STACK_OF(X509)* certs = NULL;
518        certs = signer->GetCertificates();
519        if (certs == nullptr) {
520            PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR,
521                                "No certificates configured for sign.");
522            return false;
523        }
524        sk_X509_pop_free(certs, X509_free);
525    } else {
526        return false;
527    }
528    std::unique_ptr<BCSignedDataGenerator> bcSignedDataGenerator =
529        std::make_unique<BCSignedDataGenerator>();
530    if (!ownerID.empty()) {
531        SIGNATURE_TOOLS_LOGW("generate signature get owner id not null.");
532        bcSignedDataGenerator->SetOwnerId(ownerID);
533    }
534    std::string signed_data(signedData.begin(), signedData.end());
535    std::string ret_str;
536    if (signedData.empty()) {
537        PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "Generate verity digest is null");
538        return false;
539    }
540    bool generateSignedDataFlag = bcSignedDataGenerator->GenerateSignedData(signed_data, m_signConfig, ret_str);
541    if (generateSignedDataFlag) {
542        SIGNATURE_TOOLS_LOGE("Generate signedData failed");
543        return false;
544    }
545    ret = std::vector<int8_t>(ret_str.begin(), ret_str.end());
546    return true;
547}
548} // namespace SignatureTools
549} // namespace OHOS
550