• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "pkg_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