1 /*
2 * Copyright (c) 2024 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
InsertCertProperty(const struct CertProperty * certProperty)49 int32_t InsertCertProperty(const struct CertProperty *certProperty)
50 {
51 CM_LOG_D("enter InsertCertProperty");
52 if (certProperty == nullptr) {
53 CM_LOG_E("certProperty is nullptr");
54 return CMR_ERROR_INVALID_ARGUMENT;
55 }
56 if (cmRdbDataManager == nullptr) {
57 CM_LOG_E("cmRdbDataManager is nullptr");
58 return CMR_ERROR_NULL_POINTER;
59 }
60
61 NativeRdb::ValuesBucket insertBucket;
62 insertBucket.PutString(COLUMN_URI, std::string(certProperty->uri));
63 insertBucket.PutString(COLUMN_ALIAS, std::string(certProperty->alias));
64 insertBucket.PutString(COLUMN_SUBJECT_NAME, std::string(certProperty->subjectName));
65 insertBucket.PutString(COLUMN_CERT_TYPE, std::string(certProperty->certType));
66 insertBucket.PutInt(COLUMN_CERT_STORE, certProperty->certStore);
67 insertBucket.PutInt(COLUMN_USERID, certProperty->userId);
68 insertBucket.PutInt(COLUMN_UID, certProperty->uid);
69 insertBucket.PutInt(COLUMN_AUTH_STORAGE_LEVEL, certProperty->level);
70 bool ret = cmRdbDataManager->InsertData(insertBucket);
71 if (!ret) {
72 CM_LOG_E("Failed to insert cert:%s property data", certProperty->uri);
73 return CMR_ERROR_INSERT_RDB_DATA_FAIL;
74 }
75 return CM_SUCCESS;
76 }
77
DeleteCertProperty(const char * uri)78 int32_t DeleteCertProperty(const char *uri)
79 {
80 CM_LOG_D("enter DeleteCertProperty");
81 if (uri == nullptr) {
82 CM_LOG_E("uri is invalid");
83 return CMR_ERROR_INVALID_ARGUMENT;
84 }
85 if (cmRdbDataManager == nullptr) {
86 CM_LOG_E("cmRdbDataManager is nullptr");
87 return CMR_ERROR_NULL_POINTER;
88 }
89
90 bool ret = cmRdbDataManager->DeleteData(std::string(uri), COLUMN_URI);
91 if (!ret) {
92 CM_LOG_E("Failed to delete cert:%s property data", uri);
93 return CMR_ERROR_DELETE_RDB_DATA_FAIL;
94 }
95 return CM_SUCCESS;
96 }
97
UpdateCertProperty(const struct CertProperty * certProperty)98 int32_t UpdateCertProperty(const struct CertProperty *certProperty)
99 {
100 CM_LOG_D("enter UpdateCertProperty");
101 if (certProperty == nullptr) {
102 CM_LOG_E("certProperty is nullptr");
103 return CMR_ERROR_INVALID_ARGUMENT;
104 }
105 if (cmRdbDataManager == nullptr) {
106 CM_LOG_E("cmRdbDataManager is nullptr");
107 return CMR_ERROR_NULL_POINTER;
108 }
109
110 NativeRdb::ValuesBucket updateBucket;
111 updateBucket.PutString(COLUMN_URI, std::string(certProperty->uri));
112 updateBucket.PutString(COLUMN_ALIAS, std::string(certProperty->alias));
113 updateBucket.PutString(COLUMN_SUBJECT_NAME, std::string(certProperty->subjectName));
114 updateBucket.PutString(COLUMN_CERT_TYPE, std::string(certProperty->certType));
115 updateBucket.PutInt(COLUMN_CERT_STORE, certProperty->certStore);
116 updateBucket.PutInt(COLUMN_USERID, certProperty->userId);
117 updateBucket.PutInt(COLUMN_UID, certProperty->uid);
118 bool ret = cmRdbDataManager->UpdateData(std::string(certProperty->uri), COLUMN_URI, updateBucket);
119 if (!ret) {
120 CM_LOG_E("Failed to update cert:%s property data", certProperty->uri);
121 return CMR_ERROR_UPDATE_RDB_DATA_FAIL;
122 }
123 return CM_SUCCESS;
124 }
125
GetStringValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,const std::string & columnName,char * outBuf,uint32_t outBufLen)126 static int32_t GetStringValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
127 const std::string &columnName, char *outBuf, uint32_t outBufLen)
128 {
129 int columnIndex = 0;
130 auto ret = resultSet->GetColumnIndex(columnName, columnIndex);
131 if (ret != NativeRdb::E_OK) {
132 CM_LOG_E("Failed to get column index, column: %{public}s", columnName.c_str());
133 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
134 }
135
136 std::string value;
137 ret = resultSet->GetString(columnIndex, value);
138 if (ret != NativeRdb::E_OK) {
139 CM_LOG_E("Failed to get column value, column: %{public}s", columnName.c_str());
140 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
141 }
142
143 if (memcpy_s(outBuf, outBufLen, value.c_str(), value.size() + 1) != EOK) {
144 CM_LOG_E("memcpy_s fail");
145 return CMR_ERROR_INVALID_OPERATION;
146 }
147 return CM_SUCCESS;
148 }
149
GetIntValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,const std::string & columnName,int32_t & value)150 static int32_t GetIntValue(const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
151 const std::string &columnName, int32_t &value)
152 {
153 int columnIndex = 0;
154 auto ret = resultSet->GetColumnIndex(columnName, columnIndex);
155 if (ret != NativeRdb::E_OK) {
156 CM_LOG_E("Failed to get column index, column: %{public}s", columnName.c_str());
157 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
158 }
159
160 ret = resultSet->GetInt(columnIndex, value);
161 if (ret != NativeRdb::E_OK) {
162 CM_LOG_E("Failed to get column value, column: %{public}s", columnName.c_str());
163 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
164 }
165 return CM_SUCCESS;
166 }
167
GetCertProperty(const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,struct CertProperty * certProperty)168 static int32_t GetCertProperty(const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
169 struct CertProperty *certProperty)
170 {
171 CM_LOG_D("enter GetCertProperty");
172 int32_t ret = GetStringValue(resultSet, COLUMN_URI, certProperty->uri, MAX_LEN_URI);
173 if (ret != CM_SUCCESS) {
174 CM_LOG_E("Failed to get uri");
175 return ret;
176 }
177
178 ret = GetStringValue(resultSet, COLUMN_ALIAS, certProperty->alias, MAX_LEN_CERT_ALIAS);
179 if (ret != CM_SUCCESS) {
180 CM_LOG_E("Failed to get alias");
181 return ret;
182 }
183
184 ret = GetStringValue(resultSet, COLUMN_SUBJECT_NAME, certProperty->subjectName, MAX_LEN_SUBJECT_NAME);
185 if (ret != CM_SUCCESS) {
186 CM_LOG_E("Failed to get subjectName");
187 return ret;
188 }
189
190 ret = GetStringValue(resultSet, COLUMN_CERT_TYPE, certProperty->certType, MAX_LEN_CERT_TYPE);
191 if (ret != CM_SUCCESS) {
192 CM_LOG_E("Failed to get certType");
193 return ret;
194 }
195
196 ret = GetIntValue(resultSet, COLUMN_CERT_STORE, certProperty->certStore);
197 if (ret != CM_SUCCESS) {
198 CM_LOG_E("Failed to get certStore");
199 return ret;
200 }
201
202 ret = GetIntValue(resultSet, COLUMN_USERID, certProperty->userId);
203 if (ret != CM_SUCCESS) {
204 CM_LOG_E("Failed to get userId");
205 return ret;
206 }
207
208 ret = GetIntValue(resultSet, COLUMN_UID, certProperty->uid);
209 if (ret != CM_SUCCESS) {
210 CM_LOG_E("Failed to get uid");
211 return ret;
212 }
213
214 int32_t level;
215 ret = GetIntValue(resultSet, COLUMN_AUTH_STORAGE_LEVEL, level);
216 if (ret != CM_SUCCESS) {
217 CM_LOG_E("Failed to get uid");
218 return ret;
219 }
220 certProperty->level = (enum CmAuthStorageLevel)level;
221 return ret;
222 }
223
QueryCertProperty(const char * uri,struct CertProperty * certProperty)224 int32_t QueryCertProperty(const char *uri, struct CertProperty *certProperty)
225 {
226 CM_LOG_D("enter QueryCertProperty");
227 if (uri == nullptr || certProperty == nullptr) {
228 CM_LOG_E("input param is invalid");
229 return CMR_ERROR_INVALID_ARGUMENT;
230 }
231 if (cmRdbDataManager == nullptr) {
232 CM_LOG_E("cmRdbDataManager is nullptr");
233 return CMR_ERROR_NULL_POINTER;
234 }
235
236 auto absSharedResultSet = cmRdbDataManager->QueryData(std::string(uri), COLUMN_URI);
237 if (absSharedResultSet == nullptr) {
238 CM_LOG_E("Failed to query cert: %s property data", uri);
239 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
240 }
241
242 CmScoprGuard stateGuard([&] { absSharedResultSet->Close(); });
243 int rowCount = 0;
244 int ret = absSharedResultSet->GetRowCount(rowCount);
245 if (ret != NativeRdb::E_OK) {
246 CM_LOG_E("Failed to get row count, ret: %d", ret);
247 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
248 }
249 if (rowCount <= 0) {
250 CM_LOG_D("Finish to query, cert: %s does not exist in the database", uri);
251 return CM_SUCCESS;
252 }
253
254 ret = absSharedResultSet->GoToFirstRow();
255 if (ret != NativeRdb::E_OK) {
256 CM_LOG_E("Failed to go to firstRow, ret: %d", ret);
257 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
258 }
259
260 int32_t result = GetCertProperty(absSharedResultSet, certProperty);
261 if (result != CM_SUCCESS) {
262 CM_LOG_E("Failed to get cert property data");
263 return CMR_ERROR_QUERY_RDB_DATA_FAIL;
264 }
265 return CM_SUCCESS;
266 }