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