diff --git a/bundle.json b/bundle.json index ee79ae124e371299137f2bc383291c64572b8338..4e657fe8d6baef81058292173178f6b9da8e4184 100644 --- a/bundle.json +++ b/bundle.json @@ -48,6 +48,7 @@ "init", "napi", "os_account", + "relational_store", "safwk", "samgr", "security_guard", @@ -60,10 +61,10 @@ "//base/security/certificate_manager:cert_manager_type_base" ], "fwk_group": [ - "//base/security/certificate_manager:cert_manager_type_fwk" + "//base/security/certificate_manager:cert_manager_type_fwk" ], "service_group": [ - "//base/security/certificate_manager:cert_manager_typer_services" + "//base/security/certificate_manager:cert_manager_typer_services" ] }, "inner_kits": [ diff --git a/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h b/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h index 2f3b04ed77a5e65fcbc8b861dc7adeb4110864af..f81a4c3ab6cf246e3535db1e210930713573460d 100644 --- a/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h +++ b/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h @@ -45,6 +45,7 @@ extern "C" { #define MAX_LEN_SUBJECT_NAME 256 #define MAX_LEN_PACKGE_NAME 64 #define MAX_UINT32_LEN 16 +#define MAX_LEN_CERT_TYPE 8 #define MAX_LEN_ISSUER_NAME 256 #define MAX_LEN_SERIAL 64 @@ -143,6 +144,11 @@ enum CmErrorCode { CMR_ERROR_ALIAS_LENGTH_REACHED_LIMIT = -28, CMR_ERROR_GET_ADVSECMODE_PARAM_FAIL = -29, CMR_ERROR_DEVICE_ENTER_ADVSECMODE = -30, + CMR_ERROR_CREATE_RDB_TABLE_FAIL = -31, + CMR_ERROR_INSERT_RDB_DATA_FAIL = -32, + CMR_ERROR_UPDATE_RDB_DATA_FAIL = -33, + CMR_ERROR_DELETE_RDB_DATA_FAIL = -34, + CMR_ERROR_QUERY_RDB_DATA_FAIL = -35, }; enum CMErrorCode { /* temp use */ diff --git a/services/cert_manager_standard/BUILD.gn b/services/cert_manager_standard/BUILD.gn index 45ee1b7308d1ca6891dd6c177f69efb9c7ca2bf5..f5f8f9b4c364916ac76934e354e8bdb886a8777f 100644 --- a/services/cert_manager_standard/BUILD.gn +++ b/services/cert_manager_standard/BUILD.gn @@ -55,6 +55,7 @@ ohos_shared_library("cert_manager_service") { deps = [ ":cert_manager_service.rc", "cert_manager_engine/main/core:cert_manager_engine_core_standard", + "cert_manager_engine/main/rdb:libcert_manager_rdb_static", "cert_manager_service/main/os_dependency:libcert_manager_service_os_dependency_standard_static", ] external_deps = [ diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/BUILD.gn b/services/cert_manager_standard/cert_manager_engine/main/rdb/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..a7ddb2b02bf567e7b24e1d3440c92f457f7b9540 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/BUILD.gn @@ -0,0 +1,59 @@ +# Copyright (C) 2024 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. + +import("//build/ohos.gni") + +config("cert_manager_config") { + include_dirs = [ "include" ] +} + +ohos_static_library("libcert_manager_rdb_static") { + subsystem_name = "security" + part_name = "certificate_manager" + public_configs = [ ":cert_manager_config" ] + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + boundary_sanitize = true + debug = false + integer_overflow = true + ubsan = true + } + + include_dirs = [ + "../../../../../frameworks/cert_manager_standard/main/common/include", + "../../../../../interfaces/innerkits/cert_manager_standard/main/include", + ] + + sources = [ + "src/cm_cert_property_rdb.cpp", + "src/cm_rdb_data_manager.cpp", + "src/cm_rdb_open_callback.cpp", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "relational_store:native_rdb", + ] + + defines = [ "_CM_LOG_ENABLE_" ] + + cflags_cc = [ + "-Wall", + "-Werror", + ] + cflags = cflags_cc + complete_static_lib = true +} diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_cert_property_rdb.h b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_cert_property_rdb.h new file mode 100644 index 0000000000000000000000000000000000000000..559a57867fc68de1840252538c6e2b1b7d88af62 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_cert_property_rdb.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef CM_CERT_PROPERTY_RDB_H +#define CM_CERT_PROPERTY_RDB_H + +#include "cm_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct CertProperty { + char uri[MAX_LEN_URI]; + char alias[MAX_LEN_CERT_ALIAS]; + char subjectName[MAX_LEN_SUBJECT_NAME]; + char certType[MAX_LEN_CERT_TYPE]; + int32_t certStore; + int32_t userId; + int32_t uid; +}; + +int32_t CreateCertPropertyRdb(void); + +int32_t InsertCertProperty(const struct CertProperty *certProperty); + +int32_t DeleteCertProperty(const char *uri); + +int32_t UpdateCertProperty(const struct CertProperty *certProperty); + +int32_t QueryCertProperty(const char *uri, struct CertProperty *certProperty); + +#ifdef __cplusplus +} +#endif +#endif // CM_CERT_PROPERTY_RDB_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_config.h b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_config.h new file mode 100644 index 0000000000000000000000000000000000000000..2314720492fe3eb5f410901384388ae0ce42c6ac --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_config.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef CM_RDB_CONFIG_H +#define CM_RDB_CONFIG_H + +#include +#include + +namespace OHOS { +namespace Security { +namespace CertManager { +struct RdbConfig { + int32_t version = 1; + std::string dbPath = "/data/service/el1/public/cert_manager_service/rdb"; + std::string dbName; + std::string tableName; + std::string createTableSql; +}; +} // namespace CertManager +} // namespace Security +} // namespace OHOS + +#endif // CM_RDB_CONFIG_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_data_manager.h b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_data_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..f911a9b9089da8bb7a5de1f43616038341d44751 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_data_manager.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef CM_RDB_DATA_MANAGER_H +#define CM_RDB_DATA_MANAGER_H + +#include + +#include "rdb_helper.h" + +#include "cm_rdb_config.h" + +namespace OHOS { +namespace Security { +namespace CertManager { +class CmRdbDataManager : public std::enable_shared_from_this { +public: + CmRdbDataManager(const RdbConfig &rdbConfig); + ~CmRdbDataManager(); + + bool InsertData(const NativeRdb::ValuesBucket &valuesBucket); + bool UpdateData(const std::string &primKey, const std::string &keyColumn, + const NativeRdb::ValuesBucket &valuesBucket); + bool DeleteData(const std::string &primKey, const std::string &keyColumn); + std::shared_ptr QueryData(const std::string &primKey, const std::string &keyColumn); + + bool CreateTable(); + void DelayCloseRdbStore(); + static void ClearCache(); + +private: + std::shared_ptr GetRdbStore(); + + RdbConfig rdbConfig_; + std::mutex rdbMutex_; + std::shared_ptr rdbStore_; +}; +} // namespace CertManager +} // namespace Security +} // namespace OHOS + +#endif // CM_RDB_DATA_MANAGER_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_open_callback.h b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_open_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..f74ca4411abecc513fa3e8654969f96d4f21f7b4 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_rdb_open_callback.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef CM_RDB_OPEN_CALLBACK_H +#define CM_RDB_OPEN_CALLBACK_H + +#include "rdb_open_callback.h" + +#include "cm_rdb_config.h" + +namespace OHOS { +namespace Security { +namespace CertManager { +class CmRdbOpenCallback : public NativeRdb::RdbOpenCallback { +public: + CmRdbOpenCallback(const RdbConfig &rdbConfig); + int32_t OnCreate(NativeRdb::RdbStore &rdbStore) override; + int32_t OnUpgrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion) override; + int32_t OnDowngrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion) override; + int32_t OnOpen(NativeRdb::RdbStore &rdbStore) override; + +private: + RdbConfig rdbConfig_; +}; +} // namespace CertManager +} // namespace Security +} // namespace OHOS + +#endif // CM_RDB_OPEN_CALLBACK_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_scope_guard.h b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_scope_guard.h new file mode 100644 index 0000000000000000000000000000000000000000..57188c42d6e18f87378292f1fc3e60d575e8359f --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/include/cm_scope_guard.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 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. + */ + +#ifndef CM_SCOPE_GUARD_H +#define CM_SCOPE_GUARD_H + +namespace OHOS { +namespace Security { +namespace CertManager { +class CmScoprGuard final { +public: + using Function = std::function; + explicit CmScoprGuard(Function fn) : fn_(fn), dismissed_(false) {} + + ~CmScoprGuard() + { + if (!dismissed_) { + fn_(); + } + } + + void Dismiss() + { + dismissed_ = true; + } + +private: + Function fn_; + bool dismissed_; +}; +} // namespace CertManager +} // namespace Security +} // namespace OHOS +#endif // CM_SCOPE_GUARD_H \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_cert_property_rdb.cpp b/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_cert_property_rdb.cpp new file mode 100644 index 0000000000000000000000000000000000000000..375967758c82113a86540e1886a66a1ac3cbb1f6 --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_cert_property_rdb.cpp @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2024 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 "cm_cert_property_rdb.h" + +#include "securec.h" + +#include "cm_log.h" +#include "cm_rdb_config.h" +#include "cm_rdb_data_manager.h" +#include "cm_scope_guard.h" + +using namespace OHOS; +using namespace OHOS::Security::CertManager; + +const std::string CERT_MANAGER_RDB_NAME = "/cert_manager.db"; +const std::string CERT_PROPERTY_TABLE_NAME = "cert_property"; +const std::string COLUMN_URI = "URI"; +const std::string COLUMN_ALIAS = "ALIAS"; +const std::string COLUMN_SUBJECT_NAME = "SUBJECT_NAME"; +const std::string COLUMN_CERT_TYPE = "CERT_TYPE"; +const std::string COLUMN_CERT_STORE = "CERT_STORE"; +const std::string COLUMN_USERID = "USERID"; +const std::string COLUMN_UID = "UID"; + +static std::shared_ptr cmRdbDataManager = nullptr; + +int32_t CreateCertPropertyRdb(void) +{ + CM_LOG_D("enter CreateCertPropertyRdb"); + RdbConfig rdbConfig; + rdbConfig.dbName = CERT_MANAGER_RDB_NAME; + rdbConfig.tableName = CERT_PROPERTY_TABLE_NAME; + rdbConfig.createTableSql = std::string("CREATE TABLE IF NOT EXISTS " + CERT_PROPERTY_TABLE_NAME + + "(URI TEXT PRIMARY KEY, ALIAS TEXT NOT NULL, SUBJECT_NAME TEXT NOT NULL, CERT_TYPE TEXT NOT NULL, " + + "CERT_STORE INTEGER NOT NULL, USERID INTEGER NOT NULL, UID INTEGER NOT NULL)"); + cmRdbDataManager = std::make_shared(rdbConfig); + bool ret = cmRdbDataManager->CreateTable(); + if (!ret) { + CM_LOG_E("Failed to create cert_property table"); + return CMR_ERROR_CREATE_RDB_TABLE_FAIL; + } + return CM_SUCCESS; +} + +int32_t InsertCertProperty(const struct CertProperty *certProperty) +{ + CM_LOG_D("enter InsertCertProperty"); + if (certProperty == nullptr) { + CM_LOG_E("certProperty is nullptr"); + return CMR_ERROR_INVALID_ARGUMENT; + } + if (cmRdbDataManager == nullptr) { + CM_LOG_E("cmRdbDataManager is nullptr"); + return CMR_ERROR_NULL_POINTER; + } + + NativeRdb::ValuesBucket insertBucket; + insertBucket.PutString(COLUMN_URI, std::string(certProperty->uri)); + insertBucket.PutString(COLUMN_ALIAS, std::string(certProperty->alias)); + insertBucket.PutString(COLUMN_SUBJECT_NAME, std::string(certProperty->subjectName)); + insertBucket.PutString(COLUMN_CERT_TYPE, std::string(certProperty->certType)); + insertBucket.PutInt(COLUMN_CERT_STORE, certProperty->certStore); + insertBucket.PutInt(COLUMN_USERID, certProperty->userId); + insertBucket.PutInt(COLUMN_UID, certProperty->uid); + bool ret = cmRdbDataManager->InsertData(insertBucket); + if (!ret) { + CM_LOG_E("Failed to insert cert:%s property data", certProperty->uri); + return CMR_ERROR_INSERT_RDB_DATA_FAIL; + } + return CM_SUCCESS; +} + +int32_t DeleteCertProperty(const char *uri) +{ + CM_LOG_D("enter DeleteCertProperty"); + if (uri == nullptr) { + CM_LOG_E("uri is invalid"); + return CMR_ERROR_INVALID_ARGUMENT; + } + if (cmRdbDataManager == nullptr) { + CM_LOG_E("cmRdbDataManager is nullptr"); + return CMR_ERROR_NULL_POINTER; + } + + bool ret = cmRdbDataManager->DeleteData(std::string(uri), COLUMN_URI); + if (!ret) { + CM_LOG_E("Failed to delete cert:%s property data", uri); + return CMR_ERROR_DELETE_RDB_DATA_FAIL; + } + return CM_SUCCESS; +} + +int32_t UpdateCertProperty(const struct CertProperty *certProperty) +{ + CM_LOG_D("enter UpdateCertProperty"); + if (certProperty == nullptr) { + CM_LOG_E("certProperty is nullptr"); + return CMR_ERROR_INVALID_ARGUMENT; + } + if (cmRdbDataManager == nullptr) { + CM_LOG_E("cmRdbDataManager is nullptr"); + return CMR_ERROR_NULL_POINTER; + } + + NativeRdb::ValuesBucket updateBucket; + updateBucket.PutString(COLUMN_URI, std::string(certProperty->uri)); + updateBucket.PutString(COLUMN_ALIAS, std::string(certProperty->alias)); + updateBucket.PutString(COLUMN_SUBJECT_NAME, std::string(certProperty->subjectName)); + updateBucket.PutString(COLUMN_CERT_TYPE, std::string(certProperty->certType)); + updateBucket.PutInt(COLUMN_CERT_STORE, certProperty->certStore); + updateBucket.PutInt(COLUMN_USERID, certProperty->userId); + updateBucket.PutInt(COLUMN_UID, certProperty->uid); + bool ret = cmRdbDataManager->UpdateData(std::string(certProperty->uri), COLUMN_URI, updateBucket); + if (!ret) { + CM_LOG_E("Failed to update cert:%s property data", certProperty->uri); + return CMR_ERROR_DELETE_RDB_DATA_FAIL; + } + return CM_SUCCESS; +} + +static int32_t GetStringValue(const std::shared_ptr &resultSet, + const std::string &columnName, char *outBuf, uint32_t outBufLen) +{ + int columnIndex = 0; + auto ret = resultSet->GetColumnIndex(columnName, columnIndex); + if (ret != NativeRdb::E_OK) { + CM_LOG_E("Failed to get column index, column: %{public}s", columnName.c_str()); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + + std::string value; + ret = resultSet->GetString(columnIndex, value); + if (ret != NativeRdb::E_OK) { + CM_LOG_E("Failed to get column value, column: %{public}s", columnName.c_str()); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + + if (memcpy_s(outBuf, outBufLen, value.c_str(), value.size() + 1) != EOK) { + CM_LOG_E("memcpy_s fail"); + return CMR_ERROR_INVALID_OPERATION; + } + return CM_SUCCESS; +} + +static int32_t GetIntValue(const std::shared_ptr &resultSet, + const std::string &columnName, int32_t &value) +{ + int columnIndex = 0; + auto ret = resultSet->GetColumnIndex(columnName, columnIndex); + if (ret != NativeRdb::E_OK) { + CM_LOG_E("Failed to get column index, column: %{public}s", columnName.c_str()); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + + ret = resultSet->GetInt(columnIndex, value); + if (ret != NativeRdb::E_OK) { + CM_LOG_E("Failed to get column value, column: %{public}s", columnName.c_str()); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + return CM_SUCCESS; +} + +static int32_t GetCertProperty(const std::shared_ptr &resultSet, + struct CertProperty *certProperty) +{ + int32_t ret = GetStringValue(resultSet, COLUMN_URI, certProperty->uri, MAX_LEN_URI); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get uri"); + return ret; + } + + ret = GetStringValue(resultSet, COLUMN_ALIAS, certProperty->alias, MAX_LEN_CERT_ALIAS); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get alias"); + return ret; + } + + ret = GetStringValue(resultSet, COLUMN_SUBJECT_NAME, certProperty->subjectName, MAX_LEN_SUBJECT_NAME); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get subjectName"); + return ret; + } + + ret = GetStringValue(resultSet, COLUMN_CERT_TYPE, certProperty->certType, MAX_LEN_CERT_TYPE); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get certType"); + return ret; + } + + ret = GetIntValue(resultSet, COLUMN_CERT_STORE, certProperty->certStore); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get certStore"); + return ret; + } + + ret = GetIntValue(resultSet, COLUMN_USERID, certProperty->userId); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get userId"); + return ret; + } + + ret = GetIntValue(resultSet, COLUMN_UID, certProperty->uid); + if (ret != CM_SUCCESS) { + CM_LOG_E("Failed to get uid"); + return ret; + } + return ret; +} + +int32_t QueryCertProperty(const char *uri, struct CertProperty *certProperty) +{ + CM_LOG_D("enter QueryCertProperty"); + if (uri == nullptr || certProperty == nullptr) { + CM_LOG_E("input param is invalid"); + return CMR_ERROR_INVALID_ARGUMENT; + } + if (cmRdbDataManager == nullptr) { + CM_LOG_E("cmRdbDataManager is nullptr"); + return CMR_ERROR_NULL_POINTER; + } + + auto absSharedResultSet = cmRdbDataManager->QueryData(std::string(uri), COLUMN_URI); + if (absSharedResultSet == nullptr) { + CM_LOG_E("Failed to query cert: %s property data", uri); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + + CmScoprGuard stateGuard([&] { absSharedResultSet->Close(); }); + int rowCount = 0; + int ret = absSharedResultSet->GetRowCount(rowCount); + if (ret != NativeRdb::E_OK) { + CM_LOG_E("Failed to get row count, ret: %d", ret); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + if (rowCount == 0) { + CM_LOG_I("Finish to query, cert: %s does not exist in the database", uri); + return CM_SUCCESS; + } + + ret = absSharedResultSet->GoToFirstRow(); + if (ret != NativeRdb::E_OK) { + CM_LOG_E("Failed to go to firstRow, ret: %d", ret); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + + int32_t result = GetCertProperty(absSharedResultSet, certProperty); + if (result != CM_SUCCESS) { + CM_LOG_E("Failed to get cert property data"); + return CMR_ERROR_QUERY_RDB_DATA_FAIL; + } + return CM_SUCCESS; +} \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_rdb_data_manager.cpp b/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_rdb_data_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..feadb395a7d1656249f036770eff29c2ce8e402a --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_rdb_data_manager.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2024 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 "cm_rdb_data_manager.h" + +#include "cm_log.h" +#include "cm_rdb_open_callback.h" +#include "cm_scope_guard.h" + +namespace OHOS { +namespace Security { +namespace CertManager { +const int32_t CLOSE_RDB_TIME = 20; // delay 20s stop rdbStore +CmRdbDataManager::CmRdbDataManager(const RdbConfig &rdbConfig) : rdbConfig_(rdbConfig) {} + +CmRdbDataManager::~CmRdbDataManager() +{ + std::lock_guard lock(rdbMutex_); + rdbStore_ = nullptr; +} + +bool CmRdbDataManager::InsertData(const NativeRdb::ValuesBucket &valuesBucket) +{ + CM_LOG_D("enter CmRdbDataManager InsertData"); + auto rdbStore = GetRdbStore(); + if (rdbStore == nullptr) { + CM_LOG_E("rdbStore is nullptr"); + return false; + } + + int64_t rowId = -1; + auto ret = rdbStore->InsertWithConflictResolution(rowId, rdbConfig_.tableName, valuesBucket, + NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE); + return ret == NativeRdb::E_OK; +} + +bool CmRdbDataManager::UpdateData(const std::string &primKey, const std::string &keyColumn, + const NativeRdb::ValuesBucket &valuesBucket) +{ + CM_LOG_D("enter CmRdbDataManager UpdateData"); + auto rdbStore = GetRdbStore(); + if (rdbStore == nullptr) { + CM_LOG_E("rdbStore is nullptr"); + return false; + } + + NativeRdb::AbsRdbPredicates updatePredicates(rdbConfig_.tableName); + updatePredicates.EqualTo(keyColumn, primKey); + int32_t rowId = -1; + auto ret = rdbStore->Update(rowId, valuesBucket, updatePredicates); + return ret == NativeRdb::E_OK; +} + +bool CmRdbDataManager::DeleteData(const std::string &primKey, const std::string &keyColumn) +{ + CM_LOG_D("enter CmRdbDataManager DeleteData"); + auto rdbStore = GetRdbStore(); + if (rdbStore == nullptr) { + CM_LOG_E("rdbStore is nullptr"); + return false; + } + + NativeRdb::AbsRdbPredicates deletePredicates(rdbConfig_.tableName); + deletePredicates.EqualTo(keyColumn, primKey); + int32_t rowId = -1; + auto ret = rdbStore->Delete(rowId, deletePredicates); + return ret == NativeRdb::E_OK; +} + +std::shared_ptr CmRdbDataManager::QueryData(const std::string &primKey, + const std::string &keyColumn) +{ + CM_LOG_D("enter CmRdbDataManager QueryData"); + auto rdbStore = GetRdbStore(); + if (rdbStore == nullptr) { + CM_LOG_E("rdbStore is nullptr"); + return nullptr; + } + + NativeRdb::AbsRdbPredicates queryPredicates(rdbConfig_.tableName); + queryPredicates.EqualTo(keyColumn, primKey); + auto absSharedResultSet = rdbStore->Query(queryPredicates, std::vector()); + if ((absSharedResultSet == nullptr) || (!absSharedResultSet->HasBlock())) { + CM_LOG_E("absSharedResultSet is invalid"); + return nullptr; + } + return absSharedResultSet; +} + +bool CmRdbDataManager::CreateTable() +{ + CM_LOG_I("enter CmRdbDataManager CreateTable"); + + CM_LOG_D("enter CmRdbDataManager CreateTable"); + auto rdbStore = GetRdbStore(); + if (rdbStore == nullptr) { + CM_LOG_E("rdbStore is nullptr"); + return false; + } + + if (rdbConfig_.createTableSql.empty()) { + CM_LOG_E("createTableSql is nullptr"); + return false; + } + + int ret = rdbStore->ExecuteSql(rdbConfig_.createTableSql); + if (ret != NativeRdb::E_OK) { + CM_LOG_E("Failed to create table, ret: %{public}d", ret); + return false; + } + return true; +} + +void CmRdbDataManager::DelayCloseRdbStore() +{ + CM_LOG_I("enter CmRdbDataManager DelayCloseRdbStore"); + + CM_LOG_D("enter CmRdbDataManager DelayCloseRdbStore"); + std::weak_ptr weakPtr = shared_from_this(); + auto closeTask = [weakPtr]() { + CM_LOG_D("DelayCloseRdbStore thread begin"); + std::this_thread::sleep_for(std::chrono::seconds(CLOSE_RDB_TIME)); + auto sharedPtr = weakPtr.lock(); + if (sharedPtr == nullptr) { + return; + } + std::lock_guard lock(sharedPtr->rdbMutex_); + sharedPtr->rdbStore_ = nullptr; + CM_LOG_D("DelayCloseRdbStore thread end"); + }; + std::thread closeRdbStoreThread(closeTask); + closeRdbStoreThread.detach(); +} + +void CmRdbDataManager::CmRdbDataManager::ClearCache() +{ + NativeRdb::RdbHelper::ClearCache(); +} + +std::shared_ptr CmRdbDataManager::GetRdbStore() +{ + CM_LOG_I("enter CmRdbDataManager GetRdbStore"); + + std::lock_guard lock(rdbMutex_); + if (rdbStore_ != nullptr) { + return rdbStore_; + } + + int32_t errCode = NativeRdb::E_OK; + NativeRdb::RdbStoreConfig rdbStoreConfig(rdbConfig_.dbPath + rdbConfig_.dbName); + rdbStoreConfig.SetSecurityLevel(NativeRdb::SecurityLevel::S1); + CmRdbOpenCallback cmRdbOpenCallback(rdbConfig_); + + CM_LOG_I("start CmRdbDataManager GetRdbStore"); + rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, rdbConfig_.version, cmRdbOpenCallback, errCode); + if (rdbStore_ == nullptr) { + CM_LOG_E("Failed to init cert manager rdbStore"); + } + DelayCloseRdbStore(); + return rdbStore_; +} +} // namespace CertManager +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_rdb_open_callback.cpp b/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_rdb_open_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..db027e932e827e3c3d0dcda161dfd2098ddb82ce --- /dev/null +++ b/services/cert_manager_standard/cert_manager_engine/main/rdb/src/cm_rdb_open_callback.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 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 "cm_rdb_open_callback.h" + +#include "rdb_errno.h" + +#include "cm_log.h" + +namespace OHOS { +namespace Security { +namespace CertManager { +CmRdbOpenCallback::CmRdbOpenCallback(const RdbConfig &rdbConfig) : rdbConfig_(rdbConfig) {} + +int32_t CmRdbOpenCallback::OnCreate(NativeRdb::RdbStore &rdbStore) +{ + CM_LOG_D("CmRdbOpenCallback OnCreate"); + return NativeRdb::E_OK; +} + +int32_t CmRdbOpenCallback::OnUpgrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion) +{ + CM_LOG_D("CmRdbOpenCallback OnUpgrade"); + return NativeRdb::E_OK; +} + +int32_t CmRdbOpenCallback::OnDowngrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion) +{ + CM_LOG_D("CmRdbOpenCallback OnDowngrade"); + return NativeRdb::E_OK; +} + +int32_t CmRdbOpenCallback::OnOpen(NativeRdb::RdbStore &rdbStore) +{ + CM_LOG_D("CmRdbOpenCallback OnOpen"); + return NativeRdb::E_OK; +} +} // namespace CertManager +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/cert_manager_standard/cert_manager_service.cfg b/services/cert_manager_standard/cert_manager_service.cfg index 4b7553c18ccdbd72230023316fdf089a14077a1f..93ee6e8d077d24a4eb22faa462a1ea9b0976f406 100644 --- a/services/cert_manager_standard/cert_manager_service.cfg +++ b/services/cert_manager_standard/cert_manager_service.cfg @@ -10,7 +10,8 @@ "mkdir /data/service/el1/public/cert_manager_service/certificates/priv_credential 0700 cert_manager_server cert_manager_server", "mkdir /data/service/el1/public/cert_manager_service/certificates/user_open 0701 cert_manager_server cert_manager_server", "mkdir /data/service/el1/public/cert_manager_service/certificates/user_config 0700 cert_manager_server cert_manager_server", - "mkdir /data/service/el1/public/cert_manager_service/certificates/sys_credential 0700 cert_manager_server cert_manager_server" + "mkdir /data/service/el1/public/cert_manager_service/certificates/sys_credential 0700 cert_manager_server cert_manager_server", + "mkdir /data/service/el1/public/cert_manager_service/rdb 0771 cert_manager_server cert_manager_server" ] } ], diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn b/services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn index 3ce435f1df8bf682c50385fedc06bd231efb5850..cea010b35489a2b3e549221a4a79e963b8abc738 100644 --- a/services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/BUILD.gn @@ -27,6 +27,7 @@ ohos_static_library("libcert_manager_service_os_dependency_standard_static") { } include_dirs = [ "../../../cert_manager_engine/main/core/include", + "../../../cert_manager_engine/main/rdb/include", "../../../../../interfaces/innerkits/cert_manager_standard/main/include", ] diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp index 9b1a72c8fc047d536257816f444f399497983d0b..384a612caded5045de2983d6b8f45133316a53ad 100644 --- a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/cm_sa.cpp @@ -24,6 +24,7 @@ #include "system_ability_definition.h" #include "cert_manager.h" +#include "cm_cert_property_rdb.h" #include "cm_event_observer.h" #include "cm_event_process.h" #include "cm_log.h" @@ -267,6 +268,7 @@ void CertManagerService::OnStart(const SystemAbilityOnDemandReason& startReason) CM_LOG_D("CertManagerService start success."); (void)CmBackupAllSaUserCerts(); + (void)CreateCertPropertyRdb(); } void CertManagerService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) diff --git a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.json b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.json index 624b2429f61cfe9dff61b8372afbe351ff950818..5688c9aec0dcbc41560665ba872aaed3036bb2e5 100644 --- a/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.json +++ b/services/cert_manager_standard/cert_manager_service/main/os_dependency/sa/sa_profile/cert_manager_service.json @@ -12,6 +12,9 @@ "commonevent":[ { "name":"usual.event.USER_REMOVED" + }, + { + "name":"usual.event.PACKAGE_REMOVED" } ] },