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 <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 <sys/utsname.h>
23 #include <unistd.h>
24
25 namespace OHOS {
26 namespace Security {
27 namespace CodeSign {
28 using namespace std;
29 using namespace testing::ext;
30
31 struct cert_chain_info {
32 uint32_t signing_length;
33 uint32_t issuer_length;
34 uint64_t signing;
35 uint64_t issuer;
36 uint32_t max_cert_chain;
37 uint32_t cert_path_type;
38 uint8_t reserved[32];
39 };
40
41 #define WRITE_CERT_CHAIN _IOW('k', 1, cert_chain_info)
42
43 static const uint32_t MAX_CERT_CHAIN = 3;
44 static const uint32_t CERT_PATH_TYPE = 0x103;
45 static const uint32_t GREATER_THAN_MAX_CERT_CHAIN = 4;
46 static const uint32_t LESS_THAN_MIN_CERT_CHAIN = -1;
47
48 static const string DEV_NAME = "/dev/code_sign";
49 static const string TEST_SUBJECT = "OpenHarmony Application Release";
50 static const string TEST_ISSUER = "OpenHarmony Application CA";
51
52 static bool g_isKernelLinux = false;
53 class AddCertPathTest : public testing::Test {
54 public:
AddCertPathTest()55 AddCertPathTest() {};
~AddCertPathTest()56 virtual ~AddCertPathTest() {};
SetUpTestCase()57 static void SetUpTestCase()
58 {
59 struct utsname uts;
60 if (uname(&uts) == 0 && strcmp(uts.sysname, "Linux") == 0) {
61 g_isKernelLinux = true;
62 }
63 };
TearDownTestCase()64 static void TearDownTestCase() {};
SetUp()65 void SetUp() {};
TearDown()66 void TearDown() {};
67 };
68
CallIoctl(const char * signing,const char * issuer,uint32_t max_cert_chain,uint32_t cert_path_type)69 static bool CallIoctl(const char *signing, const char *issuer, uint32_t max_cert_chain, uint32_t cert_path_type)
70 {
71 int fd = open(DEV_NAME.c_str(), O_WRONLY);
72 EXPECT_GE(fd, 0);
73
74 cert_chain_info arg = { 0 };
75 arg.signing = reinterpret_cast<uint64_t>(signing);
76 arg.issuer = reinterpret_cast<uint64_t>(issuer);
77 arg.signing_length = strlen(signing) + 1;
78 arg.issuer_length = strlen(issuer) + 1;
79 arg.max_cert_chain = max_cert_chain;
80 arg.cert_path_type = cert_path_type;
81 int ret = ioctl(fd, WRITE_CERT_CHAIN, &arg);
82
83 close(fd);
84 return ret;
85 }
86
87 /**
88 * @tc.name: AddCertPathTest_0001
89 * @tc.desc: successfully called interface
90 * @tc.type: Func
91 * @tc.require:
92 */
93 HWTEST_F(AddCertPathTest, AddCertPathTest_0001, TestSize.Level0)
94 {
95 int ret = CallIoctl(TEST_SUBJECT.c_str(), TEST_ISSUER.c_str(), MAX_CERT_CHAIN, CERT_PATH_TYPE);
96 EXPECT_GE(ret, 0);
97 }
98
99 /**
100 * @tc.name: AddCertPathTest_0002
101 * @tc.desc: calling interface with greater than path len
102 * @tc.type: Func
103 * @tc.require:
104 */
105 HWTEST_F(AddCertPathTest, AddCertPathTest_0002, TestSize.Level0)
106 {
107 if (!g_isKernelLinux) {
108 return;
109 }
110 int ret = CallIoctl(TEST_SUBJECT.c_str(), TEST_ISSUER.c_str(), GREATER_THAN_MAX_CERT_CHAIN, CERT_PATH_TYPE);
111 EXPECT_NE(ret, 0);
112 }
113
114 /**
115 * @tc.name: AddCertPathTest_0003
116 * @tc.desc: calling interface with invalid path len
117 * @tc.type: Func
118 * @tc.require:
119 */
120 HWTEST_F(AddCertPathTest, AddCertPathTest_0003, TestSize.Level0)
121 {
122 if (!g_isKernelLinux) {
123 return;
124 }
125 int ret = CallIoctl(TEST_SUBJECT.c_str(), TEST_ISSUER.c_str(), LESS_THAN_MIN_CERT_CHAIN, CERT_PATH_TYPE);
126 EXPECT_NE(ret, 0);
127 }
128 } // namespace CodeSign
129 } // namespace Security
130 } // namespace OHOS