1 /*
2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cm_cert_property_rdb.h"
17
18 #include "securec.h"
19
20 #include "cm_log.h"
21 #include "cm_rdb_config.h"
22 #include "cm_rdb_data_manager.h"
23 #include "cm_scope_guard.h"
24
25 using namespace OHOS;
26 using namespace OHOS::Security::CertManager;
27
28 static std::shared_ptr<CmRdbDataManager> cmRdbDataManager = nullptr;
29
CreateCertPropertyRdb(void)30 int32_t CreateCertPropertyRdb(void)
31 {
32 CM_LOG_D("enter CreateCertPropertyRdb");
33 RdbConfig rdbConfig;
34 rdbConfig.dbName = CERT_MANAGER_RDB_NAME;
35 rdbConfig.tableName = CERT_PROPERTY_TABLE_NAME;
36 rdbConfig.createTableSql = std::string("CREATE TABLE IF NOT EXISTS " + CERT_PROPERTY_TABLE_NAME +
37 "(URI TEXT PRIMARY KEY, ALIAS TEXT NOT NULL, SUBJECT_NAME TEXT NOT NULL, CERT_TYPE TEXT NOT NULL, " +
38 "CERT_STORE INTEGER NOT NULL, USERID INTEGER NOT NULL, UID INTEGER NOT NULL, " +
39 "AUTH_STORAGE_LEVEL INTEGER NOT NULL)");
40 cmRdbDataManager = std::make_shared<CmRdbDataManager>(rdbConfig);
41 bool ret = cmRdbDataManager->CreateTable();
42 if (!ret) {
43 CM_LOG_E("Failed to create cert_property table");
44 return CMR_ERROR_CREATE_RDB_TABLE_FAIL;
45 }
46 return CM_SUCCESS;
47 }
48
49 // LCOV_EXCL_START
InsertCertProperty(const struct CertProperty * certProperty)50 int32_t InsertCertProperty(const struct CertProperty *certProperty)
51 {
52 CM_LOG_D("enter InsertCertProperty");
53 if (certProperty == nullptr) {
54 CM_LOG_E("certProperty is nullptr");
55 return CMR_ERROR_INVALID_ARGUMENT;
56 }
57 if (cmRdbDataManager == nullptr) {
58 CM_LOG_E("cmRdbDataManager is nullptr");
59 return CMR_ERROR_NULL_POINTER;
60 }
61
62 NativeRdb::ValuesBucket insertBucket;
63 insertBucket.PutString(COLUMN_URI, std::string(certProperty->uri));
64 insertBucket.PutString(COLUMN_ALIAS, std::string(certProperty->alias));
65 insertBucket.PutString(COLUMN_SUBJECT_NAME, std::string(certProperty->subjectName));
66 insertBucket.PutString(COLUMN_CERT_TYPE, std::string(certProperty->certType));
67 insertBucket.PutInt(COLUMN_CERT_STORE, certProperty->certStore);
68 insertBucket.PutInt(COLUMN_USERID, certProperty->userId);
69 insertBucket.PutInt(COLUMN_UID, certProperty->uid);
70 insertBucket.PutInt(COLUMN_AUTH_STORAGE_LEVEL, certProperty->level);
71 bool ret = cmRdbDataManager->InsertData(insertBucket);
72 if (!ret) {
73 CM_LOG_E("Failed to insert cert:%s property data", certProperty->uri);
74 return CMR_ERROR_INSERT_RDB_DATA_FAIL;
75 }
76 return CM_SUCCESS;
77 }
78
DeleteCertProperty(const char * uri)79 int32_t DeleteCertProperty(const char *uri)
80 {
81 CM_LOG_D("enter DeleteCertProperty");
82 if (uri == nullptr) {
83 CM_LOG_E("uri is invalid");
84 return CMR_ERROR_INVALID_ARGUMENT;
85 }
86 if (cmRdbDataManager == nullptr) {
87 CM_LOG_E("cmRdbDataManager is nullptr");
88 return CMR_ERROR_NULL_POINTER;
89 }
90
91 bool ret = cmRdbDataManager->DeleteData(std::string(uri), COLUMN_URI);
92 if (!ret) {
93 CM_LOG_E("Failed to delete cert:%s property data", uri);
94 return CMR_ERROR_DELETE_RDB_DATA_FAIL;
95 }
96 return CM_SUCCESS;
97 }
98
UpdateCertProperty(const struct CertProperty * certProperty)99 int32_t UpdateCertProperty(const struct CertProperty *certProperty)
100 {
101 CM_LOG_D("enter UpdateCertProperty");
102 if (certProperty == nullptr) {
103 CM_LOG_E("certProperty is nullptr");
104 return CMR_ERROR_INVALID_ARGUMENT;
105 }
106 if (cmRdbDataManager == nullptr) {
107 CM_LOG_E("cmRdbDataManager is nullptr");
108 return CMR_ERROR_NULL_POINTER;
109 }
110
111 NativeRdb::ValuesBucket updateBucket;
112 updateBucket.PutString(COLUMN_URI, std::string(certProperty->uri));
113 updateBucket.PutString(COLUMN_ALIAS, std::string(certProperty->alias));
114 updateBucket.PutString(COLUMN_SUBJECT_NAME, std::string(certProperty->subjectName));
115 updateBucket.PutString(COLUMN_CERT_TYPE, std::string(certProperty->certType));
116 updateBucket.PutInt(COLUMN_CERT_STORE, certProperty->certStore);
117 updateBucket.PutInt(COLUMN_USERID, certProperty->userId);
118 updateBucket.PutInt(COLUMN_UID, certProperty->uid);
119 bool ret = cmRdbDataManager->UpdateData(std::string(certProperty->uri), COLUMN_URI, updateBucket);
120 if (!ret) {
121 CM_LOG_E("Failed to update cert:%s property data", certProperty->uri);
122 return CMR_ERROR_UPDATE_RDB_DATA_FAIL;
123 }
124 return CM_SUCCESS;
125 }
126
GetStringValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,const std::string & columnName,char * outBuf,uint32_t outBufLen)127 static int32_t GetStringValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
128 const std::string &columnName, char *outBuf, uint32_t outBufLen)
129 {
130 int columnIndex = 0;
131 auto ret = resultSet->GetColumnIndex(columnName, columnIndex);
132 if (ret != NativeRdb::E_OK) {
133 CM_LOG_E("Failed to get column index, column: %{public}s", columnName.c_str());
134 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
135 }
136
137 std::string value;
138 ret = resultSet->GetString(columnIndex, value);
139 if (ret != NativeRdb::E_OK) {
140 CM_LOG_E("Failed to get column value, column: %{public}s", columnName.c_str());
141 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
142 }
143
144 if (memcpy_s(outBuf, outBufLen, value.c_str(), value.size() + 1) != EOK) {
145 CM_LOG_E("memcpy_s fail");
146 return CMR_ERROR_MEM_OPERATION_COPY;
147 }
148 return CM_SUCCESS;
149 }
150
GetIntValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,const std::string & columnName,int32_t & value)151 static int32_t GetIntValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
152 const std::string &columnName, int32_t &value)
153 {
154 int columnIndex = 0;
155 auto ret = resultSet->GetColumnIndex(columnName, columnIndex);
156 if (ret != NativeRdb::E_OK) {
157 CM_LOG_E("Failed to get column index, column: %{public}s", columnName.c_str());
158 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
159 }
160
161 ret = resultSet->GetInt(columnIndex, value);
162 if (ret != NativeRdb::E_OK) {
163 CM_LOG_E("Failed to get column value, column: %{public}s", columnName.c_str());
164 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
165 }
166 return CM_SUCCESS;
167 }
168
GetCertProperty(const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,struct CertProperty * certProperty)169 static int32_t GetCertProperty(const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
170 struct CertProperty *certProperty)
171 {
172 CM_LOG_D("enter GetCertProperty");
173 int32_t ret = GetStringValue(resultSet, COLUMN_URI, certProperty->uri, MAX_LEN_URI);
174 if (ret != CM_SUCCESS) {
175 CM_LOG_E("Failed to get uri");
176 return ret;
177 }
178
179 ret = GetStringValue(resultSet, COLUMN_ALIAS, certProperty->alias, MAX_LEN_CERT_ALIAS);
180 if (ret != CM_SUCCESS) {
181 CM_LOG_E("Failed to get alias");
182 return ret;
183 }
184
185 ret = GetStringValue(resultSet, COLUMN_SUBJECT_NAME, certProperty->subjectName, MAX_LEN_SUBJECT_NAME);
186 if (ret != CM_SUCCESS) {
187 CM_LOG_E("Failed to get subjectName");
188 return ret;
189 }
190
191 ret = GetStringValue(resultSet, COLUMN_CERT_TYPE, certProperty->certType, MAX_LEN_CERT_TYPE);
192 if (ret != CM_SUCCESS) {
193 CM_LOG_E("Failed to get certType");
194 return ret;
195 }
196
197 ret = GetIntValue(resultSet, COLUMN_CERT_STORE, certProperty->certStore);
198 if (ret != CM_SUCCESS) {
199 CM_LOG_E("Failed to get certStore");
200 return ret;
201 }
202
203 ret = GetIntValue(resultSet, COLUMN_USERID, certProperty->userId);
204 if (ret != CM_SUCCESS) {
205 CM_LOG_E("Failed to get userId");
206 return ret;
207 }
208
209 ret = GetIntValue(resultSet, COLUMN_UID, certProperty->uid);
210 if (ret != CM_SUCCESS) {
211 CM_LOG_E("Failed to get uid");
212 return ret;
213 }
214
215 int32_t level;
216 ret = GetIntValue(resultSet, COLUMN_AUTH_STORAGE_LEVEL, level);
217 if (ret != CM_SUCCESS) {
218 CM_LOG_E("Failed to get level");
219 return ret;
220 }
221 certProperty->level = (enum CmAuthStorageLevel)level;
222 return ret;
223 }
224
QueryCertProperty(const char * uri,struct CertProperty * certProperty)225 int32_t QueryCertProperty(const char *uri, struct CertProperty *certProperty)
226 {
227 CM_LOG_D("enter QueryCertProperty");
228 if (uri == nullptr || certProperty == nullptr) {
229 CM_LOG_E("input param is invalid");
230 return CMR_ERROR_INVALID_ARGUMENT;
231 }
232 if (cmRdbDataManager == nullptr) {
233 CM_LOG_E("cmRdbDataManager is nullptr");
234 return CMR_ERROR_NULL_POINTER;
235 }
236
237 auto absSharedResultSet = cmRdbDataManager->QueryData(std::string(uri), COLUMN_URI);
238 if (absSharedResultSet == nullptr) {
239 CM_LOG_E("Failed to query cert: %s property data", uri);
240 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
241 }
242
243 CmScoprGuard stateGuard([&] { absSharedResultSet->Close(); });
244 int rowCount = 0;
245 int ret = absSharedResultSet->GetRowCount(rowCount);
246 if (ret != NativeRdb::E_OK) {
247 CM_LOG_E("Failed to get row count, ret: %d", ret);
248 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
249 }
250 if (rowCount <= 0) {
251 CM_LOG_I("Finish to query, cert: %s does not exist in the database", uri);
252 return CM_SUCCESS;
253 }
254
255 ret = absSharedResultSet->GoToFirstRow();
256 if (ret != NativeRdb::E_OK) {
257 CM_LOG_E("Failed to go to firstRow, ret: %d", ret);
258 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
259 }
260
261 int32_t result = GetCertProperty(absSharedResultSet, certProperty);
262 if (result != CM_SUCCESS) {
263 CM_LOG_E("Failed to get cert property data");
264 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
265 }
266 return CM_SUCCESS;
267 }
268 // LCOV_EXCL_STOP