From 980ef0d70d2d6f838952e0b6fd95b75e62ff46ca Mon Sep 17 00:00:00 2001 From: lihehe Date: Fri, 22 Dec 2023 19:50:53 +0800 Subject: [PATCH] modify the start condition of key_enable to support pre-installed app with code signature Signed-off-by: lihehe Change-Id: I37b282649755eed0c929085026aa2965a7a7e79b Signed-off-by: lihehe --- interfaces/innerkits/common/include/errcode.h | 3 +- services/key_enable/key_enable.cfg | 6 ++ services/key_enable/src/key_enable.rs | 26 ++++--- .../utils/src/local_code_sign_utils.cpp | 70 +++++++++++++++++-- services/local_code_sign/BUILD.gn | 5 +- .../include/permission_utils.h | 1 + .../local_code_sign/src/permission_utils.cpp | 19 +++++ .../signlocalcodestub_fuzzer/BUILD.gn | 3 +- 8 files changed, 110 insertions(+), 23 deletions(-) diff --git a/interfaces/innerkits/common/include/errcode.h b/interfaces/innerkits/common/include/errcode.h index 848e7e2..0dd77c2 100644 --- a/interfaces/innerkits/common/include/errcode.h +++ b/interfaces/innerkits/common/include/errcode.h @@ -38,7 +38,8 @@ enum SignErrCode { CS_ERR_HUKS_SIGN = -0x202, CS_ERR_HUKS_INIT_KEY = -0x203, CS_ERR_COMPUTE_DIGEST = -0x204, - CS_ERR_NO_OWNER_ID = -0x205 + CS_ERR_NO_OWNER_ID = -0x205, + CS_ERR_INIT_LOCAL_CERT = -0x206, }; enum OpenSSLErrCode { diff --git a/services/key_enable/key_enable.cfg b/services/key_enable/key_enable.cfg index 5e6f25b..3827f73 100644 --- a/services/key_enable/key_enable.cfg +++ b/services/key_enable/key_enable.cfg @@ -7,6 +7,11 @@ "mkdir /data/service/el0/profiles/developer 0655 installs installs", "mkdir /data/service/el0/profiles/debug 0655 installs installs" ] + }, { + "name" : "init", + "cmds" : [ + "start key_enable" + ] } ], "services" : [{ @@ -16,6 +21,7 @@ "uid" : "root", "gid" : ["root"], "secon" : "u:r:key_enable:s0", + "start-mode": "condition", "once": 1 } ] diff --git a/services/key_enable/src/key_enable.rs b/services/key_enable/src/key_enable.rs index 79dbf6d..87c49bb 100644 --- a/services/key_enable/src/key_enable.rs +++ b/services/key_enable/src/key_enable.rs @@ -199,31 +199,29 @@ fn restrict_keys(key_id: KeySerial) { } } -/// enforce keyring -fn enforce_keyring(root_cert: &PemCollection) { +/// enable trusted and local keys, and then restrict keyring +pub fn enable_all_keys() { let key_id = match get_keyring_id() { Ok(id) => id, Err(_) => return, }; - enable_trusted_keys(key_id, root_cert); - enable_local_key(key_id); - restrict_keys(key_id); -} + let root_cert = get_trusted_certs(); + // enable device keys and authed source + enable_trusted_keys(key_id, &root_cert); -fn add_cert_path(root_cert: &PemCollection) { let cert_paths = get_cert_path(); if cert_paths.add_cert_paths().is_err() { error!(LOG_LABEL, "Add trusted cert path err"); } - if add_profile_cert_path(root_cert, &cert_paths).is_err() { + + // enable developer cert + if add_profile_cert_path(&root_cert, &cert_paths).is_err() { error!(LOG_LABEL, "Add cert path from local profile"); } -} -/// enable trusted and local keys, and then restrict keyring -pub fn enable_all_keys() { - let root_cert = get_trusted_certs(); - enforce_keyring(&root_cert); - add_cert_path(&root_cert); + // enable local code sign key + enable_local_key(key_id); + restrict_keys(key_id); + info!(LOG_LABEL, "Fnished enable all keys."); } diff --git a/services/key_enable/utils/src/local_code_sign_utils.cpp b/services/key_enable/utils/src/local_code_sign_utils.cpp index f23764c..df2c329 100644 --- a/services/key_enable/utils/src/local_code_sign_utils.cpp +++ b/services/key_enable/utils/src/local_code_sign_utils.cpp @@ -15,23 +15,83 @@ #include "local_code_sign_utils.h" -#include "securec.h" +#include #include "byte_buffer.h" #include "local_code_sign_kit.h" +#include "log.h" +#include "securec.h" +#include "thread_ex.h" using namespace OHOS::Security::CodeSign; +namespace OHOS { +namespace Security { +namespace CodeSign { +constexpr uint32_t INIT_LOCAL_CERT_TIMEOUT_MS = 300000; +constexpr uint32_t INIT_LOCAL_CERT_SLEEP_US = 500 * 1000; +const std::string INIT_LOCAL_CERT_THREAD_NAME = "init_local_cert"; + +static std::condition_variable g_condition; +static std::mutex g_lock; + +class InitLocalCertThread : public OHOS::Thread { +public: + InitLocalCertThread() {} + ~InitLocalCertThread() {} + + bool GetStatus() + { + return success; + } + + ByteBuffer& GetCert() + { + return cert; + } +protected: + bool Run() + { + std::unique_lock lock(g_lock); + int32_t ret; + do { + ret = LocalCodeSignKit::InitLocalCertificate(cert); + usleep(INIT_LOCAL_CERT_SLEEP_US); + } while (ret == CS_ERR_SA_GET_PROXY); + success = (ret == CS_SUCCESS); + g_condition.notify_one(); + return true; + } +private: + bool success = false; + ByteBuffer cert; +}; +} +} +} + int32_t InitLocalCertificate(uint8_t *certData, uint32_t *certSize) { - ByteBuffer cert; - int32_t ret = LocalCodeSignKit::InitLocalCertificate(cert); - if (ret != CS_SUCCESS) { - return ret; + std::unique_ptr thread = std::make_unique(); + OHOS::ThreadStatus status = thread->Start(INIT_LOCAL_CERT_THREAD_NAME); + if (status != OHOS::ThreadStatus::OK) { + LOG_ERROR(LABEL, "initing local cert thread not start."); + return CS_ERR_INIT_LOCAL_CERT; } + + std::unique_lock lock(g_lock); + auto waitStatus = g_condition.wait_for(lock, std::chrono::milliseconds(INIT_LOCAL_CERT_TIMEOUT_MS), + [&thread]() { return thread->GetStatus(); }); + if (!waitStatus) { + LOG_ERROR(LABEL, "init local cert timeout"); + return CS_ERR_INIT_LOCAL_CERT; + } + + ByteBuffer &cert = thread->GetCert(); if (memcpy_s(certData, *certSize, cert.GetBuffer(), cert.GetSize()) != EOK) { return CS_ERR_MEMORY; } *certSize = cert.GetSize(); + return CS_SUCCESS; } \ No newline at end of file diff --git a/services/local_code_sign/BUILD.gn b/services/local_code_sign/BUILD.gn index 19de2bd..8b3f3b0 100644 --- a/services/local_code_sign/BUILD.gn +++ b/services/local_code_sign/BUILD.gn @@ -33,18 +33,19 @@ ohos_shared_library("liblocal_code_sign") { configs = [ "${code_signature_root_dir}:common_utils_config" ] deps = [ "${code_signature_root_dir}/utils:fsverity_sign_src_set", - "${openssl_dir}:libcrypto_shared", "${fsverity_utils_dir}:libfsverity_utils", + "${openssl_dir}:libcrypto_shared", ] external_deps = [ "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "c_utils:utils", "eventhandler:libeventhandler", + "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", - "hilog:libhilog", "huks:libhukssdk", + "init:libbegetutil", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", diff --git a/services/local_code_sign/include/permission_utils.h b/services/local_code_sign/include/permission_utils.h index 1898ee5..027a073 100644 --- a/services/local_code_sign/include/permission_utils.h +++ b/services/local_code_sign/include/permission_utils.h @@ -31,6 +31,7 @@ public: private: static bool VerifyCallingProcess(const std::vector &validCallers, const AccessToken::AccessTokenID &callerTokenID); + static bool HasATMInitilized(); }; } } diff --git a/services/local_code_sign/src/permission_utils.cpp b/services/local_code_sign/src/permission_utils.cpp index f5c95ab..ea98389 100644 --- a/services/local_code_sign/src/permission_utils.cpp +++ b/services/local_code_sign/src/permission_utils.cpp @@ -17,6 +17,7 @@ #include "accesstoken_kit.h" #include "cs_hisysevent.h" +#include "parameter.h" #include "ipc_skeleton.h" #include "log.h" @@ -25,6 +26,9 @@ namespace Security { namespace CodeSign { const std::vector CERTIFICATE_CALLERS = {"key_enable"}; const std::vector SIGN_CALLERS = {"installs"}; +constexpr int32_t VALUE_MAX_LEN = 32; +const char* g_accessTokenServiceInitKey = "accesstoken.permission.init"; +bool g_isAtmInited = false; bool PermissionUtils::IsValidCallerOfCert() { @@ -46,9 +50,24 @@ bool PermissionUtils::IsValidCallerOfLocalCodeSign() return false; } +bool PermissionUtils::HasATMInitilized() +{ + char value[VALUE_MAX_LEN] = {0}; + int32_t ret = GetParameter(g_accessTokenServiceInitKey, "", value, VALUE_MAX_LEN - 1); + if ((ret < 0) || (static_cast(std::atoll(value)) != 0)) { + g_isAtmInited = true; + return true; + } + return false; +} + bool PermissionUtils::VerifyCallingProcess(const std::vector &validCallers, const AccessToken::AccessTokenID &callerTokenId) { + if (!g_isAtmInited && !HasATMInitilized()) { + LOG_DEBUG(LABEL, "AccessTokenManager has not started yet."); + return true; + } for (const auto &caller: validCallers) { AccessToken::AccessTokenID tokenId = AccessToken::AccessTokenKit::GetNativeTokenId(caller); if (tokenId == callerTokenId) { diff --git a/test/fuzztest/local_code_sign_stub/signlocalcodestub_fuzzer/BUILD.gn b/test/fuzztest/local_code_sign_stub/signlocalcodestub_fuzzer/BUILD.gn index 27bc07a..7829697 100644 --- a/test/fuzztest/local_code_sign_stub/signlocalcodestub_fuzzer/BUILD.gn +++ b/test/fuzztest/local_code_sign_stub/signlocalcodestub_fuzzer/BUILD.gn @@ -9,7 +9,7 @@ # 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. +# limitations under the License. import("//build/config/features.gni") import("//build/test.gni") @@ -66,6 +66,7 @@ ohos_fuzztest("SignLocalCodeStubFuzzTest") { "hisysevent:libhisysevent", "hitrace:hitrace_meter", "huks:libhukssdk", + "init:libbegetutil", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", -- Gitee