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_managerImpl.h" 16#include <unistd.h> 17#include <cstdio> 18#include <cstring> 19#include <vector> 20#include <functional> 21#include <algorithm> 22#include <iterator> 23#include <cctype> 24#include "pkg_lz4file.h" 25#include "pkg_manager.h" 26#include "pkg_upgradefile.h" 27#include "pkg_zipfile.h" 28#include "pkg_gzipfile.h" 29//#include "securec.h" 30 31using namespace std; 32 33namespace hpackage { 34static PkgManagerImpl* g_pkgManagerInstance = nullptr; 35PkgManager* PkgManager::GetPackageInstance() 36{ 37 if (g_pkgManagerInstance == nullptr) { 38 g_pkgManagerInstance = new PkgManagerImpl(); 39 } 40 return g_pkgManagerInstance; 41} 42 43void PkgManager::ReleasePackageInstance(PkgManager* manager) 44{ 45 if (g_pkgManagerInstance != nullptr) { 46 delete g_pkgManagerInstance; 47 } 48 manager = nullptr; 49 g_pkgManagerInstance = nullptr; 50} 51 52PkgManagerImpl::~PkgManagerImpl() 53{ 54 ClearPkgFile(); 55} 56 57void PkgManagerImpl::ClearPkgFile() 58{ 59 auto iter = pkgFiles_.begin(); 60 while (iter != pkgFiles_.end()) { 61 PkgFile* file = (*iter); 62 delete file; 63 iter = pkgFiles_.erase(iter); 64 } 65 auto iter1 = pkgStreams_.begin(); 66 while (iter1 != pkgStreams_.end()) { 67 PkgStreamPtr stream = (*iter1).second; 68 delete stream; 69 iter1 = pkgStreams_.erase(iter1); 70 } 71} 72 73int32_t PkgManagerImpl::CreatePackage(const std::string& path, 74 const std::string& keyName, 75 PkgInfo* header, 76 std::vector<std::pair<std::string, ZipFileInfo>>& files) 77{ 78 int32_t ret = SetSignVerifyKeyName(keyName); 79 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 80 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 81 PkgFilePtr pkgFile = CreatePackage<ZipFileInfo>(path, (PkgFile::PkgType)header->pkgType, header, files); 82 if (pkgFile != nullptr) { 83 delete pkgFile; 84 return PKG_SUCCESS; 85 } 86 return PKG_INVALID_FILE; 87} 88 89int32_t PkgManagerImpl::CreatePackage(const std::string& path, 90 const std::string& keyName, 91 PkgInfo* header, 92 std::vector<std::pair<std::string, ComponentInfo>>& files) 93{ 94 int32_t ret = SetSignVerifyKeyName(keyName); 95 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 96 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 97 PkgFilePtr pkgFile = CreatePackage<ComponentInfo>(path, PkgFile::PKG_TYPE_UPGRADE, header, files); 98 if (pkgFile != nullptr) { 99 delete pkgFile; 100 return PKG_SUCCESS; 101 } 102 return PKG_INVALID_FILE; 103} 104 105int32_t PkgManagerImpl::CreatePackage(const std::string& path, 106 const std::string& keyName, 107 PkgInfo* header, 108 std::vector<std::pair<std::string, Lz4FileInfo>>& files) 109{ 110 int32_t ret = SetSignVerifyKeyName(keyName); 111 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 112 PKG_CHECK(files.size() == 1 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 113 PkgFilePtr pkgFile = CreatePackage<Lz4FileInfo>(path, PkgFile::PKG_TYPE_LZ4, header, files); 114 if (pkgFile != nullptr) { 115 delete pkgFile; 116 return PKG_SUCCESS; 117 } 118 return PKG_INVALID_FILE; 119} 120 121template<class T> 122PkgFilePtr PkgManagerImpl::CreatePackage(const std::string& path, 123 PkgFile::PkgType type, 124 PkgInfo* header, 125 std::vector<std::pair<std::string, T>>& files) 126{ 127 PkgStream* stream = nullptr; 128 int32_t ret = CreatePkgStream(&stream, path, 0, PkgStream::PkgStreamType_Write); 129 PKG_CHECK(ret == PKG_SUCCESS, return nullptr, "CreatePackage fail %s", path.c_str()); 130 131 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, header); 132 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); return nullptr, "CreatePackage fail %s", path.c_str()); 133 134 PkgStream* inputStream = nullptr; 135 for (size_t i = 0; i < files.size(); i++) { 136 ret = CreatePkgStream(&inputStream, files[i].first, 0, PkgStream::PkgStreamType_Read); 137 PKG_CHECK(ret == PKG_SUCCESS, break, "Create stream fail %s", files[i].first.c_str()); 138 ret = pkgFile->AddEntry(reinterpret_cast<const FileInfo*>(&(files[i].second)), 139 PkgStreamImpl::ConvertPkgStream(inputStream)); 140 PKG_CHECK(ret == PKG_SUCCESS, break, "Add entry fail %s", files[i].first.c_str()); 141 ClosePkgStream(&inputStream); 142 inputStream = nullptr; 143 } 144 if (ret != PKG_SUCCESS) { 145 ClosePkgStream(&inputStream); 146 delete pkgFile; 147 return nullptr; 148 } 149 size_t offset = 0; 150 ret = pkgFile->SavePackage(&offset); 151 if (ret != PKG_SUCCESS) { 152 delete pkgFile; 153 return nullptr; 154 } 155 ret = Sign(pkgFile->GetPkgStream(), offset, header); 156 if (ret != PKG_SUCCESS) { 157 delete pkgFile; 158 return nullptr; 159 } 160 return pkgFile; 161} 162 163PkgFilePtr PkgManagerImpl::CreatePackage(PkgStreamPtr stream, PkgFile::PkgType type, PkgInfo* header) 164{ 165 PkgFile* pkgFile = nullptr; 166 switch (type) { 167 case PkgFile::PKG_TYPE_UPGRADE: 168 pkgFile = new UpgradePkgFile(stream, header); 169 break; 170 case PkgFile::PKG_TYPE_ZIP: 171 pkgFile = new ZipPkgFile(stream); 172 break; 173 case PkgFile::PKG_TYPE_LZ4: 174 pkgFile = new Lz4PkgFile(stream); 175 break; 176 case PkgFile::PKG_TYPE_GZIP: 177 pkgFile = new GZipPkgFile(stream); 178 break; 179 default: 180 return nullptr; 181 } 182 return pkgFile; 183} 184 185int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 186 const std::string& keyPath, 187 std::vector<std::string>& fileIds) 188{ 189 if (access(packagePath.c_str(), 0) != 0) { 190 return PKG_INVALID_FILE; 191 } 192 int32_t ret = SetSignVerifyKeyName(keyPath); 193 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 194 195 // 检查对应的package是否已经解析,支持多文件解析 196 for (auto iter : pkgFiles_) { 197 PkgFilePtr pkgFile = iter; 198 if (pkgFile != nullptr && pkgFile->GetPkgStream()->GetFileName().compare(packagePath) == 0) { 199 return PKG_SUCCESS; 200 } 201 } 202 203 PkgFile::PkgType pkgType = GetPkgTypeByName(packagePath); 204 ret = PKG_INVALID_FILE; 205 unzipToFile_ = ((pkgType == PkgFile::PKG_TYPE_GZIP) ? true : unzipToFile_); 206 if (pkgType == PkgFile::PKG_TYPE_UPGRADE) { 207 ret = LoadPackage(packagePath, fileIds, pkgType); 208 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Parse %s fail ", packagePath.c_str()); 209 } else if (pkgType != PkgFile::PKG_TYPE_NONE) { 210 std::vector<std::string> innerFileNames; 211 ret = LoadPackage(packagePath, innerFileNames, pkgType); 212 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Unzip %s fail ", packagePath.c_str()); 213 214 std::string path = GetFilePath(packagePath); 215 for (auto name : innerFileNames) { 216 pkgType = GetPkgTypeByName(name); 217 if (pkgType == PkgFile::PKG_TYPE_NONE) { 218 fileIds.push_back(name); 219 continue; 220 } 221 ret = ExtraAndLoadPackage(path, name, pkgType, fileIds); 222 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); 223 return ret, "unpack %s fail in package %s ", name.c_str(), packagePath.c_str()); 224 } 225 } 226 return PKG_SUCCESS; 227} 228 229int32_t PkgManagerImpl::ExtraAndLoadPackage(const std::string& path, 230 const std::string& name, 231 PkgFile::PkgType type, 232 std::vector<std::string>& fileIds) 233{ 234 int32_t ret = PKG_SUCCESS; 235 const FileInfo* info = GetFileInfo(name); 236 PKG_CHECK(info != nullptr, return PKG_INVALID_FILE, "Create middle stream fail %s", name.c_str()); 237 238 PkgStream* stream = nullptr; 239 if (unzipToFile_) { // 中间文件解析到文件或者内存映射中 240 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_Write); 241 } else { 242 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_MemoryMap); 243 } 244 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create middle stream fail %s", name.c_str()); 245 246 ret = ExtractFile(name, stream); 247 PKG_CHECK(ret == PKG_SUCCESS, ClosePkgStream(&stream); return ret, "Extract file fail %s", name.c_str()); 248 return LoadPackageWithStream(path, fileIds, type, stream); 249} 250 251int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 252 std::vector<std::string>& fileIds, 253 PkgFile::PkgType type) 254{ 255 PkgStream* stream = nullptr; 256 int32_t ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 257 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 258 return LoadPackageWithStream(packagePath, fileIds, type, stream); 259} 260 261int32_t PkgManagerImpl::LoadPackageWithStream(const std::string& packagePath, 262 std::vector<std::string>& fileIds, 263 PkgFile::PkgType type, 264 PkgStream* stream) 265{ 266 int32_t ret = PKG_SUCCESS; 267 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, nullptr); 268 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); 269 return PKG_INVALID_PARAM, "Create package fail %s", packagePath.c_str()); 270 271 ret = pkgFile->LoadPackage(fileIds, 272 [this](const PkgInfo* info, const uint8_t* digest, size_t digestLen, uint8_t* signature, size_t sigLen) -> 273 int { 274 return Verify(info->digestMethod, digest, digestLen, signature, sigLen); 275 }); 276 277 PKG_CHECK(ret == PKG_SUCCESS, delete pkgFile; return ret, "Load package fail %s", packagePath.c_str()); 278 pkgFiles_.push_back(pkgFile); 279 return PKG_SUCCESS; 280} 281 282int32_t PkgManagerImpl::ExtractFile(const std::string &name, PkgStream *const output) 283{ 284 PKG_CHECK(output != nullptr, return PKG_INVALID_STREAM, "Invalid stream"); 285 int32_t ret = PKG_INVALID_FILE; 286 PkgEntryPtr pkgEntry = GetPkgEntry(name); 287 if (pkgEntry != nullptr && pkgEntry->GetPkgFile() != nullptr) { 288 ret = pkgEntry->GetPkgFile()->ExtractFile(pkgEntry, PkgStreamImpl::ConvertPkgStream(output)); 289 } else { 290 PKG_LOGE("Can not find file %s", name.c_str()); 291 } 292 return ret; 293} 294 295const PkgInfo* PkgManagerImpl::GetPackageInfo(const std::string& packagePath) 296{ 297 for (auto iter : pkgFiles_) { 298 PkgFilePtr pkgFile = iter; 299 if (pkgFile != nullptr && pkgFile->GetPkgType() == PkgFile::PKG_TYPE_UPGRADE) { 300 return pkgFile->GetPkgInfo(); 301 } 302 } 303 return nullptr; 304} 305 306const FileInfo* PkgManagerImpl::GetFileInfo(const std::string& path) 307{ 308 PkgEntryPtr pkgEntry = GetPkgEntry(path); 309 if (pkgEntry != nullptr) { 310 return pkgEntry->GetFileInfo(); 311 } 312 return nullptr; 313} 314 315PkgEntryPtr PkgManagerImpl::GetPkgEntry(const std::string& fileId) 316{ 317 // 根据组件信息,获取到对应的entry,需要在多个pkgfile中查找 318 for (auto iter : pkgFiles_) { 319 PkgFilePtr pkgFile = iter; 320 PkgEntryPtr pkgEntry = pkgFile->FindPkgEntry(fileId); 321 if (pkgEntry == nullptr) { 322 continue; 323 } 324 return pkgEntry; 325 } 326 return nullptr; 327} 328 329int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 330 const std::string& fileName, 331 size_t size, 332 int32_t type) 333{ 334 static char const *modeFlags[] = { "rb", "wb+" }; 335 int32_t ret = CheckFile(fileName); 336 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to check file %s ", fileName.c_str()); 337 338 if (pkgStreams_.find(fileName) != pkgStreams_.end()) { 339 PkgStreamImpl* mapStream = pkgStreams_[fileName]; 340 mapStream->AddRef(); 341 *stream = mapStream; 342 return PKG_SUCCESS; 343 } 344 345 if (type == PkgStream::PkgStreamType_Write || type == PkgStream::PkgStreamType_Read) { 346 FILE* file = nullptr; 347 file = fopen(fileName.c_str(), modeFlags[type]); 348 PKG_CHECK(file != nullptr, return PKG_INVALID_FILE, "Fail to open file %s ", fileName.c_str()); 349 *stream = new FileStream(fileName, file, type); 350 } else if (type == PkgStream::PkgStreamType_MemoryMap) { 351 size_t fileSize = size; 352 if (fileSize == 0) { // 文件必须存在,否则没有办法创建内存映射 353 if (access(fileName.c_str(), 0) != 0) { 354 return PKG_INVALID_FILE; 355 } 356 fileSize = GetFileSize(fileName); 357 } 358 PKG_CHECK(fileSize > 0, return PKG_INVALID_FILE, "Fail to check file size %s ", fileName.c_str()); 359 // 将文件映射至进程的地址空间 360 uint8_t* memoryMap = MapMemory(fileName, fileSize); 361 PKG_CHECK(memoryMap != nullptr, return PKG_INVALID_FILE, "Fail to map memory %s ", fileName.c_str()); 362 *stream = new MemoryMapStream(fileName, memoryMap, fileSize); 363 } 364 pkgStreams_[fileName] = PkgStreamImpl::ConvertPkgStream(*stream); 365 return PKG_SUCCESS; 366} 367 368int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 369 const std::string &fileName, 370 PkgStream::ExtractFileProcessor processor, 371 void* context) 372{ 373 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 374 "Can not create stream for %s", fileName.c_str()); 375 *stream = new ProcessorStream(fileName, processor, context); 376 return PKG_SUCCESS; 377} 378 379int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 380 const std::string &fileName, const uint8_t* buffer, size_t bufferSize) 381{ 382 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 383 "Can not create stream for %s", fileName.c_str()); 384 // 创建个输入stream 385 *stream = new MemoryMapStream(fileName, 386 const_cast<uint8_t*>(buffer), bufferSize, PkgStream::PkgStreamType_Buffer); 387 PKG_CHECK(*stream != nullptr, return PKG_INVALID_PARAM, 388 "Can not create stream for %s", fileName.c_str()); 389 return PKG_SUCCESS; 390} 391 392void PkgManagerImpl::ClosePkgStream(PkgStream** stream) 393{ 394 PkgStreamImpl* mapStream = PkgStreamImpl::ConvertPkgStream(*stream); 395 if (mapStream == nullptr) { 396 return; 397 } 398 399 auto iter = pkgStreams_.find(mapStream->GetFileName()); 400 if (iter != pkgStreams_.end()) { 401 mapStream->DelRef(); 402 if (mapStream->IsRef()) { 403 return; 404 } 405 pkgStreams_.erase(iter); 406 } 407 delete mapStream; 408 *stream = nullptr; 409} 410 411PkgFile::PkgType PkgManagerImpl::GetPkgTypeByName(const std::string& path) 412{ 413 int32_t pos = path.find_last_of('.'); 414 if (pos < 0) { 415 return PkgFile::PKG_TYPE_NONE; 416 } 417 std::string postfix = path.substr(pos + 1, -1); 418 std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower); 419 420 if (path.substr(pos + 1, -1).compare("bin") == 0) { 421 return PkgFile::PKG_TYPE_UPGRADE; 422 } else if (path.substr(pos + 1, -1).compare("zip") == 0) { 423 return PkgFile::PKG_TYPE_ZIP; 424 } else if (path.substr(pos + 1, -1).compare("lz4") == 0) { 425 return PkgFile::PKG_TYPE_LZ4; 426 } else if (path.substr(pos + 1, -1).compare("gz") == 0) { 427 return PkgFile::PKG_TYPE_GZIP; 428 } 429 return PkgFile::PKG_TYPE_NONE; 430} 431 432int32_t PkgManagerImpl::VerifyPackage(const std::string& packagePath, const std::string& keyPath, 433 const std::string& version, const uint8_t* digest, size_t size) 434{ 435 int32_t ret = SetSignVerifyKeyName(keyPath); 436 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 437 438 PKG_CHECK(digest != nullptr, return PKG_INVALID_PARAM, "Invalid para"); 439 PkgStream* stream = nullptr; 440 ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 441 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 442 size_t fileLen = stream->GetFileLength(); 443 PKG_CHECK(fileLen > 0, ClosePkgStream(&stream); return PKG_INVALID_FILE, "invalid file to load"); 444 PKG_CHECK(fileLen <= SIZE_MAX, ClosePkgStream(&stream); return PKG_INVALID_FILE, 445 "Invalid file len %zu to load %s", fileLen, stream->GetFileName().c_str()); 446 447 PkgFile::PkgType type = GetPkgTypeByName(packagePath); 448 int8_t digestMethod = DigestAlgorithm::GetDigestMethod(version); 449 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 450 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 451 PKG_CHECK(digestLen == size, return PKG_INVALID_PARAM, "Invalid digestLen"); 452 453 // 非升级包,需要签名验证 454 if (type != PkgFile::PKG_TYPE_UPGRADE) { 455 std::vector<uint8_t> digestNone(digestLen); // hash值,不包括签名部分 456 std::vector<uint8_t> signature(signatureLen); 457 if (digest != nullptr) { 458 std::vector<uint8_t> digestHasSign(digestLen); // 包括签名部分,做整个文件校验 459 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), digestHasSign.data(), signature.data()); 460 if (memcmp(digestHasSign.data(), digest, size) != 0) { 461 PKG_LOGE("Fail to verify package"); 462 ret = PKG_INVALID_SIGNATURE; 463 } 464 } else { 465 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), nullptr, signature.data()); 466 } 467 // 摘要不包含签名部分 468 if (ret == PKG_SUCCESS) { 469 ret = Verify(digestMethod, digestNone.data(), digestLen, signature.data(), signatureLen); 470 } 471 } else { 472 if (digest != nullptr) { 473 std::vector<uint8_t> digestHasSign(digestLen); 474 ret = GenerateFileDigest(stream, digestMethod, nullptr, digestHasSign.data(), nullptr); 475 if (memcmp(digestHasSign.data(), digest, size) != 0) { 476 PKG_LOGE("Fail to verify package"); 477 ret = PKG_INVALID_SIGNATURE; 478 } 479 } 480 } 481 ClosePkgStream(&stream); 482 return ret; 483} 484 485int32_t PkgManagerImpl::GenerateFileDigest(PkgStream* stream, uint8_t digestMethod, 486 uint8_t* digestNone, uint8_t* digestHasSign, uint8_t* signature) 487{ 488 int32_t ret = PKG_SUCCESS; 489 size_t fileLen = stream->GetFileLength(); 490 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 491 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 492 // 整包检查 493 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 494 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, "Invalid file %s", stream->GetFileName().c_str()); 495 algorithm->Init(); 496 497 // 用于签名校验 498 DigestAlgorithm::DigestAlgorithmPtr algorithmInner = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 499 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, 500 "Invalid file %s", stream->GetFileName().c_str()); 501 algorithmInner->Init(); 502 503 size_t offset = 0; 504 size_t readLen = 0; 505 size_t needReadLen = fileLen; 506 size_t buffSize = 4096; 507 std::vector<uint8_t> buff(buffSize); 508 if (signature != nullptr) { 509 if (signatureLen >= fileLen) { 510 return PKG_INVALID_SIGNATURE; 511 } 512 needReadLen = fileLen - signatureLen; 513 } 514 while (offset < needReadLen) { 515 if ((needReadLen - offset) < buffSize) { 516 buffSize = needReadLen - offset; 517 } 518 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), buffSize, offset, &readLen); 519 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 520 if (digestHasSign != nullptr) { 521 algorithm->Update(buff.data(), readLen); 522 } 523 if (digestNone != nullptr) { 524 algorithmInner->Update(buff.data(), readLen); 525 } 526 offset += readLen; 527 readLen = 0; 528 } 529 // 读最后的signatureLen大小 530 if (signature != nullptr) { 531 readLen = 0; 532 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), signatureLen, offset, &readLen); 533 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 534 if (digestHasSign != nullptr) { 535 algorithm->Update(buff.data(), readLen); 536 } 537 } 538 if (digestHasSign != nullptr) { 539 algorithm->Final(digestHasSign, digestLen); 540 } 541 542 if (digestNone != nullptr) { 543 algorithmInner->Final(digestNone, digestLen); 544 } 545 if (signature != nullptr) { 546 PKG_CHECK(!memcpy_s(signature, signatureLen, buff.data(), signatureLen), return PKG_NONE_MEMORY, 547 "GenerateFileDigest memcpy failed"); 548 } 549 return PKG_SUCCESS; 550} 551 552int32_t PkgManagerImpl::Verify(uint8_t digestMethod, const uint8_t* digest, size_t digestLen, 553 uint8_t* signature, size_t sigLen) 554{ 555 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetVerifyAlgorithm( 556 signVerifyKeyName_, digestMethod); 557 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 558 return signAlgorithm->VerifyBuffer(digest, digestLen, signature, sigLen); 559} 560 561int32_t PkgManagerImpl::Sign(PkgStream* stream, size_t offset, PkgInfo* info) 562{ 563 if (info->signMethod == PKG_SIGN_METHOD_NONE) { 564 return PKG_SUCCESS; 565 } 566 567 size_t digestLen = DigestAlgorithm::GetDigestLen(info->digestMethod); 568 std::vector<uint8_t> digest(digestLen); 569 int32_t ret = GenerateFileDigest(stream, info->digestMethod, nullptr, digest.data(), nullptr); 570 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to generate signature %s", stream->GetFileName().c_str()); 571 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetSignAlgorithm( 572 signVerifyKeyName_, info->signMethod, info->digestMethod); 573 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 574 575 size_t signLen = DigestAlgorithm::GetSignatureLen(info->digestMethod); 576 std::vector<uint8_t> signedData(signLen, 0); 577 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signLen, offset); 578 579 size_t signDataLen = 0; 580 signedData.clear(); 581 ret = signAlgorithm->SignBuffer(digest.data(), digestLen, signedData, &signDataLen); 582 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 583 PKG_CHECK(signDataLen <= signLen, return PKG_INVALID_SIGNATURE, "SignData len %zu more %zu", signDataLen, signLen); 584 PKG_LOGI("Signature %zu %zu %s", offset, signDataLen, stream->GetFileName().c_str()); 585 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signDataLen, offset); 586 ((PkgStreamImpl *)stream)->Flush(offset + signedData.size()); 587 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 588 return ret; 589} 590 591int32_t PkgManagerImpl::SetSignVerifyKeyName(const std::string& keyName) 592{ 593 if (access(keyName.c_str(), 0) != 0) { 594 return PKG_INVALID_FILE; 595 } 596 signVerifyKeyName_ = keyName; 597 return PKG_SUCCESS; 598} 599 600int32_t PkgManagerImpl::DecompressBuff(FileInfo* const info, 601 const uint8_t* data, size_t dataSize, PkgStream* const output) const 602{ 603 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 604 return PKG_INVALID_PARAM, "Param is null "); 605 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 606 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 607 "Can not get algorithm for %s", info->identity.c_str()); 608 609 // 创建个输入stream 610 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 611 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 612 //std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 613 // data, dataSize, PkgStream::PkgStreamType_Buffer); 614 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 615 "Can not create stream for %s", info->identity.c_str()); 616 PkgAlgorithmContext context = {0, 0, dataSize, 0, 0, info->digestMethod}; 617 int32_t ret = algorithm->Unpack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 618 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 619 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", dataSize, context.unpackedSize); 620 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.unpackedSize); 621 // 返回实际的大小 622 info->packedSize = context.packedSize; 623 info->unpackedSize = context.unpackedSize; 624 return PKG_SUCCESS; 625} 626int32_t PkgManagerImpl::CompressBuff(FileInfo* const info, 627 const uint8_t* data, size_t dataSize, PkgStream* const output) const 628{ 629 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 630 return PKG_INVALID_PARAM, "Param is null "); 631 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 632 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 633 "Can not get algorithm for %s", info->identity.c_str()); 634 635 // 创建个输入stream 636 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 637 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 638 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 639 "Can not create stream for %s", info->identity.c_str()); 640 PkgAlgorithmContext context = {0, 0, 0, dataSize, 0, info->digestMethod}; 641 int32_t ret = algorithm->Pack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 642 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 643 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", context.packedSize, context.unpackedSize); 644 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.packedSize); 645 info->packedSize = context.packedSize; 646 info->unpackedSize = context.unpackedSize; 647 return PKG_SUCCESS; 648} 649} // namespace hpackage 650 651/* 652 * Copyright (c) 2021 Huawei Device Co., Ltd. 653 * Licensed under the Apache License, Version 2.0 (the "License"); 654 * you may not use this file except in compliance with the License. 655 * You may obtain a copy of the License at 656 * 657 * http://www.apache.org/licenses/LICENSE-2.0 658 * 659 * Unless required by applicable law or agreed to in writing, software 660 * distributed under the License is distributed on an "AS IS" BASIS, 661 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 662 * See the License for the specific language governing permissions and 663 * limitations under the License. 664 */ 665#include "pkg_managerImpl.h" 666#include <unistd.h> 667#include <cstdio> 668#include <cstring> 669#include <vector> 670#include <functional> 671#include <algorithm> 672#include <iterator> 673#include <cctype> 674#include "pkg_lz4file.h" 675#include "pkg_manager.h" 676#include "pkg_upgradefile.h" 677#include "pkg_zipfile.h" 678#include "pkg_gzipfile.h" 679//#include "securec.h" 680 681using namespace std; 682 683namespace hpackage { 684static PkgManagerImpl* g_pkgManagerInstance = nullptr; 685PkgManager* PkgManager::GetPackageInstance() 686{ 687 if (g_pkgManagerInstance == nullptr) { 688 g_pkgManagerInstance = new PkgManagerImpl(); 689 } 690 return g_pkgManagerInstance; 691} 692 693void PkgManager::ReleasePackageInstance(PkgManager* manager) 694{ 695 if (g_pkgManagerInstance != nullptr) { 696 delete g_pkgManagerInstance; 697 } 698 manager = nullptr; 699 g_pkgManagerInstance = nullptr; 700} 701 702PkgManagerImpl::~PkgManagerImpl() 703{ 704 ClearPkgFile(); 705} 706 707void PkgManagerImpl::ClearPkgFile() 708{ 709 auto iter = pkgFiles_.begin(); 710 while (iter != pkgFiles_.end()) { 711 PkgFile* file = (*iter); 712 delete file; 713 iter = pkgFiles_.erase(iter); 714 } 715 auto iter1 = pkgStreams_.begin(); 716 while (iter1 != pkgStreams_.end()) { 717 PkgStreamPtr stream = (*iter1).second; 718 delete stream; 719 iter1 = pkgStreams_.erase(iter1); 720 } 721} 722 723int32_t PkgManagerImpl::CreatePackage(const std::string& path, 724 const std::string& keyName, 725 PkgInfo* header, 726 std::vector<std::pair<std::string, ZipFileInfo>>& files) 727{ 728 int32_t ret = SetSignVerifyKeyName(keyName); 729 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 730 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 731 PkgFilePtr pkgFile = CreatePackage<ZipFileInfo>(path, (PkgFile::PkgType)header->pkgType, header, files); 732 if (pkgFile != nullptr) { 733 delete pkgFile; 734 return PKG_SUCCESS; 735 } 736 return PKG_INVALID_FILE; 737} 738 739int32_t PkgManagerImpl::CreatePackage(const std::string& path, 740 const std::string& keyName, 741 PkgInfo* header, 742 std::vector<std::pair<std::string, ComponentInfo>>& files) 743{ 744 int32_t ret = SetSignVerifyKeyName(keyName); 745 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 746 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 747 PkgFilePtr pkgFile = CreatePackage<ComponentInfo>(path, PkgFile::PKG_TYPE_UPGRADE, header, files); 748 if (pkgFile != nullptr) { 749 delete pkgFile; 750 return PKG_SUCCESS; 751 } 752 return PKG_INVALID_FILE; 753} 754 755int32_t PkgManagerImpl::CreatePackage(const std::string& path, 756 const std::string& keyName, 757 PkgInfo* header, 758 std::vector<std::pair<std::string, Lz4FileInfo>>& files) 759{ 760 int32_t ret = SetSignVerifyKeyName(keyName); 761 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 762 PKG_CHECK(files.size() == 1 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 763 PkgFilePtr pkgFile = CreatePackage<Lz4FileInfo>(path, PkgFile::PKG_TYPE_LZ4, header, files); 764 if (pkgFile != nullptr) { 765 delete pkgFile; 766 return PKG_SUCCESS; 767 } 768 return PKG_INVALID_FILE; 769} 770 771template<class T> 772PkgFilePtr PkgManagerImpl::CreatePackage(const std::string& path, 773 PkgFile::PkgType type, 774 PkgInfo* header, 775 std::vector<std::pair<std::string, T>>& files) 776{ 777 PkgStream* stream = nullptr; 778 int32_t ret = CreatePkgStream(&stream, path, 0, PkgStream::PkgStreamType_Write); 779 PKG_CHECK(ret == PKG_SUCCESS, return nullptr, "CreatePackage fail %s", path.c_str()); 780 781 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, header); 782 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); return nullptr, "CreatePackage fail %s", path.c_str()); 783 784 PkgStream* inputStream = nullptr; 785 for (size_t i = 0; i < files.size(); i++) { 786 ret = CreatePkgStream(&inputStream, files[i].first, 0, PkgStream::PkgStreamType_Read); 787 PKG_CHECK(ret == PKG_SUCCESS, break, "Create stream fail %s", files[i].first.c_str()); 788 ret = pkgFile->AddEntry(reinterpret_cast<const FileInfo*>(&(files[i].second)), 789 PkgStreamImpl::ConvertPkgStream(inputStream)); 790 PKG_CHECK(ret == PKG_SUCCESS, break, "Add entry fail %s", files[i].first.c_str()); 791 ClosePkgStream(&inputStream); 792 inputStream = nullptr; 793 } 794 if (ret != PKG_SUCCESS) { 795 ClosePkgStream(&inputStream); 796 delete pkgFile; 797 return nullptr; 798 } 799 size_t offset = 0; 800 ret = pkgFile->SavePackage(&offset); 801 if (ret != PKG_SUCCESS) { 802 delete pkgFile; 803 return nullptr; 804 } 805 ret = Sign(pkgFile->GetPkgStream(), offset, header); 806 if (ret != PKG_SUCCESS) { 807 delete pkgFile; 808 return nullptr; 809 } 810 return pkgFile; 811} 812 813PkgFilePtr PkgManagerImpl::CreatePackage(PkgStreamPtr stream, PkgFile::PkgType type, PkgInfo* header) 814{ 815 PkgFile* pkgFile = nullptr; 816 switch (type) { 817 case PkgFile::PKG_TYPE_UPGRADE: 818 pkgFile = new UpgradePkgFile(stream, header); 819 break; 820 case PkgFile::PKG_TYPE_ZIP: 821 pkgFile = new ZipPkgFile(stream); 822 break; 823 case PkgFile::PKG_TYPE_LZ4: 824 pkgFile = new Lz4PkgFile(stream); 825 break; 826 case PkgFile::PKG_TYPE_GZIP: 827 pkgFile = new GZipPkgFile(stream); 828 break; 829 default: 830 return nullptr; 831 } 832 return pkgFile; 833} 834 835int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 836 const std::string& keyPath, 837 std::vector<std::string>& fileIds) 838{ 839 if (access(packagePath.c_str(), 0) != 0) { 840 return PKG_INVALID_FILE; 841 } 842 int32_t ret = SetSignVerifyKeyName(keyPath); 843 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 844 845 // 检查对应的package是否已经解析,支持多文件解析 846 for (auto iter : pkgFiles_) { 847 PkgFilePtr pkgFile = iter; 848 if (pkgFile != nullptr && pkgFile->GetPkgStream()->GetFileName().compare(packagePath) == 0) { 849 return PKG_SUCCESS; 850 } 851 } 852 853 PkgFile::PkgType pkgType = GetPkgTypeByName(packagePath); 854 ret = PKG_INVALID_FILE; 855 unzipToFile_ = ((pkgType == PkgFile::PKG_TYPE_GZIP) ? true : unzipToFile_); 856 if (pkgType == PkgFile::PKG_TYPE_UPGRADE) { 857 ret = LoadPackage(packagePath, fileIds, pkgType); 858 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Parse %s fail ", packagePath.c_str()); 859 } else if (pkgType != PkgFile::PKG_TYPE_NONE) { 860 std::vector<std::string> innerFileNames; 861 ret = LoadPackage(packagePath, innerFileNames, pkgType); 862 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Unzip %s fail ", packagePath.c_str()); 863 864 std::string path = GetFilePath(packagePath); 865 for (auto name : innerFileNames) { 866 pkgType = GetPkgTypeByName(name); 867 if (pkgType == PkgFile::PKG_TYPE_NONE) { 868 fileIds.push_back(name); 869 continue; 870 } 871 ret = ExtraAndLoadPackage(path, name, pkgType, fileIds); 872 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); 873 return ret, "unpack %s fail in package %s ", name.c_str(), packagePath.c_str()); 874 } 875 } 876 return PKG_SUCCESS; 877} 878 879int32_t PkgManagerImpl::ExtraAndLoadPackage(const std::string& path, 880 const std::string& name, 881 PkgFile::PkgType type, 882 std::vector<std::string>& fileIds) 883{ 884 int32_t ret = PKG_SUCCESS; 885 const FileInfo* info = GetFileInfo(name); 886 PKG_CHECK(info != nullptr, return PKG_INVALID_FILE, "Create middle stream fail %s", name.c_str()); 887 888 PkgStream* stream = nullptr; 889 if (unzipToFile_) { // 中间文件解析到文件或者内存映射中 890 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_Write); 891 } else { 892 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_MemoryMap); 893 } 894 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create middle stream fail %s", name.c_str()); 895 896 ret = ExtractFile(name, stream); 897 PKG_CHECK(ret == PKG_SUCCESS, ClosePkgStream(&stream); return ret, "Extract file fail %s", name.c_str()); 898 return LoadPackageWithStream(path, fileIds, type, stream); 899} 900 901int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 902 std::vector<std::string>& fileIds, 903 PkgFile::PkgType type) 904{ 905 PkgStream* stream = nullptr; 906 int32_t ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 907 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 908 return LoadPackageWithStream(packagePath, fileIds, type, stream); 909} 910 911int32_t PkgManagerImpl::LoadPackageWithStream(const std::string& packagePath, 912 std::vector<std::string>& fileIds, 913 PkgFile::PkgType type, 914 PkgStream* stream) 915{ 916 int32_t ret = PKG_SUCCESS; 917 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, nullptr); 918 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); 919 return PKG_INVALID_PARAM, "Create package fail %s", packagePath.c_str()); 920 921 ret = pkgFile->LoadPackage(fileIds, 922 [this](const PkgInfo* info, const uint8_t* digest, size_t digestLen, uint8_t* signature, size_t sigLen) -> 923 int { 924 return Verify(info->digestMethod, digest, digestLen, signature, sigLen); 925 }); 926 927 PKG_CHECK(ret == PKG_SUCCESS, delete pkgFile; return ret, "Load package fail %s", packagePath.c_str()); 928 pkgFiles_.push_back(pkgFile); 929 return PKG_SUCCESS; 930} 931 932int32_t PkgManagerImpl::ExtractFile(const std::string &name, PkgStream *const output) 933{ 934 PKG_CHECK(output != nullptr, return PKG_INVALID_STREAM, "Invalid stream"); 935 int32_t ret = PKG_INVALID_FILE; 936 PkgEntryPtr pkgEntry = GetPkgEntry(name); 937 if (pkgEntry != nullptr && pkgEntry->GetPkgFile() != nullptr) { 938 ret = pkgEntry->GetPkgFile()->ExtractFile(pkgEntry, PkgStreamImpl::ConvertPkgStream(output)); 939 } else { 940 PKG_LOGE("Can not find file %s", name.c_str()); 941 } 942 return ret; 943} 944 945const PkgInfo* PkgManagerImpl::GetPackageInfo(const std::string& packagePath) 946{ 947 for (auto iter : pkgFiles_) { 948 PkgFilePtr pkgFile = iter; 949 if (pkgFile != nullptr && pkgFile->GetPkgType() == PkgFile::PKG_TYPE_UPGRADE) { 950 return pkgFile->GetPkgInfo(); 951 } 952 } 953 return nullptr; 954} 955 956const FileInfo* PkgManagerImpl::GetFileInfo(const std::string& path) 957{ 958 PkgEntryPtr pkgEntry = GetPkgEntry(path); 959 if (pkgEntry != nullptr) { 960 return pkgEntry->GetFileInfo(); 961 } 962 return nullptr; 963} 964 965PkgEntryPtr PkgManagerImpl::GetPkgEntry(const std::string& fileId) 966{ 967 // 根据组件信息,获取到对应的entry,需要在多个pkgfile中查找 968 for (auto iter : pkgFiles_) { 969 PkgFilePtr pkgFile = iter; 970 PkgEntryPtr pkgEntry = pkgFile->FindPkgEntry(fileId); 971 if (pkgEntry == nullptr) { 972 continue; 973 } 974 return pkgEntry; 975 } 976 return nullptr; 977} 978 979int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 980 const std::string& fileName, 981 size_t size, 982 int32_t type) 983{ 984 static char const *modeFlags[] = { "rb", "wb+" }; 985 int32_t ret = CheckFile(fileName); 986 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to check file %s ", fileName.c_str()); 987 988 if (pkgStreams_.find(fileName) != pkgStreams_.end()) { 989 PkgStreamImpl* mapStream = pkgStreams_[fileName]; 990 mapStream->AddRef(); 991 *stream = mapStream; 992 return PKG_SUCCESS; 993 } 994 995 if (type == PkgStream::PkgStreamType_Write || type == PkgStream::PkgStreamType_Read) { 996 FILE* file = nullptr; 997 file = fopen(fileName.c_str(), modeFlags[type]); 998 PKG_CHECK(file != nullptr, return PKG_INVALID_FILE, "Fail to open file %s ", fileName.c_str()); 999 *stream = new FileStream(fileName, file, type); 1000 } else if (type == PkgStream::PkgStreamType_MemoryMap) { 1001 size_t fileSize = size; 1002 if (fileSize == 0) { // 文件必须存在,否则没有办法创建内存映射 1003 if (access(fileName.c_str(), 0) != 0) { 1004 return PKG_INVALID_FILE; 1005 } 1006 fileSize = GetFileSize(fileName); 1007 } 1008 PKG_CHECK(fileSize > 0, return PKG_INVALID_FILE, "Fail to check file size %s ", fileName.c_str()); 1009 // 将文件映射至进程的地址空间 1010 uint8_t* memoryMap = MapMemory(fileName, fileSize); 1011 PKG_CHECK(memoryMap != nullptr, return PKG_INVALID_FILE, "Fail to map memory %s ", fileName.c_str()); 1012 *stream = new MemoryMapStream(fileName, memoryMap, fileSize); 1013 } 1014 pkgStreams_[fileName] = PkgStreamImpl::ConvertPkgStream(*stream); 1015 return PKG_SUCCESS; 1016} 1017 1018int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 1019 const std::string &fileName, 1020 PkgStream::ExtractFileProcessor processor, 1021 void* context) 1022{ 1023 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 1024 "Can not create stream for %s", fileName.c_str()); 1025 *stream = new ProcessorStream(fileName, processor, context); 1026 return PKG_SUCCESS; 1027} 1028 1029int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 1030 const std::string &fileName, const uint8_t* buffer, size_t bufferSize) 1031{ 1032 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 1033 "Can not create stream for %s", fileName.c_str()); 1034 // 创建个输入stream 1035 *stream = new MemoryMapStream(fileName, 1036 const_cast<uint8_t*>(buffer), bufferSize, PkgStream::PkgStreamType_Buffer); 1037 PKG_CHECK(*stream != nullptr, return PKG_INVALID_PARAM, 1038 "Can not create stream for %s", fileName.c_str()); 1039 return PKG_SUCCESS; 1040} 1041 1042void PkgManagerImpl::ClosePkgStream(PkgStream** stream) 1043{ 1044 PkgStreamImpl* mapStream = PkgStreamImpl::ConvertPkgStream(*stream); 1045 if (mapStream == nullptr) { 1046 return; 1047 } 1048 1049 auto iter = pkgStreams_.find(mapStream->GetFileName()); 1050 if (iter != pkgStreams_.end()) { 1051 mapStream->DelRef(); 1052 if (mapStream->IsRef()) { 1053 return; 1054 } 1055 pkgStreams_.erase(iter); 1056 } 1057 delete mapStream; 1058 *stream = nullptr; 1059} 1060 1061PkgFile::PkgType PkgManagerImpl::GetPkgTypeByName(const std::string& path) 1062{ 1063 int32_t pos = path.find_last_of('.'); 1064 if (pos < 0) { 1065 return PkgFile::PKG_TYPE_NONE; 1066 } 1067 std::string postfix = path.substr(pos + 1, -1); 1068 std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower); 1069 1070 if (path.substr(pos + 1, -1).compare("bin") == 0) { 1071 return PkgFile::PKG_TYPE_UPGRADE; 1072 } else if (path.substr(pos + 1, -1).compare("zip") == 0) { 1073 return PkgFile::PKG_TYPE_ZIP; 1074 } else if (path.substr(pos + 1, -1).compare("lz4") == 0) { 1075 return PkgFile::PKG_TYPE_LZ4; 1076 } else if (path.substr(pos + 1, -1).compare("gz") == 0) { 1077 return PkgFile::PKG_TYPE_GZIP; 1078 } 1079 return PkgFile::PKG_TYPE_NONE; 1080} 1081 1082int32_t PkgManagerImpl::VerifyPackage(const std::string& packagePath, const std::string& keyPath, 1083 const std::string& version, const uint8_t* digest, size_t size) 1084{ 1085 int32_t ret = SetSignVerifyKeyName(keyPath); 1086 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 1087 1088 PKG_CHECK(digest != nullptr, return PKG_INVALID_PARAM, "Invalid para"); 1089 PkgStream* stream = nullptr; 1090 ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 1091 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 1092 size_t fileLen = stream->GetFileLength(); 1093 PKG_CHECK(fileLen > 0, ClosePkgStream(&stream); return PKG_INVALID_FILE, "invalid file to load"); 1094 PKG_CHECK(fileLen <= SIZE_MAX, ClosePkgStream(&stream); return PKG_INVALID_FILE, 1095 "Invalid file len %zu to load %s", fileLen, stream->GetFileName().c_str()); 1096 1097 PkgFile::PkgType type = GetPkgTypeByName(packagePath); 1098 int8_t digestMethod = DigestAlgorithm::GetDigestMethod(version); 1099 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 1100 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 1101 PKG_CHECK(digestLen == size, return PKG_INVALID_PARAM, "Invalid digestLen"); 1102 1103 // 非升级包,需要签名验证 1104 if (type != PkgFile::PKG_TYPE_UPGRADE) { 1105 std::vector<uint8_t> digestNone(digestLen); // hash值,不包括签名部分 1106 std::vector<uint8_t> signature(signatureLen); 1107 if (digest != nullptr) { 1108 std::vector<uint8_t> digestHasSign(digestLen); // 包括签名部分,做整个文件校验 1109 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), digestHasSign.data(), signature.data()); 1110 if (memcmp(digestHasSign.data(), digest, size) != 0) { 1111 PKG_LOGE("Fail to verify package"); 1112 ret = PKG_INVALID_SIGNATURE; 1113 } 1114 } else { 1115 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), nullptr, signature.data()); 1116 } 1117 // 摘要不包含签名部分 1118 if (ret == PKG_SUCCESS) { 1119 ret = Verify(digestMethod, digestNone.data(), digestLen, signature.data(), signatureLen); 1120 } 1121 } else { 1122 if (digest != nullptr) { 1123 std::vector<uint8_t> digestHasSign(digestLen); 1124 ret = GenerateFileDigest(stream, digestMethod, nullptr, digestHasSign.data(), nullptr); 1125 if (memcmp(digestHasSign.data(), digest, size) != 0) { 1126 PKG_LOGE("Fail to verify package"); 1127 ret = PKG_INVALID_SIGNATURE; 1128 } 1129 } 1130 } 1131 ClosePkgStream(&stream); 1132 return ret; 1133} 1134 1135int32_t PkgManagerImpl::GenerateFileDigest(PkgStream* stream, uint8_t digestMethod, 1136 uint8_t* digestNone, uint8_t* digestHasSign, uint8_t* signature) 1137{ 1138 int32_t ret = PKG_SUCCESS; 1139 size_t fileLen = stream->GetFileLength(); 1140 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 1141 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 1142 // 整包检查 1143 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 1144 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, "Invalid file %s", stream->GetFileName().c_str()); 1145 algorithm->Init(); 1146 1147 // 用于签名校验 1148 DigestAlgorithm::DigestAlgorithmPtr algorithmInner = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 1149 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, 1150 "Invalid file %s", stream->GetFileName().c_str()); 1151 algorithmInner->Init(); 1152 1153 size_t offset = 0; 1154 size_t readLen = 0; 1155 size_t needReadLen = fileLen; 1156 size_t buffSize = 4096; 1157 std::vector<uint8_t> buff(buffSize); 1158 if (signature != nullptr) { 1159 if (signatureLen >= fileLen) { 1160 return PKG_INVALID_SIGNATURE; 1161 } 1162 needReadLen = fileLen - signatureLen; 1163 } 1164 while (offset < needReadLen) { 1165 if ((needReadLen - offset) < buffSize) { 1166 buffSize = needReadLen - offset; 1167 } 1168 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), buffSize, offset, &readLen); 1169 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 1170 if (digestHasSign != nullptr) { 1171 algorithm->Update(buff.data(), readLen); 1172 } 1173 if (digestNone != nullptr) { 1174 algorithmInner->Update(buff.data(), readLen); 1175 } 1176 offset += readLen; 1177 readLen = 0; 1178 } 1179 // 读最后的signatureLen大小 1180 if (signature != nullptr) { 1181 readLen = 0; 1182 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), signatureLen, offset, &readLen); 1183 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 1184 if (digestHasSign != nullptr) { 1185 algorithm->Update(buff.data(), readLen); 1186 } 1187 } 1188 if (digestHasSign != nullptr) { 1189 algorithm->Final(digestHasSign, digestLen); 1190 } 1191 1192 if (digestNone != nullptr) { 1193 algorithmInner->Final(digestNone, digestLen); 1194 } 1195 if (signature != nullptr) { 1196 PKG_CHECK(!memcpy_s(signature, signatureLen, buff.data(), signatureLen), return PKG_NONE_MEMORY, 1197 "GenerateFileDigest memcpy failed"); 1198 } 1199 return PKG_SUCCESS; 1200} 1201 1202int32_t PkgManagerImpl::Verify(uint8_t digestMethod, const uint8_t* digest, size_t digestLen, 1203 uint8_t* signature, size_t sigLen) 1204{ 1205 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetVerifyAlgorithm( 1206 signVerifyKeyName_, digestMethod); 1207 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 1208 return signAlgorithm->VerifyBuffer(digest, digestLen, signature, sigLen); 1209} 1210 1211int32_t PkgManagerImpl::Sign(PkgStream* stream, size_t offset, PkgInfo* info) 1212{ 1213 if (info->signMethod == PKG_SIGN_METHOD_NONE) { 1214 return PKG_SUCCESS; 1215 } 1216 1217 size_t digestLen = DigestAlgorithm::GetDigestLen(info->digestMethod); 1218 std::vector<uint8_t> digest(digestLen); 1219 int32_t ret = GenerateFileDigest(stream, info->digestMethod, nullptr, digest.data(), nullptr); 1220 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to generate signature %s", stream->GetFileName().c_str()); 1221 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetSignAlgorithm( 1222 signVerifyKeyName_, info->signMethod, info->digestMethod); 1223 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 1224 1225 size_t signLen = DigestAlgorithm::GetSignatureLen(info->digestMethod); 1226 std::vector<uint8_t> signedData(signLen, 0); 1227 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signLen, offset); 1228 1229 size_t signDataLen = 0; 1230 signedData.clear(); 1231 ret = signAlgorithm->SignBuffer(digest.data(), digestLen, signedData, &signDataLen); 1232 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 1233 PKG_CHECK(signDataLen <= signLen, return PKG_INVALID_SIGNATURE, "SignData len %zu more %zu", signDataLen, signLen); 1234 PKG_LOGI("Signature %zu %zu %s", offset, signDataLen, stream->GetFileName().c_str()); 1235 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signDataLen, offset); 1236 ((PkgStreamImpl *)stream)->Flush(offset + signedData.size()); 1237 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 1238 return ret; 1239} 1240 1241int32_t PkgManagerImpl::SetSignVerifyKeyName(const std::string& keyName) 1242{ 1243 if (access(keyName.c_str(), 0) != 0) { 1244 return PKG_INVALID_FILE; 1245 } 1246 signVerifyKeyName_ = keyName; 1247 return PKG_SUCCESS; 1248} 1249 1250int32_t PkgManagerImpl::DecompressBuff(FileInfo* const info, 1251 const uint8_t* data, size_t dataSize, PkgStream* const output) const 1252{ 1253 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 1254 return PKG_INVALID_PARAM, "Param is null "); 1255 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 1256 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 1257 "Can not get algorithm for %s", info->identity.c_str()); 1258 1259 // 创建个输入stream 1260 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 1261 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 1262 //std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 1263 // data, dataSize, PkgStream::PkgStreamType_Buffer); 1264 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 1265 "Can not create stream for %s", info->identity.c_str()); 1266 PkgAlgorithmContext context = {0, 0, dataSize, 0, 0, info->digestMethod}; 1267 int32_t ret = algorithm->Unpack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 1268 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 1269 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", dataSize, context.unpackedSize); 1270 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.unpackedSize); 1271 // 返回实际的大小 1272 info->packedSize = context.packedSize; 1273 info->unpackedSize = context.unpackedSize; 1274 return PKG_SUCCESS; 1275} 1276int32_t PkgManagerImpl::CompressBuff(FileInfo* const info, 1277 const uint8_t* data, size_t dataSize, PkgStream* const output) const 1278{ 1279 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 1280 return PKG_INVALID_PARAM, "Param is null "); 1281 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 1282 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 1283 "Can not get algorithm for %s", info->identity.c_str()); 1284 1285 // 创建个输入stream 1286 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 1287 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 1288 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 1289 "Can not create stream for %s", info->identity.c_str()); 1290 PkgAlgorithmContext context = {0, 0, 0, dataSize, 0, info->digestMethod}; 1291 int32_t ret = algorithm->Pack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 1292 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 1293 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", context.packedSize, context.unpackedSize); 1294 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.packedSize); 1295 info->packedSize = context.packedSize; 1296 info->unpackedSize = context.unpackedSize; 1297 return PKG_SUCCESS; 1298} 1299} // namespace hpackage 1300/* 1301 * Copyright (c) 2021 Huawei Device Co., Ltd. 1302 * Licensed under the Apache License, Version 2.0 (the "License"); 1303 * you may not use this file except in compliance with the License. 1304 * You may obtain a copy of the License at 1305 * 1306 * http://www.apache.org/licenses/LICENSE-2.0 1307 * 1308 * Unless required by applicable law or agreed to in writing, software 1309 * distributed under the License is distributed on an "AS IS" BASIS, 1310 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311 * See the License for the specific language governing permissions and 1312 * limitations under the License. 1313 */ 1314#include "pkg_managerImpl.h" 1315#include <unistd.h> 1316#include <cstdio> 1317#include <cstring> 1318#include <vector> 1319#include <functional> 1320#include <algorithm> 1321#include <iterator> 1322#include <cctype> 1323#include "pkg_lz4file.h" 1324#include "pkg_manager.h" 1325#include "pkg_upgradefile.h" 1326#include "pkg_zipfile.h" 1327#include "pkg_gzipfile.h" 1328//#include "securec.h" 1329 1330using namespace std; 1331 1332namespace hpackage { 1333static PkgManagerImpl* g_pkgManagerInstance = nullptr; 1334PkgManager* PkgManager::GetPackageInstance() 1335{ 1336 if (g_pkgManagerInstance == nullptr) { 1337 g_pkgManagerInstance = new PkgManagerImpl(); 1338 } 1339 return g_pkgManagerInstance; 1340} 1341 1342void PkgManager::ReleasePackageInstance(PkgManager* manager) 1343{ 1344 if (g_pkgManagerInstance != nullptr) { 1345 delete g_pkgManagerInstance; 1346 } 1347 manager = nullptr; 1348 g_pkgManagerInstance = nullptr; 1349} 1350 1351PkgManagerImpl::~PkgManagerImpl() 1352{ 1353 ClearPkgFile(); 1354} 1355 1356void PkgManagerImpl::ClearPkgFile() 1357{ 1358 auto iter = pkgFiles_.begin(); 1359 while (iter != pkgFiles_.end()) { 1360 PkgFile* file = (*iter); 1361 delete file; 1362 iter = pkgFiles_.erase(iter); 1363 } 1364 auto iter1 = pkgStreams_.begin(); 1365 while (iter1 != pkgStreams_.end()) { 1366 PkgStreamPtr stream = (*iter1).second; 1367 delete stream; 1368 iter1 = pkgStreams_.erase(iter1); 1369 } 1370} 1371 1372int32_t PkgManagerImpl::CreatePackage(const std::string& path, 1373 const std::string& keyName, 1374 PkgInfo* header, 1375 std::vector<std::pair<std::string, ZipFileInfo>>& files) 1376{ 1377 int32_t ret = SetSignVerifyKeyName(keyName); 1378 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 1379 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 1380 PkgFilePtr pkgFile = CreatePackage<ZipFileInfo>(path, (PkgFile::PkgType)header->pkgType, header, files); 1381 if (pkgFile != nullptr) { 1382 delete pkgFile; 1383 return PKG_SUCCESS; 1384 } 1385 return PKG_INVALID_FILE; 1386} 1387 1388int32_t PkgManagerImpl::CreatePackage(const std::string& path, 1389 const std::string& keyName, 1390 PkgInfo* header, 1391 std::vector<std::pair<std::string, ComponentInfo>>& files) 1392{ 1393 int32_t ret = SetSignVerifyKeyName(keyName); 1394 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 1395 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 1396 PkgFilePtr pkgFile = CreatePackage<ComponentInfo>(path, PkgFile::PKG_TYPE_UPGRADE, header, files); 1397 if (pkgFile != nullptr) { 1398 delete pkgFile; 1399 return PKG_SUCCESS; 1400 } 1401 return PKG_INVALID_FILE; 1402} 1403 1404int32_t PkgManagerImpl::CreatePackage(const std::string& path, 1405 const std::string& keyName, 1406 PkgInfo* header, 1407 std::vector<std::pair<std::string, Lz4FileInfo>>& files) 1408{ 1409 int32_t ret = SetSignVerifyKeyName(keyName); 1410 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 1411 PKG_CHECK(files.size() == 1 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 1412 PkgFilePtr pkgFile = CreatePackage<Lz4FileInfo>(path, PkgFile::PKG_TYPE_LZ4, header, files); 1413 if (pkgFile != nullptr) { 1414 delete pkgFile; 1415 return PKG_SUCCESS; 1416 } 1417 return PKG_INVALID_FILE; 1418} 1419 1420template<class T> 1421PkgFilePtr PkgManagerImpl::CreatePackage(const std::string& path, 1422 PkgFile::PkgType type, 1423 PkgInfo* header, 1424 std::vector<std::pair<std::string, T>>& files) 1425{ 1426 PkgStream* stream = nullptr; 1427 int32_t ret = CreatePkgStream(&stream, path, 0, PkgStream::PkgStreamType_Write); 1428 PKG_CHECK(ret == PKG_SUCCESS, return nullptr, "CreatePackage fail %s", path.c_str()); 1429 1430 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, header); 1431 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); return nullptr, "CreatePackage fail %s", path.c_str()); 1432 1433 PkgStream* inputStream = nullptr; 1434 for (size_t i = 0; i < files.size(); i++) { 1435 ret = CreatePkgStream(&inputStream, files[i].first, 0, PkgStream::PkgStreamType_Read); 1436 PKG_CHECK(ret == PKG_SUCCESS, break, "Create stream fail %s", files[i].first.c_str()); 1437 ret = pkgFile->AddEntry(reinterpret_cast<const FileInfo*>(&(files[i].second)), 1438 PkgStreamImpl::ConvertPkgStream(inputStream)); 1439 PKG_CHECK(ret == PKG_SUCCESS, break, "Add entry fail %s", files[i].first.c_str()); 1440 ClosePkgStream(&inputStream); 1441 inputStream = nullptr; 1442 } 1443 if (ret != PKG_SUCCESS) { 1444 ClosePkgStream(&inputStream); 1445 delete pkgFile; 1446 return nullptr; 1447 } 1448 size_t offset = 0; 1449 ret = pkgFile->SavePackage(&offset); 1450 if (ret != PKG_SUCCESS) { 1451 delete pkgFile; 1452 return nullptr; 1453 } 1454 ret = Sign(pkgFile->GetPkgStream(), offset, header); 1455 if (ret != PKG_SUCCESS) { 1456 delete pkgFile; 1457 return nullptr; 1458 } 1459 return pkgFile; 1460} 1461 1462PkgFilePtr PkgManagerImpl::CreatePackage(PkgStreamPtr stream, PkgFile::PkgType type, PkgInfo* header) 1463{ 1464 PkgFile* pkgFile = nullptr; 1465 switch (type) { 1466 case PkgFile::PKG_TYPE_UPGRADE: 1467 pkgFile = new UpgradePkgFile(stream, header); 1468 break; 1469 case PkgFile::PKG_TYPE_ZIP: 1470 pkgFile = new ZipPkgFile(stream); 1471 break; 1472 case PkgFile::PKG_TYPE_LZ4: 1473 pkgFile = new Lz4PkgFile(stream); 1474 break; 1475 case PkgFile::PKG_TYPE_GZIP: 1476 pkgFile = new GZipPkgFile(stream); 1477 break; 1478 default: 1479 return nullptr; 1480 } 1481 return pkgFile; 1482} 1483 1484int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 1485 const std::string& keyPath, 1486 std::vector<std::string>& fileIds) 1487{ 1488 if (access(packagePath.c_str(), 0) != 0) { 1489 return PKG_INVALID_FILE; 1490 } 1491 int32_t ret = SetSignVerifyKeyName(keyPath); 1492 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 1493 1494 // 检查对应的package是否已经解析,支持多文件解析 1495 for (auto iter : pkgFiles_) { 1496 PkgFilePtr pkgFile = iter; 1497 if (pkgFile != nullptr && pkgFile->GetPkgStream()->GetFileName().compare(packagePath) == 0) { 1498 return PKG_SUCCESS; 1499 } 1500 } 1501 1502 PkgFile::PkgType pkgType = GetPkgTypeByName(packagePath); 1503 ret = PKG_INVALID_FILE; 1504 unzipToFile_ = ((pkgType == PkgFile::PKG_TYPE_GZIP) ? true : unzipToFile_); 1505 if (pkgType == PkgFile::PKG_TYPE_UPGRADE) { 1506 ret = LoadPackage(packagePath, fileIds, pkgType); 1507 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Parse %s fail ", packagePath.c_str()); 1508 } else if (pkgType != PkgFile::PKG_TYPE_NONE) { 1509 std::vector<std::string> innerFileNames; 1510 ret = LoadPackage(packagePath, innerFileNames, pkgType); 1511 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Unzip %s fail ", packagePath.c_str()); 1512 1513 std::string path = GetFilePath(packagePath); 1514 for (auto name : innerFileNames) { 1515 pkgType = GetPkgTypeByName(name); 1516 if (pkgType == PkgFile::PKG_TYPE_NONE) { 1517 fileIds.push_back(name); 1518 continue; 1519 } 1520 ret = ExtraAndLoadPackage(path, name, pkgType, fileIds); 1521 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); 1522 return ret, "unpack %s fail in package %s ", name.c_str(), packagePath.c_str()); 1523 } 1524 } 1525 return PKG_SUCCESS; 1526} 1527 1528int32_t PkgManagerImpl::ExtraAndLoadPackage(const std::string& path, 1529 const std::string& name, 1530 PkgFile::PkgType type, 1531 std::vector<std::string>& fileIds) 1532{ 1533 int32_t ret = PKG_SUCCESS; 1534 const FileInfo* info = GetFileInfo(name); 1535 PKG_CHECK(info != nullptr, return PKG_INVALID_FILE, "Create middle stream fail %s", name.c_str()); 1536 1537 PkgStream* stream = nullptr; 1538 if (unzipToFile_) { // 中间文件解析到文件或者内存映射中 1539 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_Write); 1540 } else { 1541 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_MemoryMap); 1542 } 1543 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create middle stream fail %s", name.c_str()); 1544 1545 ret = ExtractFile(name, stream); 1546 PKG_CHECK(ret == PKG_SUCCESS, ClosePkgStream(&stream); return ret, "Extract file fail %s", name.c_str()); 1547 return LoadPackageWithStream(path, fileIds, type, stream); 1548} 1549 1550int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 1551 std::vector<std::string>& fileIds, 1552 PkgFile::PkgType type) 1553{ 1554 PkgStream* stream = nullptr; 1555 int32_t ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 1556 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 1557 return LoadPackageWithStream(packagePath, fileIds, type, stream); 1558} 1559 1560int32_t PkgManagerImpl::LoadPackageWithStream(const std::string& packagePath, 1561 std::vector<std::string>& fileIds, 1562 PkgFile::PkgType type, 1563 PkgStream* stream) 1564{ 1565 int32_t ret = PKG_SUCCESS; 1566 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, nullptr); 1567 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); 1568 return PKG_INVALID_PARAM, "Create package fail %s", packagePath.c_str()); 1569 1570 ret = pkgFile->LoadPackage(fileIds, 1571 [this](const PkgInfo* info, const uint8_t* digest, size_t digestLen, uint8_t* signature, size_t sigLen) -> 1572 int { 1573 return Verify(info->digestMethod, digest, digestLen, signature, sigLen); 1574 }); 1575 1576 PKG_CHECK(ret == PKG_SUCCESS, delete pkgFile; return ret, "Load package fail %s", packagePath.c_str()); 1577 pkgFiles_.push_back(pkgFile); 1578 return PKG_SUCCESS; 1579} 1580 1581int32_t PkgManagerImpl::ExtractFile(const std::string &name, PkgStream *const output) 1582{ 1583 PKG_CHECK(output != nullptr, return PKG_INVALID_STREAM, "Invalid stream"); 1584 int32_t ret = PKG_INVALID_FILE; 1585 PkgEntryPtr pkgEntry = GetPkgEntry(name); 1586 if (pkgEntry != nullptr && pkgEntry->GetPkgFile() != nullptr) { 1587 ret = pkgEntry->GetPkgFile()->ExtractFile(pkgEntry, PkgStreamImpl::ConvertPkgStream(output)); 1588 } else { 1589 PKG_LOGE("Can not find file %s", name.c_str()); 1590 } 1591 return ret; 1592} 1593 1594const PkgInfo* PkgManagerImpl::GetPackageInfo(const std::string& packagePath) 1595{ 1596 for (auto iter : pkgFiles_) { 1597 PkgFilePtr pkgFile = iter; 1598 if (pkgFile != nullptr && pkgFile->GetPkgType() == PkgFile::PKG_TYPE_UPGRADE) { 1599 return pkgFile->GetPkgInfo(); 1600 } 1601 } 1602 return nullptr; 1603} 1604 1605const FileInfo* PkgManagerImpl::GetFileInfo(const std::string& path) 1606{ 1607 PkgEntryPtr pkgEntry = GetPkgEntry(path); 1608 if (pkgEntry != nullptr) { 1609 return pkgEntry->GetFileInfo(); 1610 } 1611 return nullptr; 1612} 1613 1614PkgEntryPtr PkgManagerImpl::GetPkgEntry(const std::string& fileId) 1615{ 1616 // 根据组件信息,获取到对应的entry,需要在多个pkgfile中查找 1617 for (auto iter : pkgFiles_) { 1618 PkgFilePtr pkgFile = iter; 1619 PkgEntryPtr pkgEntry = pkgFile->FindPkgEntry(fileId); 1620 if (pkgEntry == nullptr) { 1621 continue; 1622 } 1623 return pkgEntry; 1624 } 1625 return nullptr; 1626} 1627 1628int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 1629 const std::string& fileName, 1630 size_t size, 1631 int32_t type) 1632{ 1633 static char const *modeFlags[] = { "rb", "wb+" }; 1634 int32_t ret = CheckFile(fileName); 1635 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to check file %s ", fileName.c_str()); 1636 1637 if (pkgStreams_.find(fileName) != pkgStreams_.end()) { 1638 PkgStreamImpl* mapStream = pkgStreams_[fileName]; 1639 mapStream->AddRef(); 1640 *stream = mapStream; 1641 return PKG_SUCCESS; 1642 } 1643 1644 if (type == PkgStream::PkgStreamType_Write || type == PkgStream::PkgStreamType_Read) { 1645 FILE* file = nullptr; 1646 file = fopen(fileName.c_str(), modeFlags[type]); 1647 PKG_CHECK(file != nullptr, return PKG_INVALID_FILE, "Fail to open file %s ", fileName.c_str()); 1648 *stream = new FileStream(fileName, file, type); 1649 } else if (type == PkgStream::PkgStreamType_MemoryMap) { 1650 size_t fileSize = size; 1651 if (fileSize == 0) { // 文件必须存在,否则没有办法创建内存映射 1652 if (access(fileName.c_str(), 0) != 0) { 1653 return PKG_INVALID_FILE; 1654 } 1655 fileSize = GetFileSize(fileName); 1656 } 1657 PKG_CHECK(fileSize > 0, return PKG_INVALID_FILE, "Fail to check file size %s ", fileName.c_str()); 1658 // 将文件映射至进程的地址空间 1659 uint8_t* memoryMap = MapMemory(fileName, fileSize); 1660 PKG_CHECK(memoryMap != nullptr, return PKG_INVALID_FILE, "Fail to map memory %s ", fileName.c_str()); 1661 *stream = new MemoryMapStream(fileName, memoryMap, fileSize); 1662 } 1663 pkgStreams_[fileName] = PkgStreamImpl::ConvertPkgStream(*stream); 1664 return PKG_SUCCESS; 1665} 1666 1667int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 1668 const std::string &fileName, 1669 PkgStream::ExtractFileProcessor processor, 1670 void* context) 1671{ 1672 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 1673 "Can not create stream for %s", fileName.c_str()); 1674 *stream = new ProcessorStream(fileName, processor, context); 1675 return PKG_SUCCESS; 1676} 1677 1678int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 1679 const std::string &fileName, const uint8_t* buffer, size_t bufferSize) 1680{ 1681 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 1682 "Can not create stream for %s", fileName.c_str()); 1683 // 创建个输入stream 1684 *stream = new MemoryMapStream(fileName, 1685 const_cast<uint8_t*>(buffer), bufferSize, PkgStream::PkgStreamType_Buffer); 1686 PKG_CHECK(*stream != nullptr, return PKG_INVALID_PARAM, 1687 "Can not create stream for %s", fileName.c_str()); 1688 return PKG_SUCCESS; 1689} 1690 1691void PkgManagerImpl::ClosePkgStream(PkgStream** stream) 1692{ 1693 PkgStreamImpl* mapStream = PkgStreamImpl::ConvertPkgStream(*stream); 1694 if (mapStream == nullptr) { 1695 return; 1696 } 1697 1698 auto iter = pkgStreams_.find(mapStream->GetFileName()); 1699 if (iter != pkgStreams_.end()) { 1700 mapStream->DelRef(); 1701 if (mapStream->IsRef()) { 1702 return; 1703 } 1704 pkgStreams_.erase(iter); 1705 } 1706 delete mapStream; 1707 *stream = nullptr; 1708} 1709 1710PkgFile::PkgType PkgManagerImpl::GetPkgTypeByName(const std::string& path) 1711{ 1712 int32_t pos = path.find_last_of('.'); 1713 if (pos < 0) { 1714 return PkgFile::PKG_TYPE_NONE; 1715 } 1716 std::string postfix = path.substr(pos + 1, -1); 1717 std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower); 1718 1719 if (path.substr(pos + 1, -1).compare("bin") == 0) { 1720 return PkgFile::PKG_TYPE_UPGRADE; 1721 } else if (path.substr(pos + 1, -1).compare("zip") == 0) { 1722 return PkgFile::PKG_TYPE_ZIP; 1723 } else if (path.substr(pos + 1, -1).compare("lz4") == 0) { 1724 return PkgFile::PKG_TYPE_LZ4; 1725 } else if (path.substr(pos + 1, -1).compare("gz") == 0) { 1726 return PkgFile::PKG_TYPE_GZIP; 1727 } 1728 return PkgFile::PKG_TYPE_NONE; 1729} 1730 1731int32_t PkgManagerImpl::VerifyPackage(const std::string& packagePath, const std::string& keyPath, 1732 const std::string& version, const uint8_t* digest, size_t size) 1733{ 1734 int32_t ret = SetSignVerifyKeyName(keyPath); 1735 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 1736 1737 PKG_CHECK(digest != nullptr, return PKG_INVALID_PARAM, "Invalid para"); 1738 PkgStream* stream = nullptr; 1739 ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 1740 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 1741 size_t fileLen = stream->GetFileLength(); 1742 PKG_CHECK(fileLen > 0, ClosePkgStream(&stream); return PKG_INVALID_FILE, "invalid file to load"); 1743 PKG_CHECK(fileLen <= SIZE_MAX, ClosePkgStream(&stream); return PKG_INVALID_FILE, 1744 "Invalid file len %zu to load %s", fileLen, stream->GetFileName().c_str()); 1745 1746 PkgFile::PkgType type = GetPkgTypeByName(packagePath); 1747 int8_t digestMethod = DigestAlgorithm::GetDigestMethod(version); 1748 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 1749 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 1750 PKG_CHECK(digestLen == size, return PKG_INVALID_PARAM, "Invalid digestLen"); 1751 1752 // 非升级包,需要签名验证 1753 if (type != PkgFile::PKG_TYPE_UPGRADE) { 1754 std::vector<uint8_t> digestNone(digestLen); // hash值,不包括签名部分 1755 std::vector<uint8_t> signature(signatureLen); 1756 if (digest != nullptr) { 1757 std::vector<uint8_t> digestHasSign(digestLen); // 包括签名部分,做整个文件校验 1758 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), digestHasSign.data(), signature.data()); 1759 if (memcmp(digestHasSign.data(), digest, size) != 0) { 1760 PKG_LOGE("Fail to verify package"); 1761 ret = PKG_INVALID_SIGNATURE; 1762 } 1763 } else { 1764 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), nullptr, signature.data()); 1765 } 1766 // 摘要不包含签名部分 1767 if (ret == PKG_SUCCESS) { 1768 ret = Verify(digestMethod, digestNone.data(), digestLen, signature.data(), signatureLen); 1769 } 1770 } else { 1771 if (digest != nullptr) { 1772 std::vector<uint8_t> digestHasSign(digestLen); 1773 ret = GenerateFileDigest(stream, digestMethod, nullptr, digestHasSign.data(), nullptr); 1774 if (memcmp(digestHasSign.data(), digest, size) != 0) { 1775 PKG_LOGE("Fail to verify package"); 1776 ret = PKG_INVALID_SIGNATURE; 1777 } 1778 } 1779 } 1780 ClosePkgStream(&stream); 1781 return ret; 1782} 1783 1784int32_t PkgManagerImpl::GenerateFileDigest(PkgStream* stream, uint8_t digestMethod, 1785 uint8_t* digestNone, uint8_t* digestHasSign, uint8_t* signature) 1786{ 1787 int32_t ret = PKG_SUCCESS; 1788 size_t fileLen = stream->GetFileLength(); 1789 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 1790 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 1791 // 整包检查 1792 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 1793 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, "Invalid file %s", stream->GetFileName().c_str()); 1794 algorithm->Init(); 1795 1796 // 用于签名校验 1797 DigestAlgorithm::DigestAlgorithmPtr algorithmInner = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 1798 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, 1799 "Invalid file %s", stream->GetFileName().c_str()); 1800 algorithmInner->Init(); 1801 1802 size_t offset = 0; 1803 size_t readLen = 0; 1804 size_t needReadLen = fileLen; 1805 size_t buffSize = 4096; 1806 std::vector<uint8_t> buff(buffSize); 1807 if (signature != nullptr) { 1808 if (signatureLen >= fileLen) { 1809 return PKG_INVALID_SIGNATURE; 1810 } 1811 needReadLen = fileLen - signatureLen; 1812 } 1813 while (offset < needReadLen) { 1814 if ((needReadLen - offset) < buffSize) { 1815 buffSize = needReadLen - offset; 1816 } 1817 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), buffSize, offset, &readLen); 1818 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 1819 if (digestHasSign != nullptr) { 1820 algorithm->Update(buff.data(), readLen); 1821 } 1822 if (digestNone != nullptr) { 1823 algorithmInner->Update(buff.data(), readLen); 1824 } 1825 offset += readLen; 1826 readLen = 0; 1827 } 1828 // 读最后的signatureLen大小 1829 if (signature != nullptr) { 1830 readLen = 0; 1831 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), signatureLen, offset, &readLen); 1832 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 1833 if (digestHasSign != nullptr) { 1834 algorithm->Update(buff.data(), readLen); 1835 } 1836 } 1837 if (digestHasSign != nullptr) { 1838 algorithm->Final(digestHasSign, digestLen); 1839 } 1840 1841 if (digestNone != nullptr) { 1842 algorithmInner->Final(digestNone, digestLen); 1843 } 1844 if (signature != nullptr) { 1845 PKG_CHECK(!memcpy_s(signature, signatureLen, buff.data(), signatureLen), return PKG_NONE_MEMORY, 1846 "GenerateFileDigest memcpy failed"); 1847 } 1848 return PKG_SUCCESS; 1849} 1850 1851int32_t PkgManagerImpl::Verify(uint8_t digestMethod, const uint8_t* digest, size_t digestLen, 1852 uint8_t* signature, size_t sigLen) 1853{ 1854 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetVerifyAlgorithm( 1855 signVerifyKeyName_, digestMethod); 1856 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 1857 return signAlgorithm->VerifyBuffer(digest, digestLen, signature, sigLen); 1858} 1859 1860int32_t PkgManagerImpl::Sign(PkgStream* stream, size_t offset, PkgInfo* info) 1861{ 1862 if (info->signMethod == PKG_SIGN_METHOD_NONE) { 1863 return PKG_SUCCESS; 1864 } 1865 1866 size_t digestLen = DigestAlgorithm::GetDigestLen(info->digestMethod); 1867 std::vector<uint8_t> digest(digestLen); 1868 int32_t ret = GenerateFileDigest(stream, info->digestMethod, nullptr, digest.data(), nullptr); 1869 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to generate signature %s", stream->GetFileName().c_str()); 1870 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetSignAlgorithm( 1871 signVerifyKeyName_, info->signMethod, info->digestMethod); 1872 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 1873 1874 size_t signLen = DigestAlgorithm::GetSignatureLen(info->digestMethod); 1875 std::vector<uint8_t> signedData(signLen, 0); 1876 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signLen, offset); 1877 1878 size_t signDataLen = 0; 1879 signedData.clear(); 1880 ret = signAlgorithm->SignBuffer(digest.data(), digestLen, signedData, &signDataLen); 1881 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 1882 PKG_CHECK(signDataLen <= signLen, return PKG_INVALID_SIGNATURE, "SignData len %zu more %zu", signDataLen, signLen); 1883 PKG_LOGI("Signature %zu %zu %s", offset, signDataLen, stream->GetFileName().c_str()); 1884 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signDataLen, offset); 1885 ((PkgStreamImpl *)stream)->Flush(offset + signedData.size()); 1886 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 1887 return ret; 1888} 1889 1890int32_t PkgManagerImpl::SetSignVerifyKeyName(const std::string& keyName) 1891{ 1892 if (access(keyName.c_str(), 0) != 0) { 1893 return PKG_INVALID_FILE; 1894 } 1895 signVerifyKeyName_ = keyName; 1896 return PKG_SUCCESS; 1897} 1898 1899int32_t PkgManagerImpl::DecompressBuff(FileInfo* const info, 1900 const uint8_t* data, size_t dataSize, PkgStream* const output) const 1901{ 1902 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 1903 return PKG_INVALID_PARAM, "Param is null "); 1904 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 1905 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 1906 "Can not get algorithm for %s", info->identity.c_str()); 1907 1908 // 创建个输入stream 1909 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 1910 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 1911 //std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 1912 // data, dataSize, PkgStream::PkgStreamType_Buffer); 1913 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 1914 "Can not create stream for %s", info->identity.c_str()); 1915 PkgAlgorithmContext context = {0, 0, dataSize, 0, 0, info->digestMethod}; 1916 int32_t ret = algorithm->Unpack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 1917 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 1918 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", dataSize, context.unpackedSize); 1919 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.unpackedSize); 1920 // 返回实际的大小 1921 info->packedSize = context.packedSize; 1922 info->unpackedSize = context.unpackedSize; 1923 return PKG_SUCCESS; 1924} 1925int32_t PkgManagerImpl::CompressBuff(FileInfo* const info, 1926 const uint8_t* data, size_t dataSize, PkgStream* const output) const 1927{ 1928 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 1929 return PKG_INVALID_PARAM, "Param is null "); 1930 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 1931 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 1932 "Can not get algorithm for %s", info->identity.c_str()); 1933 1934 // 创建个输入stream 1935 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 1936 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 1937 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 1938 "Can not create stream for %s", info->identity.c_str()); 1939 PkgAlgorithmContext context = {0, 0, 0, dataSize, 0, info->digestMethod}; 1940 int32_t ret = algorithm->Pack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 1941 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 1942 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", context.packedSize, context.unpackedSize); 1943 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.packedSize); 1944 info->packedSize = context.packedSize; 1945 info->unpackedSize = context.unpackedSize; 1946 return PKG_SUCCESS; 1947} 1948} // namespace hpackage 1949/* 1950 * Copyright (c) 2021 Huawei Device Co., Ltd. 1951 * Licensed under the Apache License, Version 2.0 (the "License"); 1952 * you may not use this file except in compliance with the License. 1953 * You may obtain a copy of the License at 1954 * 1955 * http://www.apache.org/licenses/LICENSE-2.0 1956 * 1957 * Unless required by applicable law or agreed to in writing, software 1958 * distributed under the License is distributed on an "AS IS" BASIS, 1959 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1960 * See the License for the specific language governing permissions and 1961 * limitations under the License. 1962 */ 1963#include "pkg_managerImpl.h" 1964#include <unistd.h> 1965#include <cstdio> 1966#include <cstring> 1967#include <vector> 1968#include <functional> 1969#include <algorithm> 1970#include <iterator> 1971#include <cctype> 1972#include "pkg_lz4file.h" 1973#include "pkg_manager.h" 1974#include "pkg_upgradefile.h" 1975#include "pkg_zipfile.h" 1976#include "pkg_gzipfile.h" 1977//#include "securec.h" 1978 1979using namespace std; 1980 1981namespace hpackage { 1982static PkgManagerImpl* g_pkgManagerInstance = nullptr; 1983PkgManager* PkgManager::GetPackageInstance() 1984{ 1985 if (g_pkgManagerInstance == nullptr) { 1986 g_pkgManagerInstance = new PkgManagerImpl(); 1987 } 1988 return g_pkgManagerInstance; 1989} 1990 1991void PkgManager::ReleasePackageInstance(PkgManager* manager) 1992{ 1993 if (g_pkgManagerInstance != nullptr) { 1994 delete g_pkgManagerInstance; 1995 } 1996 manager = nullptr; 1997 g_pkgManagerInstance = nullptr; 1998} 1999 2000PkgManagerImpl::~PkgManagerImpl() 2001{ 2002 ClearPkgFile(); 2003} 2004 2005void PkgManagerImpl::ClearPkgFile() 2006{ 2007 auto iter = pkgFiles_.begin(); 2008 while (iter != pkgFiles_.end()) { 2009 PkgFile* file = (*iter); 2010 delete file; 2011 iter = pkgFiles_.erase(iter); 2012 } 2013 auto iter1 = pkgStreams_.begin(); 2014 while (iter1 != pkgStreams_.end()) { 2015 PkgStreamPtr stream = (*iter1).second; 2016 delete stream; 2017 iter1 = pkgStreams_.erase(iter1); 2018 } 2019} 2020 2021int32_t PkgManagerImpl::CreatePackage(const std::string& path, 2022 const std::string& keyName, 2023 PkgInfo* header, 2024 std::vector<std::pair<std::string, ZipFileInfo>>& files) 2025{ 2026 int32_t ret = SetSignVerifyKeyName(keyName); 2027 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 2028 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 2029 PkgFilePtr pkgFile = CreatePackage<ZipFileInfo>(path, (PkgFile::PkgType)header->pkgType, header, files); 2030 if (pkgFile != nullptr) { 2031 delete pkgFile; 2032 return PKG_SUCCESS; 2033 } 2034 return PKG_INVALID_FILE; 2035} 2036 2037int32_t PkgManagerImpl::CreatePackage(const std::string& path, 2038 const std::string& keyName, 2039 PkgInfo* header, 2040 std::vector<std::pair<std::string, ComponentInfo>>& files) 2041{ 2042 int32_t ret = SetSignVerifyKeyName(keyName); 2043 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 2044 PKG_CHECK(files.size() > 0 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 2045 PkgFilePtr pkgFile = CreatePackage<ComponentInfo>(path, PkgFile::PKG_TYPE_UPGRADE, header, files); 2046 if (pkgFile != nullptr) { 2047 delete pkgFile; 2048 return PKG_SUCCESS; 2049 } 2050 return PKG_INVALID_FILE; 2051} 2052 2053int32_t PkgManagerImpl::CreatePackage(const std::string& path, 2054 const std::string& keyName, 2055 PkgInfo* header, 2056 std::vector<std::pair<std::string, Lz4FileInfo>>& files) 2057{ 2058 int32_t ret = SetSignVerifyKeyName(keyName); 2059 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 2060 PKG_CHECK(files.size() == 1 && header != nullptr, return PKG_INVALID_PARAM, "Invalid param"); 2061 PkgFilePtr pkgFile = CreatePackage<Lz4FileInfo>(path, PkgFile::PKG_TYPE_LZ4, header, files); 2062 if (pkgFile != nullptr) { 2063 delete pkgFile; 2064 return PKG_SUCCESS; 2065 } 2066 return PKG_INVALID_FILE; 2067} 2068 2069template<class T> 2070PkgFilePtr PkgManagerImpl::CreatePackage(const std::string& path, 2071 PkgFile::PkgType type, 2072 PkgInfo* header, 2073 std::vector<std::pair<std::string, T>>& files) 2074{ 2075 PkgStream* stream = nullptr; 2076 int32_t ret = CreatePkgStream(&stream, path, 0, PkgStream::PkgStreamType_Write); 2077 PKG_CHECK(ret == PKG_SUCCESS, return nullptr, "CreatePackage fail %s", path.c_str()); 2078 2079 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, header); 2080 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); return nullptr, "CreatePackage fail %s", path.c_str()); 2081 2082 PkgStream* inputStream = nullptr; 2083 for (size_t i = 0; i < files.size(); i++) { 2084 ret = CreatePkgStream(&inputStream, files[i].first, 0, PkgStream::PkgStreamType_Read); 2085 PKG_CHECK(ret == PKG_SUCCESS, break, "Create stream fail %s", files[i].first.c_str()); 2086 ret = pkgFile->AddEntry(reinterpret_cast<const FileInfo*>(&(files[i].second)), 2087 PkgStreamImpl::ConvertPkgStream(inputStream)); 2088 PKG_CHECK(ret == PKG_SUCCESS, break, "Add entry fail %s", files[i].first.c_str()); 2089 ClosePkgStream(&inputStream); 2090 inputStream = nullptr; 2091 } 2092 if (ret != PKG_SUCCESS) { 2093 ClosePkgStream(&inputStream); 2094 delete pkgFile; 2095 return nullptr; 2096 } 2097 size_t offset = 0; 2098 ret = pkgFile->SavePackage(&offset); 2099 if (ret != PKG_SUCCESS) { 2100 delete pkgFile; 2101 return nullptr; 2102 } 2103 ret = Sign(pkgFile->GetPkgStream(), offset, header); 2104 if (ret != PKG_SUCCESS) { 2105 delete pkgFile; 2106 return nullptr; 2107 } 2108 return pkgFile; 2109} 2110 2111PkgFilePtr PkgManagerImpl::CreatePackage(PkgStreamPtr stream, PkgFile::PkgType type, PkgInfo* header) 2112{ 2113 PkgFile* pkgFile = nullptr; 2114 switch (type) { 2115 case PkgFile::PKG_TYPE_UPGRADE: 2116 pkgFile = new UpgradePkgFile(stream, header); 2117 break; 2118 case PkgFile::PKG_TYPE_ZIP: 2119 pkgFile = new ZipPkgFile(stream); 2120 break; 2121 case PkgFile::PKG_TYPE_LZ4: 2122 pkgFile = new Lz4PkgFile(stream); 2123 break; 2124 case PkgFile::PKG_TYPE_GZIP: 2125 pkgFile = new GZipPkgFile(stream); 2126 break; 2127 default: 2128 return nullptr; 2129 } 2130 return pkgFile; 2131} 2132 2133int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 2134 const std::string& keyPath, 2135 std::vector<std::string>& fileIds) 2136{ 2137 if (access(packagePath.c_str(), 0) != 0) { 2138 return PKG_INVALID_FILE; 2139 } 2140 int32_t ret = SetSignVerifyKeyName(keyPath); 2141 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 2142 2143 // 检查对应的package是否已经解析,支持多文件解析 2144 for (auto iter : pkgFiles_) { 2145 PkgFilePtr pkgFile = iter; 2146 if (pkgFile != nullptr && pkgFile->GetPkgStream()->GetFileName().compare(packagePath) == 0) { 2147 return PKG_SUCCESS; 2148 } 2149 } 2150 2151 PkgFile::PkgType pkgType = GetPkgTypeByName(packagePath); 2152 ret = PKG_INVALID_FILE; 2153 unzipToFile_ = ((pkgType == PkgFile::PKG_TYPE_GZIP) ? true : unzipToFile_); 2154 if (pkgType == PkgFile::PKG_TYPE_UPGRADE) { 2155 ret = LoadPackage(packagePath, fileIds, pkgType); 2156 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Parse %s fail ", packagePath.c_str()); 2157 } else if (pkgType != PkgFile::PKG_TYPE_NONE) { 2158 std::vector<std::string> innerFileNames; 2159 ret = LoadPackage(packagePath, innerFileNames, pkgType); 2160 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); return ret, "Unzip %s fail ", packagePath.c_str()); 2161 2162 std::string path = GetFilePath(packagePath); 2163 for (auto name : innerFileNames) { 2164 pkgType = GetPkgTypeByName(name); 2165 if (pkgType == PkgFile::PKG_TYPE_NONE) { 2166 fileIds.push_back(name); 2167 continue; 2168 } 2169 ret = ExtraAndLoadPackage(path, name, pkgType, fileIds); 2170 PKG_CHECK(ret == PKG_SUCCESS, ClearPkgFile(); 2171 return ret, "unpack %s fail in package %s ", name.c_str(), packagePath.c_str()); 2172 } 2173 } 2174 return PKG_SUCCESS; 2175} 2176 2177int32_t PkgManagerImpl::ExtraAndLoadPackage(const std::string& path, 2178 const std::string& name, 2179 PkgFile::PkgType type, 2180 std::vector<std::string>& fileIds) 2181{ 2182 int32_t ret = PKG_SUCCESS; 2183 const FileInfo* info = GetFileInfo(name); 2184 PKG_CHECK(info != nullptr, return PKG_INVALID_FILE, "Create middle stream fail %s", name.c_str()); 2185 2186 PkgStream* stream = nullptr; 2187 if (unzipToFile_) { // 中间文件解析到文件或者内存映射中 2188 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_Write); 2189 } else { 2190 ret = CreatePkgStream(&stream, path + name, info->unpackedSize, PkgStream::PkgStreamType_MemoryMap); 2191 } 2192 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create middle stream fail %s", name.c_str()); 2193 2194 ret = ExtractFile(name, stream); 2195 PKG_CHECK(ret == PKG_SUCCESS, ClosePkgStream(&stream); return ret, "Extract file fail %s", name.c_str()); 2196 return LoadPackageWithStream(path, fileIds, type, stream); 2197} 2198 2199int32_t PkgManagerImpl::LoadPackage(const std::string& packagePath, 2200 std::vector<std::string>& fileIds, 2201 PkgFile::PkgType type) 2202{ 2203 PkgStream* stream = nullptr; 2204 int32_t ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 2205 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 2206 return LoadPackageWithStream(packagePath, fileIds, type, stream); 2207} 2208 2209int32_t PkgManagerImpl::LoadPackageWithStream(const std::string& packagePath, 2210 std::vector<std::string>& fileIds, 2211 PkgFile::PkgType type, 2212 PkgStream* stream) 2213{ 2214 int32_t ret = PKG_SUCCESS; 2215 PkgFilePtr pkgFile = CreatePackage(PkgStreamImpl::ConvertPkgStream(stream), type, nullptr); 2216 PKG_CHECK(pkgFile != nullptr, ClosePkgStream(&stream); 2217 return PKG_INVALID_PARAM, "Create package fail %s", packagePath.c_str()); 2218 2219 ret = pkgFile->LoadPackage(fileIds, 2220 [this](const PkgInfo* info, const uint8_t* digest, size_t digestLen, uint8_t* signature, size_t sigLen) -> 2221 int { 2222 return Verify(info->digestMethod, digest, digestLen, signature, sigLen); 2223 }); 2224 2225 PKG_CHECK(ret == PKG_SUCCESS, delete pkgFile; return ret, "Load package fail %s", packagePath.c_str()); 2226 pkgFiles_.push_back(pkgFile); 2227 return PKG_SUCCESS; 2228} 2229 2230int32_t PkgManagerImpl::ExtractFile(const std::string &name, PkgStream *const output) 2231{ 2232 PKG_CHECK(output != nullptr, return PKG_INVALID_STREAM, "Invalid stream"); 2233 int32_t ret = PKG_INVALID_FILE; 2234 PkgEntryPtr pkgEntry = GetPkgEntry(name); 2235 if (pkgEntry != nullptr && pkgEntry->GetPkgFile() != nullptr) { 2236 ret = pkgEntry->GetPkgFile()->ExtractFile(pkgEntry, PkgStreamImpl::ConvertPkgStream(output)); 2237 } else { 2238 PKG_LOGE("Can not find file %s", name.c_str()); 2239 } 2240 return ret; 2241} 2242 2243const PkgInfo* PkgManagerImpl::GetPackageInfo(const std::string& packagePath) 2244{ 2245 for (auto iter : pkgFiles_) { 2246 PkgFilePtr pkgFile = iter; 2247 if (pkgFile != nullptr && pkgFile->GetPkgType() == PkgFile::PKG_TYPE_UPGRADE) { 2248 return pkgFile->GetPkgInfo(); 2249 } 2250 } 2251 return nullptr; 2252} 2253 2254const FileInfo* PkgManagerImpl::GetFileInfo(const std::string& path) 2255{ 2256 PkgEntryPtr pkgEntry = GetPkgEntry(path); 2257 if (pkgEntry != nullptr) { 2258 return pkgEntry->GetFileInfo(); 2259 } 2260 return nullptr; 2261} 2262 2263PkgEntryPtr PkgManagerImpl::GetPkgEntry(const std::string& fileId) 2264{ 2265 // 根据组件信息,获取到对应的entry,需要在多个pkgfile中查找 2266 for (auto iter : pkgFiles_) { 2267 PkgFilePtr pkgFile = iter; 2268 PkgEntryPtr pkgEntry = pkgFile->FindPkgEntry(fileId); 2269 if (pkgEntry == nullptr) { 2270 continue; 2271 } 2272 return pkgEntry; 2273 } 2274 return nullptr; 2275} 2276 2277int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 2278 const std::string& fileName, 2279 size_t size, 2280 int32_t type) 2281{ 2282 static char const *modeFlags[] = { "rb", "wb+" }; 2283 int32_t ret = CheckFile(fileName); 2284 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to check file %s ", fileName.c_str()); 2285 2286 if (pkgStreams_.find(fileName) != pkgStreams_.end()) { 2287 PkgStreamImpl* mapStream = pkgStreams_[fileName]; 2288 mapStream->AddRef(); 2289 *stream = mapStream; 2290 return PKG_SUCCESS; 2291 } 2292 2293 if (type == PkgStream::PkgStreamType_Write || type == PkgStream::PkgStreamType_Read) { 2294 FILE* file = nullptr; 2295 file = fopen(fileName.c_str(), modeFlags[type]); 2296 PKG_CHECK(file != nullptr, return PKG_INVALID_FILE, "Fail to open file %s ", fileName.c_str()); 2297 *stream = new FileStream(fileName, file, type); 2298 } else if (type == PkgStream::PkgStreamType_MemoryMap) { 2299 size_t fileSize = size; 2300 if (fileSize == 0) { // 文件必须存在,否则没有办法创建内存映射 2301 if (access(fileName.c_str(), 0) != 0) { 2302 return PKG_INVALID_FILE; 2303 } 2304 fileSize = GetFileSize(fileName); 2305 } 2306 PKG_CHECK(fileSize > 0, return PKG_INVALID_FILE, "Fail to check file size %s ", fileName.c_str()); 2307 // 将文件映射至进程的地址空间 2308 uint8_t* memoryMap = MapMemory(fileName, fileSize); 2309 PKG_CHECK(memoryMap != nullptr, return PKG_INVALID_FILE, "Fail to map memory %s ", fileName.c_str()); 2310 *stream = new MemoryMapStream(fileName, memoryMap, fileSize); 2311 } 2312 pkgStreams_[fileName] = PkgStreamImpl::ConvertPkgStream(*stream); 2313 return PKG_SUCCESS; 2314} 2315 2316int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 2317 const std::string &fileName, 2318 PkgStream::ExtractFileProcessor processor, 2319 void* context) 2320{ 2321 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 2322 "Can not create stream for %s", fileName.c_str()); 2323 *stream = new ProcessorStream(fileName, processor, context); 2324 return PKG_SUCCESS; 2325} 2326 2327int32_t PkgManagerImpl::CreatePkgStream(PkgStream** stream, 2328 const std::string &fileName, const uint8_t* buffer, size_t bufferSize) 2329{ 2330 PKG_CHECK(stream != nullptr, return PKG_INVALID_PARAM, 2331 "Can not create stream for %s", fileName.c_str()); 2332 // 创建个输入stream 2333 *stream = new MemoryMapStream(fileName, 2334 const_cast<uint8_t*>(buffer), bufferSize, PkgStream::PkgStreamType_Buffer); 2335 PKG_CHECK(*stream != nullptr, return PKG_INVALID_PARAM, 2336 "Can not create stream for %s", fileName.c_str()); 2337 return PKG_SUCCESS; 2338} 2339 2340void PkgManagerImpl::ClosePkgStream(PkgStream** stream) 2341{ 2342 PkgStreamImpl* mapStream = PkgStreamImpl::ConvertPkgStream(*stream); 2343 if (mapStream == nullptr) { 2344 return; 2345 } 2346 2347 auto iter = pkgStreams_.find(mapStream->GetFileName()); 2348 if (iter != pkgStreams_.end()) { 2349 mapStream->DelRef(); 2350 if (mapStream->IsRef()) { 2351 return; 2352 } 2353 pkgStreams_.erase(iter); 2354 } 2355 delete mapStream; 2356 *stream = nullptr; 2357} 2358 2359PkgFile::PkgType PkgManagerImpl::GetPkgTypeByName(const std::string& path) 2360{ 2361 int32_t pos = path.find_last_of('.'); 2362 if (pos < 0) { 2363 return PkgFile::PKG_TYPE_NONE; 2364 } 2365 std::string postfix = path.substr(pos + 1, -1); 2366 std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower); 2367 2368 if (path.substr(pos + 1, -1).compare("bin") == 0) { 2369 return PkgFile::PKG_TYPE_UPGRADE; 2370 } else if (path.substr(pos + 1, -1).compare("zip") == 0) { 2371 return PkgFile::PKG_TYPE_ZIP; 2372 } else if (path.substr(pos + 1, -1).compare("lz4") == 0) { 2373 return PkgFile::PKG_TYPE_LZ4; 2374 } else if (path.substr(pos + 1, -1).compare("gz") == 0) { 2375 return PkgFile::PKG_TYPE_GZIP; 2376 } 2377 return PkgFile::PKG_TYPE_NONE; 2378} 2379 2380int32_t PkgManagerImpl::VerifyPackage(const std::string& packagePath, const std::string& keyPath, 2381 const std::string& version, const uint8_t* digest, size_t size) 2382{ 2383 int32_t ret = SetSignVerifyKeyName(keyPath); 2384 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Invalid keyname"); 2385 2386 PKG_CHECK(digest != nullptr, return PKG_INVALID_PARAM, "Invalid para"); 2387 PkgStream* stream = nullptr; 2388 ret = CreatePkgStream(&stream, packagePath, 0, PkgStream::PkgStreamType_Read); 2389 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Create input stream fail %s", packagePath.c_str()); 2390 size_t fileLen = stream->GetFileLength(); 2391 PKG_CHECK(fileLen > 0, ClosePkgStream(&stream); return PKG_INVALID_FILE, "invalid file to load"); 2392 PKG_CHECK(fileLen <= SIZE_MAX, ClosePkgStream(&stream); return PKG_INVALID_FILE, 2393 "Invalid file len %zu to load %s", fileLen, stream->GetFileName().c_str()); 2394 2395 PkgFile::PkgType type = GetPkgTypeByName(packagePath); 2396 int8_t digestMethod = DigestAlgorithm::GetDigestMethod(version); 2397 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 2398 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 2399 PKG_CHECK(digestLen == size, return PKG_INVALID_PARAM, "Invalid digestLen"); 2400 2401 // 非升级包,需要签名验证 2402 if (type != PkgFile::PKG_TYPE_UPGRADE) { 2403 std::vector<uint8_t> digestNone(digestLen); // hash值,不包括签名部分 2404 std::vector<uint8_t> signature(signatureLen); 2405 if (digest != nullptr) { 2406 std::vector<uint8_t> digestHasSign(digestLen); // 包括签名部分,做整个文件校验 2407 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), digestHasSign.data(), signature.data()); 2408 if (memcmp(digestHasSign.data(), digest, size) != 0) { 2409 PKG_LOGE("Fail to verify package"); 2410 ret = PKG_INVALID_SIGNATURE; 2411 } 2412 } else { 2413 ret = GenerateFileDigest(stream, digestMethod, digestNone.data(), nullptr, signature.data()); 2414 } 2415 // 摘要不包含签名部分 2416 if (ret == PKG_SUCCESS) { 2417 ret = Verify(digestMethod, digestNone.data(), digestLen, signature.data(), signatureLen); 2418 } 2419 } else { 2420 if (digest != nullptr) { 2421 std::vector<uint8_t> digestHasSign(digestLen); 2422 ret = GenerateFileDigest(stream, digestMethod, nullptr, digestHasSign.data(), nullptr); 2423 if (memcmp(digestHasSign.data(), digest, size) != 0) { 2424 PKG_LOGE("Fail to verify package"); 2425 ret = PKG_INVALID_SIGNATURE; 2426 } 2427 } 2428 } 2429 ClosePkgStream(&stream); 2430 return ret; 2431} 2432 2433int32_t PkgManagerImpl::GenerateFileDigest(PkgStream* stream, uint8_t digestMethod, 2434 uint8_t* digestNone, uint8_t* digestHasSign, uint8_t* signature) 2435{ 2436 int32_t ret = PKG_SUCCESS; 2437 size_t fileLen = stream->GetFileLength(); 2438 size_t digestLen = DigestAlgorithm::GetDigestLen(digestMethod); 2439 size_t signatureLen = DigestAlgorithm::GetSignatureLen(digestMethod); 2440 // 整包检查 2441 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 2442 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, "Invalid file %s", stream->GetFileName().c_str()); 2443 algorithm->Init(); 2444 2445 // 用于签名校验 2446 DigestAlgorithm::DigestAlgorithmPtr algorithmInner = PkgAlgorithmFactory::GetDigestAlgorithm(digestMethod); 2447 PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, 2448 "Invalid file %s", stream->GetFileName().c_str()); 2449 algorithmInner->Init(); 2450 2451 size_t offset = 0; 2452 size_t readLen = 0; 2453 size_t needReadLen = fileLen; 2454 size_t buffSize = 4096; 2455 std::vector<uint8_t> buff(buffSize); 2456 if (signature != nullptr) { 2457 if (signatureLen >= fileLen) { 2458 return PKG_INVALID_SIGNATURE; 2459 } 2460 needReadLen = fileLen - signatureLen; 2461 } 2462 while (offset < needReadLen) { 2463 if ((needReadLen - offset) < buffSize) { 2464 buffSize = needReadLen - offset; 2465 } 2466 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), buffSize, offset, &readLen); 2467 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 2468 if (digestHasSign != nullptr) { 2469 algorithm->Update(buff.data(), readLen); 2470 } 2471 if (digestNone != nullptr) { 2472 algorithmInner->Update(buff.data(), readLen); 2473 } 2474 offset += readLen; 2475 readLen = 0; 2476 } 2477 // 读最后的signatureLen大小 2478 if (signature != nullptr) { 2479 readLen = 0; 2480 ret = stream->Read(reinterpret_cast<uint8_t*>(buff.data()), signatureLen, offset, &readLen); 2481 PKG_CHECK(ret == PKG_SUCCESS, return ret, "read buffer fail %s", stream->GetFileName().c_str()); 2482 if (digestHasSign != nullptr) { 2483 algorithm->Update(buff.data(), readLen); 2484 } 2485 } 2486 if (digestHasSign != nullptr) { 2487 algorithm->Final(digestHasSign, digestLen); 2488 } 2489 2490 if (digestNone != nullptr) { 2491 algorithmInner->Final(digestNone, digestLen); 2492 } 2493 if (signature != nullptr) { 2494 PKG_CHECK(!memcpy_s(signature, signatureLen, buff.data(), signatureLen), return PKG_NONE_MEMORY, 2495 "GenerateFileDigest memcpy failed"); 2496 } 2497 return PKG_SUCCESS; 2498} 2499 2500int32_t PkgManagerImpl::Verify(uint8_t digestMethod, const uint8_t* digest, size_t digestLen, 2501 uint8_t* signature, size_t sigLen) 2502{ 2503 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetVerifyAlgorithm( 2504 signVerifyKeyName_, digestMethod); 2505 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 2506 return signAlgorithm->VerifyBuffer(digest, digestLen, signature, sigLen); 2507} 2508 2509int32_t PkgManagerImpl::Sign(PkgStream* stream, size_t offset, PkgInfo* info) 2510{ 2511 if (info->signMethod == PKG_SIGN_METHOD_NONE) { 2512 return PKG_SUCCESS; 2513 } 2514 2515 size_t digestLen = DigestAlgorithm::GetDigestLen(info->digestMethod); 2516 std::vector<uint8_t> digest(digestLen); 2517 int32_t ret = GenerateFileDigest(stream, info->digestMethod, nullptr, digest.data(), nullptr); 2518 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to generate signature %s", stream->GetFileName().c_str()); 2519 SignAlgorithm::SignAlgorithmPtr signAlgorithm = PkgAlgorithmFactory::GetSignAlgorithm( 2520 signVerifyKeyName_, info->signMethod, info->digestMethod); 2521 PKG_CHECK(signAlgorithm != nullptr, return PKG_INVALID_SIGNATURE, "Invalid sign algo"); 2522 2523 size_t signLen = DigestAlgorithm::GetSignatureLen(info->digestMethod); 2524 std::vector<uint8_t> signedData(signLen, 0); 2525 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signLen, offset); 2526 2527 size_t signDataLen = 0; 2528 signedData.clear(); 2529 ret = signAlgorithm->SignBuffer(digest.data(), digestLen, signedData, &signDataLen); 2530 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 2531 PKG_CHECK(signDataLen <= signLen, return PKG_INVALID_SIGNATURE, "SignData len %zu more %zu", signDataLen, signLen); 2532 PKG_LOGI("Signature %zu %zu %s", offset, signDataLen, stream->GetFileName().c_str()); 2533 ret = ((PkgStreamImpl *)stream)->Write(signedData.data(), signDataLen, offset); 2534 ((PkgStreamImpl *)stream)->Flush(offset + signedData.size()); 2535 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to Write signature %s", stream->GetFileName().c_str()); 2536 return ret; 2537} 2538 2539int32_t PkgManagerImpl::SetSignVerifyKeyName(const std::string& keyName) 2540{ 2541 if (access(keyName.c_str(), 0) != 0) { 2542 return PKG_INVALID_FILE; 2543 } 2544 signVerifyKeyName_ = keyName; 2545 return PKG_SUCCESS; 2546} 2547 2548int32_t PkgManagerImpl::DecompressBuff(FileInfo* const info, 2549 const uint8_t* data, size_t dataSize, PkgStream* const output) const 2550{ 2551 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 2552 return PKG_INVALID_PARAM, "Param is null "); 2553 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 2554 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 2555 "Can not get algorithm for %s", info->identity.c_str()); 2556 2557 // 创建个输入stream 2558 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 2559 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 2560 //std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 2561 // data, dataSize, PkgStream::PkgStreamType_Buffer); 2562 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 2563 "Can not create stream for %s", info->identity.c_str()); 2564 PkgAlgorithmContext context = {0, 0, dataSize, 0, 0, info->digestMethod}; 2565 int32_t ret = algorithm->Unpack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 2566 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 2567 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", dataSize, context.unpackedSize); 2568 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.unpackedSize); 2569 // 返回实际的大小 2570 info->packedSize = context.packedSize; 2571 info->unpackedSize = context.unpackedSize; 2572 return PKG_SUCCESS; 2573} 2574int32_t PkgManagerImpl::CompressBuff(FileInfo* const info, 2575 const uint8_t* data, size_t dataSize, PkgStream* const output) const 2576{ 2577 PKG_CHECK(info != nullptr && data != nullptr && output != nullptr, 2578 return PKG_INVALID_PARAM, "Param is null "); 2579 PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); 2580 PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, 2581 "Can not get algorithm for %s", info->identity.c_str()); 2582 2583 // 创建个输入stream 2584 std::shared_ptr<MemoryMapStream> inStream = std::make_shared<MemoryMapStream>(info->identity, 2585 const_cast<uint8_t*>(data), dataSize, PkgStream::PkgStreamType_Buffer); 2586 PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, 2587 "Can not create stream for %s", info->identity.c_str()); 2588 PkgAlgorithmContext context = {0, 0, 0, dataSize, 0, info->digestMethod}; 2589 int32_t ret = algorithm->Pack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), &context); 2590 PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", info->identity.c_str()); 2591 PKG_LOGI("packedSize: %zu unpackedSize: %zu ", context.packedSize, context.unpackedSize); 2592 PkgStreamImpl::ConvertPkgStream(output)->Flush(context.packedSize); 2593 info->packedSize = context.packedSize; 2594 info->unpackedSize = context.unpackedSize; 2595 return PKG_SUCCESS; 2596} 2597} // namespace hpackage 2598