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
GetUpgradePkgInfo(UpgradePkgInfo * upgradePackageInfo,std::vector<std::pair<std::string,ComponentInfo>> & files,const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[])28 static int32_t GetUpgradePkgInfo(UpgradePkgInfo *upgradePackageInfo,
29 std::vector<std::pair<std::string, ComponentInfo>> &files,
30 const UpgradePkgInfoExt *pkgInfoExt,
31 ComponentInfoExt compInfo[])
32 {
33 upgradePackageInfo->updateFileVersion = pkgInfoExt->updateFileVersion;
34 if (pkgInfoExt->softwareVersion != nullptr) {
35 upgradePackageInfo->softwareVersion = pkgInfoExt->softwareVersion;
36 }
37 if (pkgInfoExt->productUpdateId != nullptr) {
38 upgradePackageInfo->productUpdateId = pkgInfoExt->productUpdateId;
39 }
40 if (pkgInfoExt->descriptPackageId != nullptr) {
41 upgradePackageInfo->descriptPackageId = pkgInfoExt->descriptPackageId;
42 }
43 if (pkgInfoExt->time != nullptr) {
44 upgradePackageInfo->time = pkgInfoExt->time;
45 }
46 if (pkgInfoExt->date != nullptr) {
47 upgradePackageInfo->date = pkgInfoExt->date;
48 }
49 upgradePackageInfo->pkgInfo.digestMethod = pkgInfoExt->digestMethod;
50 upgradePackageInfo->pkgInfo.signMethod = pkgInfoExt->signMethod;
51 upgradePackageInfo->pkgInfo.entryCount = pkgInfoExt->entryCount;
52 upgradePackageInfo->pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE;
53 files.resize(pkgInfoExt->entryCount);
54 for (uint32_t i = 0; i < pkgInfoExt->entryCount; i++) {
55 files[i].first.assign(compInfo[i].filePath);
56 ComponentInfo* info = &files[i].second;
57 UPDATER_ERROR_CHECK(!memcpy_s(info->digest, sizeof(info->digest), compInfo[i].digest, sizeof(info->digest)),
58 "GetUpgradePkgInfo memcpy failed", return PKG_NONE_MEMORY);
59 info->fileInfo.identity.assign(compInfo[i].componentAddr);
60 info->fileInfo.unpackedSize = compInfo[i].size;
61 info->fileInfo.packedSize = compInfo[i].size;
62 info->fileInfo.packMethod = PKG_COMPRESS_METHOD_NONE;
63 info->fileInfo.digestMethod = pkgInfoExt->digestMethod;
64 info->version.assign(compInfo[i].version);
65 info->id = compInfo[i].id;
66 info->resType = compInfo[i].resType;
67 info->type = compInfo[i].type;
68 info->originalSize = compInfo[i].originalSize;
69 info->compFlags = compInfo[i].flags;
70 }
71 return PKG_SUCCESS;
72 }
73
GetZipPkgInfo(PkgManager::PkgInfoPtr pkgInfo,std::vector<std::pair<std::string,ZipFileInfo>> & files,const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[])74 static int32_t GetZipPkgInfo(PkgManager::PkgInfoPtr pkgInfo,
75 std::vector<std::pair<std::string, ZipFileInfo>> &files,
76 const UpgradePkgInfoExt *pkgInfoExt,
77 ComponentInfoExt compInfo[])
78 {
79 pkgInfo->signMethod = pkgInfoExt->signMethod;
80 pkgInfo->digestMethod = pkgInfoExt->digestMethod;
81 pkgInfo->entryCount = pkgInfoExt->entryCount;
82 pkgInfo->pkgType = pkgInfoExt->pkgType;
83 files.resize(pkgInfoExt->entryCount);
84 for (uint32_t i = 0; i < pkgInfo->entryCount; i++) {
85 files[i].first.assign(compInfo[i].filePath);
86 ZipFileInfo* info = &files[i].second;
87 info->fileInfo.identity.assign(compInfo[i].componentAddr);
88 info->fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
89 info->fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
90 }
91 return PKG_SUCCESS;
92 }
93
GetLz4PkgInfo(PkgManager::PkgInfoPtr pkgInfo,std::vector<std::pair<std::string,Lz4FileInfo>> & files,const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[])94 static int32_t GetLz4PkgInfo(PkgManager::PkgInfoPtr pkgInfo,
95 std::vector<std::pair<std::string, Lz4FileInfo>> &files,
96 const UpgradePkgInfoExt *pkgInfoExt,
97 ComponentInfoExt compInfo[])
98 {
99 pkgInfo->signMethod = pkgInfoExt->signMethod;
100 pkgInfo->digestMethod = pkgInfoExt->digestMethod;
101 pkgInfo->entryCount = pkgInfoExt->entryCount;
102 pkgInfo->pkgType = PKG_PACK_TYPE_LZ4;
103 files.resize(pkgInfoExt->entryCount);
104 for (uint32_t i = 0; i < pkgInfoExt->entryCount; i++) {
105 files[i].first.assign(compInfo[i].filePath);
106 Lz4FileInfo* info = &files[i].second;
107 info->fileInfo.identity.assign(compInfo[i].componentAddr);
108 info->fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
109 info->fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
110 info->compressionLevel = MID_COMPRESS_LEVEL;
111 info->blockSizeID = 0;
112 info->contentChecksumFlag = 0;
113 info->blockIndependence = 0;
114 }
115 return PKG_SUCCESS;
116 }
117
CreatePackage(const UpgradePkgInfoExt * pkgInfoExt,ComponentInfoExt compInfo[],const char * path,const char * keyPath)118 int32_t CreatePackage(const UpgradePkgInfoExt *pkgInfoExt,
119 ComponentInfoExt compInfo[],
120 const char *path,
121 const char *keyPath)
122 {
123 PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance();
124 if (pkgInfoExt == nullptr || path == nullptr || keyPath == nullptr || manager == nullptr) {
125 LOG(ERROR) << "Check param fail ";
126 return PKG_INVALID_PARAM;
127 }
128
129 int32_t ret = PKG_SUCCESS;
130 switch (pkgInfoExt->pkgType) {
131 case PKG_PACK_TYPE_UPGRADE: {
132 UpgradePkgInfo upgradePackageInfo;
133 std::vector<std::pair<std::string, ComponentInfo>> files;
134 ret = GetUpgradePkgInfo(&upgradePackageInfo, files, pkgInfoExt, compInfo);
135 if (ret == PKG_SUCCESS) {
136 ret = manager->CreatePackage(path, keyPath, &upgradePackageInfo.pkgInfo, files);
137 }
138 break;
139 }
140 case PKG_PACK_TYPE_ZIP:
141 case PKG_PACK_TYPE_GZIP: {
142 PkgInfo info;
143 std::vector<std::pair<std::string, ZipFileInfo>> files;
144 ret = GetZipPkgInfo(&info, files, pkgInfoExt, compInfo);
145 if (ret == PKG_SUCCESS) {
146 ret = manager->CreatePackage(path, keyPath, &info, files);
147 }
148 break;
149 }
150 case PKG_PACK_TYPE_LZ4: {
151 PkgInfo info;
152 std::vector<std::pair<std::string, Lz4FileInfo>> files;
153 ret = GetLz4PkgInfo(&info, files, pkgInfoExt, compInfo);
154 if (ret == PKG_SUCCESS) {
155 ret = manager->CreatePackage(path, keyPath, &info, files);
156 }
157 break;
158 }
159 default:
160 ret = PKG_INVALID_PARAM;
161 break;
162 }
163 PkgManager::ReleasePackageInstance(manager);
164 return ret;
165 }
166
VerifyPackage(const char * packagePath,const char * keyPath,const char * version,const uint8_t * digest,size_t size)167 int32_t VerifyPackage(const char *packagePath,
168 const char *keyPath,
169 const char *version,
170 const uint8_t *digest,
171 size_t size)
172 {
173 PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance();
174 if (packagePath == nullptr || keyPath == nullptr || version == nullptr || manager == nullptr) {
175 return PKG_INVALID_PARAM;
176 }
177
178 PkgBuffer digestBuffer(const_cast<uint8_t*>(digest), size);
179 int32_t ret = manager->VerifyPackage(packagePath, keyPath, version, digestBuffer,
180 [](int32_t result, uint32_t percent) {});
181 PkgManager::ReleasePackageInstance(manager);
182 return ret;
183 }
184
VerifyPackageWithCallback(const std::string & packagePath,const std::string & keyPath,std::function<void (int32_t result,uint32_t percent)> cb)185 int32_t VerifyPackageWithCallback(const std::string &packagePath,
186 const std::string &keyPath, std::function<void(int32_t result, uint32_t percent)> cb)
187 {
188 if (packagePath.empty() || keyPath.empty() || cb == nullptr) {
189 return PKG_INVALID_PARAM;
190 }
191
192 PkgManager *manager = PkgManager::GetPackageInstance();
193 PkgBuffer digestBuffer {};
194 std::string version {};
195 int32_t ret = manager->VerifyPackage(packagePath, keyPath, version, digestBuffer, cb);
196 if (ret != 0) {
197 cb(ret, VERIFY_FINSH_PERCENT);
198 }
199 PkgManager::ReleasePackageInstance(manager);
200 return ret;
201 }
202
CreatePackageL1(const UpgradePkgInfoExt * pkgInfo,ComponentInfoExt comp[],const char * path,uint32_t * offset,char ** hashCode)203 int32_t CreatePackageL1(const UpgradePkgInfoExt *pkgInfo, ComponentInfoExt comp[],
204 const char *path, uint32_t *offset, char **hashCode)
205 {
206 PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance();
207 if (pkgInfo == nullptr || path == nullptr || hashCode == nullptr || manager == nullptr || offset == nullptr) {
208 LOG(ERROR) << "Check param fail ";
209 return PKG_INVALID_PARAM;
210 }
211 if (pkgInfo->pkgType != PKG_PACK_TYPE_UPGRADE) {
212 LOG(ERROR) << "Invalid type for l1";
213 return PKG_INVALID_PARAM;
214 }
215 UpgradePkgInfo upgradePackageInfo;
216 std::vector<std::pair<std::string, ComponentInfo>> files;
217 int32_t ret = GetUpgradePkgInfo(&upgradePackageInfo, files, pkgInfo, comp);
218 if (ret == PKG_SUCCESS) {
219 std::string hashValue;
220 upgradePackageInfo.pkgInfo.pkgFlags |= PKG_SUPPORT_L1;
221 size_t signOffset = 0;
222 ret = manager->CreatePackage(path, &upgradePackageInfo.pkgInfo, files, signOffset, hashValue);
223 *offset = signOffset;
224 *hashCode = strdup(hashValue.c_str());
225 }
226 PkgManager::ReleasePackageInstance(manager);
227 return ret;
228 }