diff --git a/interfaces/innerkits/code_sign_utils/BUILD.gn b/interfaces/innerkits/code_sign_utils/BUILD.gn
index d525b08d4acdc211512c057b7b428f7a0e0499ba..534bb0647dbbab067ba19ebda0848a7085e60ba4 100644
--- a/interfaces/innerkits/code_sign_utils/BUILD.gn
+++ b/interfaces/innerkits/code_sign_utils/BUILD.gn
@@ -46,6 +46,9 @@ ohos_shared_library("libcode_sign_utils") {
if (code_signature_support_oh_code_sign) {
defines += [ "SUPPORT_OH_CODE_SIGN" ]
}
+ if (build_variant == "root" || !code_signature_enable_xpm_mode) {
+ defines += [ "SUPPORT_PERMISSIVE_MODE" ]
+ }
external_deps = [
"ability_base:extractortool",
"appverify:libhapverify",
diff --git a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h
index 9c55e3ba0ae3c11da19a7ea4e944ea15a1856547..fd145deb00dcba5cd599e91075e9f032fa3113ea 100644
--- a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h
+++ b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h
@@ -105,10 +105,15 @@ public:
*/
static int32_t RemoveKeyInProfile(const std::string &bundleName);
/**
- * @brief inteface for get support_openharmony_ca state
+ * @brief Whether enabling code signing for app compiled by oh-sdk
* @return return ture if support oh-sdk code sign
*/
static bool isSupportOHCodeSign();
+ /**
+ * @brief Check if code signing is permissive
+ * @return return ture if in permissive mode
+ */
+ static bool InPermissiveMode();
private:
static int32_t IsSupportFsVerity(const std::string &path);
static int32_t IsFsVerityEnabled(int fd);
diff --git a/interfaces/innerkits/code_sign_utils/include/constants.h b/interfaces/innerkits/code_sign_utils/include/constants.h
index acbbf6986085668d3ce9a7d12df1cacdc0e52831..5c543ba33c197334570cd9c45603e953358bb786 100644
--- a/interfaces/innerkits/code_sign_utils/include/constants.h
+++ b/interfaces/innerkits/code_sign_utils/include/constants.h
@@ -26,7 +26,7 @@ const std::string FSV_SIG_SUFFIX = ".fsv-sig";
const std::string ENABLE_SIGNATURE_FILE_BASE_PATH = "/data/service/el1/public/bms/bundle_manager_service";
const std::string ENABLE_APP_BASE_PATH = "/data/app/el1/bundle/public";
const std::string XPM_DEBUG_FS_MODE_PATH = "/proc/sys/kernel/xpm/xpm_mode";
-const std::string SUPPORT_OH_SDK_CODE_SIGN = "1";
+const std::string PERMISSIVE_CODE_SIGN_MODE = "0";
}
}
}
diff --git a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp
index 8885a1b202ab5596ec6c79b77445bad827babf7e..7a8979f72abcacaca8ea346e10492fd60d2a3c02 100644
--- a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp
+++ b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp
@@ -247,9 +247,10 @@ int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(const std::string &owner
ret = codeSignBlock.ParseCodeSignBlock(realPath, storedEntryMap_, type);
storedEntryMap_.clear();
if (ret != CS_SUCCESS) {
- if (ret != CS_CODE_SIGN_NOT_EXISTS) {
- ReportParseCodeSig(realPath, ret);
+ if ((ret == CS_CODE_SIGN_NOT_EXISTS) && InPermissiveMode()) {
+ return CS_SUCCESS;
}
+ ReportParseCodeSig(realPath, ret);
return ret;
}
CodeSignEnableMultiTask multiTask;
@@ -320,9 +321,11 @@ int32_t CodeSignUtils::RemoveKeyInProfile(const std::string &bundleName)
LABEL, "Remove key in profile failed. errno = <%{public}d, %{public}s>", errno, strerror(errno));
return CS_ERR_PROFILE;
}
-bool CodeSignUtils::isSupportOHCodeSign()
+
+bool CodeSignUtils::InPermissiveMode()
{
-#ifdef SUPPORT_OH_CODE_SIGN
+#ifdef SUPPORT_PERMISSIVE_MODE
+ // defaults to on if file does not exsit
std::ifstream file(Constants::XPM_DEBUG_FS_MODE_PATH);
if (!file.is_open()) {
return false;
@@ -331,8 +334,9 @@ bool CodeSignUtils::isSupportOHCodeSign()
std::string content;
file >> content;
file.close();
-
- if (content == Constants::SUPPORT_OH_SDK_CODE_SIGN) {
+
+ if (content == Constants::PERMISSIVE_CODE_SIGN_MODE) {
+ LOG_DEBUG(LABEL, "Permissive mode is on.");
return true;
}
return false;
@@ -340,6 +344,15 @@ bool CodeSignUtils::isSupportOHCodeSign()
return false;
#endif
}
+
+bool CodeSignUtils::isSupportOHCodeSign()
+{
+#ifdef SUPPORT_OH_CODE_SIGN
+ return !InPermissiveMode();
+#else
+ return false;
+#endif
+}
}
}
}
diff --git a/test/unittest/code_sign_utils_test.cpp b/test/unittest/code_sign_utils_test.cpp
index 50593c4d9b6c8f6b64deb219dab4cd16644fa23a..57bf760b4bf3ea7376967f8a64d6c5ae56de9d11 100644
--- a/test/unittest/code_sign_utils_test.cpp
+++ b/test/unittest/code_sign_utils_test.cpp
@@ -23,7 +23,9 @@
#include "code_sign_utils.h"
#include "code_sign_block.h"
+#include "directory_ex.h"
#include "enable_key_utils.h"
+#include "xpm_common.h"
namespace OHOS {
namespace Security {
@@ -112,6 +114,8 @@ static const EntryMap g_hapSigNotExist = {
{"sigNotExist", APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap"},
};
+static bool g_isPermissive = false;
+
class CodeSignUtilsTest : public testing::Test {
public:
CodeSignUtilsTest() {};
@@ -120,8 +124,17 @@ public:
{
EXPECT_EQ(EnableTestKey(SUBJECT.c_str(), ISSUER.c_str()), 0);
EXPECT_EQ(EnableTestKey(OH_SUBJECT.c_str(), OH_ISSUER.c_str()), 0);
+ g_isPermissive = CodeSignUtils::InPermissiveMode();
+ if (g_isPermissive) {
+ SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, ENFORCE_MODE);
+ }
+ };
+ static void TearDownTestCase()
+ {
+ if (g_isPermissive) {
+ SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, PERMISSIVE_MODE);
+ }
};
- static void TearDownTestCase() {};
void SetUp() {};
void TearDown() {};
};
@@ -442,20 +455,8 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0016, TestSize.Level0)
{
std::string hapRealPath = APP_BASE_PATH + "/demo_with_multi_lib/demo_with_code_sign_block.hap";
EntryMap entryMap;
- std::string profileEnablePath = PROFILE_BASE_PATH + "/demo_cert/pkcs7/verify_test_profile.p7b";
- ByteBuffer buffer;
- bool flag = ReadSignatureFromFile(profileEnablePath, buffer);
- EXPECT_EQ(flag, true);
-
- string bundlName = "CodeSignUtilsTest";
- int32_t ret = CodeSignUtils::EnableKeyInProfile(bundlName, buffer);
- EXPECT_EQ(ret, CS_SUCCESS);
-
CodeSignUtils utils;
- ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF);
- EXPECT_EQ(ret, CS_SUCCESS);
-
- ret = CodeSignUtils::RemoveKeyInProfile(bundlName);
+ int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF);
EXPECT_EQ(ret, CS_SUCCESS);
std::string filePath1("libs/arm64-v8a/libc++_shared.so");
@@ -565,7 +566,7 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0021, TestSize.Level0)
*/
HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0022, TestSize.Level0)
{
- std::string profileEnablePath = PROFILE_BASE_PATH + "/demo_cert/pkcs7/verify_test_profile.p7b";
+ std::string profileEnablePath = PROFILE_BASE_PATH + "/demo_cert/pkcs7/add_and_remove_profile.p7b";
ByteBuffer buffer;
bool flag = ReadSignatureFromFile(profileEnablePath, buffer);
EXPECT_EQ(flag, true);
@@ -574,8 +575,14 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0022, TestSize.Level0)
int32_t ret = CodeSignUtils::EnableKeyInProfile(bundlName, buffer);
EXPECT_EQ(ret, CS_SUCCESS);
+ std::string pathOnDisk = "/data/service/el0/profiles/developer/CodeSignUtilsTest/profile.p7b";
+ std::string realPath;
+ EXPECT_EQ(OHOS::PathToRealPath(pathOnDisk, realPath), true);
+
ret = CodeSignUtils::RemoveKeyInProfile(bundlName);
EXPECT_EQ(ret, CS_SUCCESS);
+
+ EXPECT_EQ(OHOS::PathToRealPath(pathOnDisk, realPath), false);
}
/**
@@ -608,6 +615,43 @@ HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0023, TestSize.Level0)
ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_ALL);
EXPECT_EQ(ret, CS_SUCCESS);
}
+
+/**
+ * @tc.name: CodeSignUtilsTest_0024
+ * @tc.desc: success without signature in permissive mode
+ * @tc.type: Func
+ * @tc.require: I8R8V7
+ */
+HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0024, TestSize.Level0)
+{
+ if (!SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, PERMISSIVE_MODE)) {
+ return;
+ }
+ EntryMap entryMap;
+ CodeSignUtils utils;
+ std::string hapRealPath = APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap";
+ int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF);
+ EXPECT_EQ(ret, CS_SUCCESS);
+ SaveStringToFile(XPM_DEBUG_FS_MODE_PATH, ENFORCE_MODE);
+}
+
+/**
+ * @tc.name: CodeSignUtilsTest_0025
+ * @tc.desc: failed without signature in enforcing mode
+ * @tc.type: Func
+ * @tc.require: I8R8V7
+ */
+HWTEST_F(CodeSignUtilsTest, CodeSignUtilsTest_0025, TestSize.Level0)
+{
+ if (CodeSignUtils::InPermissiveMode()) {
+ return;
+ }
+ std::string hapRealPath = APP_BASE_PATH + "/demo_without_lib/demo_without_lib.hap";
+ EntryMap entryMap;
+ CodeSignUtils utils;
+ int32_t ret = utils.EnforceCodeSignForApp(hapRealPath, entryMap, FILE_SELF);
+ EXPECT_EQ(ret, CS_CODE_SIGN_NOT_EXISTS);
+}
} // namespace CodeSign
} // namespace Security
} // namespace OHOS
diff --git a/test/unittest/resources/demo_cert/pkcs7/add_and_remove_profile.p7b b/test/unittest/resources/demo_cert/pkcs7/add_and_remove_profile.p7b
new file mode 100644
index 0000000000000000000000000000000000000000..0be372ddb4521bd17251dc2acd26ac9ad85c06fd
Binary files /dev/null and b/test/unittest/resources/demo_cert/pkcs7/add_and_remove_profile.p7b differ
diff --git a/test/unittest/resources/ohos_test.xml b/test/unittest/resources/ohos_test.xml
index 4fa072924ac138bb5bb46d3d0c18aef923cc14a5..cf588acb9b833ed05ed8d4aea8f4cdb6f7029253 100644
--- a/test/unittest/resources/ohos_test.xml
+++ b/test/unittest/resources/ohos_test.xml
@@ -63,6 +63,7 @@
+
diff --git a/test/unittest/utils/include/xpm_common.h b/test/unittest/utils/include/xpm_common.h
index 067fcbf0986473c1b1813161eb8b4cc47720fbea..a7ccdaa6051e8bdc73eec704613e5887d5c0f96f 100644
--- a/test/unittest/utils/include/xpm_common.h
+++ b/test/unittest/utils/include/xpm_common.h
@@ -34,13 +34,16 @@ const std::string SELINUX_MODE_PATH = "/sys/fs/selinux/enforce";
const std::string PERMISSIVE_MODE = "0";
const std::string ENFORCE_MODE = "1";
-inline void SaveStringToFile(const std::string &filePath,
+inline bool SaveStringToFile(const std::string &filePath,
const std::string &value)
{
- std::fstream fout;
- fout.open(filePath, std::ios::out);
+ std::fstream fout(filePath, std::ios::out);
+ if (!fout.is_open()) {
+ return false;
+ }
fout << value;
fout.close();
+ return true;
}
bool AllocXpmRegion();