1 /*
2 * Copyright (c) 2021 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 #include "pkg_manager_impl.h"
16 #include <algorithm>
17 #include <cctype>
18 #include <cinttypes>
19 #include <cstdio>
20 #include <cstring>
21 #include <fcntl.h>
22 #include <functional>
23 #include <iterator>
24 #include <unistd.h>
25 #include <vector>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include "dump.h"
29 #include "pkg_gzipfile.h"
30 #include "pkg_lz4file.h"
31 #include "pkg_manager.h"
32 #include "pkg_upgradefile.h"
33 #include "pkg_verify_util.h"
34 #include "pkg_zipfile.h"
35 #include "scope_guard.h"
36 #include "securec.h"
37 #include "updater/updater_const.h"
38 #include "utils.h"
39 #include "zip_pkg_parse.h"
40
41 using namespace std;
42 using namespace Updater;
43
44 namespace Hpackage {
45 constexpr int32_t BUFFER_SIZE = 4096;
46 constexpr int32_t DIGEST_INFO_NO_SIGN = 0;
47 constexpr int32_t DIGEST_INFO_HAS_SIGN = 1;
48 constexpr int32_t DIGEST_INFO_SIGNATURE = 2;
49 constexpr int32_t DIGEST_FLAGS_NO_SIGN = 1;
50 constexpr int32_t DIGEST_FLAGS_HAS_SIGN = 2;
51 constexpr int32_t DIGEST_FLAGS_SIGNATURE = 4;
52 constexpr uint32_t VERIFY_FINSH_PERCENT = 100;
53
CreatePackageManager(void) const54 PkgManager::PkgManagerPtr PkgManager::PkgManagerFactory::CreatePackageManager(void) const
55 {
56 return PkgManager::CreatePackageInstance();
57 }
58
ReleasePkgManager(PkgManagerPtr pkgManger) const59 void PkgManager::PkgManagerFactory::ReleasePkgManager(PkgManagerPtr pkgManger) const
60 {
61 PkgManager::ReleasePackageInstance(pkgManger);
62 }
63
CreatePackageInstance()64 PkgManager::PkgManagerPtr PkgManager::CreatePackageInstance()
65 {
66 return new(std::nothrow) PkgManagerImpl();
67 }
68
ReleasePackageInstance(PkgManager::PkgManagerPtr manager)69 void PkgManager::ReleasePackageInstance(PkgManager::PkgManagerPtr manager)
70 {
71 if (manager == nullptr) {
72 return;
73 }
74 delete manager;
75 manager = nullptr;
76 }
77
PkgManagerImpl()78 PkgManagerImpl::PkgManagerImpl()
79 {
80 RegisterPkgFileCreator("bin", NewPkgFile<UpgradePkgFile>);
81 RegisterPkgFileCreator("zip", NewPkgFile<ZipPkgFile>);
82 RegisterPkgFileCreator("lz4", NewPkgFile<Lz4PkgFile>);
83 RegisterPkgFileCreator("gz", NewPkgFile<GZipPkgFile>);
84 }
85
~PkgManagerImpl()86 PkgManagerImpl::~PkgManagerImpl()
87 {
88 ClearPkgFile();
89 }
90
ClearPkgFile()91 void PkgManagerImpl::ClearPkgFile()
92 {
93 auto iter = pkgFiles_.begin();
94 while (iter != pkgFiles_.end()) {
95 PkgFilePtr file = (*iter);
96 delete file;
97 file = nullptr;
98 iter = pkgFiles_.erase(iter);
99 }
100 std::lock_guard<std::mutex> lock(mapLock_);
101 auto iter1 = pkgStreams_.begin();
102 while (iter1 != pkgStreams_.end()) {
103 PkgStreamPtr stream = (*iter1).second;
104 delete stream;
105 stream = nullptr;
106 iter1 = pkgStreams_.erase(iter1);
107 }
108 }
109
CreatePackage(const std::string & path,const std::string & keyName,PkgInfoPtr header,std::vector<std::pair<std::string,ZipFileInfo>> & files)110 int32_t PkgManagerImpl::CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
111 std::vector<std::pair<std::string, ZipFileInfo>> &files)
112 {
113 int32_t ret = SetSignVerifyKeyName(keyName);
114 if (ret != PKG_SUCCESS) {
115 PKG_LOGE("ZipFileInfo Invalid keyname");
116 return ret;
117 }
118 if (files.size() <= 0 || header == nullptr) {
119 PKG_LOGE("ZipFileInfo Invalid param");
120 return PKG_INVALID_PARAM;
121 }
122 size_t offset = 0;
123 PkgFilePtr pkgFile = CreatePackage<ZipFileInfo>(path, header, files, offset);
124 if (pkgFile == nullptr) {
125 return PKG_INVALID_FILE;
126 }
127 delete pkgFile;
128 pkgFile = nullptr;
129 return ret;
130 }
131
CreatePackage(const std::string & path,const std::string & keyName,PkgInfoPtr header,std::vector<std::pair<std::string,ComponentInfo>> & files)132 int32_t PkgManagerImpl::CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
133 std::vector<std::pair<std::string, ComponentInfo>> &files)
134 {
135 int32_t ret = SetSignVerifyKeyName(keyName);
136 if (ret != PKG_SUCCESS) {
137 PKG_LOGE("ComponentInfo Invalid keyname");
138 return ret;
139 }
140 if (files.size() <= 0 || header == nullptr) {
141 PKG_LOGE("ComponentInfo sssInvalid param");
142 return PKG_INVALID_PARAM;
143 }
144 size_t offset = 0;
145 PkgFilePtr pkgFile = CreatePackage<ComponentInfo>(path, header, files, offset);
146 if (pkgFile == nullptr) {
147 return PKG_INVALID_FILE;
148 }
149 ret = Sign(pkgFile->GetPkgStream(), offset, header);
150 delete pkgFile;
151 pkgFile = nullptr;
152 return ret;
153 }
154
CreatePackage(const std::string & path,const std::string & keyName,PkgInfoPtr header,std::vector<std::pair<std::string,Lz4FileInfo>> & files)155 int32_t PkgManagerImpl::CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
156 std::vector<std::pair<std::string, Lz4FileInfo>> &files)
157 {
158 int32_t ret = SetSignVerifyKeyName(keyName);
159 if (ret != PKG_SUCCESS) {
160 PKG_LOGE("Invalid keyname");
161 return ret;
162 }
163 if (files.size() != 1 || header == nullptr) {
164 PKG_LOGE("Invalid param");
165 return PKG_INVALID_PARAM;
166 }
167 size_t offset = 0;
168 PkgFilePtr pkgFile = CreatePackage<Lz4FileInfo>(path, header, files, offset);
169 if (pkgFile == nullptr) {
170 return PKG_INVALID_FILE;
171 }
172 ret = Sign(pkgFile->GetPkgStream(), offset, header);
173 delete pkgFile;
174 pkgFile = nullptr;
175 return ret;
176 }
177
178 template<class T>
CreatePackage(const std::string & path,PkgInfoPtr header,std::vector<std::pair<std::string,T>> & files,size_t & offset)179 PkgFilePtr PkgManagerImpl::CreatePackage(const std::string &path, PkgInfoPtr header,
180 std::vector<std::pair<std::string, T>> &files, size_t &offset)
181 {
182 PkgStreamPtr stream = nullptr;
183 int32_t ret = CreatePkgStream(stream, path, 0, PkgStream::PkgStreamType_Write);
184 if (ret != PKG_SUCCESS) {
185 PKG_LOGE("CreatePackage fail %s", path.c_str());
186 return nullptr;
187 }
188
189 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream),
190 static_cast<PkgFile::PkgType>(header->pkgType), header);
191 if (pkgFile == nullptr) {
192 PKG_LOGE("CreatePackage fail %s", path.c_str());
193 ClosePkgStream(stream);
194 return nullptr;
195 }
196
197 PkgStreamPtr inputStream = nullptr;
198 for (size_t i = 0; i < files.size(); i++) {
199 ret = CreatePkgStream(inputStream, files[i].first, 0, PkgStream::PkgStreamType_Read);
200 if (ret != PKG_SUCCESS) {
201 PKG_LOGE("Create stream fail %s", files[i].first.c_str());
202 break;
203 }
204 ret = pkgFile->AddEntry(reinterpret_cast<const FileInfoPtr>(&(files[i].second)), inputStream);
205 if (ret != PKG_SUCCESS) {
206 PKG_LOGE("Add entry fail %s", files[i].first.c_str());
207 break;
208 }
209 ClosePkgStream(inputStream);
210 inputStream = nullptr;
211 }
212 if (ret != PKG_SUCCESS) {
213 ClosePkgStream(inputStream);
214 delete pkgFile;
215 pkgFile = nullptr;
216 return nullptr;
217 }
218 ret = pkgFile->SavePackage(offset);
219 if (ret != PKG_SUCCESS) {
220 delete pkgFile;
221 pkgFile = nullptr;
222 return nullptr;
223 }
224 return pkgFile;
225 }
226
RegisterPkgFileCreator(const std::string & fileType,PkgFileConstructor constructor)227 void PkgManagerImpl::RegisterPkgFileCreator(const std::string &fileType, PkgFileConstructor constructor)
228 {
229 if (!pkgFileCreator_.emplace(fileType, constructor).second) {
230 LOG(ERROR) << "emplace: " << fileType << " fail";
231 }
232 }
233
CreatePackage(PkgStreamPtr stream,PkgFile::PkgType type,PkgInfoPtr header)234 PkgFilePtr PkgManagerImpl::CreatePackage(PkgStreamPtr stream, PkgFile::PkgType type, PkgInfoPtr header)
235 {
236 UNUSED(type);
237 PkgFilePtr pkgFile = nullptr;
238 std::string pkgName = stream->GetFileName();
239 std::string pkgType = GetPkgName(pkgName);
240 auto iter = pkgFileCreator_.find(pkgType);
241 if (iter == pkgFileCreator_.end()) {
242 LOG(ERROR) << "fileType is not registered: " << pkgType;
243 return pkgFile;
244 }
245 pkgFile = iter->second(this, stream, header);
246 return pkgFile;
247 }
248
LoadPackageWithoutUnPack(const std::string & packagePath,std::vector<std::string> & fileIds)249 int32_t PkgManagerImpl::LoadPackageWithoutUnPack(const std::string &packagePath,
250 std::vector<std::string> &fileIds)
251 {
252 PkgFile::PkgType pkgType = GetPkgTypeByName(packagePath);
253 int32_t ret = LoadPackage(packagePath, fileIds, pkgType);
254 if (ret != PKG_SUCCESS) {
255 PKG_LOGE("Parse %s fail ", packagePath.c_str());
256 ClearPkgFile();
257 return ret;
258 }
259 return PKG_SUCCESS;
260 }
261
ParsePackage(StreamPtr stream,std::vector<std::string> & fileIds,int32_t type)262 int32_t PkgManagerImpl::ParsePackage(StreamPtr stream, std::vector<std::string> &fileIds, int32_t type)
263 {
264 if (stream == nullptr) {
265 PKG_LOGE("Invalid stream");
266 return PKG_INVALID_PARAM;
267 }
268 PkgFilePtr pkgFile = CreatePackage(static_cast<PkgStreamPtr>(stream), static_cast<PkgFile::PkgType>(type), nullptr);
269 if (pkgFile == nullptr) {
270 PKG_LOGE("Create package fail %s", stream->GetFileName().c_str());
271 return PKG_INVALID_PARAM;
272 }
273
274 int32_t ret = pkgFile->LoadPackage(fileIds,
275 [](const PkgInfoPtr info, const std::vector<uint8_t> &digest, const std::vector<uint8_t> &signature)->int {
276 return PKG_SUCCESS;
277 });
278 if (ret != PKG_SUCCESS) {
279 PKG_LOGE("Load package fail %s", stream->GetFileName().c_str());
280 pkgFile->ClearPkgStream();
281 delete pkgFile;
282 return ret;
283 }
284 pkgFiles_.push_back(pkgFile);
285 return PKG_SUCCESS;
286 }
287
LoadPackage(const std::string & packagePath,const std::string & keyPath,std::vector<std::string> & fileIds)288 int32_t PkgManagerImpl::LoadPackage(const std::string &packagePath, const std::string &keyPath,
289 std::vector<std::string> &fileIds)
290 {
291 UPDATER_INIT_RECORD;
292 if (access(packagePath.c_str(), 0) != 0) {
293 UPDATER_LAST_WORD(PKG_INVALID_FILE, "access pkgpath failed");
294 return PKG_INVALID_FILE;
295 }
296 if (SetSignVerifyKeyName(keyPath) != PKG_SUCCESS) {
297 UPDATER_LAST_WORD(PKG_INVALID_FILE, "SetSignVerifyKeyName failed");
298 return PKG_INVALID_FILE;
299 }
300 // Check if package already loaded
301 for (auto iter : pkgFiles_) {
302 if (iter != nullptr && iter->GetPkgStream()->GetFileName().compare(packagePath) == 0) {
303 return PKG_SUCCESS;
304 }
305 }
306 PkgFile::PkgType pkgType = GetPkgTypeByName(packagePath);
307 unzipToFile_ = ((pkgType == PkgFile::PKG_TYPE_GZIP) ? true : unzipToFile_);
308 if (pkgType == PkgFile::PKG_TYPE_UPGRADE) {
309 if (LoadPackage(packagePath, fileIds, pkgType) != PKG_SUCCESS) {
310 ClearPkgFile();
311 UPDATER_LAST_WORD("LoadPackage failed", packagePath);
312 PKG_LOGE("Parse %s fail ", packagePath.c_str());
313 return PKG_INVALID_FILE;
314 }
315 } else if (pkgType != PkgFile::PKG_TYPE_NONE) {
316 std::vector<std::string> innerFileNames;
317 int32_t ret = LoadPackage(packagePath, innerFileNames, pkgType);
318 if (ret != PKG_SUCCESS) {
319 ClearPkgFile();
320 PKG_LOGE("Unzip %s fail ", packagePath.c_str());
321 return ret;
322 }
323 for (auto name : innerFileNames) {
324 pkgType = GetPkgTypeByName(name);
325 if (pkgType == PkgFile::PKG_TYPE_NONE || (pkgType == PkgFile::PKG_TYPE_UPGRADE
326 && std::find(innerFileNames.begin(), innerFileNames.end(), "board_list") != innerFileNames.end())) {
327 fileIds.push_back(name);
328 continue;
329 }
330 ret = ExtraAndLoadPackage(GetFilePath(packagePath), name, pkgType, fileIds);
331 if (ret != PKG_SUCCESS) {
332 ClearPkgFile();
333 UPDATER_LAST_WORD(ret, "ExtraAndLoadPackage failed");
334 PKG_LOGE("unpack %s fail in package %s ", name.c_str(), packagePath.c_str());
335 return ret;
336 }
337 }
338 }
339 return PKG_SUCCESS;
340 }
341
GetExtraPath(const std::string & path)342 const std::string PkgManagerImpl::GetExtraPath(const std::string &path)
343 {
344 if (path.find(Updater::SDCARD_CARD_PATH) != string::npos) {
345 return path;
346 } else if (path == UPDATRE_SCRIPT_ZIP) {
347 return "/tmp/";
348 }
349
350 return string(Updater::UPDATER_PATH) + "/";
351 }
352
ExtraAndLoadPackage(const std::string & path,const std::string & name,PkgFile::PkgType type,std::vector<std::string> & fileIds)353 int32_t PkgManagerImpl::ExtraAndLoadPackage(const std::string &path, const std::string &name,
354 PkgFile::PkgType type, std::vector<std::string> &fileIds)
355 {
356 int32_t ret = PKG_SUCCESS;
357 const FileInfo *info = GetFileInfo(name);
358 if (info == nullptr) {
359 PKG_LOGE("Create middle stream fail %s", name.c_str());
360 return PKG_INVALID_FILE;
361 }
362
363 PkgStreamPtr stream = nullptr;
364 struct stat st {};
365 const std::string tempPath = GetExtraPath(path);
366 if (stat(tempPath.c_str(), &st) != 0) {
367 #ifndef __WIN32
368 (void)mkdir(tempPath.c_str(), 0775); // 0775 : rwxrwxr-x
369 #endif
370 }
371
372 // Extract package to file or memory
373 if (unzipToFile_ || type == PkgFile::PKG_TYPE_UPGRADE) {
374 ret = CreatePkgStream(stream, tempPath + name + ".tmp", info->unpackedSize, PkgStream::PkgStreamType_Write);
375 } else {
376 ret = CreatePkgStream(stream, tempPath + name + ".tmp", info->unpackedSize, PkgStream::PkgStreamType_MemoryMap);
377 }
378 if (ret != PKG_SUCCESS) {
379 PKG_LOGE("Create middle stream fail %s", name.c_str());
380 return ret;
381 }
382
383 ret = ExtractFile(name, stream);
384 if (ret != PKG_SUCCESS) {
385 PKG_LOGE("Extract file fail %s", name.c_str());
386 ClosePkgStream(stream);
387 return ret;
388 }
389 return LoadPackageWithStream(path, fileIds, type, stream);
390 }
391
LoadPackage(const std::string & packagePath,std::vector<std::string> & fileIds,PkgFile::PkgType type)392 int32_t PkgManagerImpl::LoadPackage(const std::string &packagePath, std::vector<std::string> &fileIds,
393 PkgFile::PkgType type)
394 {
395 UPDATER_INIT_RECORD;
396 PkgStreamPtr stream = nullptr;
397 int32_t ret = CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read);
398 if (ret != PKG_SUCCESS) {
399 PKG_LOGE("Create input stream fail %s", packagePath.c_str());
400 UPDATER_LAST_WORD(ret, "CreatePkgStream failed");
401 return ret;
402 }
403 return LoadPackageWithStream(packagePath, fileIds, type, stream);
404 }
405
LoadPackageWithStreamForApp(AppPkgInfo & info,std::vector<std::string> & fileIds,StreamPtr stream)406 int32_t PkgManagerImpl::LoadPackageWithStreamForApp(AppPkgInfo &info,
407 std::vector<std::string> &fileIds, StreamPtr stream)
408 {
409 UPDATER_INIT_RECORD;
410 int32_t ret = SetSignVerifyKeyName(info.keyPath);
411 if (ret != PKG_SUCCESS) {
412 PKG_LOGE("Invalid keyname");
413 return ret;
414 }
415 ret = PKG_SUCCESS;
416 PkgFilePtr pkgFile = CreatePackage(stream, static_cast<PkgFile::PkgType>(info.type), nullptr);
417 if (pkgFile == nullptr) {
418 PKG_LOGE("Create package fail %s", info.packagePath.c_str());
419 UPDATER_LAST_WORD(ret, "Create package fail");
420 return PKG_INVALID_PARAM;
421 }
422 ret = pkgFile->ReadImgHashDataFile(info.pkgType);
423 if (ret != PKG_SUCCESS) {
424 PKG_LOGE("Read img hash data fail %s", info.pkgType.c_str());
425 delete pkgFile;
426 pkgFile = nullptr;
427 UPDATER_LAST_WORD(ret, "ReadImgHashDataFile failed");
428 return ret;
429 }
430 ret = pkgFile->LoadPackage(fileIds,
431 [this](const PkgInfoPtr info, const std::vector<uint8_t> &digest, const std::vector<uint8_t> &signature)->int {
432 return Verify(info->digestMethod, digest, signature);
433 });
434 if (ret != PKG_SUCCESS) {
435 PKG_LOGE("Load package fail %s", info.packagePath.c_str());
436 delete pkgFile;
437 pkgFile = nullptr;
438 UPDATER_LAST_WORD(ret, "Load package fail");
439 return ret;
440 }
441 pkgFiles_.push_back(pkgFile);
442 return PKG_SUCCESS;
443 }
444
LoadPackageWithStream(const std::string & packagePath,const std::string & keyPath,std::vector<std::string> & fileIds,uint8_t type,StreamPtr stream)445 int32_t PkgManagerImpl::LoadPackageWithStream(const std::string &packagePath, const std::string &keyPath,
446 std::vector<std::string> &fileIds, uint8_t type, StreamPtr stream)
447 {
448 int32_t ret = SetSignVerifyKeyName(keyPath);
449 if (ret != PKG_SUCCESS) {
450 PKG_LOGE("Invalid keyname");
451 return ret;
452 }
453
454 return LoadPackageWithStream(packagePath, fileIds, static_cast<PkgFile::PkgType>(type),
455 static_cast<PkgStreamPtr>(stream));
456 }
457
LoadPackageWithStream(const std::string & packagePath,std::vector<std::string> & fileIds,PkgFile::PkgType type,PkgStreamPtr stream)458 int32_t PkgManagerImpl::LoadPackageWithStream(const std::string &packagePath,
459 std::vector<std::string> &fileIds, PkgFile::PkgType type, PkgStreamPtr stream)
460 {
461 UPDATER_INIT_RECORD;
462 int32_t ret = PKG_SUCCESS;
463 PkgFilePtr pkgFile = CreatePackage(stream, type, nullptr);
464 if (pkgFile == nullptr) {
465 PKG_LOGE("Create package fail %s", packagePath.c_str());
466 ClosePkgStream(stream);
467 UPDATER_LAST_WORD(ret, "Create package fail");
468 return PKG_INVALID_PARAM;
469 }
470
471 ret = pkgFile->LoadPackage(fileIds,
472 [this](const PkgInfoPtr info, const std::vector<uint8_t> &digest, const std::vector<uint8_t> &signature)->int {
473 return Verify(info->digestMethod, digest, signature);
474 });
475 if (ret != PKG_SUCCESS) {
476 PKG_LOGE("Load package fail %s", packagePath.c_str());
477 delete pkgFile;
478 UPDATER_LAST_WORD(ret, "Load package fail");
479 return ret;
480 }
481 pkgFiles_.push_back(pkgFile);
482 return PKG_SUCCESS;
483 }
484
ExtractFile(const std::string & path,PkgManager::StreamPtr output)485 int32_t PkgManagerImpl::ExtractFile(const std::string &path, PkgManager::StreamPtr output)
486 {
487 UPDATER_INIT_RECORD;
488 if (output == nullptr) {
489 PKG_LOGE("Invalid stream");
490 UPDATER_LAST_WORD(PKG_INVALID_STREAM, "Invalid stream");
491 return PKG_INVALID_STREAM;
492 }
493 int32_t ret = PKG_INVALID_FILE;
494 PkgEntryPtr pkgEntry = GetPkgEntry(path);
495 if (pkgEntry != nullptr && pkgEntry->GetPkgFile() != nullptr) {
496 ret = pkgEntry->GetPkgFile()->ExtractFile(pkgEntry, PkgStreamImpl::ConvertPkgStream(output));
497 } else {
498 PKG_LOGE("Can not find file %s", path.c_str());
499 }
500 return ret;
501 }
502
ParseComponents(const std::string & packagePath,std::vector<std::string> & fileName)503 int32_t PkgManagerImpl::ParseComponents(const std::string &packagePath, std::vector<std::string> &fileName)
504 {
505 int32_t ret = PKG_INVALID_FILE;
506 for (auto iter : pkgFiles_) {
507 PkgFilePtr pkgFile = iter;
508 if (pkgFile != nullptr && pkgFile->GetPkgType() == PkgFile::PKG_TYPE_UPGRADE) {
509 return pkgFile->ParseComponents(fileName);
510 }
511 }
512 return ret;
513 }
514
GetPackageInfo(const std::string & packagePath)515 const PkgInfo *PkgManagerImpl::GetPackageInfo(const std::string &packagePath)
516 {
517 for (auto iter : pkgFiles_) {
518 PkgFilePtr pkgFile = iter;
519 if (pkgFile != nullptr && pkgFile->GetPkgType() == PkgFile::PKG_TYPE_UPGRADE) {
520 return pkgFile->GetPkgInfo();
521 }
522 }
523 return nullptr;
524 }
525
GetFileInfo(const std::string & path)526 const FileInfo *PkgManagerImpl::GetFileInfo(const std::string &path)
527 {
528 PkgEntryPtr pkgEntry = GetPkgEntry(path);
529 if (pkgEntry != nullptr) {
530 return pkgEntry->GetFileInfo();
531 }
532 return nullptr;
533 }
534
GetPkgEntry(const std::string & path)535 PkgEntryPtr PkgManagerImpl::GetPkgEntry(const std::string &path)
536 {
537 // Find out pkgEntry by fileId.
538 for (auto iter : pkgFiles_) {
539 PkgFilePtr pkgFile = iter;
540 PkgEntryPtr pkgEntry = pkgFile->FindPkgEntry(path);
541 if (pkgEntry == nullptr) {
542 continue;
543 }
544 return pkgEntry;
545 }
546 return nullptr;
547 }
548
GetPkgFileStream(const std::string & fileName)549 PkgManager::StreamPtr PkgManagerImpl::GetPkgFileStream(const std::string &fileName)
550 {
551 auto iter = pkgStreams_.find(fileName);
552 if (iter != pkgStreams_.end()) {
553 return (*iter).second;
554 }
555
556 return nullptr;
557 }
558
CreatePkgStream(StreamPtr & stream,const std::string & fileName,const PkgBuffer & buffer)559 int32_t PkgManagerImpl::CreatePkgStream(StreamPtr &stream, const std::string &fileName, const PkgBuffer &buffer)
560 {
561 PkgStreamPtr pkgStream = new MemoryMapStream(this, fileName, buffer, PkgStream::PkgStreamType_Buffer);
562 if (pkgStream == nullptr) {
563 PKG_LOGE("Failed to create stream");
564 return -1;
565 }
566 stream = pkgStream;
567 return PKG_SUCCESS;
568 }
569
CreatePkgStream(StreamPtr & stream,const std::string & fileName,uint64_t fileLen,RingBuffer * buffer)570 int32_t PkgManagerImpl::CreatePkgStream(StreamPtr &stream, const std::string &fileName,
571 uint64_t fileLen, RingBuffer *buffer)
572 {
573 PkgStreamPtr pkgStream = new(std::nothrow) FlowDataStream(this, fileName, fileLen,
574 buffer, PkgStream::PkgStreamType_FlowData);
575 if (pkgStream == nullptr) {
576 PKG_LOGE("Failed to create stream");
577 return -1;
578 }
579 stream = pkgStream;
580 return PKG_SUCCESS;
581 }
582
DoCreatePkgStream(PkgStreamPtr & stream,const std::string & fileName,int32_t type)583 int32_t PkgManagerImpl::DoCreatePkgStream(PkgStreamPtr &stream, const std::string &fileName, int32_t type)
584 {
585 UPDATER_INIT_RECORD;
586 static char const *modeFlags[] = { "rbe", "wbe+" };
587 char realPath[PATH_MAX + 1] = {};
588 #ifdef _WIN32
589 if (type == PkgStream::PkgStreamType_Read && _fullpath(realPath, fileName.c_str(), PATH_MAX) == nullptr) {
590 #else
591 if (type == PkgStream::PkgStreamType_Read && realpath(fileName.c_str(), realPath) == nullptr) {
592 #endif
593 UPDATER_LAST_WORD(PKG_INVALID_FILE, "realPath failed");
594 return PKG_INVALID_FILE;
595 }
596 if (CheckFile(fileName, type) != PKG_SUCCESS) {
597 UPDATER_LAST_WORD(PKG_INVALID_FILE, "CheckFile failed");
598 PKG_LOGE("Fail to check file %s ", fileName.c_str());
599 return PKG_INVALID_FILE;
600 }
601 std::lock_guard<std::mutex> lock(mapLock_);
602 if (pkgStreams_.find(fileName) != pkgStreams_.end()) {
603 PkgStreamPtr mapStream = pkgStreams_[fileName];
604 mapStream->AddRef();
605 stream = mapStream;
606 return PKG_SUCCESS;
607 }
608 FILE *file = nullptr;
609 if (type == PkgStream::PkgStreamType_Read) {
610 file = fopen(realPath, modeFlags[type]);
611 } else {
612 file = fopen(fileName.c_str(), modeFlags[type]);
613 }
614 if (file == nullptr) {
615 UPDATER_LAST_WORD(PKG_INVALID_FILE, "Fail to open file " + fileName);
616 PKG_LOGE("Fail to open file %s ", fileName.c_str());
617 return PKG_INVALID_FILE;
618 }
619 stream = new FileStream(this, fileName, file, type);
620 return PKG_SUCCESS;
621 }
622
623 int32_t PkgManagerImpl::CreatePkgStream(PkgStreamPtr &stream, const std::string &fileName, size_t size, int32_t type)
624 {
625 Updater::UPDATER_INIT_RECORD;
626 stream = nullptr;
627 if (type == PkgStream::PkgStreamType_Write || type == PkgStream::PkgStreamType_Read) {
628 int32_t ret = DoCreatePkgStream(stream, fileName, type);
629 if (ret != PKG_SUCCESS) {
630 UPDATER_LAST_WORD(ret, "DoCreatePkgStream failed");
631 return ret;
632 }
633 } else if (type == PkgStream::PkgStreamType_MemoryMap || type == PkgStream::PKgStreamType_FileMap) {
634 if ((size == 0) && (access(fileName.c_str(), 0) != 0)) {
635 UPDATER_LAST_WORD(PKG_INVALID_FILE, "can not access file " + fileName);
636 return PKG_INVALID_FILE;
637 }
638 size_t fileSize = (size == 0) ? GetFileSize(fileName) : size;
639 if (fileSize <= 0) {
640 UPDATER_LAST_WORD(PKG_INVALID_FILE, "Fail to check file size " + fileName);
641 PKG_LOGE("Fail to check file size %s ", fileName.c_str());
642 return PKG_INVALID_FILE;
643 }
644 uint8_t *memoryMap = nullptr;
645 if (type == PkgStream::PkgStreamType_MemoryMap) {
646 memoryMap = AnonymousMap(fileName, fileSize);
647 } else {
648 memoryMap = FileMap(fileName);
649 }
650 if (memoryMap == nullptr) {
651 UPDATER_LAST_WORD(PKG_INVALID_FILE, "Fail to map memory " + fileName);
652 PKG_LOGE("Fail to map memory %s ", fileName.c_str());
653 return PKG_INVALID_FILE;
654 }
655 PkgBuffer buffer(memoryMap, fileSize);
656 stream = new MemoryMapStream(this, fileName, buffer);
657 } else {
658 UPDATER_LAST_WORD(-1, "type is not read or write " + fileName);
659 return -1;
660 }
661 std::lock_guard<std::mutex> lock(mapLock_);
662 pkgStreams_[fileName] = stream;
663 return PKG_SUCCESS;
664 }
665
666 int32_t PkgManagerImpl::CreatePkgStream(PkgStreamPtr &stream, const std::string &fileName,
667 PkgStream::ExtractFileProcessor processor, const void *context)
668 {
669 stream = new ProcessorStream(this, fileName, processor, context);
670 if (stream == nullptr) {
671 PKG_LOGE("Failed to create stream");
672 return -1;
673 }
674 return PKG_SUCCESS;
675 }
676
677 void PkgManagerImpl::ClosePkgStream(PkgStreamPtr &stream)
678 {
679 PkgStreamPtr mapStream = stream;
680 if (mapStream == nullptr) {
681 return;
682 }
683
684 std::lock_guard<std::mutex> lock(mapLock_);
685 auto iter = pkgStreams_.find(mapStream->GetFileName());
686 if (iter != pkgStreams_.end()) {
687 mapStream->DelRef();
688 if (mapStream->IsRef()) {
689 return;
690 }
691 pkgStreams_.erase(iter);
692 }
693 delete mapStream;
694 stream = nullptr;
695 }
696
697 std::string PkgManagerImpl::GetPkgName(const std::string &path)
698 {
699 std::size_t pos = path.find_last_of('.');
700 if (pos == std::string::npos || pos < 1) {
701 return "";
702 }
703 std::string pkgName = path.substr(pos + 1, -1);
704 std::transform(pkgName.begin(), pkgName.end(), pkgName.begin(), ::tolower);
705 if (pkgName.compare("tmp") != 0) {
706 return pkgName;
707 }
708 std::size_t secPos = path.find_last_of('.', pos - 1);
709 if (secPos == std::string::npos) {
710 return "";
711 }
712 std::string secPkgName = path.substr(secPos + 1, pos - secPos - 1);
713 std::transform(secPkgName.begin(), secPkgName.end(), secPkgName.begin(), ::tolower);
714 return secPkgName;
715 }
716
717 PkgFile::PkgType PkgManagerImpl::GetPkgTypeByName(const std::string &path)
718 {
719 std::size_t pos = path.find_last_of('.');
720 if (pos == std::string::npos) {
721 return PkgFile::PKG_TYPE_NONE;
722 }
723 std::string postfix = path.substr(pos + 1, -1);
724 std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower);
725
726 if (path.compare("update.bin") == 0) {
727 return PkgFile::PKG_TYPE_UPGRADE;
728 } else if (path.substr(pos + 1, -1).compare("zip") == 0) {
729 return PkgFile::PKG_TYPE_ZIP;
730 } else if (path.substr(pos + 1, -1).compare("lz4") == 0) {
731 return PkgFile::PKG_TYPE_LZ4;
732 } else if (path.substr(pos + 1, -1).compare("gz") == 0) {
733 return PkgFile::PKG_TYPE_GZIP;
734 }
735 return PkgFile::PKG_TYPE_NONE;
736 }
737
738 int32_t PkgManagerImpl::VerifyPackage(const std::string &packagePath, const std::string &keyPath,
739 const std::string &version, const PkgBuffer &digest, VerifyCallback cb)
740 {
741 int32_t ret = SetSignVerifyKeyName(keyPath);
742 if (ret != PKG_SUCCESS) {
743 PKG_LOGE("Invalid keyname");
744 return ret;
745 }
746
747 PkgFile::PkgType type = GetPkgTypeByName(packagePath);
748 if (type != PkgFile::PKG_TYPE_UPGRADE) {
749 ret = VerifyOtaPackage(packagePath);
750 } else if (digest.buffer != nullptr) {
751 ret = VerifyBinFile(packagePath, keyPath, version, digest);
752 } else {
753 PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
754 if (pkgManager == nullptr) {
755 PKG_LOGE("pkgManager is nullptr");
756 return PKG_INVALID_SIGNATURE;
757 }
758 std::vector<std::string> components;
759 ret = pkgManager->LoadPackage(packagePath, keyPath, components);
760 PkgManager::ReleasePackageInstance(pkgManager);
761 }
762 cb(ret, VERIFY_FINSH_PERCENT);
763 if (ret != PKG_SUCCESS) {
764 PKG_LOGE("Verify file %s fail", packagePath.c_str());
765 return ret;
766 }
767 PKG_LOGI("Verify file %s success", packagePath.c_str());
768 return ret;
769 }
770
771 int32_t PkgManagerImpl::DoGenerateFileDigest(PkgStreamPtr stream, uint8_t flags, const size_t fileLen,
772 PkgBuffer &buff, std::pair<DigestAlgorithm::DigestAlgorithmPtr, DigestAlgorithm::DigestAlgorithmPtr> &algorithm)
773 {
774 size_t offset = 0;
775 size_t readLen = 0;
776 size_t needReadLen = fileLen;
777 size_t buffSize = BUFFER_SIZE;
778 if (flags & DIGEST_FLAGS_SIGNATURE) {
779 if (SIGN_TOTAL_LEN >= fileLen) {
780 return PKG_INVALID_SIGNATURE;
781 }
782 needReadLen = fileLen - SIGN_TOTAL_LEN;
783 }
784 while (offset < needReadLen) {
785 if ((needReadLen - offset) < buffSize) {
786 buffSize = needReadLen - offset;
787 }
788 int32_t ret = stream->Read(buff, offset, buffSize, readLen);
789 if (ret != PKG_SUCCESS) {
790 PKG_LOGE("read buffer fail %s", stream->GetFileName().c_str());
791 return ret;
792 }
793 if (flags & DIGEST_FLAGS_HAS_SIGN) {
794 algorithm.first->Update(buff, readLen);
795 }
796 if (flags & DIGEST_FLAGS_NO_SIGN) {
797 algorithm.second->Update(buff, readLen);
798 }
799 offset += readLen;
800 PostDecodeProgress(POST_TYPE_VERIFY_PKG, readLen, nullptr);
801 readLen = 0;
802 }
803
804 // Read last signatureLen
805 if (flags & DIGEST_FLAGS_SIGNATURE) {
806 readLen = 0;
807 int32_t ret = stream->Read(buff, offset, SIGN_TOTAL_LEN, readLen);
808 if (ret != PKG_SUCCESS) {
809 PKG_LOGE("read buffer failed %s", stream->GetFileName().c_str());
810 return ret;
811 }
812 if (flags & DIGEST_FLAGS_HAS_SIGN) {
813 algorithm.first->Update(buff, readLen);
814 }
815 PkgBuffer data(SIGN_TOTAL_LEN);
816 if (flags & DIGEST_FLAGS_NO_SIGN) {
817 algorithm.second->Update(data, SIGN_TOTAL_LEN);
818 }
819 }
820 return PKG_SUCCESS;
821 }
822
823 int32_t PkgManagerImpl::GenerateFileDigest(PkgStreamPtr stream,
824 uint8_t digestMethod, uint8_t flags, std::vector<std::vector<uint8_t>> &digestInfos, size_t hashBufferLen)
825 {
826 size_t fileLen = (hashBufferLen == 0) ? stream->GetFileLength() : hashBufferLen;
827 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod);
828 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod);
829 // Check entire package
830 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod);
831 if (algorithm == nullptr) {
832 PKG_LOGE("Invalid file %s", stream->GetFileName().c_str());
833 return PKG_NOT_EXIST_ALGORITHM;
834 }
835 algorithm->Init();
836 // Get verify algorithm
837 DigestAlgorithm::DigestAlgorithmPtr algorithmInner = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod);
838 if (algorithmInner == nullptr) {
839 PKG_LOGE("Invalid file %s", stream->GetFileName().c_str());
840 return PKG_NOT_EXIST_ALGORITHM;
841 }
842 algorithmInner->Init();
843 PkgBuffer buff(BUFFER_SIZE);
844 std::pair<DigestAlgorithm::DigestAlgorithmPtr, DigestAlgorithm::DigestAlgorithmPtr> digestAlgorithm(
845 algorithm, algorithmInner);
846 int32_t ret = DoGenerateFileDigest(stream, flags, fileLen, buff, digestAlgorithm);
847 if (ret != PKG_SUCCESS) {
848 return ret;
849 }
850 if (flags & DIGEST_FLAGS_HAS_SIGN) {
851 PkgBuffer result(digestInfos[DIGEST_INFO_HAS_SIGN].data(), digestLen);
852 algorithm->Final(result);
853 }
854 if (flags & DIGEST_FLAGS_NO_SIGN) {
855 PkgBuffer result(digestInfos[DIGEST_INFO_NO_SIGN].data(), digestLen);
856 algorithmInner->Final(result);
857 }
858
859 if (flags & DIGEST_FLAGS_SIGNATURE) {
860 uint8_t *buffer = buff.buffer;
861 if (digestMethod != PKG_DIGEST_TYPE_SHA256) {
862 buffer = buff.buffer + SIGN_SHA256_LEN;
863 }
864 if (memcpy_s(digestInfos[DIGEST_INFO_SIGNATURE].data(), signatureLen, buffer, signatureLen) != EOK) {
865 PKG_LOGE("GenerateFileDigest memcpy failed");
866 return PKG_NONE_MEMORY;
867 }
868 }
869 return PKG_SUCCESS;
870 }
871
872 int32_t PkgManagerImpl::Verify(uint8_t digestMethod, const std::vector<uint8_t> &digest,
873 const std::vector<uint8_t> &signature)
874 {
875 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetVerifyAlgorithm(
876 signVerifyKeyName_, digestMethod);
877 if (signAlgorithm == nullptr) {
878 PKG_LOGE("Invalid sign algo");
879 return PKG_INVALID_SIGNATURE;
880 }
881 return signAlgorithm->VerifyDigest(digest, signature);
882 }
883
884 int32_t PkgManagerImpl::Sign(PkgStreamPtr stream, size_t offset, const PkgInfoPtr &info)
885 {
886 if (info == nullptr) {
887 PKG_LOGE("Invalid param");
888 return PKG_INVALID_PARAM;
889 }
890 if (info->signMethod == PKG_SIGN_METHOD_NONE) {
891 return PKG_SUCCESS;
892 }
893
894 size_t digestLen = DigestAlgorithm::GetDigestLen(info->digestMethod);
895 std::vector<std::vector<uint8_t>> digestInfos(DIGEST_INFO_SIGNATURE + 1);
896 digestInfos[DIGEST_INFO_HAS_SIGN].resize(digestLen);
897 int32_t ret = GenerateFileDigest(stream, info->digestMethod, DIGEST_FLAGS_HAS_SIGN, digestInfos);
898 if (ret != PKG_SUCCESS) {
899 PKG_LOGE("Fail to generate signature %s", stream->GetFileName().c_str());
900 return ret;
901 }
902 SignAlgorithm::SignAlgorithmPtr signAlgorithm =
903 PkgAlgorithmFactory::GetSignAlgorithm(signVerifyKeyName_, info->signMethod, info->digestMethod);
904 if (signAlgorithm == nullptr) {
905 PKG_LOGE("Invalid sign algo");
906 return PKG_INVALID_SIGNATURE;
907 }
908 size_t signLen = DigestAlgorithm::GetSignatureLen(info->digestMethod);
909 std::vector<uint8_t> signedData(signLen, 0);
910 // Clear buffer
911 PkgBuffer signBuffer(signedData);
912 ret = stream->Write(signBuffer, signLen, offset);
913 size_t signDataLen = 0;
914 signedData.clear();
915 PkgBuffer digest(digestInfos[DIGEST_INFO_HAS_SIGN].data(), digestLen);
916 ret = signAlgorithm->SignBuffer(digest, signedData, signDataLen);
917 if (ret != PKG_SUCCESS) {
918 PKG_LOGE("Fail to SignBuffer %s", stream->GetFileName().c_str());
919 return ret;
920 }
921 if (signDataLen > signLen) {
922 PKG_LOGE("SignData len %zu more %zu", signDataLen, signLen);
923 return PKG_INVALID_SIGNATURE;
924 }
925 PKG_LOGI("Signature %zu %zu %s", offset, signDataLen, stream->GetFileName().c_str());
926 ret = stream->Write(signBuffer, signDataLen, offset);
927 stream->Flush(offset + signedData.size());
928 if (ret != PKG_SUCCESS) {
929 PKG_LOGE("Fail to Write signature %s", stream->GetFileName().c_str());
930 return ret;
931 }
932 PKG_LOGW("Sign file %s success", stream->GetFileName().c_str());
933 return ret;
934 }
935
936 int32_t PkgManagerImpl::SetSignVerifyKeyName(const std::string &keyName)
937 {
938 Updater::UPDATER_INIT_RECORD;
939 if (keyName == Updater::Utils::ON_SERVER) {
940 return PKG_SUCCESS;
941 }
942 if (access(keyName.c_str(), 0) != 0) {
943 UPDATER_LAST_WORD(PKG_INVALID_FILE);
944 PKG_LOGE("Invalid keyname");
945 return PKG_INVALID_FILE;
946 }
947 signVerifyKeyName_ = keyName;
948 return PKG_SUCCESS;
949 }
950
951 int32_t PkgManagerImpl::DecompressBuffer(FileInfoPtr info, const PkgBuffer &buffer, StreamPtr stream) const
952 {
953 if (info == nullptr || buffer.buffer == nullptr || stream == nullptr) {
954 PKG_LOGE("DecompressBuffer Param is null");
955 return PKG_INVALID_PARAM;
956 }
957 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info);
958 if (algorithm == nullptr) {
959 PKG_LOGE("DecompressBuffer Can not get algorithm for %s", info->identity.c_str());
960 return PKG_INVALID_PARAM;
961 }
962
963 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(
964 (PkgManager::PkgManagerPtr)this, info->identity, buffer, PkgStream::PkgStreamType_Buffer);
965 if (inStream == nullptr) {
966 PKG_LOGE("DecompressBuffer Can not create stream for %s", info->identity.c_str());
967 return PKG_INVALID_PARAM;
968 }
969 PkgAlgorithmContext context = {{0, 0}, {buffer.length, 0}, 0, info->digestMethod};
970 int32_t ret = algorithm->Unpack(inStream.get(), PkgStreamImpl::ConvertPkgStream(stream), context);
971 if (ret != PKG_SUCCESS) {
972 PKG_LOGE("Fail Decompress for %s", info->identity.c_str());
973 return ret;
974 }
975 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", buffer.length, context.unpackedSize);
976 PkgStreamImpl::ConvertPkgStream(stream)->Flush(context.unpackedSize);
977 info->packedSize = context.packedSize;
978 info->unpackedSize = context.unpackedSize;
979 algorithm->UpdateFileInfo(info);
980 return PKG_SUCCESS;
981 }
982
983 int32_t PkgManagerImpl::CompressBuffer(FileInfoPtr info, const PkgBuffer &buffer, StreamPtr stream) const
984 {
985 if (info == nullptr || buffer.buffer == nullptr || stream == nullptr) {
986 PKG_LOGE("CompressBuffer Param is null");
987 return PKG_INVALID_PARAM;
988 }
989 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info);
990 if (algorithm == nullptr) {
991 PKG_LOGE("CompressBuffer Can not get algorithm for %s", info->identity.c_str());
992 return PKG_INVALID_PARAM;
993 }
994
995 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(
996 (PkgManager::PkgManagerPtr)this, info->identity, buffer, PkgStream::PkgStreamType_Buffer);
997 if (inStream == nullptr) {
998 PKG_LOGE("CompressBuffer Can not create stream for %s", info->identity.c_str());
999 return PKG_INVALID_PARAM;
1000 }
1001 PkgAlgorithmContext context = {{0, 0}, {0, buffer.length}, 0, info->digestMethod};
1002 int32_t ret = algorithm->Pack(inStream.get(), PkgStreamImpl::ConvertPkgStream(stream), context);
1003 if (ret != PKG_SUCCESS) {
1004 PKG_LOGE("Fail Decompress for %s", info->identity.c_str());
1005 return ret;
1006 }
1007 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", context.packedSize, context.unpackedSize);
1008 PkgStreamImpl::ConvertPkgStream(stream)->Flush(context.packedSize);
1009 info->packedSize = context.packedSize;
1010 info->unpackedSize = context.unpackedSize;
1011 return PKG_SUCCESS;
1012 }
1013
1014 void PkgManagerImpl::PostDecodeProgress(int type, size_t writeDataLen, const void *context)
1015 {
1016 if (decodeProgress_ != nullptr) {
1017 decodeProgress_(type, writeDataLen, context);
1018 }
1019 }
1020
1021 int32_t PkgManagerImpl::VerifyAccPackage(const std::string &packagePath, const std::string &keyPath)
1022 {
1023 UPDATER_INIT_RECORD;
1024 PkgStreamPtr pkgStream = nullptr;
1025 int32_t ret = CreatePkgStream(pkgStream, packagePath, 0, PkgStream::PkgStreamType_Read);
1026 if (ret != PKG_SUCCESS) {
1027 PKG_LOGE("CreatePackage fail %s", packagePath.c_str());
1028 UPDATER_LAST_WORD(PKG_INVALID_FILE);
1029 return ret;
1030 }
1031
1032 PkgVerifyUtil verifyUtil;
1033 if (verifyUtil.VerifyPackageSign(pkgStream, packagePath) != PKG_SUCCESS) {
1034 ret = verifyUtil.VerifyAccPackageSign(pkgStream, keyPath);
1035 }
1036 if (ret != PKG_SUCCESS) {
1037 PKG_LOGE("Verify zpkcs7 signature failed.");
1038 UPDATER_LAST_WORD(packagePath, ret);
1039 ClosePkgStream(pkgStream);
1040 return ret;
1041 }
1042
1043 ClosePkgStream(pkgStream);
1044 return PKG_SUCCESS;
1045 }
1046
1047 int32_t PkgManagerImpl::VerifyOtaPackage(const std::string &devPath, uint64_t offset, size_t size)
1048 {
1049 #ifndef DIFF_PATCH_SDK
1050 constexpr size_t pageSize = 4096;
1051 size_t offsetAligned = (offset / pageSize) * pageSize;
1052 if (size == 0 || size + offset < offsetAligned || offset < offsetAligned) {
1053 PKG_LOGE("invalid param %zu %" PRIu64 " %zu", size, offset, offsetAligned);
1054 return PKG_INVALID_PARAM;
1055 }
1056 char devRealPath[PATH_MAX + 1] = {};
1057 if (realpath(devPath.c_str(), devRealPath) == nullptr) {
1058 PKG_LOGE("realPath is nullptr, err %s", strerror(errno));
1059 return PKG_INVALID_PARAM;
1060 }
1061 int fd = open(devRealPath, O_RDONLY | O_LARGEFILE);
1062 if (fd < 0) {
1063 PKG_LOGE("open %s fail, %s", devRealPath, strerror(errno));
1064 return PKG_INVALID_FILE;
1065 }
1066 ON_SCOPE_EXIT(closePath) {
1067 close(fd);
1068 };
1069 uint8_t *pMap = static_cast<uint8_t *>(mmap64(nullptr, size + offset - offsetAligned, PROT_READ, MAP_PRIVATE,
1070 fd, offsetAligned));
1071 if (pMap == MAP_FAILED) {
1072 PKG_LOGE("mmap64 %s fail, %s %zu %" PRIu64, devRealPath, strerror(errno), size, offset);
1073 return PKG_NONE_MEMORY;
1074 }
1075 ON_SCOPE_EXIT(unmapMem) {
1076 munmap(pMap, size + offset - offsetAligned);
1077 };
1078 PkgBuffer buffer(pMap + (offset - offsetAligned), size);
1079 PkgStreamPtr pkgStream = nullptr;
1080 int32_t ret = CreatePkgStream(pkgStream, devRealPath, buffer);
1081 if (ret != PKG_SUCCESS) {
1082 PKG_LOGE("create package stream fail %s %s", devRealPath, strerror(errno));
1083 return ret;
1084 }
1085 ON_SCOPE_EXIT(closeStream) {
1086 ClosePkgStream(pkgStream);
1087 };
1088 PkgVerifyUtil verifyUtil {};
1089 ret = verifyUtil.VerifyPackageSign(pkgStream, devRealPath);
1090 if (ret != PKG_SUCCESS) {
1091 PKG_LOGE("verify pkcs7 signature failed.");
1092 return ret;
1093 }
1094 #endif
1095 return PKG_SUCCESS;
1096 }
1097
1098 int32_t PkgManagerImpl::VerifyOtaPackage(const std::string &packagePath)
1099 {
1100 return VerifyOtaPackage(packagePath, true);
1101 }
1102
1103 int32_t PkgManagerImpl::VerifyOtaPackage(const std::string &packagePath, bool isSupportOldSig)
1104 {
1105 UPDATER_INIT_RECORD;
1106 PkgStreamPtr pkgStream = nullptr;
1107 int32_t ret = CreatePkgStream(pkgStream, packagePath, 0, PkgStream::PkgStreamType_Read);
1108 if (ret != PKG_SUCCESS) {
1109 PKG_LOGE("CreatePackage fail %s", packagePath.c_str());
1110 UPDATER_LAST_WORD(PKG_INVALID_FILE, "CreatePackage fail");
1111 return ret;
1112 }
1113
1114 PkgVerifyUtil verifyUtil {isSupportOldSig};
1115 ret = verifyUtil.VerifyPackageSign(pkgStream, packagePath);
1116 if (ret != PKG_SUCCESS) {
1117 PKG_LOGE("Verify zpkcs7 signature failed.");
1118 UPDATER_LAST_WORD(ret, "Verify zpkcs7 signature failed");
1119 ClosePkgStream(pkgStream);
1120 return ret;
1121 }
1122
1123 ClosePkgStream(pkgStream);
1124 return PKG_SUCCESS;
1125 }
1126
1127 int32_t PkgManagerImpl::VerifyBinFile(const std::string &packagePath, const std::string &keyPath,
1128 const std::string &version, const PkgBuffer &digest)
1129 {
1130 PkgStreamPtr stream = nullptr;
1131 int32_t ret = CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read);
1132 if (ret != PKG_SUCCESS) {
1133 PKG_LOGE("Create input stream fail %s", packagePath.c_str());
1134 return ret;
1135 }
1136 size_t fileLen = stream->GetFileLength();
1137 if (fileLen <= 0) {
1138 PKG_LOGE("invalid file to load");
1139 ClosePkgStream(stream);
1140 return PKG_INVALID_FILE;
1141 }
1142
1143 int8_t digestMethod = static_cast<int8_t>(DigestAlgorithm::GetDigestMethod(version));
1144 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod);
1145 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod);
1146 if (digestLen != digest.length) {
1147 PKG_LOGE("Invalid digestLen");
1148 ClosePkgStream(stream);
1149 return PKG_INVALID_PARAM;
1150 }
1151 std::vector<std::vector<uint8_t>> digestInfos(DIGEST_INFO_SIGNATURE + 1);
1152 digestInfos[DIGEST_INFO_HAS_SIGN].resize(digestLen);
1153 digestInfos[DIGEST_INFO_NO_SIGN].resize(digestLen);
1154 digestInfos[DIGEST_INFO_SIGNATURE].resize(signatureLen);
1155
1156 ret = GenerateFileDigest(stream, digestMethod, DIGEST_FLAGS_HAS_SIGN, digestInfos);
1157 if (memcmp(digestInfos[DIGEST_INFO_HAS_SIGN].data(), digest.buffer, digest.length) != 0) {
1158 PKG_LOGE("Fail to verify package %s", packagePath.c_str());
1159 ret = PKG_INVALID_SIGNATURE;
1160 }
1161
1162 ClosePkgStream(stream);
1163 return ret;
1164 }
1165 } // namespace Hpackage
1166