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