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