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