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 
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 
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