1 /*
2 * Copyright (c) 2023 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 <gtest/gtest.h>
17
18 #include "code_sign_utils.h"
19
20 namespace OHOS {
21 namespace Security {
22 namespace CodeSign {
23 using namespace testing::ext;
24 using namespace std;
25
26 static const std::string TMP_BASE_PATH = "/data/service/el1/public/bms/bundle_manager_service/tmp";
27 static const std::string APP_BASE_PATH = "/data/app/el1/bundle/public/tmp";
28
29 static const EntryMap g_hapWithoutLibRetSuc = {
30 {"Hap", APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"},
31 };
32 static const std::string g_sigWithoutLibRetSucPath =
33 TMP_BASE_PATH + "/demo_without_lib/demo_without_lib.sig";
34
35 static EntryMap g_hapWithMultiLibRetSuc = {
36 {"Hap",
37 APP_BASE_PATH + "/demo_with_multi_lib/demo_with_multi_lib.hap"},
38 {"libs/arm64-v8a/libc++_shared.so",
39 APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libc++_shared.so"},
40 {"libs/arm64-v8a/libentry.so",
41 APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libentry.so"}
42 };
43 static const std::string g_sigWithMultiLibRetSucPath =
44 TMP_BASE_PATH + "/demo_with_multi_lib/demo_with_multi_lib.sig";
45
46 // wrong hap and wrong lib
47 static EntryMap g_wrongHapWithMultiLibRetFail = {
48 {"Hap",
49 APP_BASE_PATH + "/demo_with_multi_lib_error/demo_with_multi_lib.hap"},
50 {"libs/arm64-v8a/libc++_shared.so",
51 APP_BASE_PATH + "/demo_with_multi_lib_error/libs/arm64-v8a/libc++_shared.so"},
52 {"libs/arm64-v8a/libentry.so",
53 APP_BASE_PATH + "/demo_with_multi_lib_error/libs/arm64-v8a/libentry.so"}};
54
55 // examples of Enforce code signature for app
56 static const std::vector<std::string> g_HapWithoutLibSigPkcs7ErrorPath = {
57 TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_001.sig", // Ilegal pkcs7 format
58 TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_002.sig", // Disable to find cert chain
59 TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_003.sig", // Don't support digest algorithm
60 TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_004.sig", // Don't support signature algorithm
61 TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_005.sig", // Wrong signature
62 TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_006.sig", // Expired signature
63 TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_007.sig", // Cert chain validate fail
64 };
65
66 static const std::vector<std::string> g_HapWithMultiLibSigPkcs7ErrorPath = {
67 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_001.sig", // Ilegal pkcs7 format
68 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_002.sig", // Disable to find cert chain
69 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_003.sig", // Don't support digest algorithm
70 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_004.sig", // Don't support signature algorithm
71 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_005.sig", // Wrong signature
72 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_006.sig", // Expired signature
73 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/demo_with_multi_lib_007.sig", // Cert chain validate fail
74 };
75
76 // examples of Enforce code signature for file
77 static const std::string g_fileEnableSuc = APP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libentry.so";
78 static const std::string g_filesigEnablePath =
79 TMP_BASE_PATH + "/demo_with_multi_lib/libs/arm64-v8a/libentry.so.fsv-sig";
80
81 // wrong format file
82 static const std::string g_wrongFileEnableFail =
83 APP_BASE_PATH + "/demo_with_multi_lib_error/libs/arm64-v8a/libentry.so";
84
85 static const std::vector<std::string> g_fileSigEnableFailPath = {
86 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_01.so.fsv-sig", // ilegal pkcs7 format
87 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_02.so.fsv-sig", // Disable to find cert chain
88 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_03.so.fsv-sig", // Don't support digest algorithm
89 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_04.so.fsv-sig", // Don't support signature algorithm
90 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_05.so.fsv-sig", // Wrong signature
91 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_06.so.fsv-sig", // Expired signature
92 TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_07.so.fsv-sig", // Cert chain validate fail
93 };
94
95 // examples of can't find the signature file
96 static const EntryMap g_hapSigNotExist = {
97 {"sigNotExist", APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"},
98 };
99
100 class CodeSignUtilsTest : public testing::Test {
101 public:
CodeSignUtilsTest()102 CodeSignUtilsTest() {};
~CodeSignUtilsTest()103 virtual ~CodeSignUtilsTest() {};
SetUpTestCase()104 static void SetUpTestCase() {};
TearDownTestCase()105 static void TearDownTestCase() {};
SetUp()106 void SetUp() {};
TearDown()107 void TearDown() {};
108 };
109
ReadSignatureFromFile(const std::string & path,ByteBuffer & data)110 static bool ReadSignatureFromFile(const std::string &path, ByteBuffer &data)
111 {
112 FILE *file = fopen(path.c_str(), "rb");
113 if (file == nullptr) {
114 return false;
115 }
116 if (fseek(file, 0L, SEEK_END) != 0) {
117 fclose(file);
118 return false;
119 }
120
121 size_t fileSize = ftell(file);
122 rewind(file);
123 if (!data.Resize(fileSize)) {
124 fclose(file);
125 return false;
126 }
127 size_t ret = fread(data.GetBuffer(), 1, fileSize, file);
128 (void)fclose(file);
129 return ret == fileSize;
130 }
131
132 // excute the exceptional examples first, because of it's always successful
133 // once the same file signature verified successfully
134
135 /**
136 * @tc.name: CodeSignUtilsTest_0001
137 * @tc.desc: enable code signature for app failed, reason = zip file wrong foramt
138 * @tc.type: Func
139 * @tc.require:
140 */
141 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0001, TestSize.Level0)
142 {
143 std::string sigPath = TMP_BASE_PATH + "/demo_with_multi_lib/pkcs7_error/file/libentry_01.so.fsv-sig";
144 int ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithoutLibRetSuc, sigPath);
145 EXPECT_EQ(ret, CS_ERR_EXTRACT_FILES);
146 }
147
148 /**
149 * @tc.name: CodeSignUtilsTest_0002
150 * @tc.desc: enable code signature for app failed, reason = no signature in the signatrue file
151 * @tc.type: Func
152 * @tc.require:
153 */
154 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0002, TestSize.Level0)
155 {
156 int ret = CodeSignUtils::EnforceCodeSignForApp(g_hapSigNotExist, g_sigWithoutLibRetSucPath);
157 EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE);
158 }
159
160 /**
161 * @tc.name: CodeSignUtilsTest_0003
162 * @tc.desc: enable code signature for app failed, reason = invalied signature path
163 * @tc.type: Func
164 * @tc.require:
165 */
166 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0003, TestSize.Level0)
167 {
168 int ret = CodeSignUtils::EnforceCodeSignForApp(
169 g_hapWithoutLibRetSuc, g_sigWithoutLibRetSucPath + "invalid");
170 EXPECT_EQ(ret, CS_ERR_FILE_PATH);
171 }
172
173
174 /**
175 * @tc.name: CodeSignUtilsTest_0004
176 * @tc.desc: enable code signature for app failed, reason = invalied hap path
177 * @tc.type: Func
178 * @tc.require:
179 */
180 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0004, TestSize.Level0)
181 {
182 EntryMap invalid;
183 invalid["Hap"] = "InvalidPath";
184 int ret = CodeSignUtils::EnforceCodeSignForApp(invalid, g_sigWithoutLibRetSucPath);
185 EXPECT_EQ(ret, CS_ERR_FILE_INVALID);
186 }
187
188 /**
189 * @tc.name: CodeSignUtilsTest_0005
190 * @tc.desc: enable code signature for app failed, reason = wrong format hap
191 * @tc.type: Func
192 * @tc.require:
193 */
194 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0005, TestSize.Level0)
195 {
196 int ret = CodeSignUtils::EnforceCodeSignForApp(
197 g_wrongHapWithMultiLibRetFail, g_sigWithMultiLibRetSucPath);
198 EXPECT_EQ(ret, CS_ERR_ENABLE);
199 }
200
201 /**
202 * @tc.name: CodeSignUtilsTest_0006
203 * @tc.desc: enable code signature for app failed, reason = enable failed
204 * @tc.type: Func
205 * @tc.require:
206 */
207 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0006, TestSize.Level0)
208 {
209 size_t num = g_HapWithoutLibSigPkcs7ErrorPath.size();
210 int ret;
211 // wrong hap signature
212 for (size_t i = 0; i < num; i++) {
213 ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithoutLibRetSuc, g_HapWithoutLibSigPkcs7ErrorPath[i]);
214 EXPECT_EQ(ret, CS_ERR_ENABLE);
215 }
216
217 // wrong so signature
218 num = g_HapWithMultiLibSigPkcs7ErrorPath.size();
219 for (size_t i = 0; i < num; i++) {
220 ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithMultiLibRetSuc, g_HapWithMultiLibSigPkcs7ErrorPath[i]);
221 EXPECT_EQ(ret, CS_ERR_ENABLE);
222 }
223 }
224
225 /**
226 * @tc.name: CodeSignUtilsTest_0007
227 * @tc.desc: enable code signature for file, reason = wrong foramt pkcs7
228 * @tc.type: Func
229 * @tc.require:
230 */
231 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0007, TestSize.Level0)
232 {
233 ByteBuffer buffer;
234 bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
235 EXPECT_EQ(flag, true);
236 int ret = CodeSignUtils::EnforceCodeSignForFile(g_wrongFileEnableFail, buffer);
237 EXPECT_EQ(ret, CS_ERR_ENABLE);
238 }
239
240 /**
241 * @tc.name: CodeSignUtilsTest_0008
242 * @tc.desc: enable code signature for file, reason = enable failed
243 * @tc.type: Func
244 * @tc.require:
245 */
246 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0008, TestSize.Level0)
247 {
248 size_t num = g_fileSigEnableFailPath.size();
249 int ret;
250 for (size_t i = 0; i < num; i++) {
251 ByteBuffer buffer;
252 bool flag = ReadSignatureFromFile(g_fileSigEnableFailPath[i], buffer);
253 EXPECT_EQ(flag, true);
254 ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer);
255 EXPECT_EQ(ret, CS_ERR_ENABLE);
256 }
257 }
258
259 /**
260 * @tc.name: CodeSignUtilsTest_0009
261 * @tc.desc: enable code signature for file failed, reason = invalid path
262 * @tc.type: Func
263 * @tc.require:
264 */
265 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0009, TestSize.Level0)
266 {
267 ByteBuffer buffer;
268 bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
269 EXPECT_EQ(flag, true);
270 int ret = CodeSignUtils::EnforceCodeSignForFile("invalidPath", buffer);
271 EXPECT_EQ(ret, CS_ERR_FILE_PATH);
272 }
273
274 /**
275 * @tc.name: CodeSignUtilsTest_0010
276 * @tc.desc: enable code signature for file failed, reason = no signature
277 * @tc.type: Func
278 * @tc.require:
279 */
280 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0010, TestSize.Level0)
281 {
282 ByteBuffer buffer;
283 bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
284 EXPECT_EQ(flag, true);
285
286 int ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, NULL, buffer.GetSize());
287 EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE);
288
289 ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer.GetBuffer(), 0);
290 EXPECT_EQ(ret, CS_ERR_NO_SIGNATURE);
291 }
292
293 /**
294 * @tc.name: CodeSignUtilsTest_0011
295 * @tc.desc: enable code signature for file successfully
296 * @tc.type: Func
297 * @tc.require:
298 */
299 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0011, TestSize.Level0)
300 {
301 ByteBuffer buffer;
302 bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer);
303 EXPECT_EQ(flag, true);
304
305 int ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer);
306 EXPECT_EQ(ret, CS_SUCCESS);
307 }
308
309 /**
310 * @tc.name: CodeSignUtilsTest_0012
311 * @tc.desc: enable code signature for app successfully
312 * @tc.type: Func
313 * @tc.require:
314 */
315 HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0012, TestSize.Level0)
316 {
317 int ret;
318 ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithoutLibRetSuc, g_sigWithoutLibRetSucPath);
319 EXPECT_EQ(ret, CS_SUCCESS);
320
321 ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithMultiLibRetSuc, g_sigWithMultiLibRetSucPath);
322 EXPECT_EQ(ret, CS_SUCCESS);
323 }
324 } // namespace CodeSign
325 } // namespace Security
326 } // namespace OHOS