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 ENCRYPTED_DATABASE_BACKUP_NAME;
42 static const std::string ENCRYPTED_DATABASE_NAME2;
43 static const std::string ENCRYPTED_DATABASE_BACKUP_NAME2;
44 static const std::string UNENCRYPTED_DATABASE_NAME;
45 static std::shared_ptr<RdbStore> testStore;
46 };
47
48 const std::string RdbEncryptTest::ENCRYPTED_DATABASE_NAME = RDB_TEST_PATH + "encrypted.db";
49 const std::string RdbEncryptTest::ENCRYPTED_DATABASE_BACKUP_NAME = RDB_TEST_PATH + "encrypted_bak.db";
50 const std::string RdbEncryptTest::ENCRYPTED_DATABASE_NAME2 = RDB_TEST_PATH + "encrypted2.db";
51 const std::string RdbEncryptTest::ENCRYPTED_DATABASE_BACKUP_NAME2 = RDB_TEST_PATH + "encrypted2_bak.db";
52 const std::string RdbEncryptTest::UNENCRYPTED_DATABASE_NAME = RDB_TEST_PATH + "unencrypted.db";
53
54 std::shared_ptr<RdbStore> RdbEncryptTest::testStore = nullptr;
55
56 class EncryptTestOpenCallback : public RdbOpenCallback {
57 public:
58 int OnCreate(RdbStore &store) override;
59 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
60 static const std::string CREATE_TABLE_TEST;
61 };
62
63 std::string const EncryptTestOpenCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY "
64 "KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, "
65 "salary REAL, blobType BLOB)";
66
OnCreate(RdbStore & store)67 int EncryptTestOpenCallback::OnCreate(RdbStore &store)
68 {
69 return store.ExecuteSql(CREATE_TABLE_TEST);
70 }
71
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)72 int EncryptTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
73 {
74 return E_OK;
75 }
76
SetUpTestCase(void)77 void RdbEncryptTest::SetUpTestCase(void)
78 {
79 }
80
TearDownTestCase(void)81 void RdbEncryptTest::TearDownTestCase(void)
82 {
83 }
84
SetUp(void)85 void RdbEncryptTest::SetUp(void)
86 {
87 RdbHelper::ClearCache();
88 RdbHelper::DeleteRdbStore(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
89 RdbHelper::DeleteRdbStore(RdbEncryptTest::UNENCRYPTED_DATABASE_NAME);
90 }
91
TearDown(void)92 void RdbEncryptTest::TearDown(void)
93 {
94 RdbHelper::ClearCache();
95 RdbHelper::DeleteRdbStore(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
96 RdbHelper::DeleteRdbStore(RdbEncryptTest::UNENCRYPTED_DATABASE_NAME);
97 }
98
99 /**
100 * @tc.name: RdbStore_Encrypt_Decrypt_Test_001
101 * @tc.desc: test RdbStore Get Encrypt Store
102 * @tc.type: FUNC
103 */
104 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_01, TestSize.Level1)
105 {
106 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
107 config.SetEncryptStatus(true);
108 config.SetBundleName("com.example.TestEncrypt1");
109 EncryptTestOpenCallback helper;
110 int errCode;
111 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
112 EXPECT_NE(store, nullptr);
113 }
114
115 /**
116 * @tc.name: RdbStore_Encrypt_Decrypt_Test_002
117 * @tc.desc: test RdbStore Get Unencrypted Store
118 * @tc.type: FUNC
119 */
120 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_02, TestSize.Level1)
121 {
122 RdbStoreConfig config(RdbEncryptTest::UNENCRYPTED_DATABASE_NAME);
123 config.SetEncryptStatus(false);
124 config.SetBundleName("com.example.TestEncrypt2");
125 EncryptTestOpenCallback helper;
126 int errCode;
127 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
128 EXPECT_NE(store, nullptr);
129 }
130
131 /**
132 * @tc.name: RdbStore_Encrypt_Decrypt_Test_003
133 * @tc.desc: test create encrypted Rdb and insert data ,then query
134 * @tc.type: FUNC
135 */
136 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_03, TestSize.Level1)
137 {
138 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
139 config.SetEncryptStatus(true);
140 config.SetBundleName("com.example.TestEncrypt3");
141 EncryptTestOpenCallback helper;
142 int errCode;
143 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
144 EXPECT_NE(store, nullptr);
145
146 int64_t id;
147
148 int ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
149 EXPECT_EQ(ret, E_OK);
150 EXPECT_EQ(1, id);
151
152 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
153 EXPECT_NE(resultSet, nullptr);
154
155 ret = resultSet->GoToNextRow();
156 EXPECT_EQ(ret, E_OK);
157
158 int columnIndex;
159 int intVal;
160 std::string strVal;
161
162 ret = resultSet->GetColumnIndex("id", columnIndex);
163 EXPECT_EQ(ret, E_OK);
164 ret = resultSet->GetInt(columnIndex, intVal);
165 EXPECT_EQ(ret, E_OK);
166 EXPECT_EQ(1, intVal);
167
168 ret = resultSet->GetColumnIndex("name", columnIndex);
169 EXPECT_EQ(ret, E_OK);
170 ret = resultSet->GetString(columnIndex, strVal);
171 EXPECT_EQ(ret, E_OK);
172 EXPECT_EQ("zhangsan", strVal);
173
174 ret = resultSet->GoToNextRow();
175 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
176
177 ret = resultSet->Close();
178 EXPECT_EQ(ret, E_OK);
179 }
180
181 /**
182 * @tc.name: RdbStore_Encrypt_Decrypt_Test_004
183 * @tc.desc: test RdbStore key file.
184 * @tc.type: FUNC
185 */
186 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_04, TestSize.Level1)
187 {
188 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
189 config.SetEncryptStatus(true);
190 config.SetBundleName("com.example.TestEncrypt4");
191 EncryptTestOpenCallback helper;
192 int errCode;
193 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
194 EXPECT_NE(store, nullptr);
195 std::string keyPath = RDB_TEST_PATH + "key/encrypted.pub_key";
196 int ret = access(keyPath.c_str(), F_OK);
197 EXPECT_EQ(ret, 0);
198
199 store = nullptr;
200 RdbHelper::DeleteRdbStore(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
201 ret = access(keyPath.c_str(), F_OK);
202 EXPECT_EQ(ret, -1);
203 }
204
205 /**
206 * @tc.name: RdbStore_Encrypt_Decrypt_Test_005
207 * @tc.desc: test RdbStore Get Encrypted Store with empty boundlename
208 * @tc.type: FUNC
209 */
210 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_05, TestSize.Level1)
211 {
212 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
213 config.SetEncryptStatus(true);
214 config.SetBundleName("");
215 EncryptTestOpenCallback helper;
216 int errCode;
217 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
218 EXPECT_NE(store, nullptr);
219 }
220
221 /**
222 * @tc.name: RdbStore_Encrypt_Decrypt_Test_006
223 * @tc.desc: test GetRdbStore with specified key
224 * @tc.type: FUNC
225 */
226 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_06, TestSize.Level1)
227 {
228 std::vector<uint8_t> key{ 1, 2, 3 };
229 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
230 config.SetEncryptKey(key);
231 EncryptTestOpenCallback helper;
232 int errCode;
233 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
234 EXPECT_NE(store, nullptr);
235
236 std::string keyPath = RDB_TEST_PATH + "key/" + "encrypted.pub_key";
237 std::string newKeyPath = RDB_TEST_PATH + "key/" + +"encrypted.pub_key.new";
238 bool isFileExists = OHOS::FileExists(keyPath);
239 EXPECT_EQ(isFileExists, false);
240 isFileExists = OHOS::FileExists(newKeyPath);
241 EXPECT_EQ(isFileExists, false);
242
243 store.reset();
244 RdbHelper::ClearCache();
245
246 std::vector<uint8_t> wrongKey{ 4, 5, 6 };
247 config.SetEncryptKey(wrongKey);
248 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
249 EXPECT_EQ(store, nullptr);
250 }
251
252 /**
253 * @tc.name: RdbStore_Encrypt_Decrypt_Test_007
254 * @tc.desc: test RemoveSuffix when pos == std::string::npos
255 * @tc.type: FUNC
256 */
257 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_07, TestSize.Level1)
258 {
259 std::string path = RDB_TEST_PATH + "test";
260 RdbHelper::DeleteRdbStore(path);
261 RdbStoreConfig config(path);
262 config.SetEncryptStatus(true);
263 config.SetBundleName("com.example.TestEncrypt7");
264 EncryptTestOpenCallback helper;
265 int errCode;
266 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
267 EXPECT_NE(store, nullptr);
268
269 store = nullptr;
270 errCode = RdbHelper::DeleteRdbStore(path);
271 EXPECT_EQ(errCode, E_OK);
272 }
273
274 /**
275 * @tc.name: RdbStore_Encrypt_Decrypt_Test_008
276 * @tc.desc: test RdbStore Get Encrypt Store without SetBundleName
277 * @tc.type: FUNC
278 */
279 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_008, TestSize.Level1)
280 {
281 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
282 config.SetEncryptStatus(true);
283 EncryptTestOpenCallback helper;
284 int errCode;
285 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
286 EXPECT_NE(store, nullptr);
287 }
288
289 /**
290 * @tc.name: RdbStore_Encrypt_Decrypt_Test_009
291 * @tc.desc: test create encrypted Rdb and insert data ,then query
292 * @tc.type: FUNC
293 */
294 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_009, TestSize.Level1)
295 {
296 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
297 config.SetEncryptStatus(true);
298 config.SetBundleName("com.example.TestEncrypt9");
299 EncryptTestOpenCallback helper;
300 int errCode;
301 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
302 EXPECT_NE(store, nullptr);
303
304 int64_t id;
305
306 int ret = store->Insert(id, "test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
307 EXPECT_EQ(ret, E_OK);
308 EXPECT_EQ(1, id);
309
310 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test");
311 EXPECT_NE(resultSet, nullptr);
312
313 ret = resultSet->GoToNextRow();
314 EXPECT_EQ(ret, E_OK);
315
316 int columnIndex;
317 double dVal;
318 std::vector<uint8_t> blob;
319
320 ret = resultSet->GetColumnIndex("salary", columnIndex);
321 EXPECT_EQ(ret, E_OK);
322 ret = resultSet->GetDouble(columnIndex, dVal);
323 EXPECT_EQ(ret, E_OK);
324 EXPECT_EQ(100.5, dVal);
325
326 ret = resultSet->GetColumnIndex("blobType", columnIndex);
327 EXPECT_EQ(ret, E_OK);
328 ret = resultSet->GetBlob(columnIndex, blob);
329 EXPECT_EQ(ret, E_OK);
330 EXPECT_EQ(3, static_cast<int>(blob.size()));
331 EXPECT_EQ(1, blob[0]);
332
333 ret = resultSet->GoToNextRow();
334 EXPECT_EQ(ret, E_ROW_OUT_RANGE);
335
336 ret = resultSet->Close();
337 EXPECT_EQ(ret, E_OK);
338 }
339
340 /**
341 * @tc.name: RdbStore_Encrypt_010
342 * @tc.desc: test create encrypted Rdb and open in non encrypted mode ,then E_OK
343 * @tc.type: FUNC
344 */
345 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_010, TestSize.Level1)
346 {
347 RdbStoreConfig config(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
348 config.SetEncryptStatus(true);
349 config.SetBundleName("com.example.TestEncrypt10");
350
351 EncryptTestOpenCallback helper;
352 int errCode;
353 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
354 EXPECT_NE(store, nullptr);
355 EXPECT_EQ(errCode, E_OK);
356
357 std::string keyPath = RDB_TEST_PATH + "key/encrypted.pub_key";
358 int ret = access(keyPath.c_str(), F_OK);
359 EXPECT_EQ(ret, 0);
360
361 config.SetEncryptStatus(false);
362 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
363 EXPECT_NE(store, nullptr);
364 EXPECT_EQ(errCode, E_OK);
365 }
366
367 /**
368 * @tc.name: RdbStore_Encrypt_011
369 * @tc.desc: test create unencrypted Rdb and open in encrypted mode ,then E_OK
370 * @tc.type: FUNC
371 */
372 HWTEST_F(RdbEncryptTest, RdbStore_Encrypt_011, TestSize.Level1)
373 {
374 RdbStoreConfig config(RdbEncryptTest::UNENCRYPTED_DATABASE_NAME);
375 config.SetEncryptStatus(false);
376 config.SetBundleName("com.example.TestEncrypt11");
377 EncryptTestOpenCallback helper;
378 int errCode;
379 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
380 EXPECT_NE(store, nullptr);
381 EXPECT_EQ(errCode, E_OK);
382
383 std::string keyPath = RDB_TEST_PATH + "key/unencrypted.pub_key";
384 int ret = access(keyPath.c_str(), F_OK);
385 EXPECT_EQ(ret, -1);
386
387 config.SetEncryptStatus(true);
388 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
389 EXPECT_NE(store, nullptr);
390 EXPECT_EQ(errCode, E_OK);
391 }
392
393 /**
394 * @tc.name: RdbStore_RdbPassword_001
395 * @tc.desc: Abnomal test RdbStore RdbPassword class
396 * @tc.type: FUNC
397 */
398 HWTEST_F(RdbEncryptTest, AbnomalRdbStore_RdbPassword_001, TestSize.Level2)
399 {
400 RdbPassword password1;
401 RdbPassword password2;
402 int errCode = E_OK;
403 uint8_t inputData[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
404 std::ostringstream ss;
405 std::copy(inputData, inputData + sizeof(inputData), std::ostream_iterator<int>(ss));
406
407 // if size_t > 128
408 errCode = password1.SetValue(inputData, 256);
409 EXPECT_EQ(E_ERROR, errCode);
410
411 // if inputData is nullptr
412 errCode = password1.SetValue(nullptr, sizeof(inputData));
413 EXPECT_EQ(E_ERROR, errCode);
414
415 errCode = password1.SetValue(inputData, sizeof(inputData));
416 EXPECT_EQ(E_OK, errCode);
417 errCode = password2.SetValue(inputData, sizeof(inputData));
418 EXPECT_EQ(E_OK, errCode);
419
420 EXPECT_EQ(true, password1 == password2);
421 }
422
423 /**
424 * @tc.name: KeyFilePath_test_001, open different databases and obtain the corresponding key files
425 * @tc.desc: 1.create db1
426 * 2.create db2
427 * 3.create table in the db2
428 * 4.backup db1
429 * 5.restore db1
430 *
431 * @tc.type: FUNC
432 */
433 HWTEST_F(RdbEncryptTest, KeyFilePath_test_001, TestSize.Level2)
434 {
435 RdbStoreConfig config1(RdbEncryptTest::ENCRYPTED_DATABASE_NAME);
436 config1.SetEncryptStatus(true);
437 config1.SetBundleName("com.example.TestEncrypt1");
438 EncryptTestOpenCallback helper1;
439 int errCode = E_ERROR;
440 std::shared_ptr<RdbStore> store1 = RdbHelper::GetRdbStore(config1, 1, helper1, errCode);
441 EXPECT_NE(nullptr, store1);
442 EXPECT_EQ(E_OK, errCode);
443
444 RdbStoreConfig config2(RdbEncryptTest::ENCRYPTED_DATABASE_NAME2);
445 config2.SetEncryptStatus(true);
446 config2.SetBundleName("com.example.TestEncrypt1");
447 EncryptTestOpenCallback helper2;
448 std::shared_ptr<RdbStore> store2 = RdbHelper::GetRdbStore(config2, 1, helper2, errCode);
449 EXPECT_NE(nullptr, store2);
450 EXPECT_EQ(E_OK, errCode);
451
452 EXPECT_EQ(E_OK, store1->Backup(RdbEncryptTest::ENCRYPTED_DATABASE_BACKUP_NAME));
453 EXPECT_EQ(E_OK, store1->Restore(RdbEncryptTest::ENCRYPTED_DATABASE_BACKUP_NAME));
454
455 EXPECT_EQ(E_OK, store2->Backup(RdbEncryptTest::ENCRYPTED_DATABASE_BACKUP_NAME2));
456 EXPECT_EQ(E_OK, store2->Restore(RdbEncryptTest::ENCRYPTED_DATABASE_BACKUP_NAME2));
457 }