• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 <fcntl.h>
18 #include <gtest/gtest.h>
19 #include <gtest/hwext/gtest-multithread.h>
20 #include <string>
21 
22 #include "access_token_setter.h"
23 #include "byte_buffer.h"
24 #include "code_sign_test_common.h"
25 #include "code_sign_utils.h"
26 #include "local_code_sign_kit.h"
27 #include "local_key_helper.h"
28 #include "log.h"
29 
30 using namespace OHOS::Security::CodeSign;
31 using namespace std;
32 using namespace testing::ext;
33 using namespace testing::mt;
34 
35 namespace OHOS {
36 namespace Security {
37 namespace CodeSign {
38 static constexpr uint32_t MULTI_THREAD_NUM = 10;
39 static constexpr int64_t BUFFER_SIZE = 1024;
40 static const std::string AN_BASE_PATH = "/data/local/ark-cache/tmp/multi_thread/";
41 static const std::string ORIGIN_AN_FILE = AN_BASE_PATH + "demo.an";
42 static const std::string DEMO_WITHOWNER_ID = AN_BASE_PATH + "demoWithownerID.an";
43 
44 static const char *VALID_CALLER = "compiler_service";
45 
GetFileSize(int32_t fd)46 uint64_t GetFileSize(int32_t fd)
47 {
48     struct stat st;
49     if (fstat(fd, &st) != 0) {
50         LOG_ERROR("Stat file failed, errno = <%{public}d, %{public}s>",
51             errno, strerror(errno));
52         return 0;
53     }
54     return st.st_size;
55 }
56 
DupFile(const std::string & path)57 static bool DupFile(const std::string &path)
58 {
59     int32_t fin = open(ORIGIN_AN_FILE.c_str(), O_RDONLY);
60     if (fin < 0) {
61         return false;
62     }
63     uint32_t fileSize = GetFileSize(fin);
64     int32_t fout = open(path.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0777);
65     if (fout < 0) {
66         close(fin);
67         return false;
68     }
69     ssize_t curSize = 0;
70     char buffer[BUFFER_SIZE];
71     bool ret = true;
72     while (curSize < fileSize) {
73         ssize_t len = read(fin, buffer, BUFFER_SIZE);
74         if (len <= 0) {
75             break;
76         }
77         curSize += len;
78         write(fout, buffer, len);
79     }
80     close(fin);
81     close(fout);
82     return ret;
83 }
84 
LocalCodeSignAndEnforce()85 void LocalCodeSignAndEnforce()
86 {
87     ByteBuffer sig;
88     uint64_t selfTokenId = GetSelfTokenID();
89     EXPECT_TRUE(MockTokenId(VALID_CALLER));
90     int ret = LocalCodeSignKit::SignLocalCode(ORIGIN_AN_FILE, sig);
91     std::thread::id thisId = std::this_thread::get_id();
92     std::ostringstream oss;
93     oss << thisId;
94     std::string thisIdStr = oss.str();
95     std::string tmpFileName = AN_BASE_PATH + thisIdStr + ".an";
96     EXPECT_EQ(DupFile(tmpFileName), true);
97     EXPECT_EQ(0, SetSelfTokenID(selfTokenId));
98     EXPECT_EQ(ret, CS_SUCCESS);
99     ret = CodeSignUtils::EnforceCodeSignForFile(tmpFileName, sig);
100     EXPECT_EQ(ret, GetEnforceFileResult());
101 }
102 
LocalCodeSignAndEnforceWithOwnerID()103 void LocalCodeSignAndEnforceWithOwnerID()
104 {
105     ByteBuffer sig;
106     uint64_t selfTokenId = GetSelfTokenID();
107     EXPECT_TRUE(MockTokenId(VALID_CALLER));
108     std::string ownerID = "AppName123";
109     int ret = LocalCodeSignKit::SignLocalCode(ownerID, DEMO_WITHOWNER_ID, sig);
110     std::thread::id thisId = std::this_thread::get_id();
111     std::ostringstream oss;
112     oss << thisId;
113     std::string thisIdStr = oss.str();
114     std::string tmpFileName = AN_BASE_PATH + thisIdStr + "demoWithownerID.an";
115     EXPECT_EQ(DupFile(tmpFileName), true);
116     EXPECT_EQ(0, SetSelfTokenID(selfTokenId));
117     EXPECT_EQ(ret, CS_SUCCESS);
118     ret = CodeSignUtils::EnforceCodeSignForFile(tmpFileName, sig);
119     EXPECT_EQ(ret, GetEnforceFileResult());
120 }
121 
122 class MultiThreadLocalSignTest : public testing::Test {
123 public:
MultiThreadLocalSignTest()124     MultiThreadLocalSignTest() {};
~MultiThreadLocalSignTest()125     virtual ~MultiThreadLocalSignTest() {};
SetUpTestCase()126     static void SetUpTestCase() {};
TearDownTestCase()127     static void TearDownTestCase() {};
SetUp()128     void SetUp() {};
TearDown()129     void TearDown() {};
130 };
131 
132 /**
133  * @tc.name: MultiThreadLocalSignTest_0001
134  * @tc.desc: sign AN files and enforce using multi threads
135  * @tc.type: Func
136  * @tc.require:
137  */
138 HWMTEST_F(MultiThreadLocalSignTest, MultiThreadLocalSignTest_0001, TestSize.Level1, MULTI_THREAD_NUM)
139 {
140     LocalCodeSignAndEnforce();
141 }
142 
143 /**
144  * @tc.name: MultiThreadLocalSignTest_0002
145  * @tc.desc: sign AN files with owner ID and enforce using multi threads
146  * @tc.type: Func
147  * @tc.require:
148  */
149 HWMTEST_F(MultiThreadLocalSignTest, MultiThreadLocalSignTest_0002, TestSize.Level1, MULTI_THREAD_NUM)
150 {
151     LocalCodeSignAndEnforceWithOwnerID();
152 }
153 } // namespace CodeSign
154 } // namespace Security
155 } // namespace OHOS