1 /*
2  * Copyright (c) 2024 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 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <unistd.h>
19 #include <cstddef>
20 #include <cstdint>
21 #include <cstdio>
22 
23 #include "zip_signer.h"
24 
25 namespace OHOS {
26 namespace SignatureTools {
27 static constexpr int ALIGNMENT = 4;
28 const char* UNSIGNED_HAP_FILE_PATH = "./zip/unsigned.hap";
29 const char* SIGNED_HAP_FILE_PATH = "./zip/signed.hap";
30 const char* OUT_HAP_FILE_PATH = "./zip/output.hap";
31 const char* DATA_DESC_HAP_FILE_PATH = "./zip/data_descriptor_hap.hap";
32 
ZipSignerCompleteFlowFunc(const uint8_t* data, size_t size)33 void ZipSignerCompleteFlowFunc(const uint8_t* data, size_t size)
34 {
35     std::ifstream inputFile(SIGNED_HAP_FILE_PATH, std::ios::binary);
36     std::ofstream outputFile(OUT_HAP_FILE_PATH, std::ios::binary | std::ios::trunc);
37     auto zip = std::make_shared<ZipSigner>();
38     if (!zip->Init(inputFile)) {
39         return;
40     }
41     zip->Alignment(ALIGNMENT);
42     zip->RemoveSignBlock();
43     zip->ToFile(inputFile, outputFile);
44 }
45 
ZipSignerInfoFunc(const uint8_t* data, size_t size)46 void ZipSignerInfoFunc(const uint8_t* data, size_t size)
47 {
48     std::ifstream inputFile(SIGNED_HAP_FILE_PATH, std::ios::binary);
49     auto zip = std::make_shared<ZipSigner>();
50     if (!zip->Init(inputFile)) {
51         return;
52     }
53     std::vector<ZipEntry*> zipEntries{nullptr};
54     zip->SetZipEntries(zipEntries);
55     zip->SetSigningOffset(size);
56     std::string signingBlock(reinterpret_cast<const char*>(data), size);
57     zip->SetSigningBlock(signingBlock);
58     zip->SetCDOffset(size);
59     zip->SetEOCDOffset(size);
60     zip->SetEndOfCentralDirectory(nullptr);
61 
62     zip->GetZipEntries();
63     zip->GetSigningOffset();
64     zip->GetSigningBlock();
65     zip->GetCDOffset();
66     zip->GetEOCDOffset();
67     zip->GetEndOfCentralDirectory();
68 }
69 
ZipEntryHeaderInfoFunc(const uint8_t* data, size_t size)70 void ZipEntryHeaderInfoFunc(const uint8_t* data, size_t size)
71 {
72     std::ifstream inputFile(SIGNED_HAP_FILE_PATH, std::ios::binary);
73     auto zip = std::make_shared<ZipSigner>();
74     if (!zip->Init(inputFile)) {
75         return;
76     }
77     auto zipEntries = zip->GetZipEntries();
78     for (const auto& zipEntry : zipEntries) {
79         auto zipEntryData = zipEntry->GetZipEntryData();
80         auto zipEntryHeader = zipEntryData->GetZipEntryHeader();
81 
82         std::string fileName(reinterpret_cast<const char*>(data), size);
83         zipEntryHeader->SetFileName(fileName);
84 
85         zipEntryHeader->GetCrc32();
86         zipEntryHeader->GetLastTime();
87         zipEntryHeader->GetLastDate();
88         zipEntryHeader->GetCompressedSize();
89         zipEntryHeader->GetUnCompressedSize();
90         zipEntryHeader->GetHeaderLength();
91         zipEntryHeader->GetSIGNATURE();
92         zipEntryHeader->GetVersion();
93     }
94 }
95 
CentralDirectoryInfoFunc(const uint8_t* data, size_t size)96 void CentralDirectoryInfoFunc(const uint8_t* data, size_t size)
97 {
98     std::ifstream inputFile(UNSIGNED_HAP_FILE_PATH, std::ios::binary);
99     auto zip = std::make_shared<ZipSigner>();
100     if (!zip->Init(inputFile)) {
101         return;
102     }
103     auto zipEntries = zip->GetZipEntries();
104     for (const auto& zipEntry : zipEntries) {
105         auto cd = zipEntry->GetCentralDirectory();
106         cd->GetLength();
107         cd->GetCdLength();
108         cd->GetSIGNATURE();
109         cd->GetVersion();
110         cd->GetVersionExtra();
111         cd->GetFlag();
112         cd->GetLastTime();
113         cd->GetLastDate();
114         cd->GetCrc32();
115         cd->GetDiskNumStart();
116         cd->GetInternalFile();
117         cd->GetExternalFile();
118         cd->GetFileName();
119 
120         std::string comment(reinterpret_cast<const char*>(data), size);
121         cd->SetComment(comment);
122 
123         cd->GetComment();
124     }
125 }
126 
DataDescriptorInfoFunc(const uint8_t* data, size_t size)127 void DataDescriptorInfoFunc(const uint8_t* data, size_t size)
128 {
129     std::ifstream inputFile(DATA_DESC_HAP_FILE_PATH, std::ios::binary);
130     auto zip = std::make_shared<ZipSigner>();
131     if (!zip->Init(inputFile)) {
132         return;
133     }
134     auto zipEntries = zip->GetZipEntries();
135     for (const auto& zipEntry : zipEntries) {
136         auto zipEntryData = zipEntry->GetZipEntryData();
137         auto dataDescriptor = zipEntryData->GetDataDescriptor();
138         if (!dataDescriptor) {
139             continue;
140         }
141         dataDescriptor->GetDesLength();
142         dataDescriptor->GetSIGNATURE();
143         dataDescriptor->GetCrc32();
144         dataDescriptor->GetCompressedSize();
145         dataDescriptor->GetUnCompressedSize();
146     }
147 }
148 
AlignmentFunc(const uint8_t* data, size_t size)149 void AlignmentFunc(const uint8_t* data, size_t size)
150 {
151     std::ifstream inputFile(UNSIGNED_HAP_FILE_PATH, std::ios::binary);
152     auto zip = std::make_shared<ZipSigner>();
153     int aliBytes = 102400;
154     if (!zip->Init(inputFile)) {
155         return;
156     }
157     auto zipEntries = zip->GetZipEntries();
158     for (const auto& zipEntry : zipEntries) {
159         zipEntry->Alignment(aliBytes);
160     }
161 }
162 
EndOfCentralDirectoryInfoFunc(const uint8_t* data, size_t size)163 void EndOfCentralDirectoryInfoFunc(const uint8_t* data, size_t size)
164 {
165     std::ifstream inputFile(UNSIGNED_HAP_FILE_PATH, std::ios::binary);
166     auto zip = std::make_shared<ZipSigner>();
167     if (!zip->Init(inputFile)) {
168         return;
169     }
170     auto eocd = zip->GetEndOfCentralDirectory();
171     eocd->GetLength();
172     eocd->GetEocdLength();
173     eocd->GetSIGNATURE();
174     eocd->GetDiskNum();
175     eocd->GetcDStartDiskNum();
176     eocd->GetThisDiskCDNum();
177 
178     std::string comment(reinterpret_cast<const char*>(data), size);
179     eocd->SetComment(comment);
180 
181     eocd->GetComment();
182 }
183 
DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)184 void DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
185 {
186     if (data == nullptr || size == 0) {
187         return;
188     }
189 
190     ZipSignerCompleteFlowFunc(data, size);
191     ZipSignerInfoFunc(data, size);
192     ZipEntryHeaderInfoFunc(data, size);
193     CentralDirectoryInfoFunc(data, size);
194     DataDescriptorInfoFunc(data, size);
195     AlignmentFunc(data, size);
196     EndOfCentralDirectoryInfoFunc(data, size);
197 }
198 } // namespace SignatureTools
199 } // namespace OHOS
200 
201 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)202 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
203 {
204     /* Run your code on data */
205     (void)rename("./zip/data_descriptor_hap.txt", OHOS::SignatureTools::DATA_DESC_HAP_FILE_PATH);
206     (void)rename("./zip/unsigned.txt", OHOS::SignatureTools::UNSIGNED_HAP_FILE_PATH);
207     (void)rename("./zip/signed.txt", OHOS::SignatureTools::SIGNED_HAP_FILE_PATH);
208     sync();
209     OHOS::SignatureTools::DoSomethingInterestingWithMyAPI(data, size);
210     return 0;
211 }