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 
26 namespace OHOS {
27 namespace SignatureTools {
28 const int BUFFER_SIZE = 16 * 1024;
29 const int FILE_NAME_SIZE = 512;
30 const std::vector<std::string> CodeSigning::SUPPORT_FILE_FORM = { "hap", "hsp", "hqf" };
31 const std::string CodeSigning::HAP_SIGNATURE_ENTRY_NAME = "Hap";
32 const std::string CodeSigning::ENABLE_SIGN_CODE_VALUE = "1";
33 const std::string CodeSigning::LIBS_PATH_PREFIX = "libs/";
34 
35 const FsVerityHashAlgorithm FS_SHA256(1, "SHA-256", 256 / 8);
36 const FsVerityHashAlgorithm FS_SHA512(2, "SHA-512", 512 / 8);
37 const int8_t LOG_2_OF_FSVERITY_HASH_PAGE_SIZE = 12;
38 
CodeSigning(SignerConfig* signConfig)39 CodeSigning::CodeSigning(SignerConfig* signConfig) : mPools(new Uscript::ThreadPool(POOL_SIZE))
40 {
41     m_signConfig = signConfig;
42 }
43 
CodeSigning()44 CodeSigning::CodeSigning() : mPools(new Uscript::ThreadPool(POOL_SIZE))
45 {
46 }
47 
GetCodeSignBlock(const std::string &input, int64_t offset, const std::string &inForm, const std::string &profileContent, ZipSigner& zip, std::vector<int8_t>& ret)48 bool 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 
ComputeDataSize(ZipSigner& zip)101 uint32_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 
GetTimestamp()128 int64_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 
SignFile(std::istream& inputStream, int64_t fileSize, bool storeTree, int64_t fsvTreeOffset, const std::string &ownerID, std::pair<SignInfo, std::vector<int8_t>>& ret)135 bool 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 
GetElfCodeSignBlock(const std::string &input, int64_t offset, const std::string &inForm, const std::string &profileContent, std::vector<int8_t>& codesignData)176 bool 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 
SignNativeLibs(const std::string &input, std::string &ownerID)222 bool 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 
UpdateCodeSignBlock()241 void 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 
GetNativeEntriesFromHap(const std::string& packageName, UnzipHandleParam& param)253 bool 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 
GetSingleFileStreamFromZip(unzFile &zFile, char fileName[], unz_file_info &zFileInfo, int &readFileSize, std::stringbuf &sb)279 bool 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 
RunParseZipInfo(const std::string& packageName, UnzipHandleParam& param, uLong index)313 bool 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 
HandleZipGlobalInfo(const std::string& packageName, unzFile& zFile, unz_global_info& zGlobalInfo, UnzipHandleParam& param)364 bool 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 
DoNativeLibVerify(std::string fileName, std::stringbuf& sb, UnzipHandleParam& param, int readFileSize)385 bool 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 
DoNativeLibSignOrVerify(std::string fileName, std::stringbuf& sb, UnzipHandleParam& param, int readFileSize)425 bool 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 
CheckUnzParam(unzFile& zFile, unz_file_info& zFileInfo, char fileName[], size_t* nameLen)450 bool 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 
CheckFileName(unzFile& zFile, char fileName[], size_t* nameLen)472 bool 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 
IsNativeFile(const std::string& input)491 bool 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 
GenerateSignature(const std::vector<int8_t>& signedData, const std::string& ownerID, std::vector<int8_t>& ret)509 bool 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