• 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 "package/package.h"
16 #include <cstdio>
17 #include <cstdlib>
18 #include <iostream>
19 #include <memory>
20 #include "log/log.h"
21 #include "package/pkg_manager.h"
22 #include "securec.h"
23 
24 using namespace Updater;
25 using namespace Hpackage;
26 constexpr uint32_t VERIFY_FINSH_PERCENT = 100;
27 
28 namespace {
GetUpgradePkgInfo(UpgradePkgInfo * upgradePackageInfo,std::vector<std::pair<std::string,ComponentInfo>> & files,const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[])29 int32_t GetUpgradePkgInfo(UpgradePkgInfo *upgradePackageInfo,
30     std::vector<std::pair<std::string, ComponentInfo>> &files,
31     const UpgradePkgInfoExt *pkgInfoExt,
32     ComponentInfoExt compInfo[])
33 {
34     upgradePackageInfo->updateFileVersion = pkgInfoExt->updateFileVersion;
35     if (pkgInfoExt->softwareVersion != nullptr) {
36         upgradePackageInfo->softwareVersion = pkgInfoExt->softwareVersion;
37     }
38     if (pkgInfoExt->productUpdateId != nullptr) {
39         upgradePackageInfo->productUpdateId = pkgInfoExt->productUpdateId;
40     }
41     if (pkgInfoExt->descriptPackageId != nullptr) {
42         upgradePackageInfo->descriptPackageId = pkgInfoExt->descriptPackageId;
43     }
44     if (pkgInfoExt->time != nullptr) {
45         upgradePackageInfo->time = pkgInfoExt->time;
46     }
47     if (pkgInfoExt->date != nullptr) {
48         upgradePackageInfo->date = pkgInfoExt->date;
49     }
50     upgradePackageInfo->pkgInfo.digestMethod = pkgInfoExt->digestMethod;
51     upgradePackageInfo->pkgInfo.signMethod = pkgInfoExt->signMethod;
52     upgradePackageInfo->pkgInfo.entryCount = pkgInfoExt->entryCount;
53     upgradePackageInfo->pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE;
54     files.resize(pkgInfoExt->entryCount);
55     for (uint32_t i = 0; i < pkgInfoExt->entryCount; i++) {
56         files[i].first.assign(compInfo[i].filePath);
57         ComponentInfo* info = &files[i].second;
58         if (memcpy_s(info->digest, sizeof(info->digest), compInfo[i].digest, sizeof(info->digest)) != EOK) {
59             LOG(ERROR) << "GetUpgradePkgInfo memcpy failed";
60             return PKG_NONE_MEMORY;
61         }
62         info->fileInfo.identity.assign(compInfo[i].componentAddr);
63         info->fileInfo.unpackedSize = compInfo[i].size;
64         info->fileInfo.packedSize = compInfo[i].size;
65         info->fileInfo.packMethod = PKG_COMPRESS_METHOD_NONE;
66         info->fileInfo.digestMethod = pkgInfoExt->digestMethod;
67         info->version.assign(compInfo[i].version);
68         info->id = compInfo[i].id;
69         info->resType = compInfo[i].resType;
70         info->type = compInfo[i].type;
71         info->originalSize = compInfo[i].originalSize;
72         info->compFlags = compInfo[i].flags;
73     }
74     return PKG_SUCCESS;
75 }
76 
GetZipPkgInfo(PkgManager::PkgInfoPtr pkgInfo,std::vector<std::pair<std::string,ZipFileInfo>> & files,const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[])77 int32_t GetZipPkgInfo(PkgManager::PkgInfoPtr pkgInfo,
78     std::vector<std::pair<std::string, ZipFileInfo>> &files,
79     const UpgradePkgInfoExt *pkgInfoExt,
80     ComponentInfoExt compInfo[])
81 {
82     pkgInfo->signMethod = pkgInfoExt->signMethod;
83     pkgInfo->digestMethod  = pkgInfoExt->digestMethod;
84     pkgInfo->entryCount = pkgInfoExt->entryCount;
85     pkgInfo->pkgType = pkgInfoExt->pkgType;
86     files.resize(pkgInfoExt->entryCount);
87     for (uint32_t i = 0; i < pkgInfo->entryCount; i++) {
88         files[i].first.assign(compInfo[i].filePath);
89         ZipFileInfo* info = &files[i].second;
90         info->fileInfo.identity.assign(compInfo[i].componentAddr);
91         info->fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
92         info->fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
93     }
94     return PKG_SUCCESS;
95 }
96 
GetLz4PkgInfo(PkgManager::PkgInfoPtr pkgInfo,std::vector<std::pair<std::string,Lz4FileInfo>> & files,const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[])97 int32_t GetLz4PkgInfo(PkgManager::PkgInfoPtr pkgInfo,
98     std::vector<std::pair<std::string, Lz4FileInfo>> &files,
99     const UpgradePkgInfoExt *pkgInfoExt,
100     ComponentInfoExt compInfo[])
101 {
102     pkgInfo->signMethod = pkgInfoExt->signMethod;
103     pkgInfo->digestMethod  = pkgInfoExt->digestMethod;
104     pkgInfo->entryCount = pkgInfoExt->entryCount;
105     pkgInfo->pkgType = PKG_PACK_TYPE_LZ4;
106     files.resize(pkgInfoExt->entryCount);
107     for (uint32_t i = 0; i < pkgInfoExt->entryCount; i++) {
108         files[i].first.assign(compInfo[i].filePath);
109         Lz4FileInfo* info = &files[i].second;
110         info->fileInfo.identity.assign(compInfo[i].componentAddr);
111         info->fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
112         info->fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
113         info->compressionLevel = MID_COMPRESS_LEVEL;
114         info->blockSizeID = 0;
115         info->contentChecksumFlag = 0;
116         info->blockIndependence = 0;
117     }
118     return PKG_SUCCESS;
119 }
120 }
121 
CreatePackage(const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[],const char * path,const char * keyPath)122 int32_t CreatePackage(const UpgradePkgInfoExt *pkgInfoExt,
123     ComponentInfoExt compInfo[],
124     const char *path,
125     const char *keyPath)
126 {
127     PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance();
128     if (pkgInfoExt == nullptr || path == nullptr || keyPath == nullptr || manager == nullptr) {
129         LOG(ERROR) << "Check param fail ";
130         return PKG_INVALID_PARAM;
131     }
132 
133     int32_t ret = PKG_SUCCESS;
134     switch (pkgInfoExt->pkgType) {
135         case PKG_PACK_TYPE_UPGRADE: {
136             UpgradePkgInfo upgradePackageInfo;
137             std::vector<std::pair<std::string, ComponentInfo>> files;
138             ret = GetUpgradePkgInfo(&upgradePackageInfo, files, pkgInfoExt, compInfo);
139             if (ret == PKG_SUCCESS) {
140                 ret = manager->CreatePackage(path, keyPath, &upgradePackageInfo.pkgInfo, files);
141             }
142             break;
143         }
144         case PKG_PACK_TYPE_ZIP:
145         case PKG_PACK_TYPE_GZIP: {
146             PkgInfo info;
147             std::vector<std::pair<std::string, ZipFileInfo>> files;
148             ret = GetZipPkgInfo(&info, files, pkgInfoExt, compInfo);
149             if (ret == PKG_SUCCESS) {
150                 ret = manager->CreatePackage(path, keyPath, &info, files);
151             }
152             break;
153         }
154         case PKG_PACK_TYPE_LZ4: {
155             PkgInfo info;
156             std::vector<std::pair<std::string, Lz4FileInfo>> files;
157             ret = GetLz4PkgInfo(&info, files, pkgInfoExt, compInfo);
158             if (ret == PKG_SUCCESS) {
159                 ret = manager->CreatePackage(path, keyPath, &info, files);
160             }
161             break;
162         }
163         default:
164             ret = PKG_INVALID_PARAM;
165             break;
166     }
167     PkgManager::ReleasePackageInstance(manager);
168     return ret;
169 }
170 
VerifyPackage(const char * packagePath,const char * keyPath,const char * version,const uint8_t * digest,size_t size)171 int32_t VerifyPackage(const char *packagePath,
172     const char *keyPath,
173     const char *version,
174     const uint8_t *digest,
175     size_t size)
176 {
177     PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance();
178     if (packagePath == nullptr || keyPath == nullptr || version == nullptr || manager == nullptr) {
179         return PKG_INVALID_PARAM;
180     }
181 
182     PkgBuffer digestBuffer(const_cast<uint8_t*>(digest), size);
183     int32_t ret = manager->VerifyPackage(packagePath, keyPath, version, digestBuffer,
184         [](int32_t result, uint32_t percent) {});
185     PkgManager::ReleasePackageInstance(manager);
186     return ret;
187 }
188 
VerifyPackageWithCallback(const std::string & packagePath,const std::string & keyPath,std::function<void (int32_t result,uint32_t percent)> cb)189 int32_t VerifyPackageWithCallback(const std::string &packagePath,
190     const std::string &keyPath, std::function<void(int32_t result, uint32_t percent)> cb)
191 {
192     if (packagePath.empty() || keyPath.empty() || cb == nullptr) {
193         return PKG_INVALID_PARAM;
194     }
195 
196     PkgManager *manager = PkgManager::GetPackageInstance();
197     PkgBuffer digestBuffer {};
198     std::string version {};
199     int32_t ret = manager->VerifyPackage(packagePath, keyPath, version, digestBuffer, cb);
200     if (ret != 0) {
201         cb(ret, VERIFY_FINSH_PERCENT);
202     }
203     PkgManager::ReleasePackageInstance(manager);
204     return ret;
205 }
206 
ExtraPackageDir(const char * packagePath,const char * keyPath,const char * dir,const char * outPath)207 int32_t ExtraPackageDir(const char *packagePath, [[maybe_unused]] const char *keyPath, const char *dir,
208     const char *outPath)
209 {
210     PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance();
211     if (packagePath == nullptr || outPath == nullptr || manager == nullptr) {
212         LOG(ERROR) << "Check param fail ";
213         return PKG_INVALID_PARAM;
214     }
215 
216     std::vector<std::string> components;
217     int32_t ret = manager->LoadPackageWithoutUnPack(std::string(packagePath), components);
218     if (ret != PKG_SUCCESS) {
219         LOG(ERROR) << "LoadPackageWithoutUnPack fail";
220         PkgManager::ReleasePackageInstance(manager);
221         return ret;
222     }
223 
224     for (size_t i = 0; i < components.size(); i++) {
225         if (dir != nullptr && components[i].compare(0, strlen(dir), dir) != 0) {
226             continue;
227         }
228         PkgManager::StreamPtr outStream = nullptr;
229         manager->CreatePkgStream(outStream, std::string(outPath) + components[i], 0, PkgStream::PkgStreamType_Write);
230         if (outStream == nullptr) {
231             LOG(ERROR) << "CreatePkgStream fail";
232             PkgManager::ReleasePackageInstance(manager);
233             return PKG_INVALID_STREAM;
234         }
235         manager->ExtractFile(components[i], outStream);
236         manager->ClosePkgStream(outStream);
237     }
238     PkgManager::ReleasePackageInstance(manager);
239     return PKG_SUCCESS;
240 }
241 
ExtraPackageFile(const char * packagePath,const char * keyPath,const char * file,const char * outPath)242 int32_t ExtraPackageFile(const char *packagePath, [[maybe_unused]] const char *keyPath, const char *file,
243     const char *outPath)
244 {
245     PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance();
246     if (packagePath == nullptr || outPath == nullptr || file == nullptr || manager == nullptr) {
247         LOG(ERROR) << "Check param fail ";
248         return PKG_INVALID_PARAM;
249     }
250 
251     std::vector<std::string> components;
252     int32_t ret = manager->LoadPackageWithoutUnPack(std::string(packagePath), components);
253     if (ret != PKG_SUCCESS) {
254         LOG(ERROR) << "LoadPackageWithoutUnPack fail";
255         PkgManager::ReleasePackageInstance(manager);
256         return ret;
257     }
258 
259     PkgManager::StreamPtr outStream = nullptr;
260     manager->CreatePkgStream(outStream, std::string(outPath) + file, 0, PkgStream::PkgStreamType_Write);
261     if (outStream == nullptr) {
262         LOG(ERROR) << "CreatePkgStream fail";
263         PkgManager::ReleasePackageInstance(manager);
264         return PKG_INVALID_STREAM;
265     }
266     manager->ExtractFile(file, outStream);
267 
268     manager->ClosePkgStream(outStream);
269     PkgManager::ReleasePackageInstance(manager);
270     return PKG_SUCCESS;
271 }