From 77dc554eef16a70734454a1033615f7c30c71dbe Mon Sep 17 00:00:00 2001 From: yuzhaoyang Date: Thu, 19 Oct 2023 18:25:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BB=A3=E7=A0=81=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yuzhaoyang --- test/unittest/BUILD.gn | 8 ++ test/unittest/code_sign_ioctl_test.cpp | 113 ++++++++++++++++++ test/unittest/code_sign_utils_test.cpp | 48 +++++++- .../pkcs7_error/demo_without_lib_008.sig | Bin 0 -> 1385 bytes test/unittest/resources/ohos_test.xml | 1 + 5 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 test/unittest/code_sign_ioctl_test.cpp create mode 100644 test/unittest/resources/demo_without_lib/pkcs7_error/demo_without_lib_008.sig diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index b33b425..22070e5 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -14,6 +14,13 @@ import("//build/test.gni") import("../../code_signature.gni") +ohos_unittest("code_sign_ioctl_unittest") { + module_out_path = "security/code_signature" + sources = [ "code_sign_ioctl_test.cpp" ] + + deps = [ "${googletest_dir}:gtest" ] +} + ohos_unittest("code_sign_utils_unittest") { module_out_path = "security/code_signature" resource_config_file = "resources/ohos_test.xml" @@ -125,6 +132,7 @@ group("unittest_group") { testonly = true if (!defined(ohos_lite)) { deps = [ + ":code_sign_ioctl_unittest", ":code_sign_utils_unittest", ":local_code_sign_unittest", ":multi_thread_local_sign_unittest", diff --git a/test/unittest/code_sign_ioctl_test.cpp b/test/unittest/code_sign_ioctl_test.cpp new file mode 100644 index 0000000..848c05e --- /dev/null +++ b/test/unittest/code_sign_ioctl_test.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace Security { +namespace CodeSign { +using namespace std; +using namespace testing::ext; + +struct cert_chain_info { + uint32_t signing_length; + uint32_t issuer_length; + uint64_t signing; + uint64_t issuer; + uint32_t max_cert_chain; + uint8_t reserved[36]; +}; + +#define WRITE_CERT_CHAIN _IOW('k', 1, cert_chain_info) + +static const uint32_t MAX_CERT_CHAIN = 3; +static const uint32_t GREATER_THAN_MAX_CERT_CHAIN = 4; +static const uint32_t LESS_THAN_MIN_CERT_CHAIN = -1; + +static const string DEV_NAME = "/dev/code_sign"; +static const string TEST_SUBJECT = "OpenHarmony Application Release"; +static const string TEST_ISSUER = "OpenHarmony Application CA"; + +static bool CallIoctl(const char *signing, const char *issuer, uint32_t max_cert_chain) +{ + int fd = open(DEV_NAME.c_str(), O_WRONLY); + EXPECT_GE(fd, 0); + + cert_chain_info arg = { 0 }; + arg.signing = reinterpret_cast(signing); + arg.issuer = reinterpret_cast(issuer); + arg.signing_length = strlen(signing) + 1; + arg.issuer_length = strlen(issuer) + 1; + arg.max_cert_chain = max_cert_chain; + int ret = ioctl(fd, WRITE_CERT_CHAIN, &arg); + + close(fd); + return ret; +} + +class CodeSignIoctlTest : public testing::Test { +public: + CodeSignIoctlTest() {}; + virtual ~CodeSignIoctlTest() {}; + static void SetUpTestCase() {}; + static void TearDownTestCase() {}; + void SetUp() {}; + void TearDown() {}; +}; + +/** + * @tc.name: CodeSignIoctlTest_0001 + * @tc.desc: successfully called interface + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignIoctlTest, CodeSignIoctlTest_0001, TestSize.Level0) +{ + int ret = CallIoctl(TEST_SUBJECT.c_str(), TEST_ISSUER.c_str(), MAX_CERT_CHAIN); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.name: CodeSignIoctlTest_0002 + * @tc.desc: calling interface with greater than path len + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignIoctlTest, CodeSignIoctlTest_0002, TestSize.Level0) +{ + int ret = CallIoctl(TEST_SUBJECT.c_str(), TEST_ISSUER.c_str(), GREATER_THAN_MAX_CERT_CHAIN); + EXPECT_NE(ret, 0); +} + +/** + * @tc.name: CodeSignIoctlTest_0003 + * @tc.desc: calling interface with invalid path len + * @tc.type: Func + * @tc.require: + */ +HWTEST_F(CodeSignIoctlTest, CodeSignIoctlTest_0003, TestSize.Level0) +{ + int ret = CallIoctl(TEST_SUBJECT.c_str(), TEST_ISSUER.c_str(), LESS_THAN_MIN_CERT_CHAIN); + EXPECT_NE(ret, 0); +} +} // namespace CodeSign +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/code_sign_utils_test.cpp b/test/unittest/code_sign_utils_test.cpp index fd4c39b..0b978ba 100644 --- a/test/unittest/code_sign_utils_test.cpp +++ b/test/unittest/code_sign_utils_test.cpp @@ -13,7 +13,13 @@ * limitations under the License. */ +#include +#include +#include #include +#include +#include +#include #include "code_sign_utils.h" @@ -23,8 +29,23 @@ namespace CodeSign { using namespace testing::ext; using namespace std; +struct cert_chain_info { + uint32_t signing_length; + uint32_t issuer_length; + uint64_t signing; + uint64_t issuer; + uint32_t max_cert_chain; + uint8_t reserved[36]; +}; + +#define WRITE_CERT_CHAIN _IOW('k', 1, cert_chain_info) + +static const uint32_t MAX_CERT_CHAIN = 3; static const std::string TMP_BASE_PATH = "/data/service/el1/public/bms/bundle_manager_service/tmp"; static const std::string APP_BASE_PATH = "/data/app/el1/bundle/public/tmp"; +static const string DEV_NAME = "/dev/code_sign"; +static const string SUBJECT = "Huawei: HarmonyOS Application Code Signature"; +static const string ISSUER = "Huawei CBG Software Signing Service CA Test"; static const EntryMap g_hapWithoutLibRetSuc = { {"Hap", APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"}, @@ -61,6 +82,7 @@ static const std::vector g_HapWithoutLibSigPkcs7ErrorPath = { TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_005.sig", // Wrong signature TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_006.sig", // Expired signature TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_007.sig", // Cert chain validate fail + TMP_BASE_PATH + "/demo_without_lib/pkcs7_error/demo_without_lib_008.sig", // Wrong issuer }; static const std::vector g_HapWithMultiLibSigPkcs7ErrorPath = { @@ -107,6 +129,23 @@ public: void TearDown() {}; }; +static bool CallIoctl(const char *signing, const char *issuer, uint32_t max_cert_chain) +{ + int fd = open(DEV_NAME.c_str(), O_WRONLY); + EXPECT_GE(fd, 0); + + cert_chain_info arg = { 0 }; + arg.signing = reinterpret_cast(signing); + arg.issuer = reinterpret_cast(issuer); + arg.signing_length = strlen(signing) + 1; + arg.issuer_length = strlen(issuer) + 1; + arg.max_cert_chain = max_cert_chain; + int ret = ioctl(fd, WRITE_CERT_CHAIN, &arg); + + close(fd); + return ret; +} + static bool ReadSignatureFromFile(const std::string &path, ByteBuffer &data) { FILE *file = fopen(path.c_str(), "rb"); @@ -298,11 +337,14 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0010, TestSize.Level0) */ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0011, TestSize.Level0) { + int ret = CallIoctl(SUBJECT.c_str(), ISSUER.c_str(), MAX_CERT_CHAIN); + EXPECT_EQ(ret, 0); + ByteBuffer buffer; bool flag = ReadSignatureFromFile(g_filesigEnablePath, buffer); EXPECT_EQ(flag, true); - int ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer); + ret = CodeSignUtils::EnforceCodeSignForFile(g_fileEnableSuc, buffer); EXPECT_EQ(ret, CS_SUCCESS); } @@ -314,7 +356,9 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0011, TestSize.Level0) */ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0012, TestSize.Level0) { - int ret; + int ret = CallIoctl(SUBJECT.c_str(), ISSUER.c_str(), MAX_CERT_CHAIN); + EXPECT_EQ(ret, 0); + ret = CodeSignUtils::EnforceCodeSignForApp(g_hapWithoutLibRetSuc, g_sigWithoutLibRetSucPath); EXPECT_EQ(ret, CS_SUCCESS); diff --git a/test/unittest/resources/demo_without_lib/pkcs7_error/demo_without_lib_008.sig b/test/unittest/resources/demo_without_lib/pkcs7_error/demo_without_lib_008.sig new file mode 100644 index 0000000000000000000000000000000000000000..6d562d1ac8ebdafaa8e81464a7fa416eb51a2e99 GIT binary patch literal 1385 zcmV-v1(y0yO9KQH000080A_VfS8%QOq_%apy|fRzOPYqXlbG?0i6&ub@*HLq z!k9F9zXutwn3~9h@*eNUy~1w84C4=X<~R4AbAEH?+;cwPIbh>v5
  • ==?YC2p6^6 zxH`r)6Gafx9Xb%a)ck0K!f+H}jGxyKyUpbV*wA|BXzdt^ps1_r)o#DF_or(~;1O5?P6$!OIMM^$S%dFJM9)=cQZy+9FV@k)jo;=FE25O79Hguha|>`d z#VVuLnyEHZVilckpbhC_6=j}BYbdcIQap*WSfQu4yHo~4fCQN|L@t}km?2Ikr2Q<# z?e9wogn+hE`bMkGdZQt0yhnn44{O9zXN7mZgE1uQcaZ^_5lKRxVnB-L@Wo6w?#UKmc z1wMY);XF~2f?F4xPp=+dn)?}YKR_?08lOIRSLm{+Q}!X{#O=>7ByReU@T4Jdj(}S% z=?^~a1p(d#@8s9w(-K?NWB%@f_r9)~adBn5g9$L24U6$`2!l`pXFfR~1CnqJAP^T9 zE{b&Nr?Xm3!z2>ZY&u9|G+5^9DRYpHZ3t`YB^tFvW3qsN&EtU}UvL~lxr-oC zKmn2VaC=yO=wIY9XGko}R8uTW|57aGc`1x1h&do+v-QK>fd8X140FZ`({X@8NzO96 zzqkJ5dSS(bfFtJC5pNnRx(aAq;{SScuI?yQm!r?lHq{T+EsoS2`7RFiFS*q8$()&cd@r;oXD>M8^&iCFZj-Q z(msFD%U$D>+cBQ_FO2tr-fdusoEV>IG+J4nl~M=N05VcWl7mB}Aq>)TXY+rmYaVzy z$aV?H#W}uM8V5h3I6fv@K5m`pbG$n*I5aD#msMQ~ue(>B3m$hX@>sC;is|Cm>w4{; z8+hAI zVGs_~Fr7+s;`f{PS0x|>Xxo&K0?9DVo@AerpYZ2A7N*%5l$BM)XgY%$Y0NaRItbTL zW^0y-3L~Mv#LTdfk}mzBk#=%O=fF%9yek@g8&?WMiY3ELx6T!Q>2hAaDN5)S)5}|0 z8`iyN;)#cyTFf=>jS5lo7T>y>coeu1mDLwFTqv$As@_?5Yu}B+prd>93Xax3-4nI5 zu5#cT`kX9e(=y*Bg=u-V1AR)ilQv`wGYuuP9ANH$q|dQj+HE8|4PAfkBpyaOFDU5Y zh`5j*-*!U?GvT39Qa*SpNE}g|^u@(~9!=dF7A3h&pHfsKZFbv~EPV zcO3W@?QJV8h`C~~9-z*V&k>aCuJq-_7JJ5j1yD-?0zUv0000080A_VfS8%Q