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
36using namespace std;
37using namespace Hpackage;
38using namespace Updater;
39using namespace testing::ext;
40
41namespace UpdaterUt {
42class PackageVerifyTest : public PkgTest {
43public:
44    PackageVerifyTest() {}
45    ~PackageVerifyTest() override {}
46public:
47    int TestGetFileSize(const std::string &testfileName)
48    {
49        int32_t ret = GetFileSize(testfileName);
50        return ret;
51    }
52
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
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
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
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
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
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
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
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
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
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
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
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
279HWTEST_F(PackageVerifyTest, TestPkgVerifyFailed, TestSize.Level1)
280{
281    PackageVerifyTest test;
282    EXPECT_EQ(0, test.TestPkgVerifyFailed());
283}
284
285HWTEST_F(PackageVerifyTest, TestPkcs7SignedDataFailed, TestSize.Level1)
286{
287    PackageVerifyTest test;
288    EXPECT_EQ(0, test.TestPkcs7SignedDataFailed());
289}
290
291HWTEST_F(PackageVerifyTest, TestOpensslUtilFailed, TestSize.Level1)
292{
293    PackageVerifyTest test;
294    EXPECT_EQ(0, test.TestOpensslUtilFailed());
295}
296
297HWTEST_F(PackageVerifyTest, TestCertVerifyFailed, TestSize.Level1)
298{
299    PackageVerifyTest test;
300    EXPECT_EQ(0, test.TestCertVerifyFailed());
301}
302
303HWTEST_F(PackageVerifyTest, TestExtraPackageDir, TestSize.Level1)
304{
305    PackageVerifyTest test;
306    EXPECT_EQ(0, test.TestExtraPackageDir());
307}
308
309HWTEST_F(PackageVerifyTest, TestExtraPackageFile, TestSize.Level1)
310{
311    PackageVerifyTest test;
312    EXPECT_EQ(0, test.TestExtraPackageFile());
313}
314
315HWTEST_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
324HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed01, TestSize.Level1)
325{
326    PackageVerifyTest test;
327    EXPECT_EQ(0, test.TestHashDataVerifierFailed01());
328}
329
330HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed02, TestSize.Level1)
331{
332    PackageVerifyTest test;
333    EXPECT_EQ(0, test.TestHashDataVerifierFailed02());
334}
335
336HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed03, TestSize.Level1)
337{
338    PackageVerifyTest test;
339    EXPECT_EQ(0, test.TestHashDataVerifierFailed03());
340}
341
342HWTEST_F(PackageVerifyTest, TestHashDataVerifierFailed04, TestSize.Level1)
343{
344    PackageVerifyTest test;
345    EXPECT_EQ(0, test.TestHashDataVerifierFailed04());
346}
347
348HWTEST_F(PackageVerifyTest, TestHashDataVerifierSuccess, TestSize.Level1)
349{
350    PackageVerifyTest test;
351    EXPECT_EQ(0, test.TestHashDataVerifierSuccess());
352}
353}
354