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