1 /*
2  * Copyright (c) 2023-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 <cstdio>
17 #include <cstring>
18 #include <fcntl.h>
19 #include <gtest/gtest.h>
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 
24 #include "code_sign_utils.h"
25 #include "code_sign_block.h"
26 #include "directory_ex.h"
27 #include "enable_key_utils.h"
28 #include "xpm_common.h"
29 
30 namespace OHOS {
31 namespace Security {
32 namespace CodeSign {
33 using namespace testing::ext;
34 using namespace std;
35 
36 static const std::string TMP_BASE_PATH = "/data/service/el1/public/bms/bundle_manager_service/tmp";
37 static const std::string TEST_APP_DTAT_DIR = "/data/app/el1/bundle/public/com.example.codesignaturetest";
38 static const std::string APP_BASE_PATH = "/data/app/el1/bundle/public/tmp";
39 static const string SUBJECT = "Huawei: HarmonyOS Application Code Signature";
40 static const string ISSUER = "Huawei CBG Software Signing Service CA Test";
41 static const string OH_SUBJECT = "OpenHarmony Application Release";
42 static const string OH_ISSUER = "OpenHarmony Application CA";
43 static const std::string PROFILE_BASE_PATH = "/data/service/el0/profiles/tmp";
44 
45 static const EntryMap g_hapWithoutLibRetSuc = {
46     {"Hap", APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"},
47 };
48 static const std::string g_sigWithoutLibRetSucPath =
49     TMP_BASE_PATH + "/demo_without_lib/demo_without_lib.sig";
50 
51 static EntryMap g_hapWithMultiLibRetSuc = {
52     {"Hap",
53         APP_BASE_PATH + "/demo_with_multi_lib/demo_with_multi_lib.hap"},
54     {"libs/arm64-v8a/libc++_shared.so",
55         APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libc++_shared.so"},
56     {"libs/arm64-v8a/libentry.so",
57         APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libentry.so"}
58 };
59 static const std::string g_sigWithMultiLibRetSucPath =
60     TMP_BASE_PATH + "/demo_with_multi_lib/demo_with_multi_lib.sig";
61 
62 // wrong hap and wrong lib
63 static EntryMap g_wrongHapWithMultiLibRetFail = {
64     {"Hap",
65      APP_BASE_PATH + "/demo_with_multi_lib_error/demo_with_multi_lib.hap"},
66     {"libs/arm64-v8a/libc++_shared.so",
67      APP_BASE_PATH + "/demo_with_multi_lib_error/libs/arm64-v8a/libc++_shared.so"},
68     {"libs/arm64-v8a/libentry.so",
69      APP_BASE_PATH + "/demo_with_multi_lib_error/libs/arm64-v8a/libentry.so"}};
70 
71 // examples of Enforce code signature for app
72 static const std::vector<std::string> g_HapWithoutLibSigPkcs7ErrorPath = {
73     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_001.sig", // Ilegal pkcs7 format
74     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_002.sig", // Disable to find cert chain
75     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_003.sig", // Don't support digest algorithm
76     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_004.sig", // Don't support signature algorithm
77     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_005.sig", // Wrong signature
78     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_006.sig", // Expired signature
79     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_007.sig", // Cert chain validate fail
80     TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_008.sig", // Wrong issuer
81 };
82 
83 static const std::vector<std::string> g_HapWithMultiLibSigPkcs7ErrorPath = {
84     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_001.sig", // Ilegal pkcs7 format
85     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_002.sig", // Disable to find cert chain
86     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_003.sig", // Don't support digest algorithm
87     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_004.sig", // Don't support signature algorithm
88     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_005.sig", // Wrong signature
89     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_006.sig", // Expired signature
90     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_007.sig", // Cert chain validate fail
91 };
92 
93 // examples of Enforce code signature for file
94 static const std::string g_fileEnableSuc = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libentry.so";
95 static const std::string g_filesigEnablePath =
96     TMP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libentry.so.fsv-sig";
97 
98 // wrong format file
99 static const std::string g_wrongFileEnableFail =
100     APP_BASE_PATH + "/demo_with_multi_lib_error/libs/arm64-v8a/libentry.so";
101 
102 static const std::vector<std::string> g_fileSigEnableFailPath = {
103     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_01.so.fsv-sig", // ilegal pkcs7 format
104     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_02.so.fsv-sig", // Disable to find cert chain
105     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_03.so.fsv-sig", // Don't support digest algorithm
106     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_04.so.fsv-sig", // Don't support signature algorithm
107     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_05.so.fsv-sig", // Wrong signature
108     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_06.so.fsv-sig", // Expired signature
109     TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_07.so.fsv-sig", // Cert chain validate fail
110 };
111 
112 // examples of can't find the signature file
113 static const EntryMap g_hapSigNotExist = {
114     {"sigNotExist", APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"},
115 };
116 
117 static bool g_isPermissive = false;
118 
119 class CodeSignUtilsTest : public testing::Test {
120 public:
CodeSignUtilsTest()121     CodeSignUtilsTest() {};
~CodeSignUtilsTest()122     virtual ~CodeSignUtilsTest() {};
SetUpTestCase()123     static void SetUpTestCase()
124     {
125         EXPECT_EQ(EnableTestKey(SUBJECT.c_str(), ISSUER.c_str()), 0);
126         EXPECT_EQ(EnableTestKey(OH_SUBJECT.c_str(), OH_ISSUER.c_str()), 0);
127         g_isPermissive = CodeSignUtils::InPermissiveMode();
128         if (g_isPermissive) {
129             SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, ENFORCE_MODE);
130         }
131     };
TearDownTestCase()132     static void TearDownTestCase()
133     {
134         if (g_isPermissive) {
135             SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, PERMISSIVE_MODE);
136         }
137     };
SetUp()138     void SetUp() {};
TearDown()139     void TearDown() {};
140 };
141 
ReadSignatureFromFile(const std::string & path,ByteBuffer & data)142 static bool ReadSignatureFromFile(const std::string &path, ByteBuffer &data)
143 {
144     FILE *file = fopen(path.c_str(), "rb");
145     if (file == nullptr) {
146         return false;
147     }
148     if (fseek(file, 0L, SEEK_END) != 0) {
149         fclose(file);
150         return false;
151     }
152 
153     size_t fileSize = ftell(file);
154     rewind(file);
155     if (!data.Resize(fileSize)) {
156         fclose(file);
157         return false;
158     }
159     size_t ret = fread(data.GetBuffer(), 1, fileSize, file);
160     (void)fclose(file);
161     return ret == fileSize;
162 }
163 
164 // excute the exceptional examples first, because of it's always successful
165 // once the same file signature verified successfully
166 
167 /**
168  * @tc.name: CodeSignUtilsTest_0001
169  * @tc.desc: enable code signature for app failed, reason = zip file wrong foramt
170  * @tc.type: Func
171  * @tc.require:
172  */
173 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0001, TestSize.Level0)
174 {
175     std::string sigPath = TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_01.so.fsv-sig";
176     int ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithoutLibRetSuc, sigPath);
177     EXPECT_EQ(ret, CS_ERR_EXTRACT_FILES);
178 }
179 
180 /**
181  * @tc.name: CodeSignUtilsTest_0002
182  * @tc.desc: enable code signature for app failed, reason = no signature in the signatrue file
183  * @tc.type: Func
184  * @tc.require:
185  */
186 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0002, TestSize.Level0)
187 {
188     int ret = CodeSignUtils::EnforceCodeSignForApp(g_hapSigNotExist, g_sigWithoutLibRetSucPath);
189     EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE);
190 }
191 
192 /**
193  * @tc.name: CodeSignUtilsTest_0003
194  * @tc.desc: enable code signature for app failed, reason = invalied signature path
195  * @tc.type: Func
196  * @tc.require:
197  */
198 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0003, TestSize.Level0)
199 {
200     int ret = CodeSignUtils::EnforceCodeSignForApp(
201         g_hapWithoutLibRetSuc, g_sigWithoutLibRetSucPath + "invalid");
202     EXPECT_EQ(ret, CS_ERR_FILE_PATH);
203 }
204 
205 
206 /**
207  * @tc.name: CodeSignUtilsTest_0004
208  * @tc.desc: enable code signature for app failed, reason = invalied hap path
209  * @tc.type: Func
210  * @tc.require:
211  */
212 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0004, TestSize.Level0)
213 {
214     EntryMap invalid;
215     invalid["Hap"] = "InvalidPath";
216     int ret = CodeSignUtils::EnforceCodeSignForApp(invalid, g_sigWithoutLibRetSucPath);
217     EXPECT_EQ(ret, CS_ERR_FILE_INVALID);
218 }
219 
220 /**
221  * @tc.name: CodeSignUtilsTest_0005
222  * @tc.desc: enable code signature for app failed, reason = wrong format hap
223  * @tc.type: Func
224  * @tc.require:
225  */
226 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0005, TestSize.Level0)
227 {
228     int ret = CodeSignUtils::EnforceCodeSignForApp(
229         g_wrongHapWithMultiLibRetFail, g_sigWithMultiLibRetSucPath);
230     EXPECT_EQ(ret, CS_ERR_ENABLE);
231 }
232 
233 /**
234  * @tc.name: CodeSignUtilsTest_0006
235  * @tc.desc: enable code signature for app failed, reason = enable failed
236  * @tc.type: Func
237  * @tc.require:
238  */
239 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0006, TestSize.Level0)
240 {
241     size_t num = g_HapWithoutLibSigPkcs7ErrorPath.size();
242     int ret;
243     // wrong hap signature
244     for (size_t i = 0; i < num; i++) {
245         ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithoutLibRetSuc, g_HapWithoutLibSigPkcs7ErrorPath[i]);
246         EXPECT_EQ(ret, CS_ERR_ENABLE);
247     }
248 
249     // wrong so signature
250     num = g_HapWithMultiLibSigPkcs7ErrorPath.size();
251     for (size_t i = 0; i < num; i++) {
252         ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithMultiLibRetSuc, g_HapWithMultiLibSigPkcs7ErrorPath[i]);
253         EXPECT_EQ(ret, CS_ERR_ENABLE);
254     }
255 }
256 
257 /**
258  * @tc.name: CodeSignUtilsTest_0007
259  * @tc.desc: enable code signature for file, reason = wrong foramt pkcs7
260  * @tc.type: Func
261  * @tc.require:
262  */
263 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0007, TestSize.Level0)
264 {
265     ByteBuffer buffer;
266     bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
267     EXPECT_EQ(flag, true);
268     int ret = CodeSignUtils::EnforceCodeSignForFile(g_wrongFileEnableFail, buffer);
269     EXPECT_EQ(ret, CS_ERR_ENABLE);
270 }
271 
272 /**
273  * @tc.name: CodeSignUtilsTest_0008
274  * @tc.desc: enable code signature for file, reason = enable failed
275  * @tc.type: Func
276  * @tc.require:
277  */
278 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0008, TestSize.Level0)
279 {
280     size_t num = g_fileSigEnableFailPath.size();
281     int ret;
282     for (size_t i = 0; i < num; i++) {
283         ByteBuffer buffer;
284         bool flag = ReadSignatureFromFile(g_fileSigEnableFailPath[i], buffer);
285         EXPECT_EQ(flag, true);
286         ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer);
287         EXPECT_EQ(ret, CS_ERR_ENABLE);
288     }
289 }
290 
291 /**
292  * @tc.name: CodeSignUtilsTest_0009
293  * @tc.desc: enable code signature for file failed, reason = invalid path
294  * @tc.type: Func
295  * @tc.require:
296  */
297 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0009, TestSize.Level0)
298 {
299     ByteBuffer buffer;
300     bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
301     EXPECT_EQ(flag, true);
302     int ret = CodeSignUtils::EnforceCodeSignForFile("invalidPath", buffer);
303     EXPECT_EQ(ret, CS_ERR_FILE_PATH);
304 }
305 
306 /**
307  * @tc.name: CodeSignUtilsTest_0010
308  * @tc.desc: enable code signature for file failed, reason = no signature
309  * @tc.type: Func
310  * @tc.require:
311  */
312 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0010, TestSize.Level0)
313 {
314     ByteBuffer buffer;
315     bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
316     EXPECT_EQ(flag, true);
317 
318     int ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, NULL, buffer.GetSize());
319     EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE);
320 
321     ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer.GetBuffer(), 0);
322     EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE);
323 }
324 
325 /**
326  * @tc.name: CodeSignUtilsTest_0011
327  * @tc.desc: enable code signature for file successfully
328  * @tc.type: Func
329  * @tc.require:
330  */
331 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0011, TestSize.Level0)
332 {
333     ByteBuffer buffer;
334     bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
335     EXPECT_EQ(flag, true);
336 
337     int32_t ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer);
338     EXPECT_EQ(ret, CS_SUCCESS);
339 }
340 
341 /**
342  * @tc.name: CodeSignUtilsTest_0012
343  * @tc.desc: enable code signature for app successfully
344  * @tc.type: Func
345  * @tc.require:
346  */
347 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0012, TestSize.Level0)
348 {
349     int32_t ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithoutLibRetSuc, g_sigWithoutLibRetSucPath);
350     EXPECT_EQ(ret, CS_SUCCESS);
351 
352     ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithMultiLibRetSuc, g_sigWithMultiLibRetSucPath);
353     EXPECT_EQ(ret, CS_SUCCESS);
354 }
355 
356 /**
357  * @tc.name: CodeSignUtilsTest_0013
358  * @tc.desc: parse owner ID from signature failed, reason = invalid signature
359  * @tc.type: Func
360  * @tc.require: issueI88PPA
361  */
362 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0013, TestSize.Level0)
363 {
364     ByteBuffer buffer;
365     std::string ownerID;
366     std::string invalid = "invalid msg";
367     buffer.CopyFrom((const uint8_t *)invalid.c_str(), invalid.length());
368     int ret = CodeSignUtils::ParseOwnerIdFromSignature(buffer, ownerID);
369     EXPECT_EQ(ret, CS_ERR_OPENSSL_PKCS7);
370 }
371 
372 /**
373  * @tc.name: CodeSignUtilsTest_0014
374  * @tc.desc: Parse code signature for hap successfully
375  * @tc.type: Func
376  * @tc.require:
377  */
378 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0014, TestSize.Level0)
379 {
380     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap";
381     EntryMap entryMap;
382 
383     CodeSignBlock codeSignBlock;
384     int32_t ret = codeSignBlock.ParseCodeSignBlock(hapRealPath, entryMap, FILE_SELF);
385     EXPECT_EQ(ret, CS_SUCCESS);
386 
387     std::string targetFile;
388     struct code_sign_enable_arg arg = {0};
389 
390     ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg);
391     EXPECT_EQ(ret, CS_SUCCESS);
392     EXPECT_EQ(arg.version, 1);
393     EXPECT_EQ(arg.cs_version, 1);
394     EXPECT_EQ(arg.hash_algorithm, 1);
395     EXPECT_EQ(arg.block_size, 0x1000);
396     EXPECT_EQ(arg.sig_size, 0x862);
397     EXPECT_EQ(arg.data_size, 0x5000);
398     EXPECT_EQ(arg.salt_size, 0);
399     EXPECT_EQ(arg.flags, 1);
400     EXPECT_EQ(arg.tree_offset, 0x10c000);
401 
402     ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg);
403     EXPECT_EQ(ret, CS_SUCCESS_END);
404 }
405 
406 /**
407  * @tc.name: CodeSignUtilsTest_0015
408  * @tc.desc: parse code signature for native libs successfully
409  * @tc.type: Func
410  * @tc.require:
411  */
412 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0015, TestSize.Level0)
413 {
414     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap";
415     EntryMap entryMap;
416     std::string filePath1("libs/arm64-v8a/libc++_shared.so");
417     std::string targetPath1 = TEST_APP_DTAT_DIR + "libs/arm64/libc++_shared.so";
418     entryMap.emplace(filePath1, targetPath1);
419     std::string filePath2("libs/arm64-v8a/libentry.so");
420     std::string targetPath2 = TEST_APP_DTAT_DIR + "libs/arm64/libentry.so";
421     entryMap.emplace(filePath2, targetPath2);
422 
423     CodeSignBlock codeSignBlock;
424     int32_t ret = codeSignBlock.ParseCodeSignBlock(hapRealPath, entryMap, FILE_ENTRY_ONLY);
425     EXPECT_EQ(ret, CS_SUCCESS);
426 
427     int32_t count = 0;
428     do {
429         std::string targetFile;
430         struct code_sign_enable_arg arg = {0};
431         ret = codeSignBlock.GetOneFileAndCodeSignInfo(targetFile, arg);
432         if (ret != CS_SUCCESS_END) {
433             EXPECT_EQ(ret, CS_SUCCESS);
434             EXPECT_EQ(arg.version, 1);
435             EXPECT_EQ(arg.cs_version, 1);
436             EXPECT_EQ(arg.hash_algorithm, 1);
437             EXPECT_EQ(arg.block_size, 0x1000);
438             EXPECT_EQ(arg.salt_size, 0);
439             EXPECT_EQ(arg.flags, 0);
440             EXPECT_EQ(arg.tree_offset, 0);
441             count++;
442             continue;
443         }
444     } while (ret == CS_SUCCESS);
445     EXPECT_EQ(count, 0x2);
446 }
447 
448 /**
449  * @tc.name: CodeSignUtilsTest_0016
450  * @tc.desc: enable code signature for app
451  * @tc.type: Func
452  * @tc.require:
453  */
454 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0016, TestSize.Level0)
455 {
456     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap";
457     EntryMap entryMap;
458     CodeSignUtils utils;
459     int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF);
460     EXPECT_EQ(ret, CS_SUCCESS);
461 
462     std::string filePath1("libs/arm64-v8a/libc++_shared.so");
463     std::string targetPath1 = TEST_APP_DTAT_DIR + "libs/arm64/libc++_shared.so";
464     entryMap.emplace(filePath1, targetPath1);
465     std::string filePath2("libs/arm64-v8a/libentry.so");
466     std::string targetPath2 = TEST_APP_DTAT_DIR + "libs/arm64/libentry.so";
467     entryMap.emplace(filePath2, targetPath2);
468 
469     ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD);
470     EXPECT_EQ(ret, CS_SUCCESS);
471 
472     ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL);
473     EXPECT_EQ(ret, CS_ERR_FILE_PATH);
474 }
475 
476 /**
477  * @tc.name: CodeSignUtilsTest_0017
478  * @tc.desc: enable code signature for debug app with libs
479  * @tc.type: Func
480  * @tc.require:
481  */
482 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0017, TestSize.Level0)
483 {
484     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-debug.hap";
485     EntryMap entryMap;
486     CodeSignUtils utils;
487     int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("DEBUG_LIB_ID",
488         hapRealPath, entryMap, FILE_SELF);
489     EXPECT_EQ(ret, CS_SUCCESS);
490 }
491 
492 /**
493  * @tc.name: CodeSignUtilsTest_0018
494  * @tc.desc: enable code signature for release app with libs
495  * @tc.type: Func
496  * @tc.require:
497  */
498 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0018, TestSize.Level0)
499 {
500     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-release.hap";
501     EntryMap entryMap;
502     CodeSignUtils utils;
503     int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("test-app-identifier",
504         hapRealPath, entryMap, FILE_SELF);
505     EXPECT_EQ(ret, CS_SUCCESS);
506 }
507 
508 /**
509  * @tc.name: CodeSignUtilsTest_0019
510  * @tc.desc: enable code signature for debug app with libs
511  * @tc.type: Func
512  * @tc.require:
513  */
514 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0019, TestSize.Level0)
515 {
516     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-debug.hap";
517     EntryMap entryMap;
518     CodeSignUtils utils;
519     int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("INVALID_ID",
520         hapRealPath, entryMap, FILE_SELF);
521     EXPECT_EQ(ret, CS_ERR_INVALID_OWNER_ID);
522 }
523 
524 /**
525  * @tc.name: CodeSignUtilsTest_0020
526  * @tc.desc: enable code signature for release app with libs
527  * @tc.type: Func
528  * @tc.require:
529  */
530 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0020, TestSize.Level0)
531 {
532     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-release.hap";
533     EntryMap entryMap;
534     CodeSignUtils utils;
535     int32_t ret = utils.EnforceCodeSignForAppWithOwnerId("INVALID_ID",
536         hapRealPath, entryMap, FILE_SELF);
537     EXPECT_EQ(ret, CS_ERR_INVALID_OWNER_ID);
538 }
539 
540 /**
541  * @tc.name: CodeSignUtilsTest_0023
542  * @tc.desc: enable code signature for app
543  * @tc.type: Func
544  * @tc.require:
545  */
546 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0023, TestSize.Level0)
547 {
548     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap";
549     EntryMap entryMap;
550 
551     std::string filePath1("libs/arm64-v8a/libc++_shared.so");
552     std::string targetPath1 = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/code_sign_block/libc++_shared.so";
553     entryMap.emplace(filePath1, targetPath1);
554 
555     CodeSignUtils utils;
556     int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ONLY);
557     EXPECT_EQ(ret, CS_SUCCESS);
558 
559     std::string filePath2("libs/arm64-v8a/libentry.so");
560     std::string targetPath2 = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/code_sign_block/libentry.so";
561     entryMap.emplace(filePath2, targetPath2);
562 
563     ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD);
564     EXPECT_EQ(ret, CS_SUCCESS);
565 
566     entryMap.clear();
567     ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL);
568     EXPECT_EQ(ret, CS_SUCCESS);
569 }
570 
571 /**
572  * @tc.name: CodeSignUtilsTest_0024
573  * @tc.desc: success without signature in permissive mode
574  * @tc.type: Func
575  * @tc.require: I8R8V7
576  */
577 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0024, TestSize.Level0)
578 {
579     if (!SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, PERMISSIVE_MODE)) {
580         return;
581     }
582     EntryMap entryMap;
583     CodeSignUtils utils;
584     std::string hapRealPath = APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap";
585     int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF);
586     EXPECT_EQ(ret, CS_SUCCESS);
587     SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, ENFORCE_MODE);
588 }
589 
590 /**
591  * @tc.name: CodeSignUtilsTest_0025
592  * @tc.desc: failed without signature in enforcing mode
593  * @tc.type: Func
594  * @tc.require: I8R8V7
595  */
596 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0025, TestSize.Level0)
597 {
598     if (CodeSignUtils::InPermissiveMode()) {
599         return;
600     }
601     std::string hapRealPath = APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap";
602     EntryMap entryMap;
603     CodeSignUtils utils;
604     int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF);
605     EXPECT_EQ(ret, CS_CODE_SIGN_NOT_EXISTS);
606 }
607 
608 /**
609  * @tc.name: CodeSignUtilsTest_0026
610  * @tc.desc: hap so mismatch scenarios
611  * @tc.type: Func
612  * @tc.require:
613  */
614 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0026, TestSize.Level0)
615 {
616     EntryMap entryMap;
617     CodeSignUtils utils;
618     std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/entry-default-signed-release.hap";
619 
620     std::string filePath1("libs/arm64-v8a/code_sign_block/libc++_shared.so");
621     std::string targetPath1 = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/code_sign_block/libc++_shared.so";
622     entryMap.emplace(filePath1, targetPath1);
623     std::string filePath2("libs/arm64-v8a/code_sign_block/libentry.so");
624     std::string targetPath2 = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/code_sign_block/libentry.so";
625     entryMap.emplace(filePath2, targetPath2);
626 
627     int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ENTRY_ADD);
628     EXPECT_EQ(ret, CS_SUCCESS);
629     entryMap.clear();
630 
631     ret = utils.EnforceCodeSignForAppWithOwnerId("test-app-identifier", hapRealPath, entryMap, FILE_ALL);
632     EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE);
633 }
634 }  // namespace CodeSign
635 }  // namespace Security
636 }  // namespace OHOS
637