support enforcing and permissive mode for code signing

Signed-off-by: lihehe <lihehao@huawei.com>
Change-Id: Ic345be537542a85506315ed0c760917e7eaf125e
This commit is contained in:
lihehe 2023-12-25 21:15:58 +08:00
parent a54a7c08c4
commit 7b5b02a7a4
8 changed files with 95 additions and 26 deletions

View File

@ -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",

View File

@ -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);

View File

@ -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";
}
}
}

View File

@ -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
}
}
}
}

View File

@ -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

View File

@ -63,6 +63,7 @@
<option name="push" value="demo_with_multi_lib/entry-default-signed-debug.hap -> /data/app/el1/bundle/public/tmp/demo_with_multi_lib" src="res"/>
<option name="push" value="demo_cert/pkcs7/verify_test_profile.p7b -> /data/service/el0/profiles/tmp/demo_cert/pkcs7" src="res"/>
<option name="push" value="demo_cert/pkcs7/verify_test_profile.hap -> /data/app/el1/bundle/public/tmp" src="res"/>
<option name="push" value="demo_cert/pkcs7/add_and_remove_profile.p7b -> /data/service/el0/profiles/tmp/demo_cert/pkcs7" src="res"/>
</preparer>
<cleaner>
<option name="shell" value="rm -rf /data/service/el1/public/bms/bundle_manager_service/tmp"/>

View File

@ -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();