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 <cstdlib>
17#include <gtest/gtest.h>
18#include <string>
19
20#include "access_token_setter.h"
21#include "byte_buffer.h"
22#include "code_sign_utils.h"
23#include "local_code_sign_client.h"
24#include "local_code_sign_kit.h"
25#include "local_code_sign_load_callback.h"
26#include "local_key_helper.h"
27#include "log.h"
28#include "signer_info.h"
29
30using namespace OHOS::Security::CodeSign;
31using namespace testing::ext;
32using namespace std;
33
34namespace OHOS {
35namespace Security {
36namespace CodeSign {
37static const std::string AN_BASE_PATH = "/data/local/ark-cache/tmp/";
38static const std::string DEMO_AN_PATH = AN_BASE_PATH + "demo.an";
39static const std::string DEMO_AN_PATH2 = AN_BASE_PATH + "demo2.an";
40
41class LocalCodeSignTest : public testing::Test {
42public:
43    LocalCodeSignTest() {};
44    virtual ~LocalCodeSignTest() {};
45    static void SetUpTestCase() {};
46    static void TearDownTestCase() {};
47    void SetUp() {};
48    void TearDown() {};
49};
50
51/**
52 * @tc.name: LocalCodeSignTest_0001
53 * @tc.desc: init local certificate successfully
54 * @tc.type: Func
55 * @tc.require:
56 */
57HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0001, TestSize.Level0)
58{
59    ByteBuffer cert;
60    uint64_t selfTokenId = NativeTokenSet("key_enable");
61    int ret = LocalCodeSignKit::InitLocalCertificate(cert);
62    NativeTokenReset(selfTokenId);
63    EXPECT_EQ(ret, CS_SUCCESS);
64}
65
66/**
67 * @tc.name: LocalCodeSignTest_0002
68 * @tc.desc: init local certificate failed with invalid caller
69 * @tc.type: Func
70 * @tc.require:
71 */
72HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0002, TestSize.Level0)
73{
74    ByteBuffer cert;
75    int ret = LocalCodeSignKit::InitLocalCertificate(cert);
76    EXPECT_EQ(ret, CS_ERR_NO_PERMISSION);
77}
78
79/**
80 * @tc.name: LocalCodeSignTest_0003
81 * @tc.desc: sign local code successfully, owner ID is empty
82 * @tc.type: Func
83 * @tc.require:
84 */
85HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0003, TestSize.Level0)
86{
87    ByteBuffer sig;
88    uint64_t selfTokenId = NativeTokenSet("compiler_service");
89    int ret = LocalCodeSignKit::SignLocalCode(DEMO_AN_PATH, sig);
90    NativeTokenReset(selfTokenId);
91    EXPECT_EQ(ret, CS_SUCCESS);
92    std::string retOwnerID;
93    ret = CodeSignUtils::ParseOwnerIdFromSignature(sig, retOwnerID);
94    EXPECT_EQ(ret, CS_ERR_NO_OWNER_ID);
95    EXPECT_EQ(retOwnerID, "");
96    ret = CodeSignUtils::EnforceCodeSignForFile(DEMO_AN_PATH, sig);
97    EXPECT_EQ(ret, GetEnforceFileResult());
98}
99
100/**
101 * @tc.name: LocalCodeSignTest_0004
102 * @tc.desc: sign local code failed with invalid caller
103 * @tc.type: Func
104 * @tc.require:
105 */
106HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0004, TestSize.Level0)
107{
108    ByteBuffer sig;
109    int ret = LocalCodeSignKit::SignLocalCode(DEMO_AN_PATH, sig);
110    EXPECT_EQ(ret, CS_ERR_NO_PERMISSION);
111}
112
113/**
114 * @tc.name: LocalCodeSignTest_0005
115 * @tc.desc: sign local code failed with wrong path
116 * @tc.type: Func
117 * @tc.require:
118 */
119HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0005, TestSize.Level0)
120{
121    ByteBuffer sig;
122    uint64_t selfTokenId = NativeTokenSet("compiler_service");
123    int ret = LocalCodeSignKit::SignLocalCode(DEMO_AN_PATH + "invalid", sig);
124    NativeTokenReset(selfTokenId);
125    EXPECT_EQ(ret, CS_ERR_FILE_PATH);
126}
127
128/**
129 * @tc.name: LocalCodeSignTest_0006
130 * @tc.desc: local codesignsvr died
131 * @tc.type: Func
132 * @tc.require:
133 */
134HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0006, TestSize.Level0)
135{
136    LocalCodeSignClient *client = GetLocalCodeSignClient();
137    EXPECT_NE(client, nullptr);
138    sptr<ISystemAbilityManager> systemAbilityManager =
139        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
140    EXPECT_NE(systemAbilityManager, nullptr);
141    sptr<IRemoteObject> remoteObject =
142        systemAbilityManager->GetSystemAbility(LOCAL_CODE_SIGN_SA_ID);
143    client->OnRemoteLocalCodeSignSvrDied(remoteObject);
144}
145
146/**
147 * @tc.name: LocalCodeSignTest_0007
148 * @tc.desc: sign local code with owner ID successfully, parse owner ID from signature success
149 * @tc.type: Func
150 * @tc.require: issueI88PPA
151 */
152HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0007, TestSize.Level0)
153{
154    ByteBuffer sig;
155    uint64_t selfTokenId = NativeTokenSet("compiler_service");
156    std::string ownerID = "AppName123";
157    int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig);
158    NativeTokenReset(selfTokenId);
159    EXPECT_EQ(ret, CS_SUCCESS);
160
161    std::string retOwnerID;
162    ret = CodeSignUtils::ParseOwnerIdFromSignature(sig, retOwnerID);
163    EXPECT_EQ(ownerID, retOwnerID);
164    ret = CodeSignUtils::EnforceCodeSignForFile(DEMO_AN_PATH2, sig);
165    EXPECT_EQ(ret, GetEnforceFileResult());
166}
167
168/**
169 * @tc.name: LocalCodeSignTest_0008
170 * @tc.desc: sign local code with empty owner ID successfully
171 * @tc.type: Func
172 * @tc.require: issueI88PPA
173 */
174HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0008, TestSize.Level0)
175{
176    ByteBuffer sig;
177    uint64_t selfTokenId = NativeTokenSet("compiler_service");
178    std::string ownerID = "";
179    int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig);
180    NativeTokenReset(selfTokenId);
181    EXPECT_EQ(ret, CS_SUCCESS);
182    std::string retOwnerID;
183    ret = CodeSignUtils::ParseOwnerIdFromSignature(sig, retOwnerID);
184    EXPECT_EQ(ret, CS_ERR_NO_OWNER_ID);
185    EXPECT_EQ(retOwnerID, "");
186}
187
188/**
189 * @tc.name: LocalCodeSignTest_0009
190 * @tc.desc: sign local code with owner ID failed, reason = invalid path
191 * @tc.type: Func
192 * @tc.require: issueI88PPA
193 */
194HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0009, TestSize.Level0)
195{
196    ByteBuffer sig;
197    uint64_t selfTokenId = NativeTokenSet("compiler_service");
198    std::string ownerID = "AppName123";
199    int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2 + "invalid", sig);
200    NativeTokenReset(selfTokenId);
201    EXPECT_EQ(ret, CS_ERR_FILE_PATH);
202}
203
204/**
205 * @tc.name: LocalCodeSignTest_0010
206 * @tc.desc: sign local code failed with invalid caller
207 * @tc.type: Func
208 * @tc.require: issueI88PPA
209 */
210HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0010, TestSize.Level0)
211{
212    ByteBuffer sig;
213    std::string ownerID = "AppName123";
214    int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig);
215    EXPECT_EQ(ret, CS_ERR_NO_PERMISSION);
216}
217
218/**
219 * @tc.name: LocalCodeSignTest_0011
220 * @tc.desc: sign local code failed with ownerID exceed 128 bytes
221 * @tc.type: Func
222 * @tc.require: issueI8FCGF
223 */
224HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0011, TestSize.Level0)
225{
226    ByteBuffer sig;
227    uint64_t selfTokenId = NativeTokenSet("compiler_service");
228    std::string ownerID(33, 'a');
229    int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig);
230    NativeTokenReset(selfTokenId);
231    EXPECT_EQ(ret, CS_ERR_INVALID_OWNER_ID);
232}
233
234/**
235 * @tc.name: LocalCodeSignTest_0012
236 * @tc.desc: sign local code failed with ownerID exceed 128 bytes
237 * @tc.type: Func
238 * @tc.require: issueI8FCGF
239 */
240HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0012, TestSize.Level0)
241{
242    ByteBuffer sig;
243    uint64_t selfTokenId = NativeTokenSet("compiler_service");
244    std::string ownerID = "AppName123";
245
246    int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig);
247
248    NativeTokenSet("local_code_sign");
249    sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
250    EXPECT_NE(samgr, nullptr);
251
252    ret = samgr->UnloadSystemAbility(LOCAL_CODE_SIGN_SA_ID);
253    EXPECT_EQ(ret, ERR_OK);
254    NativeTokenSet("compiler_service");
255    LocalCodeSignKit::SignLocalCode(ownerID, DEMO_AN_PATH2, sig);
256    NativeTokenReset(selfTokenId);
257}
258
259/**
260 * @tc.name: LocalCodeSignTest_0013
261 * @tc.desc: load sa success and return remote object is not null
262 * @tc.type: Func
263 * @tc.require:
264 */
265HWTEST_F(LocalCodeSignTest, LocalCodeSignTest_0013, TestSize.Level0)
266{
267    LocalCodeSignLoadCallback cb;
268    cb.OnLoadSystemAbilityFail(LOCAL_CODE_SIGN_SA_ID);
269    cb.OnLoadSystemAbilitySuccess(LOCAL_CODE_SIGN_SA_ID - 1, nullptr);
270    cb.OnLoadSystemAbilitySuccess(LOCAL_CODE_SIGN_SA_ID, nullptr);
271
272    sptr<ISystemAbilityManager> systemAbilityManager =
273        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
274    EXPECT_NE(systemAbilityManager, nullptr);
275    sptr<IRemoteObject> remoteObject =
276        systemAbilityManager->GetSystemAbility(LOCAL_CODE_SIGN_SA_ID);
277    cb.OnLoadSystemAbilitySuccess(LOCAL_CODE_SIGN_SA_ID, remoteObject);
278}
279} // namespace CodeSign
280} // namespace Security
281} // namespace OHOS
282