• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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