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
16 #ifndef PKG_FUZZ_TEST
17 #define PKG_FUZZ_TEST
18
19 #include <cstring>
20 #include <fcntl.h>
21 #include <iostream>
22 #include <sys/mman.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include "pkg_algorithm.h"
26 #include "pkg_manager.h"
27 #include "pkg_manager_impl.h"
28 #include "pkg_utils.h"
29 #include "log.h"
30 #include "utils.h"
31
32 using Updater::InitUpdaterLogger;
33 using Hpackage::PkgManager;
34 using Hpackage::PkgManagerImpl;
35 using Hpackage::PkgStream;
36 using Hpackage::PkgAlgorithmFactory;
37 using Hpackage::DigestAlgorithm;
38 using Hpackage::ComponentInfo;
39 using Hpackage::FileInfo;
40 using Hpackage::ZipFileInfo;
41 using Hpackage::PkgInfo;
42
43 namespace OHOS {
44 const std::string TEST_PATH_FROM = "/data/updater/src/";
45 const std::string TEST_PATH_TO = "/data/updater/dst/";
46
GetFuzzPrivateKeyName(int type = 0)47 inline std::string GetFuzzPrivateKeyName(int type = 0)
48 {
49 std::string name = TEST_PATH_FROM;
50 if (type == PKG_DIGEST_TYPE_SHA384) {
51 name += "rsa_private_key384.pem";
52 } else {
53 name += "rsa_private_key2048.pem";
54 }
55 return name;
56 }
57
GetFuzzCertName(int type = 0)58 inline std::string GetFuzzCertName(int type = 0)
59 {
60 std::string name = TEST_PATH_FROM;
61 if (type == PKG_DIGEST_TYPE_SHA384) {
62 name += "signing_cert384.crt";
63 } else {
64 name += "signing_cert.crt";
65 }
66 return name;
67 }
68
69 class FuzzPkgTest {
70 public:
FuzzPkgTest()71 FuzzPkgTest()
72 {
73 pkgManager_ = static_cast<PkgManagerImpl*>(PkgManager::CreatePackageInstance());
74 }
~FuzzPkgTest()75 virtual ~FuzzPkgTest()
76 {
77 PkgManager::ReleasePackageInstance(pkgManager_);
78 pkgManager_ = nullptr;
79 }
80
81 protected:
SetUp()82 void SetUp()
83 {
84 InitUpdaterLogger("UPDATER ", "updater_log.log", "updater_status.log", "error_code.log");
85 // 先创建目标目录
86 if (access(TEST_PATH_TO.c_str(), R_OK | W_OK) == -1) {
87 mkdir(TEST_PATH_TO.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
88 }
89 }
TestBody()90 void TestBody() {}
TearDown()91 void TearDown() {}
92
BuildFileDigest(uint8_t &digest, size_t size, const std::string &pkgPath)93 int32_t BuildFileDigest(uint8_t &digest, size_t size, const std::string &pkgPath)
94 {
95 PkgManager::StreamPtr stream = nullptr;
96 int32_t ret = pkgManager_->CreatePkgStream(stream, pkgPath, 0, PkgStream::PkgStreamType_Read);
97 if (ret != 0) {
98 PKG_LOGE("Create input stream fail %s", pkgPath.c_str());
99 return ret;
100 }
101 size_t fileLength = stream->GetFileLength();
102 if (fileLength <= 0 || fileLength > SIZE_MAX) {
103 PKG_LOGE("Invalid file len %zu to load %s", fileLength, stream->GetFileName().c_str());
104 pkgManager_->ClosePkgStream(stream);
105 return -1;
106 }
107
108 size_t bufSize = 4096;
109 Hpackage::PkgBuffer buff(bufSize);
110 // 整包检查
111 DigestAlgorithm::DigestAlgorithmPtr alg =
112 PkgAlgorithmFactory::GetDigestAlgorithm(PKG_DIGEST_TYPE_SHA256);
113 if (alg == nullptr) {
114 PKG_LOGE("Invalid file %s", stream->GetFileName().c_str());
115 pkgManager_->ClosePkgStream(stream);
116 return -1;
117 }
118 alg->Init();
119
120 size_t offset = 0;
121 size_t readLen = 0;
122 while (offset < fileLength) {
123 ret = stream->Read(buff, offset, bufSize, readLen);
124 if (ret != 0) {
125 PKG_LOGE("read buffer fail %s", stream->GetFileName().c_str());
126 pkgManager_->ClosePkgStream(stream);
127 return ret;
128 }
129 alg->Update(buff, readLen);
130
131 offset += readLen;
132 readLen = 0;
133 }
134 Hpackage::PkgBuffer buffer(&digest, size);
135 alg->Final(buffer);
136 pkgManager_->ClosePkgStream(stream);
137 return 0;
138 }
139
ExtractFile(PkgManager::PkgManagerPtr manager, std::vector<std::string> components, size_t num)140 void ExtractFile(PkgManager::PkgManagerPtr manager, std::vector<std::string> components, size_t num)
141 {
142 PkgManager::StreamPtr outStream = nullptr;
143 PKG_LOGI("comp [%zu] file name: %s \r\n", num, (TEST_PATH_TO + components[num]).c_str());
144 manager->CreatePkgStream(outStream, TEST_PATH_TO + components[num], 0, PkgStream::PkgStreamType_Write);
145 if (outStream == nullptr) {
146 return;
147 }
148 (void)manager->ExtractFile(components[num], outStream);
149 manager->ClosePkgStream(outStream);
150 const FileInfo *info = manager->GetFileInfo(components[num]);
151 if (info->packMethod == PKG_COMPRESS_METHOD_NONE) {
152 const ComponentInfo* compInfo = (const ComponentInfo*)manager->GetFileInfo(components[num]);
153 if (compInfo != nullptr) {
154 PKG_LOGI("comp [%zu] componentAddr: %s \n", num, (*compInfo).fileInfo.identity.c_str());
155 PKG_LOGI("comp [%zu] version: %s \n", num, (*compInfo).version.c_str());
156 PKG_LOGI("comp [%zu] originalSize: %zu \n", num, (*compInfo).originalSize);
157 PKG_LOGI("comp [%zu] size: %zu \n", num, (*compInfo).fileInfo.unpackedSize);
158 PKG_LOGI("comp [%zu] id: %d \n", num, (*compInfo).id);
159 PKG_LOGI("comp [%zu] resType: %d \n", num, (*compInfo).resType);
160 PKG_LOGI("comp [%zu] flags: %d \n", num, (*compInfo).compFlags);
161 PKG_LOGI("comp [%zu] type: %d \n", num, (*compInfo).type);
162 }
163 } else {
164 PKG_LOGI("FileInfo [%zu] id: %s \n", num, info->identity.c_str());
165 PKG_LOGI("FileInfo [%zu] unpackedSize: %zu \n", num, info->unpackedSize);
166 PKG_LOGI("FileInfo [%zu] packedSize: %zu \n", num, info->packedSize);
167 PKG_LOGI("FileInfo [%zu] packMethod: %d \n", num, info->packMethod);
168 PKG_LOGI("FileInfo [%zu] digestMethod: %d \n", num, info->digestMethod);
169 PKG_LOGI("FileInfo [%zu] flags: %d \n", num, info->flags);
170 }
171 }
172
CreateZipPackage(const std::vector<std::string> &testNames, const std::string pkgName, const std::string &base, int digestMethod)173 int CreateZipPackage(const std::vector<std::string> &testNames,
174 const std::string pkgName, const std::string &base, int digestMethod)
175 {
176 PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
177 std::vector<std::pair<std::string, ZipFileInfo>> files;
178 // 构建要打包的zip文件
179 for (auto name : testNames) {
180 ZipFileInfo zipFile;
181 zipFile.fileInfo.identity = name;
182 zipFile.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
183 zipFile.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
184 std::string fileName = base + name;
185 files.push_back(std::pair<std::string, ZipFileInfo>(fileName, zipFile));
186 }
187
188 PkgInfo pkgInfo;
189 pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
190 pkgInfo.digestMethod = digestMethod;
191 pkgInfo.pkgType = PKG_PACK_TYPE_ZIP;
192 int32_t ret = pkgManager->CreatePackage(pkgName, GetFuzzPrivateKeyName(digestMethod), &pkgInfo, files);
193 PkgManager::ReleasePackageInstance(pkgManager);
194 return ret;
195 }
196 std::vector<std::string> testFileNames_ = {
197 "test_math.us",
198 "test_native.us",
199 "testscript.us",
200 "Verse-script.us",
201 "libcrypto.a",
202 "ggg.zip",
203 "loadScript.us",
204 "registerCmd.us",
205 "test_function.us",
206 "test_if.us",
207 "test_logic.us",
208 };
209 PkgManagerImpl* pkgManager_ = nullptr;
210 std::string testCombinePkgName = "test_CombinePackage.zip";
211 std::string testPackagePath = "/data/updater/package/";
212 std::string testPackageName = "test_package.bin";
213 std::string testZipPackageName = "test_package.zip";
214 std::string testLz4PackageName = "test_package.lz4";
215 std::string testGZipPackageName = "test_package.gz";
216 };
217 }
218 #endif // PKG_FUZZ_TEST
219