1 /*
2 * Copyright (c) 2021 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 <gtest/gtest.h>
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20
21 #include <string>
22
23 #include "common.h"
24 #include "file_ex.h"
25 #include "rdb_errno.h"
26 #include "rdb_helper.h"
27 #include "rdb_open_callback.h"
28 #include "rdb_security_manager.h"
29
30 using namespace testing::ext;
31 using namespace OHOS::NativeRdb;
32
33 class RdbEncryptTest : public testing::Test {
34 public:
35 static void SetUpTestCase(void);
36 static void TearDownTestCase(void);
37 void SetUp();
38 void TearDown();
39
40 static const std::string ENCRYPTED_DATABASE_NAME;
41 static const std::string UNENCRYPTED_DATABASE_NAME;
42 static std::shared_ptr<RdbStore> testStore;
43 };
44
45 const std::string RdbEncryptTest::ENCRYPTED_DATABASE_NAME = RDB_TEST_PATH + "encrypted.db";
46 const std::string RdbEncryptTest::UNENCRYPTED_DATABASE_NAME = RDB_TEST_PATH + "unencrypted.db";
47
48 std::shared_ptr<RdbStore> RdbEncryptTest::testStore = nullptr;
49
50 class EncryptTestOpenCallback : public RdbOpenCallback {
51 public:
52 int OnCreate(RdbStore &rdbStore) override;
53 int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override;
54 static const std::string CREATE_TABLE_TEST;
55 };
56
57 std::string const EncryptTestOpenCallback::CREATE_TABLE_TEST = std::string("CREATE TABLE IF NOT EXISTS test ")
58 + std::string("(id INTEGER PRIMARY KEY "
59 "AUTOINCREMENT, "
60 "name TEXT NOT NULL, age INTEGER, "
61 "salary "
62 "REAL, blobType BLOB)");
63
OnCreate(RdbStore & store)64 int EncryptTestOpenCallback::OnCreate(RdbStore &store)
65 {
66 return store.ExecuteSql(CREATE_TABLE_TEST);
67 }
68
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)69 int EncryptTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
70 {
71 return E_OK;
72 }
73
SetUpTestCase(void)74 void RdbEncryptTest::SetUpTestCase(void)
75 {
76 }
77
TearDownTestCase(void)78 void RdbEncryptTest::TearDownTestCase(void)
79 {
80
81 }
82
SetUp(void)83 void RdbEncryptTest::SetUp(void)
84 {
85 }
86
TearDown(void)87 void RdbEncryptTest::TearDown(void)
88 {
89 RdbHelper::ClearCache();
90 RdbHelper::DeleteRdbStore(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
91 RdbHelper::DeleteRdbStore(RdbEncryptTest::UNENCRYPTED_DATABASE_NAME);
92 }
93
94 /**
95 * @tc.name: RdbStore_Encrypt_Decrypt_Test_001
96 * @tc.desc: test RdbStore Get Encrypt Store
97 * @tc.type: FUNC
98 * @tc.require:
99 * @tc.author:
100 */
101 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_01, TestSize.Level1)
102 {
103 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
104 config.SetEncryptStatus(true);
105 config.SetBundleName("com.example.TestEncrypt1");
106 EncryptTestOpenCallback helper;
107 int errCode;
108 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
109 EXPECT_NE(store, nullptr);
110 }
111
112 /**
113 * @tc.name: RdbStore_Encrypt_Decrypt_Test_002
114 * @tc.desc: test RdbStore Get Unencrypted Store
115 * @tc.type: FUNC
116 * @tc.require:
117 * @tc.author:
118 */
119 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_02, TestSize.Level1)
120 {
121 RdbStoreConfig config(RdbEncryptTest::UNENCRYPTED_DATABASE_NAME);
122 config.SetEncryptStatus(false);
123 config.SetBundleName("com.example.TestEncrypt2");
124 EncryptTestOpenCallback helper;
125 int errCode;
126 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
127 EXPECT_NE(store, nullptr);
128 }
129
130 /**
131 * @tc.name: RdbStore_Encrypt_Decrypt_Test_003
132 * @tc.desc: test create encrypted Rdb and insert data ,then query
133 * @tc.type: FUNC
134 * @tc.require:
135 * @tc.author:
136 */
137 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_03, TestSize.Level1)
138 {
139 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
140 config.SetEncryptStatus(true);
141 config.SetBundleName("com.example.TestEncrypt3");
142 EncryptTestOpenCallback helper;
143 int errCode;
144 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
145 EXPECT_NE(store, nullptr);
146
147 int64_t id;
148 ValuesBucket values;
149
150 values.PutInt("id", 1);
151 values.PutString("name", std::string("zhangsan"));
152 values.PutInt("age", 18);
153 values.PutDouble("salary", 100.5);
154 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
155 int ret = store->Insert(id, "test", values);
156 EXPECT_EQ(ret, E_OK);
157 EXPECT_EQ(1, id);
158
159 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
160 EXPECT_NE(resultSet, nullptr);
161
162 ret = resultSet->GoToNextRow();
163 EXPECT_EQ(ret, E_OK);
164
165 int columnIndex;
166 int intVal;
167 std::string strVal;
168 double dVal;
169 std::vector<uint8_t> blob;
170
171 ret = resultSet->GetColumnIndex("id", columnIndex);
172 EXPECT_EQ(ret, E_OK);
173 ret = resultSet->GetInt(columnIndex, intVal);
174 EXPECT_EQ(ret, E_OK);
175 EXPECT_EQ(1, intVal);
176
177 ret = resultSet->GetColumnIndex("name", columnIndex);
178 EXPECT_EQ(ret, E_OK);
179 ret = resultSet->GetString(columnIndex, strVal);
180 EXPECT_EQ(ret, E_OK);
181 EXPECT_EQ("zhangsan", strVal);
182
183 ret = resultSet->GetColumnIndex("age", columnIndex);
184 EXPECT_EQ(ret, E_OK);
185 ret = resultSet->GetInt(columnIndex, intVal);
186 EXPECT_EQ(ret, E_OK);
187 EXPECT_EQ(18, intVal);
188
189 ret = resultSet->GetColumnIndex("salary", columnIndex);
190 EXPECT_EQ(ret, E_OK);
191 ret = resultSet->GetDouble(columnIndex, dVal);
192 EXPECT_EQ(ret, E_OK);
193 EXPECT_EQ(100.5, dVal);
194
195 ret = resultSet->GetColumnIndex("blobType", columnIndex);
196 EXPECT_EQ(ret, E_OK);
197 ret = resultSet->GetBlob(columnIndex, blob);
198 EXPECT_EQ(ret, E_OK);
199 EXPECT_EQ(3, static_cast<int>(blob.size()));
200 EXPECT_EQ(1, blob[0]);
201
202 ret = resultSet->GoToNextRow();
203 EXPECT_EQ(ret, E_ERROR);
204
205 ret = resultSet->Close();
206 EXPECT_EQ(ret, E_OK);
207 }
208
209 /**
210 * @tc.name: RdbStore_Encrypt_Decrypt_Test_004
211 * @tc.desc: test RdbStore key file.
212 * @tc.type: FUNC
213 * @tc.require:
214 * @tc.author:
215 */
216 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_04, TestSize.Level1)
217 {
218 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
219 config.SetEncryptStatus(true);
220 config.SetBundleName("com.example.TestEncrypt4");
221 EncryptTestOpenCallback helper;
222 int errCode;
223 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
224 EXPECT_NE(store, nullptr);
225 std::string keyPath = RDB_TEST_PATH + "key/encrypted.pub_key";
226 int ret = access(keyPath.c_str(), F_OK);
227 EXPECT_EQ(ret, 0);
228
229 RdbHelper::DeleteRdbStore(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
230 ret = access(keyPath.c_str(), F_OK);
231 EXPECT_EQ(ret, -1);
232 }
233
234 /**
235 * @tc.name: RdbStore_Encrypt_Decrypt_Test_005
236 * @tc.desc: test RdbStore Get Encrypted Store with empty boundlename
237 * @tc.type: FUNC
238 * @tc.require:
239 * @tc.author:
240 */
241 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_05, TestSize.Level1)
242 {
243 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
244 config.SetEncryptStatus(true);
245 config.SetBundleName("");
246 EncryptTestOpenCallback helper;
247 int errCode;
248 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
249 EXPECT_EQ(store, nullptr);
250 }
251
252 /**
253 * @tc.name: RdbStore_Encrypt_Decrypt_Test_006
254 * @tc.desc: test SaveSecretKeyToFile when KeyFileType isNot PUB_KEY_FILE
255 * @tc.type: FUNC
256 * @tc.require:
257 * @tc.author:
258 */
259 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_06, TestSize.Level1)
260 {
261 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
262 config.SetEncryptStatus(true);
263 config.SetBundleName("com.example.TestEncrypt6");
264 EncryptTestOpenCallback helper;
265 int errCode;
266 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
267 EXPECT_NE(store, nullptr);
268 bool ret =
269 RdbSecurityManager::GetInstance().CheckKeyDataFileExists(RdbSecurityManager::KeyFileType::PUB_KEY_BAK_FILE);
270 EXPECT_EQ(ret, false);
271 std::vector<uint8_t> key = RdbSecurityManager::GetInstance().GenerateRandomNum(RdbSecurityManager::RDB_KEY_SIZE);
272 bool flag = RdbSecurityManager::GetInstance().SaveSecretKeyToFile(
273 RdbSecurityManager::KeyFileType::PUB_KEY_BAK_FILE, key);
274 EXPECT_EQ(flag, true);
275 }
276
277 /**
278 * @tc.name: RdbStore_Encrypt_Decrypt_Test_007
279 * @tc.desc: test GetRdbPassword when KeyFileType isNot PUB_KEY_FILE
280 * @tc.type: FUNC
281 * @tc.require:
282 * @tc.author:
283 */
284 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_07, TestSize.Level1)
285 {
286 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
287 config.SetEncryptStatus(true);
288 config.SetBundleName("com.example.TestEncrypt7");
289 EncryptTestOpenCallback helper;
290 int errCode;
291 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
292 EXPECT_NE(store, nullptr);
293 auto key = RdbSecurityManager::GetInstance().GetRdbPassword(RdbSecurityManager::KeyFileType::PUB_KEY_BAK_FILE);
294 RdbPassword password = {};
295 EXPECT_EQ(key, password);
296 }
297
298 /**
299 * @tc.name: RdbStore_Encrypt_Decrypt_Test_008
300 * @tc.desc: test RemoveSuffix when pos == std::string::npos
301 * @tc.type: FUNC
302 * @tc.require:
303 * @tc.author:
304 */
305 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_08, TestSize.Level1)
306 {
307 std::string path = RDB_TEST_PATH + "test";
308 RdbStoreConfig config(path);
309 config.SetEncryptStatus(true);
310 config.SetBundleName("com.example.TestEncrypt8");
311 EncryptTestOpenCallback helper;
312 int errCode;
313 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
314 EXPECT_NE(store, nullptr);
315 }
316
317 /**
318 * @tc.name: RdbStore_Encrypt_Decrypt_Test_009
319 * @tc.desc: test GetKeyDistributedStatus and SetKeyDistributedStatus
320 * @tc.type: FUNC
321 * @tc.require:
322 * @tc.author:
323 */
324 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_09, TestSize.Level1)
325 {
326 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
327 config.SetEncryptStatus(true);
328 config.SetBundleName("com.example.TestEncrypt9");
329 EncryptTestOpenCallback helper;
330 int errCode;
331 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
332 EXPECT_NE(store, nullptr);
333
334 bool distributedStatus = false;
335 int ret = RdbSecurityManager::GetInstance().GetKeyDistributedStatus(
336 RdbSecurityManager::KeyFileType::PUB_KEY_FILE, distributedStatus);
337 EXPECT_EQ(ret, E_OK);
338 EXPECT_EQ(distributedStatus, false);
339 ret = RdbSecurityManager::GetInstance().GetKeyDistributedStatus(
340 RdbSecurityManager::KeyFileType::PUB_KEY_BAK_FILE, distributedStatus);
341 EXPECT_EQ(ret, E_ERROR);
342 EXPECT_EQ(distributedStatus, false);
343 ret = RdbSecurityManager::GetInstance().SetKeyDistributedStatus(
344 RdbSecurityManager::KeyFileType::PUB_KEY_FILE, true);
345 EXPECT_EQ(ret, E_OK);
346 ret = RdbSecurityManager::GetInstance().GetKeyDistributedStatus(
347 RdbSecurityManager::KeyFileType::PUB_KEY_FILE, distributedStatus);
348 EXPECT_EQ(ret, E_OK);
349 EXPECT_EQ(distributedStatus, true);
350 ret = RdbSecurityManager::GetInstance().SetKeyDistributedStatus(
351 RdbSecurityManager::KeyFileType::PUB_KEY_BAK_FILE, distributedStatus);
352 EXPECT_EQ(ret, E_ERROR);
353 }
354