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: AR000H68LL
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: AR000H68LL
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: AR000H68LL
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: AR000H68LL
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: AR000H68LL
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: AR000H68LL
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
__anon259049c50202null408 std::thread t1([db] {
409 std::string sql = "PARGMA rekey=" + REKEY_KEY;
410 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
411 });
412 t1.join();
413
414 /**
415 * @tc.steps: step3. Get sync data.
416 * @tc.expected: Failed.
417 */
418 auto store = GetRelationalStore();
419 ASSERT_NE(store, nullptr);
420 ContinueToken token = nullptr;
421 QueryObject query(Query::Select(g_tableName));
422 std::vector<SingleVerKvEntry *> entries;
423 EXPECT_NE(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
424
425 RefObject::DecObjRef(g_store);
426 g_mgr.CloseStore(g_delegate);
427 g_delegate = nullptr;
428
429 /**
430 * @tc.steps: step4. Open store with new key.
431 * @tc.expected: Succeed.
432 */
433 option1.passwd = g_rekeyPasswd;
434 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option1, g_delegate), DBStatus::OK);
435 ASSERT_NE(g_delegate, nullptr);
436 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
437
438 /**
439 * @tc.steps: step5. Get sync data.
440 * @tc.expected: Succeed.
441 */
442 store = GetRelationalStore();
443 ASSERT_NE(store, nullptr);
444 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
445 FreeEntires(entries);
446 sqlite3_close(db);
447 RefObject::DecObjRef(g_store);
448 }
449
450 /**
451 * @tc.name: OpenEncryptedDBWithDifferentPasswd_001
452 * @tc.desc: Open encrypted db with different password in split mode.
453 * @tc.type: FUNC
454 * @tc.require: AR000H68LL
455 * @tc.author: lidongwei
456 */
457 HWTEST_F(DistributedDBRelationalEncryptedDbTest, OpenEncryptedDBWithDifferentPasswd_001, TestSize.Level1)
458 {
459 /**
460 * @tc.steps: step1. Create an encrypted db.
461 * @tc.expected: Succeed.
462 */
463 sqlite3 *db = nullptr;
464 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
465 string sql =
466 "PRAGMA key='" + CORRECT_KEY + "';"
467 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
468 "PRAGMA journal_mode=WAL;"
469 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
470 ExecSqlAndAssertOK(db, sql);
471
472 /**
473 * @tc.steps: step2. Open store.
474 * @tc.expected: Succeed, return OK.
475 */
476 RelationalStoreDelegate::Option option {
477 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, DEFAULT_ITER };
478 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::OK);
479 ASSERT_NE(g_delegate, nullptr);
480
481 /**
482 * @tc.steps: step3. Open store with different key or iter times.
483 * @tc.expected: Failed, return INVALID_PASSWD_OR_CORRUPTED_DB.
484 */
485 RelationalStoreDelegate *delegate = nullptr;
486 option = { nullptr, false, true, CipherType::DEFAULT, g_incorrectPasswd, DEFAULT_ITER };
487 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
488 EXPECT_EQ(delegate, nullptr);
489
490 option = { nullptr, false, true, CipherType::DEFAULT, g_incorrectPasswd, CUSTOMIZED_ITER };
491 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
492 EXPECT_EQ(delegate, nullptr);
493
494 option = { nullptr, false, false, CipherType::DEFAULT, g_correctPasswd, DEFAULT_ITER };
495 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
496 EXPECT_EQ(delegate, nullptr);
497
498 /**
499 * @tc.steps: step4. Open store with different cipher.
500 * @tc.expected: Succeed, return OK.
501 */
502 option = { nullptr, false, true, CipherType::AES_256_GCM, g_correctPasswd, DEFAULT_ITER };
503 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, delegate), DBStatus::OK);
504 EXPECT_NE(delegate, nullptr);
505
506 EXPECT_EQ(g_mgr.CloseStore(delegate), DBStatus::OK);
507 sqlite3_close(db);
508 }
509
510 /**
511 * @tc.name: RemoteQueryForEncryptedDb_001
512 * @tc.desc: Exec remote query on encrypted db.
513 * @tc.type: FUNC
514 * @tc.require: AR000H68LL
515 * @tc.author: lidongwei
516 */
517 HWTEST_F(DistributedDBRelationalEncryptedDbTest, RemoteQueryForEncryptedDb_001, TestSize.Level1)
518 {
519 /**
520 * @tc.steps: step1. Create an encrypted db.
521 * @tc.expected: Succeed.
522 */
523 sqlite3 *db = nullptr;
524 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
525 string sql =
526 "PRAGMA key='" + CORRECT_KEY + "';"
527 "PRAGMA codec_kdf_iter=" + std::to_string(DEFAULT_ITER) + ";"
528 "PRAGMA codec_hmac_algo=SHA256;"
529 "PRAGMA codec_rekey_hmac_algo=SHA256;"
530 "PRAGMA journal_mode=WAL;"
531 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
532 ExecSqlAndAssertOK(db, sql);
533
534 /**
535 * @tc.steps: step2. Open store and create distributed table.
536 * @tc.expected: Succeed, return OK.
537 */
538 RelationalStoreDelegate::Option option {
539 nullptr, false, true, CipherType::DEFAULT, g_correctPasswd, DEFAULT_ITER };
540 EXPECT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, option, g_delegate), DBStatus::OK);
541 ASSERT_NE(g_delegate, nullptr);
542 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
543
544 /**
545 * @tc.steps: step3. Remote query.
546 * @tc.expected: Return not INVALID_PASSWD_OR_CORRUPTED_DB.
547 */
548 int invalidTime = 1000; // 1000 for test.
549 std::shared_ptr<ResultSet> result = nullptr;
550 EXPECT_NE(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, invalidTime, result),
551 DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
552
553 /**
554 * @tc.steps: step4. Rekey.
555 */
__anon259049c50302null556 std::thread t1([db] {
557 std::string sql = "PARGMA rekey=" + REKEY_KEY;
558 EXPECT_EQ(sqlite3_rekey(db, REKEY_KEY.data(), REKEY_KEY.size()), SQLITE_OK);
559 });
560 t1.join();
561
562 /**
563 * @tc.steps: step5. Remote query.
564 * @tc.expected: Return INVALID_PASSWD_OR_CORRUPTED_DB.
565 */
566 EXPECT_EQ(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, invalidTime, result),
567 DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB);
568 sqlite3_close(db);
569 }
570 #endif // RELATIONAL_STORE
571 #endif // OMIT_ENCRYPT
572