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