1/*
2 * Copyright (c) 2024-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 <cstdio>
20#include <fstream>
21#include <memory>
22#include <string>
23#include <filesystem>
24#include <gtest/gtest.h>
25
26#include "file_utils.h"
27#include "hap_signer_block_utils.h"
28#include "zip_entry.h"
29#include "zip_signer.h"
30#include "zip_utils.h"
31
32namespace OHOS {
33namespace SignatureTools {
34const std::string UNSIGNED_HAP_PATH = "./zip/unsigned.hap";
35const std::string SIGNED_HAP_PATH = "./zip/signed.hap";
36const std::string EMPTY_HAP_PATH = "./zip/empty.hap";
37const std::string DATA_DESCRIPTOR_HAP_PATH = "./zip/data_descriptor_hap.hap";
38const std::string EOCD_ONLY_HAP_PATH = "./zip/eocd_only.hap";
39const std::string DUMMY_HAP_PATH = "./zip/dummy.hap";
40const std::string ZIP_ENTRIES_WRONG_HAP_V1_PATH = "./zip/zip_entries_wrong_v1.hap";
41const std::string ZIP_ENTRIES_WRONG_HAP_V2_PATH = "./zip/zip_entries_wrong_v2.hap";
42const std::string ZIP_ENTRIES_WRONG_HAP_V3_PATH = "./zip/zip_entries_wrong_v3.hap";
43const std::string ZIP_ENTRIES_WRONG_HAP_V4_PATH = "./zip/zip_entries_wrong_v4.hap";
44const std::string ZIP_ENTRY_DATA_WRONG_HAP_PATH = "./zip/zip_entry_data_wrong.hap";
45const std::string CD_ONLY_HAP_V1_PATH = "./zip/cd_only_v1.hap";
46const std::string CD_ONLY_HAP_V2_PATH = "./zip/cd_only_v2.hap";
47const std::string OUTPUT_HAP_PATH = "./zip/output.hap";
48const std::string ZERO_HAP_PATH = "./zip/zero.hap";
49const static int ALIGNMENT = 4;
50class ZipSignerTest : public testing::Test {
51public:
52    static void SetUpTestCase(void);
53    static void TearDownTestCase(void);
54    void SetUp();
55    void TearDown();
56};
57
58void ZipSignerTest::SetUpTestCase(void)
59{
60    (void)rename("./zip/cd_only_v1.txt", CD_ONLY_HAP_V1_PATH.c_str());
61    (void)rename("./zip/cd_only_v2.txt", CD_ONLY_HAP_V2_PATH.c_str());
62    (void)rename("./zip/data_descriptor_hap.txt", DATA_DESCRIPTOR_HAP_PATH.c_str());
63    (void)rename("./zip/unsigned.txt", UNSIGNED_HAP_PATH.c_str());
64    (void)rename("./zip/signed.txt", SIGNED_HAP_PATH.c_str());
65    (void)rename("./zip/zip_entries_wrong_v1.txt", ZIP_ENTRIES_WRONG_HAP_V1_PATH.c_str());
66    (void)rename("./zip/zip_entries_wrong_v2.txt", ZIP_ENTRIES_WRONG_HAP_V2_PATH.c_str());
67    (void)rename("./zip/zip_entries_wrong_v3.txt", ZIP_ENTRIES_WRONG_HAP_V3_PATH.c_str());
68    (void)rename("./zip/zip_entries_wrong_v4.txt", ZIP_ENTRIES_WRONG_HAP_V4_PATH.c_str());
69    (void)rename("./zip/zip_entry_data_wrong.txt", ZIP_ENTRY_DATA_WRONG_HAP_PATH.c_str());
70    sync();
71}
72
73void ZipSignerTest::TearDownTestCase(void)
74{
75}
76
77void ZipSignerTest::SetUp()
78{
79}
80
81void ZipSignerTest::TearDown()
82{
83}
84
85/**
86 * @tc.name: Test ZipSigner Full process
87 * @tc.desc: Test function of ZipSigner interface for SUCCESS.
88 * @tc.type: FUNC
89 * @tc.require: SR000H63TL
90 */
91HWTEST_F(ZipSignerTest, FullProcessTest001, testing::ext::TestSize.Level1)
92{
93    /*
94     * @tc.steps: step1. test ZipSigner full process function
95     * @tc.expected: step1. use the unsigned hap file, the return will be true.
96     */
97    std::ifstream rawInput(UNSIGNED_HAP_PATH, std::ios::binary);
98    std::ofstream rawOutput(OUTPUT_HAP_PATH, std::ios::binary | std::ios::trunc | std::ios::out);
99    auto zip1 = std::make_shared<ZipSigner>();
100    ASSERT_TRUE(zip1->Init(rawInput));
101    zip1->Alignment(ALIGNMENT);
102    zip1->RemoveSignBlock();
103    ASSERT_TRUE(zip1->ToFile(rawInput, rawOutput));
104    rawOutput.close();
105    rawInput.close();
106
107    /*
108     * @tc.steps: step2. test ZipSigner full process function
109     * @tc.expected: step2. use the signed hap file, the return will be true.
110     */
111    std::ifstream wholeInput(SIGNED_HAP_PATH, std::ios::binary);
112    std::ofstream wholeOutput(OUTPUT_HAP_PATH, std::ios::binary | std::ios::trunc | std::ios::out);
113    auto zip2 = std::make_shared<ZipSigner>();
114    ASSERT_TRUE(zip2->Init(wholeInput));
115    zip2->Alignment(ALIGNMENT);
116    zip2->RemoveSignBlock();
117    ASSERT_TRUE(zip2->ToFile(wholeInput, wholeOutput));
118    wholeOutput.close();
119    wholeInput.close();
120
121    /*
122     * @tc.steps: step3. test ZipSigner full process function
123     * @tc.expected: step3. use the hap file with data descriptor, the return will be true.
124     */
125    std::ifstream dataDescInput(DATA_DESCRIPTOR_HAP_PATH, std::ios::binary);
126    std::ofstream dataDescOutput(OUTPUT_HAP_PATH, std::ios::binary | std::ios::trunc | std::ios::out);
127    auto zip3 = std::make_shared<ZipSigner>();
128    ASSERT_TRUE(zip3->Init(dataDescInput));
129    zip3->Alignment(ALIGNMENT);
130    zip3->RemoveSignBlock();
131    ASSERT_TRUE(zip3->ToFile(dataDescInput, dataDescOutput));
132    dataDescOutput.close();
133    dataDescInput.close();
134}
135
136/**
137 * @tc.name: Test ZipSigner Init Function
138 * @tc.desc: Test function of ZipSigner interface for SUCCESS and FAIL
139 * @tc.type: FUNC
140 * @tc.require: SR000H63TL
141 */
142HWTEST_F(ZipSignerTest, ZipSignerInitTest001, testing::ext::TestSize.Level1)
143{
144    /*
145     * @tc.steps: step1. test Init function
146     * @tc.expected: step1. make the hap file is not exist, the return will be false.
147     */
148    auto zip1 = std::make_shared<ZipSigner>();
149    std::ifstream dummyInput(DUMMY_HAP_PATH, std::ios::binary);
150    ASSERT_FALSE(zip1->Init(dummyInput));
151    /*
152     * @tc.steps: step2. test Init function
153     * @tc.expected: step2. make the hap file is empty, the return will be false.
154     */
155    std::ofstream emptyOuptut(EMPTY_HAP_PATH, std::ios::binary | std::ios::trunc | std::ios::out);
156    emptyOuptut << "";
157    emptyOuptut.close();
158    auto zip2 = std::make_shared<ZipSigner>();
159    std::ifstream emptyInput(EMPTY_HAP_PATH, std::ios::binary);
160    ASSERT_FALSE(zip2->Init(emptyInput));
161    emptyInput.close();
162
163    /*
164     * @tc.steps: step3. test Init function
165     * @tc.expected: step3. make the hap file is ONLY have the eocd block, the return will be false.
166     */
167    std::ofstream eocdOutput(EOCD_ONLY_HAP_PATH, std::ios::binary | std::ios::trunc | std::ios::out);
168    char eocd[] = {0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00,
169                    0x46, 0x02, 0x00, 0x00, 0x00, 0x00};
170    eocdOutput.write(eocd, sizeof(eocd) / sizeof(eocd[0]));
171    eocdOutput.close();
172    auto zip3 = std::make_shared<ZipSigner>();
173    std::ifstream eocdInput(EOCD_ONLY_HAP_PATH, std::ios::binary);
174    ASSERT_FALSE(zip3->Init(eocdInput));
175    eocdInput.close();
176}
177
178/**
179 * @tc.name: Test GetZipEntries Function
180 * @tc.desc: Test function of ZipSigner::GetZipEntries() interface for FAIL.
181 * @tc.type: FUNC
182 * @tc.require: SR000H63TL
183 */
184HWTEST_F(ZipSignerTest, GetZipEntriesTest001, testing::ext::TestSize.Level1)
185{
186    /*
187     * @tc.steps: step1. test GetZipEntries function
188     * @tc.expected: step1. make the cd offset int front of entry end, return will be false.
189     */
190    std::ifstream inputFile(ZIP_ENTRIES_WRONG_HAP_V3_PATH, std::ios::binary);
191    auto zip = std::make_shared<ZipSigner>();
192    ASSERT_FALSE(zip->Init(inputFile));
193}
194
195/**
196 * @tc.name: Test Alignment Function
197 * @tc.desc: Test function of ZipEntry::Alignment() interface.
198 * @tc.type: FUNC
199 * @tc.require: SR000H63TL
200 */
201HWTEST_F(ZipSignerTest, AlignmentTest001, testing::ext::TestSize.Level1)
202{
203    /*
204     * @tc.steps: step1. test Alignment function
205     * @tc.expected: step1. make the alignment is equal to 0, return will be equal to -1.
206     */
207    std::ifstream inputFile(SIGNED_HAP_PATH, std::ios::binary);
208    auto zip1 = std::make_shared<ZipSigner>();
209    ASSERT_TRUE(zip1->Init(inputFile));
210    auto zipEntries1 = zip1->GetZipEntries();
211    int zeroAlignment = 0;
212    for (const auto& zipEntry : zipEntries1) {
213        ASSERT_EQ(zipEntry->Alignment(zeroAlignment), -1);
214    }
215
216    /*
217     * @tc.steps: step2. test Alignment function
218     * @tc.expected: step2. make the alignment is equal to 4, return will be equal to 0.
219     */
220    auto zip2 = std::make_shared<ZipSigner>();
221    ASSERT_TRUE(zip2->Init(inputFile));
222    auto zipEntries2 = zip2->GetZipEntries();
223    for (const auto& zipEntry : zipEntries2) {
224        ASSERT_EQ(zipEntry->Alignment(ALIGNMENT), 0);
225    }
226
227    /*
228     * @tc.steps: step3. test Alignment function
229     * @tc.expected: step3. make the alignment is equal to 4, return will be equal to 1.
230     */
231    std::ifstream zipEntriesInput(ZIP_ENTRIES_WRONG_HAP_V4_PATH, std::ios::binary);
232    auto zip3 = std::make_shared<ZipSigner>();
233    ASSERT_TRUE(zip3->Init(zipEntriesInput));
234    auto zipEntries3 = zip3->GetZipEntries();
235    for (const auto& zipEntry : zipEntries3) {
236        ASSERT_EQ(zipEntry->Alignment(ALIGNMENT), 1);
237    }
238
239    zipEntriesInput.close();
240    inputFile.close();
241}
242
243/**
244 * @tc.name: Test GetCDOffset Function
245 * @tc.desc: Test function of ZipSigner::GetCDOffset() interface for SUCCESS.
246 * @tc.type: FUNC
247 * @tc.require: SR000H63TL
248 */
249HWTEST_F(ZipSignerTest, GetCDOffsetTest001, testing::ext::TestSize.Level1)
250{
251    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
252    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
253    bool res = zip->Init(inputFile);
254    uint64_t cdOffset = zip->GetCDOffset();
255    EXPECT_EQ(res && cdOffset != 0, true);
256}
257
258/**
259 * @tc.name: Test GetEOCDOffset Function
260 * @tc.desc: Test function of ZipSigner::GetEOCDOffset() interface for SUCCESS.
261 * @tc.type: FUNC
262 * @tc.require: SR000H63TL
263 */
264HWTEST_F(ZipSignerTest, GetEOCDOffsetTest001, testing::ext::TestSize.Level1)
265{
266    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
267    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
268    bool res = zip->Init(inputFile);
269    uint64_t eocdOffset = zip->GetEOCDOffset();
270    EXPECT_EQ(res && eocdOffset != 0, true);
271}
272
273/**
274 * @tc.name: Test ToFile Function
275 * @tc.desc: Test function of ZipSigner::ToFile() interface for SUCCESS.
276 * @tc.type: FUNC
277 * @tc.require: SR000H63TL
278 */
279HWTEST_F(ZipSignerTest, ToFileTest001, testing::ext::TestSize.Level1)
280{
281    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
282    std::ofstream outputFile(OUTPUT_HAP_PATH, std::ios::binary | std::ios::trunc);
283    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
284    bool initRes = zip->Init(inputFile);
285    bool toFileRes = zip->ToFile(inputFile, outputFile);
286    EXPECT_EQ(initRes && toFileRes, true);
287}
288
289/**
290 * @tc.name: Test ToFile Function
291 * @tc.desc: Test function of ZipSigner::ToFile() interface for FAIL.
292 * @tc.type: FUNC
293 * @tc.require: SR000H63TL
294 */
295HWTEST_F(ZipSignerTest, ToFileTest002, testing::ext::TestSize.Level1)
296{
297    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
298    /*
299     * @tc.steps: step1. test ToFile function
300     * @tc.expected: step1. make the output file stream is bad, return will be false.
301     */
302    std::ofstream outputFile("", std::ios::binary | std::ios::trunc);
303    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
304    bool initRes = zip->Init(inputFile);
305    bool toFileRes = zip->ToFile(inputFile, outputFile);
306    EXPECT_EQ(initRes && !toFileRes, true);
307}
308
309/**
310 * @tc.name: Test ToFile Function
311 * @tc.desc: Test function of ZipSigner::ToFile() interface for FAIL.
312 * @tc.type: FUNC
313 * @tc.require: SR000H63TL
314 */
315HWTEST_F(ZipSignerTest, ToFileTest003, testing::ext::TestSize.Level1)
316{
317    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
318    std::ofstream outputFile("", std::ios::binary | std::ios::trunc);
319    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
320    bool initRes = zip->Init(inputFile);
321    /*
322     * @tc.steps: step1. test ToFile function
323     * @tc.expected: step1. make the input file stream is bad, return will be false.
324     */
325    std::ifstream bad("", std::ios::binary);
326
327    bool toFileRes = zip->ToFile(bad, outputFile);
328    EXPECT_EQ(initRes && !toFileRes, true);
329}
330
331/**
332 * @tc.name: Test ToFile Function
333 * @tc.desc: Test function of ZipSigner::ToFile() interface for SUCCESS.
334 * @tc.type: FUNC
335 * @tc.require: SR000H63TL
336 */
337HWTEST_F(ZipSignerTest, ToFileTest004, testing::ext::TestSize.Level1)
338{
339    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
340    std::ofstream outputFile(OUTPUT_HAP_PATH, std::ios::binary | std::ios::trunc);
341    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
342    ASSERT_TRUE(zip->Init(inputFile));
343    ASSERT_TRUE(zip->ToFile(inputFile, outputFile));
344}
345
346/*
347 * @tc.name: Alignment_Test_001
348 * @tc.desc: Test function of ZipEntry::Alignment() interface for SUCCESS.
349 * @tc.type: FUNC
350 * @tc.require: SR000H63TL
351 */
352HWTEST_F(ZipSignerTest, ZipEntryAlignmentTest001, testing::ext::TestSize.Level1)
353{
354    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
355    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
356    bool res = zip->Init(inputFile);
357    std::vector<ZipEntry*> zipEntries = zip->GetZipEntries();
358    int alignment = 4;
359    for (auto& zipEntry : zipEntries) {
360        int add = zipEntry->Alignment(alignment);
361        EXPECT_EQ(res && add > 0, true);
362    }
363}
364
365/**
366 * @tc.name: Test GetEOCDByBytes Function
367 * @tc.desc: Test function of EndOfCentralDirectory::GetEOCDByBytes() interface for SUCCESS.
368 * @tc.type: FUNC
369 * @tc.require: SR000H63TL
370 */
371HWTEST_F(ZipSignerTest, EndOfCentralDirectoryGetEOCDByBytesTest001, testing::ext::TestSize.Level1)
372{
373    std::ifstream input(UNSIGNED_HAP_PATH, std::ios::binary);
374    input.seekg(0, std::ios::end);
375    uint64_t fileSize = input.tellg();
376    input.seekg(0, std::ios::beg);
377
378    int eocdLength = EndOfCentralDirectory::EOCD_LENGTH;
379    uint64_t eocdOffset = reinterpret_cast<uint64_t>(fileSize - eocdLength);
380
381    std::string retStr;
382    int res = FileUtils::ReadFileByOffsetAndLength(input, eocdOffset, eocdLength, retStr);
383    std::optional<EndOfCentralDirectory*> eocdByBytes = EndOfCentralDirectory::GetEOCDByBytes(retStr);
384    EXPECT_EQ(res == 0 && eocdByBytes != std::nullopt, true);
385}
386
387/**
388 * @tc.name: Test GetEOCDByBytes Function
389 * @tc.desc: Test function of EndOfCentralDirectory::GetEOCDByBytes() interface for FAIL.
390 * @tc.type: FUNC
391 * @tc.require: SR000H63TL
392 */
393HWTEST_F(ZipSignerTest, EndOfCentralDirectoryGetEOCDByBytesTest002, testing::ext::TestSize.Level1)
394{
395    /*
396     * @tc.steps: step1. test GetEOCDByBytes function
397     * @tc.expected: step1. make the eocd bytes is empty, the return will be nullopt.
398     */
399    std::string str;
400    std::optional<EndOfCentralDirectory*> eocdByBytes = EndOfCentralDirectory::GetEOCDByBytes(str);
401    EXPECT_EQ(eocdByBytes == std::nullopt, true);
402}
403
404/**
405 * @tc.name: Test GetEOCDByBytes Function
406 * @tc.desc: Test function of EndOfCentralDirectory::GetEOCDByBytes() interface for FAIL.
407 * @tc.type: FUNC
408 * @tc.require: SR000H63TL
409 */
410HWTEST_F(ZipSignerTest, EndOfCentralDirectoryGetEOCDByBytesTest003, testing::ext::TestSize.Level1)
411{
412    /*
413     * @tc.steps: step1. test GetEOCDByBytes function
414     * @tc.expected: step1. make the eocd bytes is all of zero, the return will be nullopt.
415     */
416    std::string bytes(22, 0);
417    std::optional<EndOfCentralDirectory*> eocdByBytes = EndOfCentralDirectory::GetEOCDByBytes(bytes);
418    EXPECT_EQ(eocdByBytes == std::nullopt, true);
419}
420
421/**
422 * @tc.name: Test GetEOCDByBytes Function
423 * @tc.desc: Test function of EndOfCentralDirectory::GetEOCDByBytes() interface for FAIL with eocd length is wrong
424 * @tc.type: FUNC
425 * @tc.require: SR000H63TL
426 */
427HWTEST_F(ZipSignerTest, EndOfCentralDirectoryGetEOCDByBytesTest004, testing::ext::TestSize.Level1)
428{
429    std::string bytes{
430        80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
431    };
432    std::optional<EndOfCentralDirectory*> eocdByBytes = EndOfCentralDirectory::GetEOCDByBytes(bytes);
433    EXPECT_EQ(eocdByBytes == std::nullopt, true);
434}
435
436/**
437 * @tc.name: Test GetEOCDByBytes Function
438 * @tc.desc: Test function of EndOfCentralDirectory::GetEOCDByBytes() interface for SUCCESS with comment.
439 * @tc.type: FUNC
440 * @tc.require: SR000H63TL
441 */
442HWTEST_F(ZipSignerTest, EndOfCentralDirectoryGetEOCDByBytesTest005, testing::ext::TestSize.Level1)
443{
444    std::string bytes{
445        80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1
446    };
447    std::optional<EndOfCentralDirectory*> eocdByBytes = EndOfCentralDirectory::GetEOCDByBytes(bytes);
448    EXPECT_EQ(eocdByBytes != std::nullopt, true);
449    std::string eocdBytes = eocdByBytes.value()->ToBytes();
450    EXPECT_EQ(eocdBytes.size() > 0, true);
451}
452
453/**
454 * @tc.name: Test GetEOCDByBytes Function
455 * @tc.desc: Test function of EndOfCentralDirectory::SetComment() interface.
456 * @tc.type: FUNC
457 * @tc.require: SR000H63TL
458 */
459HWTEST_F(ZipSignerTest, EndOfCentralDirectorySetCommentTest001, testing::ext::TestSize.Level1)
460{
461    std::string bytes{
462        80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
463    };
464    std::optional<EndOfCentralDirectory*> eocdByBytes = EndOfCentralDirectory::GetEOCDByBytes(bytes);
465    std::string comment{1};
466    eocdByBytes.value()->SetComment(comment);
467    EXPECT_EQ(eocdByBytes != std::nullopt, true);
468}
469
470/**
471 * @tc.name: Test ToBytes Function
472 * @tc.desc: Test function of EndOfCentralDirectory::ToBytes() interface for SUCCESS.
473 * @tc.type: FUNC
474 * @tc.require: SR000H63TL
475 */
476HWTEST_F(ZipSignerTest, EndOfCentralDirectoryToBytesTest001, testing::ext::TestSize.Level1)
477{
478    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
479    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
480    bool initRes = zip->Init(inputFile);
481    EndOfCentralDirectory* eocd = zip->GetEndOfCentralDirectory();
482    std::string eocdBytes = eocd->ToBytes();
483    int signature = eocd->GetSIGNATURE();
484    int diskNum = eocd->GetDiskNum();
485    std::string comment = eocd->GetComment();
486    EXPECT_EQ(initRes && eocd && eocdBytes.size() > 0 && signature != -1 && comment.size() == 0 && diskNum != -1,
487              true);
488}
489
490/**
491 * @tc.name: Test EndOfCentralDirectory Class
492 * @tc.desc: Test function of EndOfCentralDirectory interface for SUCCESS.
493 * @tc.type: FUNC
494 * @tc.require: SR000H63TL
495 */
496HWTEST_F(ZipSignerTest, EndOfCentralDirectoryTest001, testing::ext::TestSize.Level1)
497{
498    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
499    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
500    bool initRes = zip->Init(inputFile);
501    EndOfCentralDirectory* eocd = zip->GetEndOfCentralDirectory();
502    int eocdLength = eocd->GetEocdLength();
503    int cdStartDiskNum = eocd->GetcDStartDiskNum();
504    int diskCDNum = eocd->GetThisDiskCDNum();
505    int eocdLen = eocd->GetLength();
506    EXPECT_EQ(initRes && eocd && eocdLength > 0 && cdStartDiskNum != -1 && diskCDNum != -1 && eocdLen != -1,
507              true);
508}
509
510/**
511 * @tc.name: Test SetCentralDirectoryOffset Function
512 * @tc.desc: Test function of ZipUtils::SetCentralDirectoryOffset() interface for SUCCESS.
513 * @tc.type: FUNC
514 * @tc.require: SR000H63TL
515 */
516HWTEST_F(ZipSignerTest, ZipUtilsSetCentralDirectoryOffsetTest001, testing::ext::TestSize.Level1)
517{
518    std::shared_ptr<RandomAccessFile> outputHap = std::make_shared<RandomAccessFile>();
519    EXPECT_EQ(outputHap->Init(UNSIGNED_HAP_PATH), true);
520    std::pair<ByteBuffer, int64_t> eocdPair;
521    EXPECT_EQ(HapSignerBlockUtils::FindEocdInHap(*outputHap, eocdPair), true);
522    int64_t centralDirectoryOffset;
523    EXPECT_EQ(HapSignerBlockUtils::GetCentralDirectoryOffset(eocdPair.first, eocdPair.second,
524                                                             centralDirectoryOffset),
525              true);
526    int64_t newCentralDirOffset = centralDirectoryOffset + 10;
527    eocdPair.first.SetPosition(0);
528    EXPECT_EQ(ZipUtils::SetCentralDirectoryOffset(eocdPair.first, newCentralDirOffset), true);
529}
530
531/**
532 * @tc.name: Test SetCentralDirectoryOffset Function
533 * @tc.desc: Test function of ZipUtils::SetCentralDirectoryOffset() interface.
534 * @tc.type: FUNC
535 * @tc.require: SR000H63TL
536 */
537HWTEST_F(ZipSignerTest, ZipUtilsSetCentralDirectoryOffsetTest002, testing::ext::TestSize.Level1)
538{
539    std::shared_ptr<RandomAccessFile> outputHap = std::make_shared<RandomAccessFile>();
540    EXPECT_EQ(outputHap->Init(UNSIGNED_HAP_PATH), true);
541    std::pair<ByteBuffer, int64_t> eocdPair;
542    EXPECT_EQ(HapSignerBlockUtils::FindEocdInHap(*outputHap, eocdPair), true);
543    eocdPair.first.SetPosition(0);
544    /*
545     * @tc.steps: step1. test SetCentralDirectoryOffset function
546     * @tc.expected: step1. make the central directory offset is -1, the return will be false.
547     */
548    EXPECT_EQ(ZipUtils::SetCentralDirectoryOffset(eocdPair.first, -1), false);
549}
550
551/**
552 * @tc.name: Test SetCentralDirectoryOffset Function
553 * @tc.desc: Test function of ZipUtils::SetCentralDirectoryOffset() interface for FAIL.
554 * @tc.type: FUNC
555 * @tc.require: SR000H63TL
556 */
557HWTEST_F(ZipSignerTest, ZipUtilsSetCentralDirectoryOffsetTest003, testing::ext::TestSize.Level1)
558{
559    std::shared_ptr<RandomAccessFile> outputHap = std::make_shared<RandomAccessFile>();
560    ASSERT_TRUE(outputHap->Init(UNSIGNED_HAP_PATH));
561    std::pair<ByteBuffer, int64_t> eocdPair;
562    ASSERT_TRUE(HapSignerBlockUtils::FindEocdInHap(*outputHap, eocdPair));
563    eocdPair.first.SetPosition(0);
564    /*
565     * @tc.steps: step1. test SetCentralDirectoryOffset function
566     * @tc.expected: step1. make the central directory offset is 0x100000000LL, it's greater than 0xffffffffLL,
567     * the return will be false.
568     */
569    ASSERT_FALSE(ZipUtils::SetCentralDirectoryOffset(eocdPair.first, 0x100000000LL));
570}
571
572/**
573 * @tc.name: Test ZipEntryHeader Class
574 * @tc.desc: Test function of ZipEntryHeader for SUCCESS.
575 * @tc.type: FUNC
576 * @tc.require: SR000H63TL
577 */
578HWTEST_F(ZipSignerTest, ZipEntryHeaderTest001, testing::ext::TestSize.Level1)
579{
580    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
581    auto zip = std::make_shared<ZipSigner>();
582    ASSERT_TRUE(zip->Init(inputFile));
583
584    auto zipEntries = zip->GetZipEntries();
585    ASSERT_NE(zipEntries.size(), 0);
586
587    for (const auto& zipEntry : zipEntries) {
588        auto zipEntryData = zipEntry->GetZipEntryData();
589        ASSERT_NE(zipEntryData, nullptr);
590
591        int crc32 = zipEntryData->GetZipEntryHeader()->GetCrc32();
592        ASSERT_NE(crc32, -1);
593        short lastTime = zipEntryData->GetZipEntryHeader()->GetLastTime();
594        ASSERT_NE(lastTime, -1);
595        short lastData = zipEntryData->GetZipEntryHeader()->GetLastDate();
596        ASSERT_NE(lastData, -1);
597        int64_t compressedSize = zipEntryData->GetZipEntryHeader()->GetCompressedSize();
598        ASSERT_NE(compressedSize, -1);
599        int64_t unCompressedSize = zipEntryData->GetZipEntryHeader()->GetUnCompressedSize();
600        ASSERT_NE(unCompressedSize, -1);
601        int headerLength = zipEntryData->GetZipEntryHeader()->GetHeaderLength();
602        ASSERT_NE(headerLength, -1);
603        int signature = zipEntryData->GetZipEntryHeader()->GetSIGNATURE();
604        ASSERT_NE(signature, -1);
605        short version = zipEntryData->GetZipEntryHeader()->GetVersion();
606        ASSERT_NE(version, -1);
607        zipEntryData->GetZipEntryHeader()->SetFileName("");
608    }
609}
610
611/**
612 * @tc.name: Test ZipEntryHeader Class
613 * @tc.desc: Test function ToBytes of ZipEntryHeader for FAIL.
614 * @tc.type: FUNC
615 * @tc.require: SR000H63TL
616 */
617HWTEST_F(ZipSignerTest, ZipEntryHeaderTest002, testing::ext::TestSize.Level1)
618{
619    /*
620     * @tc.steps: step1. test ReadFileName and ReadExtra function
621     * @tc.expected: step1. make the file name and extra is empty, the return will be 0.
622     */
623    ZipEntryHeader zipEntryHeader;
624    zipEntryHeader.ReadFileName("");
625    zipEntryHeader.ReadExtra("");
626    std::string bytes = zipEntryHeader.ToBytes();
627    ASSERT_EQ(bytes.size(), 0);
628}
629
630/**
631 * @tc.name: Test DataDescriptor Class
632 * @tc.desc: Test function of DataDescriptor for SUCCESS.
633 * @tc.type: FUNC
634 * @tc.require: SR000H63TL
635 */
636HWTEST_F(ZipSignerTest, DataDescriptorTest001, testing::ext::TestSize.Level1)
637{
638    std::ifstream inputFile(DATA_DESCRIPTOR_HAP_PATH, std::ios::binary);
639    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
640    bool zipRes = zip->Init(inputFile);
641    std::vector<ZipEntry*> zipEntries = zip->GetZipEntries();
642    EXPECT_EQ(zipRes && zipEntries.size() > 0, true);
643    for (const auto& zipEntry : zipEntries) {
644        ZipEntryData* zipEntryData = zipEntry->GetZipEntryData();
645        DataDescriptor* dataDescriptor = zipEntryData->GetDataDescriptor();
646        if (dataDescriptor) {
647            uint64_t compressedSize = dataDescriptor->GetCompressedSize();
648            uint64_t unCompressedSize = dataDescriptor->GetUnCompressedSize();
649            int crc32 = dataDescriptor->GetCrc32();
650            int signature = dataDescriptor->GetSIGNATURE();
651            int desLength = dataDescriptor->GetDesLength();
652            EXPECT_EQ(zipEntryData != nullptr && dataDescriptor != nullptr && compressedSize != -1 &&
653                      unCompressedSize != -1 && crc32 != -1 && signature != -1 && desLength != -1, true);
654        } else {
655            EXPECT_EQ(dataDescriptor == nullptr, true);
656        }
657    }
658}
659
660/**
661 * @tc.name: Test DataDescriptor Class
662 * @tc.desc: Test function of GetDataDescriptor for FAIL.
663 * @tc.type: FUNC
664 * @tc.require: SR000H63TL
665 */
666HWTEST_F(ZipSignerTest, GetDataDescriptorTest001, testing::ext::TestSize.Level1)
667{
668    /*
669     * @tc.steps: step1. test GetDataDescriptor and GetDataDescriptor function
670     * @tc.expected: step1. make the data descriptor is error, the return will be nullptr.
671     */
672    std::string bytes1{1};
673    ASSERT_EQ(DataDescriptor::GetDataDescriptor(bytes1), nullptr);
674
675    std::string bytes2(16, 0);
676    ASSERT_EQ(DataDescriptor::GetDataDescriptor(bytes2), nullptr);
677}
678
679/**
680 * @tc.name: Test CentralDirectory Class
681 * @tc.desc: Test function of CentralDirectory for SUCCESS.
682 * @tc.type: FUNC
683 * @tc.require: SR000H63TL
684 */
685HWTEST_F(ZipSignerTest, CentralDirectoryTest001, testing::ext::TestSize.Level1)
686{
687    std::ifstream inputFile(UNSIGNED_HAP_PATH, std::ios::binary);
688    std::shared_ptr<ZipSigner> zip = std::make_shared<ZipSigner>();
689    bool zipRes = zip->Init(inputFile);
690    std::vector<ZipEntry*> zipEntries = zip->GetZipEntries();
691    EXPECT_EQ(zipRes && zipEntries.size() > 0, true);
692    CentralDirectory* cd = zipEntries[0]->GetCentralDirectory();
693    int cdLength = cd->GetCdLength();
694    int signature = cd->GetSIGNATURE();
695    short flag = cd->GetFlag();
696    short lastTime = cd->GetLastTime();
697    short lastDate = cd->GetLastDate();
698    int crc32 = cd->GetCrc32();
699    std::string fileName = cd->GetFileName();
700    short version = cd->GetVersion();
701    short versionExtra = cd->GetVersionExtra();
702    int diskNumStart = cd->GetDiskNumStart();
703    short internalFile = cd->GetInternalFile();
704    int externalFile = cd->GetExternalFile();
705    std::string comment = cd->GetComment();
706    EXPECT_EQ(cd != nullptr && cdLength != -1 && signature != -1 && flag != -1 && lastTime != -1 && lastDate != -1 &&
707              crc32 != -1 && fileName.size() > 0 && version != -1 && versionExtra != -1 && diskNumStart != -1 &&
708              internalFile != -1 && externalFile != -1 && comment.size() == 0, true);
709}
710
711/**
712 * @tc.name: Test CentralDirectory Class
713 * @tc.desc: Test function of CentralDirectory for FAIL.
714 * @tc.type: FUNC
715 * @tc.require: SR000H63TL
716 */
717HWTEST_F(ZipSignerTest, CentralDirectoryTest002, testing::ext::TestSize.Level1)
718{
719    /*
720     * @tc.steps: step1. test GetCentralDirectory function
721     * @tc.expected: step1. make the central directory is error, the return will be nullptr.
722     */
723    ByteBuffer bf(1);
724    CentralDirectory* cd = new CentralDirectory();
725    EXPECT_EQ(CentralDirectory::GetCentralDirectory(bf, cd), false);
726    delete cd;
727}
728
729/**
730 * @tc.name: Test CentralDirectory Class
731 * @tc.desc: Test function of CentralDirectory for SUCCESS with comment.
732 * @tc.type: FUNC
733 * @tc.require: SR000H63TL
734 */
735HWTEST_F(ZipSignerTest, CentralDirectoryTest003, testing::ext::TestSize.Level1)
736{
737    std::string str;
738    EXPECT_EQ(FileUtils::ReadFile(CD_ONLY_HAP_V1_PATH, str) == 0, true);
739    ByteBuffer bf(str.c_str(), str.size());
740    CentralDirectory* cd = new CentralDirectory();
741    EXPECT_EQ(CentralDirectory::GetCentralDirectory(bf, cd), true);
742    std::string cdBytes = cd->ToBytes();
743    EXPECT_EQ(cdBytes.size() > 0, true);
744}
745
746/**
747 * @tc.name: Test CentralDirectory Class
748 * @tc.desc: Test function of CentralDirectory for SUCCESS without fileNameLength.
749 * @tc.type: FUNC
750 * @tc.require: SR000H63TL
751 */
752HWTEST_F(ZipSignerTest, CentralDirectoryTest004, testing::ext::TestSize.Level1)
753{
754    std::string str;
755    EXPECT_EQ(FileUtils::ReadFile(CD_ONLY_HAP_V2_PATH, str) == 0, true);
756    ByteBuffer bf(str.c_str(), str.size());
757    CentralDirectory* cd = new CentralDirectory();
758    EXPECT_EQ(CentralDirectory::GetCentralDirectory(bf, cd), true);
759    std::string cdBytes = cd->ToBytes();
760    EXPECT_EQ(cdBytes.size() > 0, true);
761}
762
763/**
764 * @tc.name: Test ZipEntryHeader Class
765 * @tc.desc: Test function of GetZipEntryHeader for SUCCESS.
766 * @tc.type: FUNC
767 * @tc.require: SR000H63TL
768 */
769HWTEST_F(ZipSignerTest, GetZipEntryHeaderTest001, testing::ext::TestSize.Level1)
770{
771    std::string headBytes{1};
772    ZipEntryHeader* entryHeader = ZipEntryHeader::GetZipEntryHeader(headBytes);
773    EXPECT_EQ(entryHeader == nullptr, true);
774    delete entryHeader;
775}
776
777/**
778 * @tc.name: Test ZipEntryData Class
779 * @tc.desc: Test function of GetZipEntry for FAIL.
780 * @tc.type: FUNC
781 * @tc.require: SR000H63TL
782 */
783HWTEST_F(ZipSignerTest, GetZipEntryTest001, testing::ext::TestSize.Level1)
784{
785    std::ofstream zeroOutput(ZERO_HAP_PATH, std::ios::binary | std::ios::trunc | std::ios::out);
786    std::string zeros(1024, 0x00);
787    zeroOutput.write(zeros.c_str(), zeros.size());
788    zeroOutput.close();
789
790    std::ifstream inputFile(ZERO_HAP_PATH, std::ios::binary);
791    ZipEntryData* zipEntryData = ZipEntryData::GetZipEntry(inputFile, 0, 1024);
792    EXPECT_EQ(zipEntryData == nullptr, true);
793}
794
795/**
796 * @tc.name: Test ZipEntryData Class
797 * @tc.desc: Test function of GetZipEntry for success.
798 * @tc.type: FUNC
799 * @tc.require: SR000H63TL
800 */
801HWTEST_F(ZipSignerTest, GetZipEntryTest002, testing::ext::TestSize.Level1)
802{
803    /*
804     * @tc.steps: step1. test ZipEntryData::ReadEntryFileNameAndExtraByOffset function
805     * @tc.expected: step1. FileNameLength and ExtraLength is zero
806     */
807    std::ifstream inputFile(ZIP_ENTRY_DATA_WRONG_HAP_PATH, std::ios::binary);
808    ZipEntryData* zipEntryData = ZipEntryData::GetZipEntry(inputFile, 0, 1024);
809    ASSERT_EQ(zipEntryData != nullptr, true);
810}
811
812/**
813 * @tc.name: Test ZipSigner Class
814 * @tc.desc: Test ZipSigner interfaces for SUCCESS.
815 * @tc.type: FUNC
816 * @tc.require: SR000H63TL
817 */
818HWTEST_F(ZipSignerTest, ZipSignerTest001, testing::ext::TestSize.Level1)
819{
820    ZipSigner zip;
821    std::ifstream ifs(ZIP_ENTRIES_WRONG_HAP_V2_PATH, std::ios::binary);
822    ASSERT_TRUE(zip.Init(ifs));
823    std::vector<ZipEntry*> zipEntries{nullptr};
824    zip.SetZipEntries(zipEntries);
825    zip.SetSigningOffset(1);
826    int64_t offset = zip.GetSigningOffset();
827    EXPECT_EQ(offset, 1);
828    std::string signingBlock{0x1, 0x1, 0x1, 0x1, 0x1};
829    zip.SetSigningBlock(signingBlock);
830    signingBlock = zip.GetSigningBlock();
831    EXPECT_NE(signingBlock.size(), 0);
832    zip.SetCDOffset(1);
833    zip.SetEOCDOffset(1);
834    zip.SetEndOfCentralDirectory(nullptr);
835}
836} // namespace SignatureTools
837} // namespace OHOS