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