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