1 /*
2 * Copyright (c) 2022 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 #ifndef OMIT_ENCRYPT
16 #ifdef RELATIONAL_STORE
17 #include <gtest/gtest.h>
18
19 #include "data_transformer.h"
20 #include "db_common.h"
21 #include "db_constant.h"
22 #include "db_errno.h"
23 #include "db_types.h"
24 #include "distributeddb_data_generate_unit_test.h"
25 #include "distributeddb_tools_unit_test.h"
26 #include "generic_single_ver_kv_entry.h"
27 #include "log_print.h"
28 #include "relational_store_delegate.h"
29 #include "relational_store_instance.h"
30 #include "relational_store_manager.h"
31 #include "relational_store_sqlite_ext.h"
32 #include "relational_sync_able_storage.h"
33 #include "sqlite_relational_store.h"
34 #include "sqlite_utils.h"
35 #include "virtual_communicator_aggregator.h"
36
37 using namespace testing::ext;
38 using namespace DistributedDB;
39 using namespace DistributedDBUnitTest;
40 using namespace std;
41
42 namespace {
43 string g_testDir;
44 string g_storePath;
45 string g_storeID = "dftStoreID";
46 string g_tableName = "data";
47 const string CORRECT_KEY = "a correct key";
48 CipherPassword g_correctPasswd;
49 const string REKEY_KEY = "a key after rekey";
50 CipherPassword g_rekeyPasswd;
51 const string INCORRECT_KEY = "a incorrect key";
52 CipherPassword g_incorrectPasswd;
53 const int DEFAULT_ITER = 5000;
54 const int CUSTOMIZED_ITER = 10000;
55
56 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
57 RelationalStoreDelegate *g_delegate = nullptr;
58 IRelationalStore *g_store = nullptr;
59
InitStoreProp(const std::string & storePath,const std::string & appId,const std::string & userId,RelationalDBProperties & properties)60 void InitStoreProp(const std::string &storePath, const std::string &appId, const std::string &userId,
61 RelationalDBProperties &properties)
62 {
63 properties.SetStringProp(RelationalDBProperties::DATA_DIR, storePath);
64 properties.SetStringProp(RelationalDBProperties::APP_ID, appId);
65 properties.SetStringProp(RelationalDBProperties::USER_ID, userId);
66 properties.SetStringProp(RelationalDBProperties::STORE_ID, g_storeID);
67 std::string identifier = userId + "-" + appId + "-" + g_storeID;
68 std::string hashIdentifier = DBCommon::TransferHashString(identifier);
69 properties.SetStringProp(RelationalDBProperties::IDENTIFIER_DATA, hashIdentifier);
70 }
71
GetRelationalStore()72 const RelationalSyncAbleStorage *GetRelationalStore()
73 {
74 RelationalDBProperties properties;
75 InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
76 int errCode = E_OK;
77 g_store = RelationalStoreInstance::GetDataBase(properties, errCode);
78 if (g_store == nullptr) {
79 LOGE("Get db failed:%d", errCode);
80 return nullptr;
81 }
82 return static_cast<SQLiteRelationalStore *>(g_store)->GetStorageEngine();
83 }
84
ExecSqlAndAssertOK(sqlite3 * db,const std::string & sql)85 void ExecSqlAndAssertOK(sqlite3 *db, const std::string &sql)
86 {
87 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
88 }
89
FreeEntires(std::vector<SingleVerKvEntry * > & entries)90 void FreeEntires(std::vector<SingleVerKvEntry *> &entries)
91 {
92 for (auto *&it : entries) {
93 if (it != nullptr) {
94 delete it;
95 it = nullptr;
96 }
97 }
98 }
99 }
100
101 class DistributedDBRelationalEncryptedDbTest : public testing::Test {
102 public:
103 static void SetUpTestCase(void);
104 static void TearDownTestCase(void);
105 void SetUp();
106 void TearDown();
107 };
108
SetUpTestCase(void)109 void DistributedDBRelationalEncryptedDbTest::SetUpTestCase(void)
110 {
111 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
112 g_storePath = g_testDir + "/getDataTest.db";
113 LOGI("The test db is:%s", g_testDir.c_str());
114
115 auto communicator = new (std::nothrow) VirtualCommunicatorAggregator();
116 ASSERT_TRUE(communicator != nullptr);
117 RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicator);
118
119 g_correctPasswd.SetValue(reinterpret_cast<const uint8_t *>(CORRECT_KEY.data()), CORRECT_KEY.size());
120 g_rekeyPasswd.SetValue(reinterpret_cast<const uint8_t *>(REKEY_KEY.data()), REKEY_KEY.size());
121 g_incorrectPasswd.SetValue(reinterpret_cast<const uint8_t *>(INCORRECT_KEY.data()), INCORRECT_KEY.size());
122 }
123
TearDownTestCase(void)124 void DistributedDBRelationalEncryptedDbTest::TearDownTestCase(void)
125 {
126 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
127 }
128
SetUp(void)129 void DistributedDBRelationalEncryptedDbTest::SetUp(void)
130 {
131 DistributedDBToolsUnitTest::PrintTestCaseInfo();
132 }
133
TearDown(void)134 void DistributedDBRelationalEncryptedDbTest::TearDown(void)
135 {
136 if (g_delegate != nullptr) {
137 EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
138 g_delegate = nullptr;
139 }
140 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
141 LOGE("rm test db files error.");
142 }
143 return;
144 }
145
146 /**
147 * @tc.name: OpenEncryptedDBWithoutPasswd_001
148 * @tc.desc: Open encrypted db without password in collaboration mode.
149 * @tc.type: FUNC
150 * @tc.require:
151 * @tc.author: lidongwei
152 */
153 HWTEST_F(DistributedDBRelationalEncryptedDbTest, OpenEncryptedDBWithoutPasswdInCollMode_001, TestSize.Level1)
154 {
155 /**
156 * @tc.steps: step1. Create an encrypted db.
157 * @tc.expected: Succeed.
158 */
159 sqlite3 *db = nullptr;
160 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
161 string sql =
162 "PRAGMA key='" + CORRECT_KEY + "';"
163 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
164 "PRAGMA codec_hmac_algo=SHA256;"
165 "PRAGMA codec_rekey_hmac_algo=SHA256;"
166 "PRAGMA journal_mode=WAL;"
167 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
168 ExecSqlAndAssertOK(db, sql);
169
170 /**
171 * @tc.steps: step2. Open store.
172 * @tc.expected: Failed, return INVALID_PASSWD_OR_CORRUPTED_DB.
173 */
174 RelationalStoreDelegate::Option option { nullptr };
175 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
176 EXPECT_EQ(g_delegate, nullptr);
177 sqlite3_close(db);
178 }
179
180 /**
181 * @tc.name: OpenEncryptedDBWithoutPasswdInSplitMode_001
182 * @tc.desc: Open encrypted db without password in split mode.
183 * @tc.type: FUNC
184 * @tc.require:
185 * @tc.author: lidongwei
186 */
187 HWTEST_F(DistributedDBRelationalEncryptedDbTest, OpenEncryptedDBWithoutPasswdInSplitMode_001, TestSize.Level1)
188 {
189 /**
190 * @tc.steps: step1. Create an encrypted db.
191 * @tc.expected: Succeed.
192 */
193 sqlite3 *db = nullptr;
194 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
195 string sql =
196 "PRAGMA key='" + CORRECT_KEY + "';"
197 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
198 "PRAGMA codec_hmac_algo=SHA256;"
199 "PRAGMA codec_rekey_hmac_algo=SHA256;"
200 "PRAGMA journal_mode=WAL;"
201 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
202 ExecSqlAndAssertOK(db, sql);
203
204 /**
205 * @tc.steps: step2. Open store.
206 * @tc.expected: Failed, return INVALID_PASSWD_OR_CORRUPTED_DB.
207 */
208 RelationalStoreDelegate::Option option { nullptr };
209 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
210 EXPECT_EQ(g_delegate, nullptr);
211 sqlite3_close(db);
212 }
213
214 /**
215 * @tc.name: OpenEncryptedDBWithPasswdInSplitMode_001
216 * @tc.desc: Open encrypted db with password in split mode.
217 * @tc.type: FUNC
218 * @tc.require:
219 * @tc.author: lidongwei
220 */
221 HWTEST_F(DistributedDBRelationalEncryptedDbTest, OpenEncryptedDBWithPasswdInSplitMode_001, TestSize.Level1)
222 {
223 /**
224 * @tc.steps: step1. Create an encrypted db.
225 * @tc.expected: Succeed.
226 */
227 sqlite3 *db = nullptr;
228 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
229 string sql =
230 "PRAGMA key='" + CORRECT_KEY + "';"
231 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
232 "PRAGMA codec_hmac_algo=SHA256;"
233 "PRAGMA codec_rekey_hmac_algo=SHA256;"
234 "PRAGMA journal_mode=WAL;"
235 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
236 ExecSqlAndAssertOK(db, sql);
237
238 /**
239 * @tc.steps: step2. Open store.
240 * @tc.expected: Succeed, return OK.
241 */
242 RelationalStoreDelegate::Option option {
243 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, DEFAULT_ITER };
244 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::OK);
245 ASSERT_NE(g_delegate, nullptr);
246 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
247
248 /**
249 * @tc.steps: step3. Insert several data.
250 * @tc.expected: Succeed, return OK.
251 */
252 ExecSqlAndAssertOK(db, "INSERT OR REPLACE INTO " + g_tableName + " VALUES(1, 1);");
253 ExecSqlAndAssertOK(db, "INSERT OR REPLACE INTO " + g_tableName + " VALUES(2, 2);");
254 ExecSqlAndAssertOK(db, "INSERT OR REPLACE INTO " + g_tableName + " VALUES(3, 3);");
255
256 /**
257 * @tc.steps: step4. Get sync data.
258 * @tc.expected: Succeed, get 3 data.
259 */
260 auto store = GetRelationalStore();
261 ASSERT_NE(store, nullptr);
262 ContinueToken token = nullptr;
263 QueryObject query(Query::Select(g_tableName));
264 std::vector<SingleVerKvEntry *> entries;
265 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
266 EXPECT_EQ(entries.size(), 3u);
267 FreeEntires(entries);
268 sqlite3_close(db);
269 RefObject::DecObjRef(g_store);
270 }
271
272 /**
273 * @tc.name: OpenEncryptedDBWithInvalidParameters_001
274 * @tc.desc: Open encrypted db with invalid parameters in split mode.
275 * @tc.type: FUNC
276 * @tc.require:
277 * @tc.author: lidongwei
278 */
279 HWTEST_F(DistributedDBRelationalEncryptedDbTest, OpenEncryptedDBWithInvalidParameters_001, TestSize.Level1)
280 {
281 /**
282 * @tc.steps: step1. Create an encrypted db.
283 * @tc.expected: Succeed.
284 */
285 sqlite3 *db = nullptr;
286 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
287 string sql =
288 "PRAGMA key='" + CORRECT_KEY + "';"
289 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
290 "PRAGMA codec_hmac_algo=SHA256;"
291 "PRAGMA codec_rekey_hmac_algo=SHA256;"
292 "PRAGMA journal_mode=WAL;"
293 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
294 ExecSqlAndAssertOK(db, sql);
295
296 /**
297 * @tc.steps: step2. Open store with invalid password.
298 * @tc.expected: Failed, return INVALID_ARGS.
299 */
300 RelationalStoreDelegate::Option option1 {
301 nullptr, false, true, CipherType::DEFAULT, CipherPassword {}, DEFAULT_ITER };
302 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option1, g_delegate), DBStatus::INVALID_ARGS);
303 ASSERT_EQ(g_delegate, nullptr);
304
305 /**
306 * @tc.steps: step3. Open store with invalid password.
307 * @tc.expected: Failed, return INVALID_ARGS.
308 */
309 RelationalStoreDelegate::Option option2 {
310 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, 0u };
311 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option2, g_delegate), DBStatus::INVALID_ARGS);
312 ASSERT_EQ(g_delegate, nullptr);
313 sqlite3_close(db);
314 }
315
316 /**
317 * @tc.name: OpenEncryptedDBWithCustomizedIterTimes_001
318 * @tc.desc: Open encrypted db with customized iterate times.
319 * @tc.type: FUNC
320 * @tc.require:
321 * @tc.author: lidongwei
322 */
323 HWTEST_F(DistributedDBRelationalEncryptedDbTest, OpenEncryptedDBWithCustomizedIterTimes_001, TestSize.Level1)
324 {
325 /**
326 * @tc.steps: step1. Create an encrypted db.
327 * @tc.expected: Succeed.
328 */
329 sqlite3 *db = nullptr;
330 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
331 string sql =
332 "PRAGMA key='" + CORRECT_KEY + "';"
333 "PRAGMA codec_kdf_iter=" + std::to_string(CUSTOMIZED_ITER) + ";"
334 "PRAGMA codec_hmac_algo=SHA256;"
335 "PRAGMA codec_rekey_hmac_algo=SHA256;"
336 "PRAGMA journal_mode=WAL;"
337 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
338 ExecSqlAndAssertOK(db, sql);
339
340 /**
341 * @tc.steps: step2. Open store.
342 * @tc.expected: Succeed, return OK.
343 */
344 RelationalStoreDelegate::Option option1 {
345 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, CUSTOMIZED_ITER };
346 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option1, g_delegate), DBStatus::OK);
347 ASSERT_NE(g_delegate, nullptr);
348 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
349
350 /**
351 * @tc.steps: step3. Insert several data.
352 * @tc.expected: Succeed, return OK.
353 */
354 ExecSqlAndAssertOK(db, "INSERT OR REPLACE INTO " + g_tableName + " VALUES(1, 1);");
355 ExecSqlAndAssertOK(db, "INSERT OR REPLACE INTO " + g_tableName + " VALUES(2, 2);");
356 ExecSqlAndAssertOK(db, "INSERT OR REPLACE INTO " + g_tableName + " VALUES(3, 3);");
357
358 /**
359 * @tc.steps: step4. Get sync data.
360 * @tc.expected: Succeed, get 3 data.
361 */
362 auto store = GetRelationalStore();
363 ASSERT_NE(store, nullptr);
364 ContinueToken token = nullptr;
365 QueryObject query(Query::Select(g_tableName));
366 std::vector<SingleVerKvEntry *> entries;
367 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
368 EXPECT_EQ(entries.size(), 3u);
369 FreeEntires(entries);
370 sqlite3_close(db);
371 RefObject::DecObjRef(g_store);
372 }
373
374 /**
375 * @tc.name: RekeyAfterOpenStore_001
376 * @tc.desc: Rekey after open store.
377 * @tc.type: FUNC
378 * @tc.require:
379 * @tc.author: lidongwei
380 */
381 HWTEST_F(DistributedDBRelationalEncryptedDbTest, RekeyAfterOpenStore_001, TestSize.Level1)
382 {
383 /**
384 * @tc.steps: step1. Create an encrypted db.
385 * @tc.expected: Succeed.
386 */
387 sqlite3 *db = nullptr;
388 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
389 string sql =
390 "PRAGMA key='" + CORRECT_KEY + "';"
391 "PRAGMA codec_kdf_iter=" + std::to_string(CUSTOMIZED_ITER) + ";"
392 "PRAGMA codec_hmac_algo=SHA256;"
393 "PRAGMA codec_rekey_hmac_algo=SHA256;"
394 "PRAGMA journal_mode=WAL;"
395 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
396 ExecSqlAndAssertOK(db, sql);
397
398 /**
399 * @tc.steps: step2. Open store.
400 * @tc.expected: Succeed, return OK.
401 */
402 RelationalStoreDelegate::Option option1 {
403 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, CUSTOMIZED_ITER };
404 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option1, g_delegate), DBStatus::OK);
405 ASSERT_NE(g_delegate, nullptr);
406 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
407 EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
408 g_delegate = nullptr;
__anon5107aaaf0202null409 std::thread t1([db] {
410 std::string sql = "PARGMA rekey=" + REKEY_KEY;
411 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
412 });
413 t1.join();
414
415 /**
416 * @tc.steps: step3. Open store with new key.
417 * @tc.expected: Succeed.
418 */
419 option1.passwd = g_rekeyPasswd;
420 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option1, g_delegate), DBStatus::OK);
421 ASSERT_NE(g_delegate, nullptr);
422 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
423
424 /**
425 * @tc.steps: step4. Get sync data.
426 * @tc.expected: Succeed.
427 */
428 auto store = GetRelationalStore();
429 ASSERT_NE(store, nullptr);
430 ContinueToken token = nullptr;
431 QueryObject query(Query::Select(g_tableName));
432 std::vector<SingleVerKvEntry *> entries;
433 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
434 FreeEntires(entries);
435 sqlite3_close(db);
436 RefObject::DecObjRef(g_store);
437 }
438
439 /**
440 * @tc.name: OpenEncryptedDBWithDifferentPasswd_001
441 * @tc.desc: Open encrypted db with different password in split mode.
442 * @tc.type: FUNC
443 * @tc.require:
444 * @tc.author: lidongwei
445 */
446 HWTEST_F(DistributedDBRelationalEncryptedDbTest, OpenEncryptedDBWithDifferentPasswd_001, TestSize.Level1)
447 {
448 /**
449 * @tc.steps: step1. Create an encrypted db.
450 * @tc.expected: Succeed.
451 */
452 sqlite3 *db = nullptr;
453 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
454 string sql =
455 "PRAGMA key='" + CORRECT_KEY + "';"
456 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
457 "PRAGMA journal_mode=WAL;"
458 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
459 ExecSqlAndAssertOK(db, sql);
460 sqlite3_close(db);
461
462 /**
463 * @tc.steps: step2. Open store.
464 * @tc.expected: Succeed, return OK.
465 */
466 RelationalStoreDelegate::Option option {
467 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, DEFAULT_ITER };
468 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::OK);
469 ASSERT_NE(g_delegate, nullptr);
470
471 /**
472 * @tc.steps: step3. Open store with different key or iter times.
473 * @tc.expected: Failed, return INVALID_PASSWD_OR_CORRUPTED_DB.
474 */
475 RelationalStoreDelegate *delegate = nullptr;
476 option = { nullptr, false, true, CipherType::DEFAULT, g_incorrectPasswd, DEFAULT_ITER };
477 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
478 EXPECT_EQ(delegate, nullptr);
479
480 option = { nullptr, false, true, CipherType::DEFAULT, g_incorrectPasswd, CUSTOMIZED_ITER };
481 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
482 EXPECT_EQ(delegate, nullptr);
483
484 option = { nullptr, false, false, CipherType::DEFAULT, g_correctPasswd, DEFAULT_ITER };
485 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
486 EXPECT_EQ(delegate, nullptr);
487
488 /**
489 * @tc.steps: step4. Open store with different cipher.
490 * @tc.expected: Succeed, return OK.
491 */
492 option = { nullptr, false, true, CipherType::AES_256_GCM, g_correctPasswd, DEFAULT_ITER };
493 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::OK);
494 EXPECT_NE(delegate, nullptr);
495
496 EXPECT_EQ(g_mgr.CloseStore(delegate), DBStatus::OK);
497 }
498
499 /**
500 * @tc.name: RemoteQueryForEncryptedDb_001
501 * @tc.desc: Exec remote query on encrypted db.
502 * @tc.type: FUNC
503 * @tc.require:
504 * @tc.author: lidongwei
505 */
506 HWTEST_F(DistributedDBRelationalEncryptedDbTest, RemoteQueryForEncryptedDb_001, TestSize.Level1)
507 {
508 /**
509 * @tc.steps: step1. Create an encrypted db.
510 * @tc.expected: Succeed.
511 */
512 sqlite3 *db = nullptr;
513 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
514 string sql =
515 "PRAGMA key='" + CORRECT_KEY + "';"
516 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
517 "PRAGMA codec_hmac_algo=SHA256;"
518 "PRAGMA codec_rekey_hmac_algo=SHA256;"
519 "PRAGMA journal_mode=WAL;"
520 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
521 ExecSqlAndAssertOK(db, sql);
522 sqlite3_close(db);
523
524 /**
525 * @tc.steps: step2. Open store and create distributed table.
526 * @tc.expected: Succeed, return OK.
527 */
528 RelationalStoreDelegate::Option option {
529 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, DEFAULT_ITER };
530 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::OK);
531 ASSERT_NE(g_delegate, nullptr);
532 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
533
534 /**
535 * @tc.steps: step3. Remote query.
536 * @tc.expected: Return not INVALID_PASSWD_OR_CORRUPTED_DB.
537 */
538 int invalidTime = 1000; // 1000 for test.
539 std::shared_ptr<ResultSet> result = nullptr;
540 EXPECT_NE(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, invalidTime, result),
541 DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
542
543 /**
544 * @tc.steps: step4. Rekey.
545 */
546 EXPECT_EQ(g_mgr.CloseStore(g_delegate), OK);
547 g_delegate = nullptr;
548 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
__anon5107aaaf0302null549 std::thread t1([db] {
550 std::string sql = "PARGMA rekey=" + REKEY_KEY;
551 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
552 });
553 t1.join();
554 sqlite3_close(db);
555 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::OK);
556 ASSERT_NE(g_delegate, nullptr);
557 /**
558 * @tc.steps: step5. Remote query.
559 * @tc.expected: Return INVALID_PASSWD_OR_CORRUPTED_DB.
560 */
561 EXPECT_NE(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, invalidTime, result),
562 DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
563 }
564 #endif // RELATIONAL_STORE
565 #endif // OMIT_ENCRYPT
566