1 /*
2  * Copyright (c) 2022 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 <cstring>
17 #include <fcntl.h>
18 #include <gtest/gtest.h>
19 #include <iostream>
20 #include <unistd.h>
21 #include "log.h"
22 #include "pkg_algorithm.h"
23 #include "pkg_manager.h"
24 #include "pkg_manager_impl.h"
25 #include "pkg_test.h"
26 #include "pkg_utils.h"
27 
28 #include "package.h"
29 #include "cert_verify.h"
30 #include "hash_data_verifier.h"
31 #include "openssl_util.h"
32 #include "pkg_verify_util.h"
33 #include "zip_pkg_parse.h"
34 #include "pkcs7_signed_data.h"
35 
36 using namespace std;
37 using namespace Hpackage;
38 using namespace Updater;
39 using namespace testing::ext;
40 
41 namespace UpdaterUt {
42 class PackageVerifyTest : public PkgTest {
43 public:
PackageVerifyTest()44     PackageVerifyTest() {}
~PackageVerifyTest()45     ~PackageVerifyTest() override {}
46 public:
TestGetFileSize(const std::string & testfileName)47     int TestGetFileSize(const std::string &testfileName)
48     {
49         int32_t ret = GetFileSize(testfileName);
50         return ret;
51     }
52 
TestExtraPackageFile()53     int TestExtraPackageFile()
54     {
55         int32_t ret = ExtraPackageFile(nullptr, nullptr, nullptr, nullptr);
56         EXPECT_EQ(ret, PKG_INVALID_PARAM);
57 
58         std::string packagePath = "invalid_path";
59         std::string keyPath = "invalid_key";
60         std::string file = "invalid_file";
61         std::string outPath = "invalid_path";
62         ret = ExtraPackageFile(packagePath.c_str(), keyPath.c_str(), file.c_str(), outPath.c_str());
63         EXPECT_EQ(ret, PKG_INVALID_FILE);
64 
65         packagePath = testPackagePath + "test_package.zip";
66         keyPath = "/data/updater/src/signing_cert.crt";
67         file = "updater.bin";
68         ret = ExtraPackageFile(packagePath.c_str(), keyPath.c_str(), file.c_str(), testPackagePath.c_str());
69         EXPECT_EQ(ret, PKG_SUCCESS);
70         return 0;
71     }
72 
TestExtraPackageDir()73     int TestExtraPackageDir()
74     {
75         int32_t ret = ExtraPackageDir(nullptr, nullptr, nullptr, nullptr);
76         EXPECT_EQ(ret, PKG_INVALID_PARAM);
77 
78         std::string packagePath = "invalid_path";
79         std::string keyPath = "invalid_key";
80         std::string outPath = "invalid_path";
81         ret = ExtraPackageDir(packagePath.c_str(), keyPath.c_str(), nullptr, outPath.c_str());
82         EXPECT_EQ(ret, PKG_INVALID_FILE);
83 
84         packagePath = testPackagePath + "test_package.zip";
85         keyPath = "/data/updater/src/signing_cert.crt";
86         ret = ExtraPackageDir(packagePath.c_str(), keyPath.c_str(), nullptr, testPackagePath.c_str());
87         EXPECT_EQ(ret, PKG_SUCCESS);
88         return 0;
89     }
90 
TestCertVerifyFailed()91     int TestCertVerifyFailed()
92     {
93         BIO *certbio = BIO_new_file(GetTestPrivateKeyName(0).c_str(), "r");
94         X509 *rcert = PEM_read_bio_X509(certbio, nullptr, nullptr, nullptr);
95         if (certbio != nullptr) {
96             BIO_free(certbio);
97         }
98         SingleCertHelper singleCert;
99         int32_t ret = singleCert.CertChainCheck(nullptr, nullptr);
100         EXPECT_EQ(ret, -1);
101         ret = singleCert.CertChainCheck(nullptr, rcert);
102         EXPECT_EQ(ret, -1);
103 
104         ret = CertVerify::GetInstance().CheckCertChain(nullptr, nullptr);
105         EXPECT_EQ(ret, -1);
106 
107         bool result = VerifyX509CertByIssuerCert(nullptr, nullptr);
108         EXPECT_EQ(result, false);
109         result = VerifyX509CertByIssuerCert(rcert, rcert);
110         EXPECT_EQ(result, false);
111         return 0;
112     }
113 
TestOpensslUtilFailed()114     int TestOpensslUtilFailed()
115     {
116         std::vector<uint8_t> asn1Data;
117         int32_t ret = GetASN1OctetStringData(nullptr, asn1Data);
118         EXPECT_EQ(ret, -1);
119 
120         int32_t algoNid {};
121         ret = GetX509AlgorithmNid(nullptr, algoNid);
122         EXPECT_EQ(ret, -1);
123 
124         X509 *result = GetX509CertFromPemString(" ");
125         EXPECT_EQ(result, nullptr);
126         result = GetX509CertFromPemFile("invalid_file");
127         EXPECT_EQ(result, nullptr);
128 
129         BIO *certbio = BIO_new_file(GetTestPrivateKeyName(0).c_str(), "r");
130         X509 *cert = PEM_read_bio_X509(certbio, nullptr, nullptr, nullptr);
131         if (certbio != nullptr) {
132             BIO_free(certbio);
133         }
134         bool boolResult = VerifyX509CertByIssuerCert(nullptr, nullptr);
135         EXPECT_EQ(boolResult, false);
136         boolResult = VerifyX509CertByIssuerCert(cert, cert);
137         EXPECT_EQ(boolResult, false);
138 
139         ret = VerifyDigestByPubKey(nullptr, 0, asn1Data, asn1Data);
140         EXPECT_EQ(ret, -1);
141         ret = CalcSha256Digest(nullptr, 0, asn1Data);
142         EXPECT_EQ(ret, -1);
143 
144         std::string stringResult = GetStringFromX509Name(nullptr);
145         EXPECT_EQ(stringResult, "");
146         stringResult = GetX509CertSubjectName(nullptr);
147         EXPECT_EQ(stringResult, "");
148         stringResult = GetX509CertSubjectName(cert);
149         EXPECT_EQ(stringResult, "");
150         stringResult = GetX509CertIssuerName(nullptr);
151         EXPECT_EQ(stringResult, "");
152         stringResult = GetX509CertIssuerName(cert);
153         EXPECT_EQ(stringResult, "");
154         return 0;
155     }
156 
TestPkcs7SignedDataFailed()157     int TestPkcs7SignedDataFailed()
158     {
159         Pkcs7SignedData signedData;
160         uint8_t srcData[] = "A";
161         std::vector<uint8_t> hash;
162         std::vector<std::vector<uint8_t>> sigs;
163 
164         int32_t ret = signedData.Verify();
165         EXPECT_EQ(ret, -1);
166         ret = signedData.GetHashFromSignBlock(nullptr, 0, hash);
167         EXPECT_EQ(ret, -1);
168         ret = signedData.GetHashFromSignBlock(srcData, 0, hash);
169         EXPECT_EQ(ret, -1);
170         ret = signedData.GetHashFromSignBlock(srcData, 1, hash);
171         EXPECT_EQ(ret, -1);
172         ret = signedData.ReadSig(nullptr, 0, sigs);
173         EXPECT_EQ(ret, PKCS7_INVALID_PARAM_ERR);
174         ret = signedData.ReadSig(srcData, 0, sigs);
175         EXPECT_EQ(ret, PKCS7_INVALID_PARAM_ERR);
176         ret = signedData.ReadSig(srcData, 1, sigs);
177         EXPECT_EQ(ret, PKCS7_INIT_ERR);
178         return 0;
179     }
180 
TestPkgVerifyFailed()181     int TestPkgVerifyFailed()
182     {
183         PkgVerifyUtil pkgVerify;
184         std::vector<uint8_t> data;
185         size_t testData = 0;
186         uint16_t commentTotalLenAll = 0;
187         int32_t ret = pkgVerify.VerifyPackageSign(nullptr, "");
188         EXPECT_EQ(ret, PKG_INVALID_PARAM);
189         ret = pkgVerify.GetSignature(nullptr, testData, data, commentTotalLenAll);
190         EXPECT_NE(ret, PKG_SUCCESS);
191         ret = pkgVerify.HashCheck(nullptr, testData, data, "");
192         EXPECT_EQ(ret, PKG_INVALID_PARAM);
193         ret = pkgVerify.ParsePackage(nullptr, testData, testData, commentTotalLenAll);
194         EXPECT_NE(ret, PKG_SUCCESS);
195         ret = pkgVerify.Pkcs7verify(data, data);
196         EXPECT_NE(ret, PKG_SUCCESS);
197         return 0;
198     }
199 
TestHashDataVerifierFailed01()200     int TestHashDataVerifierFailed01()
201     {
202         // verifier with null pkg manager
203         HashDataVerifier verifier {nullptr};
204         EXPECT_FALSE(verifier.LoadHashDataAndPkcs7(""));
205         EXPECT_FALSE(verifier.VerifyHashData("build_tools/", "updater_binary", nullptr));
206         FileStream filestream(nullptr, "", nullptr, PkgStream::PkgStreamType_Read);
207         EXPECT_FALSE(verifier.VerifyHashData("build_tools/", "updater_binary", &filestream));
208         return 0;
209     }
210 
TestHashDataVerifierFailed02()211     int TestHashDataVerifierFailed02()
212     {
213         // no hash signed data in pkg
214         std::string invalidPkgPath = "updater_full_without_hsd.zip";
215         HashDataVerifier verifier {pkgManager_};
216         EXPECT_FALSE(verifier.LoadHashDataAndPkcs7(testPackagePath + invalidPkgPath));
217 
218         // invalid package path
219         EXPECT_FALSE(verifier.LoadHashDataAndPkcs7("invalid package path"));
220         return 0;
221     }
222 
TestHashDataVerifierFailed03()223     int TestHashDataVerifierFailed03()
224     {
225         // invalid hash signed data format
226         std::string invalidPkgPath = "updater_full_with_invalid_hsd.zip";
227         std::vector<std::string> fileIds {};
228         EXPECT_EQ(PKG_SUCCESS, pkgManager_->LoadPackage(testPackagePath + invalidPkgPath,
229             Utils::GetCertName(), fileIds));
230         HashDataVerifier verifier {pkgManager_};
231         EXPECT_FALSE(verifier.LoadHashDataAndPkcs7(testPackagePath + invalidPkgPath));
232         return 0;
233     }
234 
TestHashDataVerifierFailed04()235     int TestHashDataVerifierFailed04()
236     {
237         // invalid pkg footer
238         std::string invalidPkgPath = "updater_full_with_invalid_footer.zip";
239         HashDataVerifier verifier {pkgManager_};
240         EXPECT_FALSE(verifier.LoadHashDataAndPkcs7(testPackagePath + invalidPkgPath));
241         return 0;
242     }
243 
VerifyFileByVerifier(const HashDataVerifier & verifier,const std::string & fileName)244     int VerifyFileByVerifier(const HashDataVerifier &verifier, const std::string &fileName)
245     {
246         const FileInfo *info = pkgManager_->GetFileInfo(fileName);
247         EXPECT_NE(info, nullptr) << "info is null " << fileName;
248         if (info == nullptr) {
249             return -1;
250         }
251         PkgManager::StreamPtr outStream = nullptr;
252         PkgBuffer buffer{info->unpackedSize};
253         EXPECT_EQ(PKG_SUCCESS, pkgManager_->CreatePkgStream(outStream, fileName, buffer)) << fileName;
254         EXPECT_EQ(PKG_SUCCESS, pkgManager_->ExtractFile(fileName, outStream)) << fileName;
255         EXPECT_TRUE(verifier.VerifyHashData("build_tools/", fileName, outStream));
256         EXPECT_FALSE(verifier.VerifyHashData("build_tools/", "invalid", outStream));
257         pkgManager_->ClosePkgStream(outStream);
258         return 0;
259     }
260 
TestHashDataVerifierSuccess()261     int TestHashDataVerifierSuccess()
262     {
263         std::vector<std::string> fileIds {};
264         EXPECT_EQ(PKG_SUCCESS, pkgManager_->LoadPackage(testPackagePath + "updater_full_with_hsd.zip",
265             Utils::GetCertName(), fileIds));
266         HashDataVerifier verifier {pkgManager_};
267         EXPECT_TRUE(verifier.LoadHashDataAndPkcs7(testPackagePath + testZipPackageName));
268 
269         // secondary load directly return true
270         EXPECT_TRUE(verifier.LoadHashDataAndPkcs7(testPackagePath + testZipPackageName));
271         std::vector<std::string> fileList { "updater_binary", "loadScript.us", "Verse-script.us" };
272         for (const auto &fileName : fileList) {
273             EXPECT_EQ(VerifyFileByVerifier(verifier, fileName), 0);
274         }
275         return 0;
276     }
277 };
278 
279 HWTEST_F(PackageVerifyTest, TestPkgVerifyFailed, TestSize.Level1)
280 {
281     PackageVerifyTest test;
282     EXPECT_EQ(0, test.TestPkgVerifyFailed());
283 }
284 
285 HWTEST_F(PackageVerifyTest, TestPkcs7SignedDataFailed, TestSize.Level1)
286 {
287     PackageVerifyTest test;
288     EXPECT_EQ(0, test.TestPkcs7SignedDataFailed());
289 }
290 
291 HWTEST_F(PackageVerifyTest, TestOpensslUtilFailed, TestSize.Level1)
292 {
293     PackageVerifyTest test;
294     EXPECT_EQ(0, test.TestOpensslUtilFailed());
295 }
296 
297 HWTEST_F(PackageVerifyTest, TestCertVerifyFailed, TestSize.Level1)
298 {
299     PackageVerifyTest test;
300     EXPECT_EQ(0, test.TestCertVerifyFailed());
301 }
302 
303 HWTEST_F(PackageVerifyTest, TestExtraPackageDir, TestSize.Level1)
304 {
305     PackageVerifyTest test;
306     EXPECT_EQ(0, test.TestExtraPackageDir());
307 }
308 
309 HWTEST_F(PackageVerifyTest, TestExtraPackageFile, TestSize.Level1)
310 {
311     PackageVerifyTest test;
312     EXPECT_EQ(0, test.TestExtraPackageFile());
313 }
314 
315 HWTEST_F(PackageVerifyTest, TestGetFileSize, TestSize.Level1)
316 {
317     PackageVerifyTest test;
318     std::string testFileName = "invalid_path";
319     EXPECT_EQ(0, test.TestGetFileSize(testFileName));
320     testFileName = testPackagePath + "test_package.zip";
321     EXPECT_EQ(1368949, test.TestGetFileSize(testFileName));
322 }
323 
324 HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed01, TestSize.Level1)
325 {
326     PackageVerifyTest test;
327     EXPECT_EQ(0, test.TestHashDataVerifierFailed01());
328 }
329 
330 HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed02, TestSize.Level1)
331 {
332     PackageVerifyTest test;
333     EXPECT_EQ(0, test.TestHashDataVerifierFailed02());
334 }
335 
336 HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed03, TestSize.Level1)
337 {
338     PackageVerifyTest test;
339     EXPECT_EQ(0, test.TestHashDataVerifierFailed03());
340 }
341 
342 HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed04, TestSize.Level1)
343 {
344     PackageVerifyTest test;
345     EXPECT_EQ(0, test.TestHashDataVerifierFailed04());
346 }
347 
348 HWTEST_F(PackageVerifyTest, TestHashDataVerifierSuccess, TestSize.Level1)
349 {
350     PackageVerifyTest test;
351     EXPECT_EQ(0, test.TestHashDataVerifierSuccess());
352 }
353 }
354