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