1 /*
2 * Copyright (c) 2023 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 #define LOG_TAG "RdbRekeyTest"
17 #include <gtest/gtest.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 #include <securec.h>
22
23 #include <fstream>
24 #include <iostream>
25 #include <string>
26 #include <thread>
27
28 #include "block_data.h"
29 #include "common.h"
30 #include "file_ex.h"
31 #include "logger.h"
32 #include "rdb_errno.h"
33 #include "rdb_helper.h"
34 #include "rdb_open_callback.h"
35 #include "rdb_security_manager.h"
36 #include "sqlite_utils.h"
37
38 using namespace testing::ext;
39 using namespace OHOS::NativeRdb;
40 using namespace OHOS::Rdb;
41 class RdbRekeyTest : public testing::Test {
42 public:
43 static void SetUpTestCase();
44 static void TearDownTestCase();
45 void SetUp() override;
46 void TearDown() override;
47
48 static std::string RemoveSuffix(const std::string &name);
49 static std::chrono::system_clock::time_point GetKeyFileDate(const std::string &dbName);
50 static bool ChangeKeyFileDate(const std::string &dbName, int rep);
51 static bool SaveNewKey(const std::string &dbName);
52 static RdbStoreConfig GetRdbConfig(const std::string &name);
53 static RdbStoreConfig GetRdbNotRekeyConfig(const std::string &name);
54 static void InsertData(std::shared_ptr<RdbStore> &store);
55 static void CheckQueryData(std::shared_ptr<RdbStore> &store);
56
57 static const std::string encryptedDatabaseName;
58 static const std::string encryptedDatabasePath;
59 static const std::string encryptedDatabaseKeyDir;
60 static const std::string encryptedDatabaseMockName;
61 static const std::string encryptedDatabaseMockPath;
62 static constexpr int HOURS_EXPIRED = (24 * 365) + 1;
63 static constexpr int HOURS_LONG_LONG_AGO = 30 * (24 * 365);
64 static constexpr int HOURS_NOT_EXPIRED = (24 * 30);
65 };
66
67 const std::string RdbRekeyTest::encryptedDatabaseName = "encrypted.db";
68 const std::string RdbRekeyTest::encryptedDatabasePath = RDB_TEST_PATH + encryptedDatabaseName;
69 const std::string RdbRekeyTest::encryptedDatabaseKeyDir = RDB_TEST_PATH + "key/";
70 const std::string RdbRekeyTest::encryptedDatabaseMockName = "encrypted_mock.db";
71 const std::string RdbRekeyTest::encryptedDatabaseMockPath = RDB_TEST_PATH + encryptedDatabaseMockName;
72
73 class RekeyTestOpenCallback : public RdbOpenCallback {
74 public:
75 int OnCreate(RdbStore &store) override;
76 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
77 static const std::string createTableTest;
78 };
79
80 std::string const RekeyTestOpenCallback::createTableTest = "CREATE TABLE IF NOT EXISTS test "
81 "(id INTEGER PRIMARY KEY "
82 "AUTOINCREMENT, "
83 "name TEXT NOT NULL, age INTEGER, "
84 "salary "
85 "REAL, blobType BLOB)";
86
OnCreate(RdbStore & store)87 int RekeyTestOpenCallback::OnCreate(RdbStore &store)
88 {
89 return store.ExecuteSql(createTableTest);
90 }
91
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)92 int RekeyTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
93 {
94 return E_OK;
95 }
96
SetUpTestCase()97 void RdbRekeyTest::SetUpTestCase()
98 {
99 }
100
TearDownTestCase()101 void RdbRekeyTest::TearDownTestCase()
102 {
103 }
104
SetUp()105 void RdbRekeyTest::SetUp()
106 {
107 RdbHelper::ClearCache();
108 RdbHelper::DeleteRdbStore(RdbRekeyTest::encryptedDatabasePath);
109 RdbStoreConfig config = GetRdbConfig(encryptedDatabasePath);
110 RekeyTestOpenCallback helper;
111 int errCode;
112 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
113 EXPECT_NE(store, nullptr);
114 InsertData(store);
115 store.reset();
116 RdbHelper::ClearCache();
117 }
118
TearDown()119 void RdbRekeyTest::TearDown()
120 {
121 RdbHelper::ClearCache();
122 RdbHelper::DeleteRdbStore(RdbRekeyTest::encryptedDatabasePath);
123 }
124
RemoveSuffix(const std::string & name)125 std::string RdbRekeyTest::RemoveSuffix(const std::string &name)
126 {
127 std::string suffix(".db");
128 auto pos = name.rfind(suffix);
129 if (pos == std::string::npos || pos < name.length() - suffix.length()) {
130 return name;
131 }
132 return { name, 0, pos };
133 }
134
GetKeyFileDate(const std::string & dbName)135 std::chrono::system_clock::time_point RdbRekeyTest::GetKeyFileDate(const std::string &dbName)
136 {
137 std::chrono::system_clock::time_point timePoint;
138 std::string name = RemoveSuffix(dbName);
139 auto keyPath = RDB_TEST_PATH + "key/" + name + ".pub_key_v1";
140 if (!OHOS::FileExists(keyPath)) {
141 return timePoint;
142 }
143 std::vector<char> content;
144 auto loaded = OHOS::LoadBufferFromFile(keyPath, content);
145 if (!loaded) {
146 return timePoint;
147 }
148 auto iter = content.begin();
149 iter++;
150 constexpr uint32_t dateFileLength = sizeof(time_t) / sizeof(uint8_t);
151 std::vector<uint8_t> date;
152 date.assign(iter, iter + dateFileLength);
153 timePoint = std::chrono::system_clock::from_time_t(*reinterpret_cast<time_t *>(const_cast<uint8_t *>(&date[0])));
154 return timePoint;
155 }
156
ChangeKeyFileDate(const std::string & dbName,int rep)157 bool RdbRekeyTest::ChangeKeyFileDate(const std::string &dbName, int rep)
158 {
159 std::string name = RemoveSuffix(dbName);
160 auto keyPath = RDB_TEST_PATH + "key/" + name + ".pub_key_v1";
161 if (!OHOS::FileExists(keyPath)) {
162 return false;
163 }
164 std::vector<char> content;
165 auto loaded = OHOS::LoadBufferFromFile(keyPath, content);
166 if (!loaded) {
167 return false;
168 }
169 auto time =
170 std::chrono::system_clock::to_time_t(std::chrono::system_clock::system_clock::now() - std::chrono::hours(rep));
171 std::vector<char> date(reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time));
172 std::copy(date.begin(), date.end(), ++content.begin());
173
174 auto saved = OHOS::SaveBufferToFile(keyPath, content);
175 return saved;
176 }
177
SaveNewKey(const string & dbName)178 bool RdbRekeyTest::SaveNewKey(const string &dbName)
179 {
180 std::string name = RemoveSuffix(dbName);
181 auto keyPath = RDB_TEST_PATH + "key/" + name + ".pub_key_v1";
182 auto newKeyPath = RDB_TEST_PATH + "key/" + name + ".pub_key.new";
183 if (!OHOS::FileExists(keyPath)) {
184 return false;
185 }
186 std::vector<char> content;
187 auto loaded = OHOS::LoadBufferFromFile(keyPath, content);
188 if (!loaded) {
189 return false;
190 }
191 OHOS::SaveBufferToFile(newKeyPath, content);
192 content[content.size() - 1] = 'E';
193 return OHOS::SaveBufferToFile(keyPath, content);
194 }
195
GetRdbConfig(const std::string & name)196 RdbStoreConfig RdbRekeyTest::GetRdbConfig(const std::string &name)
197 {
198 RdbStoreConfig config(name);
199 config.SetEncryptStatus(true);
200 config.SetBundleName("com.example.test_rekey");
201 config.EnableRekey(true);
202 return config;
203 }
204
GetRdbNotRekeyConfig(const std::string & name)205 RdbStoreConfig RdbRekeyTest::GetRdbNotRekeyConfig(const std::string &name)
206 {
207 RdbStoreConfig config(name);
208 config.SetEncryptStatus(true);
209 config.SetBundleName("com.example.test_rekey");
210 config.EnableRekey(false);
211 return config;
212 }
213
InsertData(std::shared_ptr<RdbStore> & store)214 void RdbRekeyTest::InsertData(std::shared_ptr<RdbStore> &store)
215 {
216 int64_t id;
217 ValuesBucket values;
218 std::string name = "zhangsan";
219 int age = 18;
220 double salary = 100.5;
221 std::vector<uint8_t> blob{ 1, 2, 3 };
222 values.PutString("name", name);
223 values.PutInt("age", age);
224 values.PutDouble("salary", salary);
225 values.PutBlob("blobType", blob);
226 int insertRet = store->Insert(id, "test", values);
227 EXPECT_EQ(insertRet, E_OK);
228 }
229
CheckQueryData(std::shared_ptr<RdbStore> & store)230 void RdbRekeyTest::CheckQueryData(std::shared_ptr<RdbStore> &store)
231 {
232 std::shared_ptr<ResultSet> resultSet =
233 store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector<std::string>{ "zhangsan" });
234 EXPECT_NE(resultSet, nullptr);
235 int result = resultSet->GoToFirstRow();
236 EXPECT_EQ(result, E_OK);
237 int columnIndex;
238 std::string strVal;
239 ColumnType columnType;
240 result = resultSet->GetColumnIndex("name", columnIndex);
241 EXPECT_EQ(result, E_OK);
242 result = resultSet->GetColumnType(columnIndex, columnType);
243 EXPECT_EQ(result, E_OK);
244 EXPECT_EQ(columnType, ColumnType::TYPE_STRING);
245 result = resultSet->GetString(columnIndex, strVal);
246 EXPECT_EQ(result, E_OK);
247 EXPECT_EQ("zhangsan", strVal);
248
249 result = resultSet->Close();
250 EXPECT_EQ(result, E_OK);
251 }
252
253 /**
254 * @tc.name: Rdb_Rekey_Test_001
255 * @tc.desc: test RdbStore rekey function
256 * @tc.type: FUNC
257 */
258 HWTEST_F(RdbRekeyTest, Rdb_Rekey_01, TestSize.Level1)
259 {
260 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
261 std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key.new";
262
263 bool isFileExists = OHOS::FileExists(keyPath);
264 ASSERT_TRUE(isFileExists);
265
266 bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbRekeyTest::HOURS_EXPIRED);
267 ASSERT_TRUE(isFileDateChanged);
268
269 RdbStoreConfig config = GetRdbConfig(RdbRekeyTest::encryptedDatabasePath);
270 RekeyTestOpenCallback helper;
271 int errCode = E_OK;
272 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
273 ASSERT_NE(store, nullptr);
274 ASSERT_EQ(errCode, E_OK);
275
276 isFileExists = OHOS::FileExists(keyPath);
277 ASSERT_TRUE(isFileExists);
278 isFileExists = OHOS::FileExists(newKeyPath);
279 ASSERT_FALSE(isFileExists);
280
281 CheckQueryData(store);
282 }
283
284 /**
285 * @tc.name: Rdb_Rekey_Test_002
286 * @tc.desc: test RdbStore with not outdated password
287 * @tc.type: FUNC
288 */
289 HWTEST_F(RdbRekeyTest, Rdb_Rekey_02, TestSize.Level1)
290 {
291 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
292 bool isFileExists = OHOS::FileExists(keyPath);
293 ASSERT_TRUE(isFileExists);
294
295 bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbRekeyTest::HOURS_NOT_EXPIRED);
296 ASSERT_TRUE(isFileDateChanged);
297
298 auto changedDate = GetKeyFileDate(encryptedDatabaseName);
299 ASSERT_TRUE(std::chrono::system_clock::now() - changedDate > std::chrono::hours(RdbRekeyTest::HOURS_NOT_EXPIRED));
300
301 RdbStoreConfig config = GetRdbConfig(RdbRekeyTest::encryptedDatabasePath);
302 RekeyTestOpenCallback helper;
303 int errCode = E_OK;
304 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
305 ASSERT_NE(store, nullptr);
306 ASSERT_EQ(errCode, E_OK);
307 CheckQueryData(store);
308 }
309
310 /**
311 * @tc.name: Rdb_Rekey_Test_003
312 * @tc.desc: try to open store and execute RekeyRecover() without key and new key files.
313 * @tc.type: FUNC
314 */
315 HWTEST_F(RdbRekeyTest, Rdb_Rekey_03, TestSize.Level1)
316 {
317 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
318 std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key.new";
319
320 bool isFileExists = OHOS::FileExists(keyPath);
321 ASSERT_TRUE(isFileExists);
322
323 SqliteUtils::DeleteFile(keyPath);
324 isFileExists = OHOS::FileExists(keyPath);
325 ASSERT_FALSE(isFileExists);
326 isFileExists = OHOS::FileExists(newKeyPath);
327 ASSERT_FALSE(isFileExists);
328
329 RekeyTestOpenCallback helper;
330 int errCode = E_OK;
331 RdbStoreConfig config = GetRdbConfig(encryptedDatabasePath);
332 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
333 ASSERT_NE(store, nullptr);
334 ASSERT_EQ(errCode, E_OK);
335 store = nullptr;
336 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
337 ASSERT_NE(store, nullptr);
338 ASSERT_EQ(errCode, E_OK);
339 }
340
341 /**
342 * @tc.name: Rdb_Rekey_Test_004
343 * @tc.desc: try to open store and modify create date to a future time.
344 * @tc.type: FUNC
345 */
346 HWTEST_F(RdbRekeyTest, Rdb_Rekey_04, TestSize.Level1)
347 {
348 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
349 std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key.new";
350
351 bool isFileExists = OHOS::FileExists(keyPath);
352 ASSERT_TRUE(isFileExists);
353
354 bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, -RdbRekeyTest::HOURS_EXPIRED);
355 ASSERT_TRUE(isFileDateChanged);
356
357 RdbStoreConfig config = GetRdbConfig(RdbRekeyTest::encryptedDatabasePath);
358 RekeyTestOpenCallback helper;
359 int errCode;
360 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
361 ASSERT_NE(store, nullptr);
362
363 isFileExists = OHOS::FileExists(keyPath);
364 ASSERT_TRUE(isFileExists);
365 isFileExists = OHOS::FileExists(newKeyPath);
366 ASSERT_FALSE(isFileExists);
367
368 CheckQueryData(store);
369 }
370
371 /**
372 * @tc.name: Rdb_Rekey_RenameFailed_05
373 * @tc.desc: re key and rename failed the new key file.
374 * @tc.type: FUNC
375 */
376 HWTEST_F(RdbRekeyTest, Rdb_Rekey_RenameFailed_05, TestSize.Level1)
377 {
378 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
379 std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key.new";
380
381 bool isFileExists = OHOS::FileExists(keyPath);
382 ASSERT_TRUE(isFileExists);
383
384 bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbRekeyTest::HOURS_LONG_LONG_AGO);
385 ASSERT_TRUE(isFileDateChanged);
386
387 RdbStoreConfig config = GetRdbConfig(RdbRekeyTest::encryptedDatabasePath);
388 RekeyTestOpenCallback helper;
389 int errCode = E_OK;
390 for (int i = 0; i < 50; ++i) {
391 auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
392 ASSERT_NE(store, nullptr);
393 ASSERT_EQ(errCode, E_OK);
394 store = nullptr;
395 SaveNewKey(encryptedDatabaseName);
396 }
397
398 auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
399 CheckQueryData(store);
400 }
401
402 /**
403 * @tc.name: Rdb_Delete_Rekey_Test_06
404 * @tc.desc: test RdbStore rekey function
405 * @tc.type: FUNC
406 */
407 HWTEST_F(RdbRekeyTest, Rdb_Rekey_06, TestSize.Level1)
408 {
409 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
410 std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key.new";
411
412 bool isFileExists = OHOS::FileExists(keyPath);
413 ASSERT_TRUE(isFileExists);
414
415 bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbRekeyTest::HOURS_EXPIRED);
416 ASSERT_TRUE(isFileDateChanged);
417
418 auto changedDate = GetKeyFileDate(encryptedDatabaseName);
419 ASSERT_TRUE(std::chrono::system_clock::now() - changedDate > std::chrono::hours(RdbRekeyTest::HOURS_EXPIRED));
420
421 RdbStoreConfig config = GetRdbNotRekeyConfig(RdbRekeyTest::encryptedDatabasePath);
422 RekeyTestOpenCallback helper;
423 int errCode = E_OK;
424 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
425 ASSERT_NE(store, nullptr);
426 ASSERT_EQ(errCode, E_OK);
427
428 isFileExists = OHOS::FileExists(keyPath);
429 ASSERT_TRUE(isFileExists);
430 isFileExists = OHOS::FileExists(newKeyPath);
431 ASSERT_FALSE(isFileExists);
432
433 ASSERT_TRUE(std::chrono::system_clock::now() - changedDate > std::chrono::hours(RdbRekeyTest::HOURS_EXPIRED));
434 CheckQueryData(store);
435 }
436
437 /**
438 * @tc.name: Rdb_Delete_Rekey_Test_07
439 * @tc.desc: test deleting the key file of the encrypted database
440 * @tc.type: FUNC
441 */
442 HWTEST_F(RdbRekeyTest, Rdb_Rekey_07, TestSize.Level1)
443 {
444 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
445 config.SetSecurityLevel(SecurityLevel::S1);
446 config.SetAllowRebuild(true);
447 config.SetEncryptStatus(true);
448 config.SetBundleName("com.example.test_rekey");
449 RekeyTestOpenCallback helper;
450 int errCode = E_OK;
451 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
452 ASSERT_NE(store, nullptr);
453 ASSERT_EQ(errCode, E_OK);
454
455 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
456 bool isFileExists = OHOS::FileExists(keyPath);
457 ASSERT_TRUE(isFileExists);
458 struct stat fileStat;
459 ino_t inodeNumber1 = -1;
460 if (stat(keyPath.c_str(), &fileStat) == 0) {
461 inodeNumber1 = fileStat.st_ino;
462 }
463 store = nullptr;
464
465 {
466 std::ofstream fsDb(encryptedDatabasePath, std::ios_base::binary | std::ios_base::out);
467 fsDb.seekp(64);
468 fsDb.write("hello", 5);
469 fsDb.close();
470 }
471
472 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
473 isFileExists = OHOS::FileExists(keyPath);
474 ASSERT_TRUE(isFileExists);
475 ino_t inodeNumber2 = -1;
476 if (stat(keyPath.c_str(), &fileStat) == 0) {
477 inodeNumber2 = fileStat.st_ino;
478 }
479
480 ASSERT_NE(inodeNumber1, inodeNumber2);
481 }
482
483 /**
484 * @tc.name: Rdb_Delete_Rekey_Test_08
485 * @tc.desc: test deleting the key file of the encrypted database
486 * @tc.type: FUNC
487 */
488 HWTEST_F(RdbRekeyTest, Rdb_Rekey_08, TestSize.Level1)
489 {
490 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
491 config.SetSecurityLevel(SecurityLevel::S1);
492 config.SetAllowRebuild(false);
493 config.SetEncryptStatus(true);
494 config.SetBundleName("com.example.test_rekey");
495 RekeyTestOpenCallback helper;
496 int errCode = E_OK;
497 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
498 ASSERT_NE(store, nullptr);
499 ASSERT_EQ(errCode, E_OK);
500
501 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
502 bool isFileExists = OHOS::FileExists(keyPath);
503 ASSERT_TRUE(isFileExists);
504 struct stat fileStat;
505 ino_t inodeNumber1 = -1;
506 if (stat(keyPath.c_str(), &fileStat) == 0) {
507 inodeNumber1 = fileStat.st_ino;
508 }
509 store = nullptr;
510
511 {
512 std::ofstream fsDb(encryptedDatabasePath, std::ios_base::binary | std::ios_base::out);
513 fsDb.seekp(64);
514 fsDb.write("hello", 5);
515 fsDb.close();
516 }
517
518 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
519 isFileExists = OHOS::FileExists(keyPath);
520 ASSERT_TRUE(isFileExists);
521 ino_t inodeNumber2 = -1;
522 if (stat(keyPath.c_str(), &fileStat) == 0) {
523 inodeNumber2 = fileStat.st_ino;
524 }
525
526 ASSERT_EQ(inodeNumber1, inodeNumber2);
527 }
528
529 /**
530 * @tc.name: Rdb_Delete_Rekey_Test_009
531 * @tc.desc: test rekey the encrypted database
532 * @tc.type: FUNC
533 */
534 HWTEST_F(RdbRekeyTest, Rdb_Rekey_009, TestSize.Level1)
535 {
536 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
537 config.SetSecurityLevel(SecurityLevel::S1);
538 config.SetAllowRebuild(false);
539 config.SetEncryptStatus(true);
540 config.SetBundleName("com.example.test_rekey");
541 RekeyTestOpenCallback helper;
542 int errCode = E_OK;
543 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
544 ASSERT_NE(store, nullptr);
545 ASSERT_EQ(errCode, E_OK);
546
547 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
548 "name TEXT NOT NULL, age INTEGER)");
549
550 int64_t id;
551 ValuesBucket values;
552 values.PutInt("id", 1);
553 values.PutString("name", std::string("zhangsan"));
554 values.PutInt("age", 18);
555 int ret = store->Insert(id, "test1", values);
556 EXPECT_EQ(ret, E_OK);
557 EXPECT_EQ(1, id);
558
559 RdbStoreConfig::CryptoParam cryptoParam1;
560 cryptoParam1.iterNum = -1;
561 errCode = store->Rekey(cryptoParam1);
562 ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
563
564 RdbStoreConfig::CryptoParam cryptoParam2;
565 cryptoParam2.encryptAlgo = -1;
566 errCode = store->Rekey(cryptoParam2);
567 ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
568
569 RdbStoreConfig::CryptoParam cryptoParam3;
570 cryptoParam3.hmacAlgo = -1;
571 errCode = store->Rekey(cryptoParam3);
572 ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
573
574 RdbStoreConfig::CryptoParam cryptoParam4;
575 cryptoParam4.kdfAlgo = -1;
576 errCode = store->Rekey(cryptoParam4);
577 ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
578
579 RdbStoreConfig::CryptoParam cryptoParam5;
580 cryptoParam5.cryptoPageSize = -1;
581 errCode = store->Rekey(cryptoParam5);
582 ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
583
584 values.Clear();
585 values.PutInt("id", 2);
586 values.PutString("name", std::string("lisi"));
587 values.PutInt("age", 19);
588 ret = store->Insert(id, "test1", values);
589 EXPECT_EQ(ret, E_OK);
590 EXPECT_EQ(2, id);
591 }
592
593 /**
594 * @tc.name: Rdb_Delete_Rekey_Test_010
595 * @tc.desc: test rekey the encrypted database
596 * @tc.type: FUNC
597 */
598 HWTEST_F(RdbRekeyTest, Rdb_Rekey_010, TestSize.Level1)
599 {
600 const std::string encryptedDatabaseName1 = "encrypted1.db";
601 const std::string encryptedDatabasePath1 = RDB_TEST_PATH + encryptedDatabaseName1;
602 RdbStoreConfig config(encryptedDatabasePath1);
603 config.SetSecurityLevel(SecurityLevel::S1);
604 config.SetBundleName("com.example.test_rekey");
605 RekeyTestOpenCallback helper;
606 int errCode = E_OK;
607 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
608 ASSERT_NE(store, nullptr);
609 ASSERT_EQ(errCode, E_OK);
610
611 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
612 "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
613
614 int64_t id;
615 ValuesBucket values;
616 values.PutInt("id", 1);
617 values.PutString("name", std::string("zhangsan1"));
618 values.PutInt("age", 50);
619 values.PutDouble("salary", 263);
620 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3, 4, 5});
621 int ret = store->Insert(id, "test1", values);
622 EXPECT_EQ(ret, E_OK);
623 EXPECT_EQ(1, id);
624
625 RdbStoreConfig::CryptoParam cryptoParam;
626 auto isEncrypt = config.IsEncrypt();
627 ASSERT_EQ(isEncrypt, false);
628 errCode = store->Rekey(cryptoParam);
629 ASSERT_EQ(errCode, E_NOT_SUPPORT);
630
631 cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
632 errCode = store->Rekey(cryptoParam);
633 ASSERT_EQ(errCode, E_NOT_SUPPORT);
634
635 values.Clear();
636 values.PutInt("id", 2);
637 values.PutString("name", std::string("lisi1"));
638 values.PutInt("age", 191);
639 values.PutDouble("salary", 2001.5);
640 values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6, 7 });
641 ret = store->Insert(id, "test1", values);
642 EXPECT_EQ(ret, E_OK);
643 EXPECT_EQ(2, id);
644
645 auto resultSet = store->QueryByStep("SELECT * FROM test1");
646 ASSERT_NE(resultSet, nullptr);
647 int32_t rowCount{};
648 ret = resultSet->GetRowCount(rowCount);
649 ASSERT_EQ(ret, E_OK);
650 ASSERT_EQ(rowCount, 2);
651
652 ret = RdbHelper::DeleteRdbStore(config);
653 EXPECT_EQ(ret, E_OK);
654 }
655
656 /**
657 * @tc.name: Rdb_Delete_Rekey_Test_011
658 * @tc.desc: test rekey other parameters
659 * @tc.type: FUNC
660 */
661 HWTEST_F(RdbRekeyTest, Rdb_Rekey_011, TestSize.Level1)
662 {
663 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
664 config.SetSecurityLevel(SecurityLevel::S1);
665 config.SetBundleName("com.example.test_rekey");
666 config.SetEncryptStatus(true);
667 RekeyTestOpenCallback helper;
668 int errCode = E_OK;
669 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
670 ASSERT_NE(store, nullptr);
671 ASSERT_EQ(errCode, E_OK);
672
673 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
674 "name TEXT NOT NULL, age INTEGER)");
675
676 int64_t id;
677 ValuesBucket values;
678 values.PutInt("id", 1);
679 values.PutString("name", std::string("1zhangsan"));
680 values.PutInt("age", 118);
681 int ret = store->Insert(id, "test1", values);
682 EXPECT_EQ(ret, E_OK);
683 EXPECT_EQ(1, id);
684
685 RdbStoreConfig::CryptoParam cryptoParam1;
686 cryptoParam1.iterNum = 500;
687 errCode = store->Rekey(cryptoParam1);
688 ASSERT_EQ(errCode, E_NOT_SUPPORT);
689
690 RdbStoreConfig::CryptoParam cryptoParam2;
691 cryptoParam2.encryptAlgo = EncryptAlgo::AES_256_CBC;
692 errCode = store->Rekey(cryptoParam2);
693 ASSERT_EQ(errCode, E_NOT_SUPPORT);
694
695 RdbStoreConfig::CryptoParam cryptoParam3;
696 cryptoParam3.hmacAlgo = HmacAlgo::SHA512;
697 errCode = store->Rekey(cryptoParam3);
698 ASSERT_EQ(errCode, E_NOT_SUPPORT);
699
700 RdbStoreConfig::CryptoParam cryptoParam4;
701 cryptoParam4.kdfAlgo = KdfAlgo::KDF_SHA512;
702 errCode = store->Rekey(cryptoParam4);
703 ASSERT_EQ(errCode, E_NOT_SUPPORT);
704
705 RdbStoreConfig::CryptoParam cryptoParam5;
706 cryptoParam5.cryptoPageSize = 2048;
707 errCode = store->Rekey(cryptoParam5);
708 ASSERT_EQ(errCode, E_NOT_SUPPORT);
709
710 ret = RdbHelper::DeleteRdbStore(config);
711 EXPECT_EQ(ret, E_OK);
712 }
713
714 /**
715 * @tc.name: Rdb_Delete_Rekey_Test_12
716 * @tc.desc: test custom encrypt rekey
717 * @tc.type: FUNC
718 */
719 HWTEST_F(RdbRekeyTest, Rdb_Rekey_012, TestSize.Level1)
720 {
721 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
722 config.SetSecurityLevel(SecurityLevel::S1);
723 config.SetEncryptStatus(true);
724 RdbStoreConfig::CryptoParam cryptoParam;
725 cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
726 config.SetCryptoParam(cryptoParam);
727 config.SetBundleName("com.example.test_rekey");
728 RekeyTestOpenCallback helper;
729 int errCode = E_OK;
730 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
731 ASSERT_NE(store, nullptr);
732 ASSERT_EQ(errCode, E_OK);
733
734 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
735 "name TEXT NOT NULL, age INTEGER)");
736
737 int64_t id;
738 ValuesBucket values;
739 values.PutInt("id", 1);
740 values.PutString("name", std::string("zhangsan"));
741 values.PutInt("age", 18);
742 int ret = store->Insert(id, "test1", values);
743 EXPECT_EQ(ret, E_OK);
744 EXPECT_EQ(1, id);
745
746 RdbStoreConfig::CryptoParam newCryptoParam;
747 newCryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 2, 3, 4, 5, 1 };
748 errCode = store->Rekey(newCryptoParam);
749 ASSERT_EQ(errCode, E_OK);
750
751 values.Clear();
752 values.PutInt("id", 2);
753 values.PutString("name", std::string("lisi"));
754 values.PutInt("age", 19);
755 ret = store->Insert(id, "test1", values);
756 EXPECT_EQ(ret, E_OK);
757 EXPECT_EQ(2, id);
758
759 store = nullptr;
760 config.SetCryptoParam(newCryptoParam);
761 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
762 ASSERT_NE(store, nullptr);
763 ASSERT_EQ(errCode, E_OK);
764 auto resultSet = store->QueryByStep("SELECT * FROM test1");
765 ASSERT_NE(resultSet, nullptr);
766 int32_t rowCount{};
767 ret = resultSet->GetRowCount(rowCount);
768 ASSERT_EQ(ret, E_OK);
769 ASSERT_EQ(rowCount, 2);
770
771 RdbHelper::DeleteRdbStore(config);
772 EXPECT_EQ(ret, E_OK);
773 }
774
775
776 /**
777 * @tc.name: Rdb_Delete_Rekey_Test_013
778 * @tc.desc: test rekey
779 * @tc.type: FUNC
780 */
781 HWTEST_F(RdbRekeyTest, Rdb_Rekey_013, TestSize.Level1)
782 {
783 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
784 config.SetSecurityLevel(SecurityLevel::S1);
785 config.SetEncryptStatus(true);
786 config.SetBundleName("com.example.test_rekey");
787 RekeyTestOpenCallback helper;
788 int errCode = E_OK;
789 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
790 ASSERT_NE(store, nullptr);
791 ASSERT_EQ(errCode, E_OK);
792
793 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
794 "name TEXT NOT NULL, age INTEGER)");
795
796 int64_t id;
797 ValuesBucket values;
798 values.PutInt("id", 1);
799 values.PutString("name", std::string("zhangsan"));
800 values.PutInt("age", 18);
801 int ret = store->Insert(id, "test1", values);
802 EXPECT_EQ(ret, E_OK);
803 EXPECT_EQ(1, id);
804
805 int changedRows;
806 values.Clear();
807 values.PutInt("age", 30);
808 ret = store->Update(changedRows, "test1", values);
809 EXPECT_EQ(ret, E_OK);
810 EXPECT_EQ(1, changedRows);
811
812 RdbStoreConfig::CryptoParam cryptoParam;
813 cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
814 errCode = store->Rekey(cryptoParam);
815 ASSERT_EQ(errCode, E_NOT_SUPPORT);
816
817 values.Clear();
818 values.PutInt("id", 2);
819 values.PutString("name", std::string("lisi"));
820 values.PutInt("age", 19);
821 ret = store->Insert(id, "test1", values);
822 EXPECT_EQ(ret, E_OK);
823 EXPECT_EQ(2, id);
824
825 values.Clear();
826 values.PutInt("age", 60);
827 ret = store->Update(changedRows, "test1", values);
828 EXPECT_EQ(ret, E_OK);
829 EXPECT_EQ(2, changedRows);
830
831 ret = RdbHelper::DeleteRdbStore(config);
832 EXPECT_EQ(ret, E_OK);
833 }
834
835 /**
836 * @tc.name: Rdb_Delete_Rekey_Test_014
837 * @tc.desc: test rekey
838 * @tc.type: FUNC
839 */
840 HWTEST_F(RdbRekeyTest, Rdb_Rekey_014, TestSize.Level1)
841 {
842 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
843 config.SetSecurityLevel(SecurityLevel::S1);
844 config.SetEncryptStatus(true);
845 config.SetBundleName("com.example.test_rekey");
846 RekeyTestOpenCallback helper;
847 int errCode = E_OK;
848 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
849 ASSERT_NE(store, nullptr);
850 ASSERT_EQ(errCode, E_OK);
851
852 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
853 "name TEXT NOT NULL, age INTEGER)");
854
855 int64_t id;
856 ValuesBucket values;
857 values.PutInt("id", 1);
858 values.PutString("name", std::string("zhangsan"));
859 values.PutInt("age", 18);
860 int ret = store->Insert(id, "test1", values);
861 EXPECT_EQ(ret, E_OK);
862 EXPECT_EQ(1, id);
863
864 RdbStoreConfig::CryptoParam cryptoParam;
865 errCode = store->Rekey(cryptoParam);
866 ASSERT_EQ(errCode, E_OK);
867
868 values.Clear();
869 values.PutInt("id", 2);
870 values.PutString("name", std::string("lisi"));
871 values.PutInt("age", 19);
872 ret = store->Insert(id, "test1", values);
873 EXPECT_EQ(ret, E_OK);
874 EXPECT_EQ(2, id);
875
876 int changedRows = 0;
877 AbsRdbPredicates predicates("test1");
878 predicates.EqualTo("id", 1);
879 ret = store->Delete(changedRows, predicates);
880 EXPECT_EQ(ret, E_OK);
881 EXPECT_EQ(changedRows, 1);
882
883 store = nullptr;
884 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
885 ASSERT_NE(store, nullptr);
886 ASSERT_EQ(errCode, E_OK);
887 auto resultSet = store->QueryByStep("SELECT * FROM test1");
888 ASSERT_NE(resultSet, nullptr);
889 int32_t rowCount{};
890 ret = resultSet->GetRowCount(rowCount);
891 ASSERT_EQ(ret, E_OK);
892 ASSERT_EQ(rowCount, 1);
893 }
894
895
896 /**
897 * @tc.name: Rdb_Delete_Rekey_Test_015
898 * @tc.desc: test rekey
899 * @tc.type: FUNC
900 */
901 HWTEST_F(RdbRekeyTest, Rdb_Rekey_015, TestSize.Level1)
902 {
903 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
904 config.SetSecurityLevel(SecurityLevel::S1);
905 config.SetEncryptStatus(true);
906 RdbStoreConfig::CryptoParam cryptoParam;
907 cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
908 config.SetCryptoParam(cryptoParam);
909 config.SetBundleName("com.example.test_rekey");
910 RekeyTestOpenCallback helper;
911 RdbHelper::DeleteRdbStore(config);
912 int errCode = E_OK;
913 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
914 ASSERT_NE(store, nullptr);
915 ASSERT_EQ(errCode, E_OK);
916
917 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
918 "name TEXT NOT NULL, age INTEGER)");
919 int64_t id;
920 ValuesBucket values;
921 values.PutInt("id", 1);
922 values.PutString("name", std::string("zhangsan"));
923 values.PutInt("age", 18);
924
925 int ret = store->Insert(id, "test1", values);
926 EXPECT_EQ(ret, E_OK);
927 EXPECT_EQ(1, id);
928
929 RdbStoreConfig::CryptoParam newCryptoParam;
930 errCode = store->Rekey(newCryptoParam);
931 ASSERT_EQ(errCode, E_NOT_SUPPORT);
932
933 values.Clear();
934 values.PutInt("id", 2);
935 values.PutString("name", std::string("lisi"));
936 values.PutInt("age", 19);
937 ret = store->Insert(id, "test1", values);
938 EXPECT_EQ(ret, E_OK);
939 EXPECT_EQ(2, id);
940
941 store = nullptr;
942 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
943 ASSERT_NE(store, nullptr);
944 ASSERT_EQ(errCode, E_OK);
945 auto resultSet = store->QueryByStep("SELECT * FROM test1");
946 ASSERT_NE(resultSet, nullptr);
947 int32_t rowCount{};
948 ret = resultSet->GetRowCount(rowCount);
949 ASSERT_EQ(ret, E_OK);
950 ASSERT_EQ(rowCount, 2);
951
952 RdbHelper::DeleteRdbStore(config);
953 EXPECT_EQ(ret, E_OK);
954 }
955
956 /**
957 * @tc.name: Rdb_Delete_Rekey_Test_016
958 * @tc.desc: test transaction rekey
959 * @tc.type: FUNC
960 */
961 HWTEST_F(RdbRekeyTest, Rdb_Rekey_016, TestSize.Level1)
962 {
963 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
964 config.SetSecurityLevel(SecurityLevel::S1);
965 config.SetAllowRebuild(false);
966 config.SetEncryptStatus(true);
967 RdbStoreConfig::CryptoParam cryptoParam;
968 cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
969 config.SetCryptoParam(cryptoParam);
970 config.SetBundleName("com.example.test_rekey");
971 RekeyTestOpenCallback helper;
972 int errCode = E_OK;
973 RdbHelper::DeleteRdbStore(config);
974 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
975 ASSERT_NE(store, nullptr);
976 ASSERT_EQ(errCode, E_OK);
977
978 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
979 "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
980
981 auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
982 ASSERT_EQ(ret, E_OK);
983 ASSERT_NE(transaction, nullptr);
984
985 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
986 ASSERT_EQ(result.first, E_OK);
987 ASSERT_EQ(1, result.second);
988
989 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
990 bool isFileExists = OHOS::FileExists(keyPath);
991 ASSERT_FALSE(isFileExists);
992
993 RdbStoreConfig::CryptoParam newCryptoParam;
994 newCryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 5, 4, 3, 2, 1 };
995 errCode = store->Rekey(newCryptoParam);
996 ASSERT_EQ(errCode, E_DATABASE_BUSY);
997
998 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
999 ASSERT_EQ(result.first, E_OK);
1000 ASSERT_EQ(2, result.second);
1001
1002 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
1003 ASSERT_NE(resultSet, nullptr);
1004 int32_t rowCount{};
1005 ret = resultSet->GetRowCount(rowCount);
1006 ASSERT_EQ(ret, E_OK);
1007 ASSERT_EQ(rowCount, 2);
1008
1009 ret = transaction->Commit();
1010 ASSERT_EQ(ret, E_OK);
1011
1012 resultSet = store->QueryByStep("SELECT * FROM test");
1013 ASSERT_NE(resultSet, nullptr);
1014 resultSet->GetRowCount(rowCount);
1015 EXPECT_EQ(rowCount, 2);
1016
1017 RdbHelper::DeleteRdbStore(config);
1018 EXPECT_EQ(ret, E_OK);
1019 }
1020
1021 /**
1022 * @tc.name: Rdb_Delete_Rekey_Test_017
1023 * @tc.desc: test transaction rekey
1024 * @tc.type: FUNC
1025 */
1026 HWTEST_F(RdbRekeyTest, Rdb_Rekey_017, TestSize.Level1)
1027 {
1028 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
1029 config.SetSecurityLevel(SecurityLevel::S1);
1030 config.SetAllowRebuild(false);
1031 config.SetEncryptStatus(true);
1032 RdbStoreConfig::CryptoParam cryptoParam;
1033 config.SetCryptoParam(cryptoParam);
1034 config.SetBundleName("com.example.test_rekey");
1035 RekeyTestOpenCallback helper;
1036 int errCode = E_OK;
1037 RdbHelper::DeleteRdbStore(config);
1038 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1039 ASSERT_NE(store, nullptr);
1040 ASSERT_EQ(errCode, E_OK);
1041
1042 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
1043 "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
1044
1045 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
1046 ASSERT_EQ(ret, E_OK);
1047 ASSERT_NE(transaction, nullptr);
1048
1049 auto result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[0]));
1050 ASSERT_EQ(result.first, E_OK);
1051 ASSERT_EQ(1, result.second);
1052
1053 std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v1";
1054 bool isFileExists = OHOS::FileExists(keyPath);
1055 ASSERT_TRUE(isFileExists);
1056
1057 RdbStoreConfig::CryptoParam newCryptoParam;
1058 errCode = store->Rekey(newCryptoParam);
1059 ASSERT_EQ(errCode, E_DATABASE_BUSY);
1060
1061 result = transaction->Insert("test", UTUtils::SetRowData(UTUtils::g_rowData[1]));
1062 ASSERT_EQ(result.first, E_OK);
1063 ASSERT_EQ(2, result.second);
1064
1065 auto resultSet = transaction->QueryByStep("SELECT * FROM test");
1066 ASSERT_NE(resultSet, nullptr);
1067 int32_t rowCount{};
1068 ret = resultSet->GetRowCount(rowCount);
1069 ASSERT_EQ(ret, E_OK);
1070 ASSERT_EQ(rowCount, 2);
1071
1072 ret = transaction->Commit();
1073 ASSERT_EQ(ret, E_OK);
1074
1075 resultSet = store->QueryByStep("SELECT * FROM test");
1076 ASSERT_NE(resultSet, nullptr);
1077 resultSet->GetRowCount(rowCount);
1078 EXPECT_EQ(rowCount, 2);
1079
1080 RdbHelper::DeleteRdbStore(config);
1081 EXPECT_EQ(ret, E_OK);
1082 }
1083
1084 /**
1085 * @tc.name: Rdb_Delete_Rekey_Test_018
1086 * @tc.desc: rekey test
1087 * @tc.type: FUNC
1088 */
1089 HWTEST_F(RdbRekeyTest, Rdb_Rekey_018, TestSize.Level1)
1090 {
1091 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
1092 config.SetEncryptStatus(true);
1093 config.SetReadOnly(true);
1094 config.SetBundleName("com.example.test_rekey");
1095 RekeyTestOpenCallback helper;
1096 int errCode = E_OK;
1097 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1098 ASSERT_NE(store, nullptr);
1099 ASSERT_EQ(errCode, E_OK);
1100
1101 RdbStoreConfig::CryptoParam cryptoParam1;
1102
1103 errCode = store->Rekey(cryptoParam1);
1104 ASSERT_EQ(errCode, E_NOT_SUPPORT);
1105
1106 int ret = RdbHelper::DeleteRdbStore(config);
1107 EXPECT_EQ(ret, E_OK);
1108 }
1109
1110 /**
1111 * @tc.name: Rdb_Delete_Rekey_Test_019
1112 * @tc.desc: mutltiThread rekey test
1113 * @tc.type: FUNC
1114 */
1115 HWTEST_F(RdbRekeyTest, Rdb_Rekey_019, TestSize.Level1)
1116 {
1117 RdbStoreConfig config(RdbRekeyTest::encryptedDatabasePath);
1118 RdbStoreConfig::CryptoParam cryptoParam;
1119 cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
1120 config.SetCryptoParam(cryptoParam);
1121 config.SetBundleName("com.example.test_rekey");
1122 config.SetEncryptStatus(true);
1123 RekeyTestOpenCallback helper;
1124 int errCode = E_OK;
1125 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1126 ASSERT_NE(store, nullptr);
1127 ASSERT_EQ(errCode, E_OK);
1128
1129 auto blockResult = std::make_shared<OHOS::BlockData<bool>>(3, false);
__anona65c86970102() 1130 std::thread thread([store, blockResult]() {
1131 RdbStoreConfig::CryptoParam cryptoParam;
1132 cryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 2, 3, 4, 5, 1 };
1133 int ret1 = store->Rekey(cryptoParam);
1134 LOG_INFO("Rdb_Rekey_019 thread Rekey finish, code:%{public}d", ret1);
1135 blockResult->SetValue(true);
1136 });
1137 thread.detach();
1138 RdbStoreConfig::CryptoParam cryptoParam2;
1139 cryptoParam2.encryptKey_ = std::vector<uint8_t>{ 6, 5, 3, 4, 2, 1 };
1140 int ret2 = store->Rekey(cryptoParam2);
1141 LOG_INFO("Rdb_Rekey_019 main Rekey finish, code:%{public}d", ret2);
1142 EXPECT_TRUE(blockResult->GetValue());
1143
1144 store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
1145 "name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
1146
1147 int64_t id;
1148 ValuesBucket values;
1149 values.PutInt("id", 1);
1150 values.PutString("name", std::string("zhangsan1"));
1151 values.PutInt("age", 50);
1152 values.PutDouble("salary", 263);
1153 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3, 4, 5 });
1154 int ret = store->Insert(id, "test1", values);
1155 EXPECT_EQ(ret, E_OK);
1156 EXPECT_EQ(1, id);
1157
1158 int changedRows;
1159 values.Clear();
1160 values.PutInt("age", 30);
1161 ret = store->Update(changedRows, "test1", values);
1162 EXPECT_EQ(ret, E_OK);
1163 EXPECT_EQ(1, changedRows);
1164
1165 auto resultSet = store->QueryByStep("SELECT * FROM test1");
1166 int32_t rowCount{};
1167 ret = resultSet->GetRowCount(rowCount);
1168 ASSERT_EQ(ret, E_OK);
1169 ASSERT_EQ(rowCount, 1);
1170 }
1171
1172 /**
1173 * @tc.name: DecryptV1Test_001
1174 * @tc.desc: RdbSecurityManager DecryptV1 test
1175 * @tc.type: FUNC
1176 */
1177 HWTEST_F(RdbRekeyTest, DecryptV1Test_001, TestSize.Level1)
1178 {
1179 RdbSecurityManager manager;
1180 RdbSecretContent content;
1181 std::string invalidStr = ".pub";
1182 auto str = manager.ReplaceSuffix(invalidStr);
1183 EXPECT_EQ(invalidStr, str);
1184 bool res = false;
1185 RdbSecretKeyData keyData;
1186 std::tie(res, keyData) = manager.DecryptV1(content);
1187 EXPECT_FALSE(res);
1188
1189 content.encrypt_ = {0x01, 0x02, 0x03, 0x04};
1190 std::tie(res, keyData) = manager.DecryptV1(content);
1191 EXPECT_FALSE(res);
1192
1193 std::vector<uint8_t> timeData(sizeof(time_t), 0x00);
1194 time_t testTime = 1630400000;
1195 errno_t err = memcpy_s(timeData.data(),
1196 timeData.size(),
1197 &testTime,
1198 sizeof(time_t)
1199 );
1200 EXPECT_EQ(err, EOK);
1201
1202 std::vector<uint8_t> key(16, 0x01);
1203 content.encrypt_ = {0x01};
1204 content.encrypt_.insert(content.encrypt_.end(), timeData.begin(), timeData.end());
1205 content.encrypt_.insert(content.encrypt_.end(), key.begin(), key.end());
1206 content.nonce_.resize(RdbSecretContent::NONCE_VALUE_SIZE, 0x01);
1207
1208 std::tie(res, keyData) = manager.DecryptV1(content);
1209 EXPECT_FALSE(res);
1210 EXPECT_EQ(keyData.distributed, 0x01);
1211 EXPECT_EQ(keyData.timeValue, testTime);
1212 }
1213
1214 /**
1215 * @tc.name: DecryptV1Test_002
1216 * @tc.desc: RdbSecurityManager decryptV1 key length invalid test
1217 * @tc.type: FUNC
1218 */
1219 HWTEST_F(RdbRekeyTest, DecryptV1Test_002, TestSize.Level1)
1220 {
1221 RdbSecurityManager manager;
1222 RdbSecretContent content;
1223 content.encrypt_.push_back(0x01);
1224
1225 time_t testTime = 1630400000;
1226 std::vector<uint8_t> timeData(sizeof(time_t));
1227 errno_t err = memcpy_s(
1228 timeData.data(),
1229 timeData.size(),
1230 &testTime,
1231 sizeof(time_t)
1232 );
1233 EXPECT_EQ(err, EOK);
1234
1235 content.encrypt_.insert(content.encrypt_.end(), timeData.begin(), timeData.end());
1236 const size_t keyDataSize = RdbSecurityManager::AEAD_LEN + 1;
1237 std::vector<uint8_t> keyData(keyDataSize, 0x01);
1238 content.encrypt_.insert(content.encrypt_.end(), keyData.begin(), keyData.end());
1239 content.nonce_.resize(RdbSecretContent::NONCE_VALUE_SIZE, 0x02);
1240 auto result = manager.DecryptV1(content);
1241 EXPECT_TRUE(result.first);
1242 EXPECT_EQ(result.second.distributed, 0x01);
1243 EXPECT_EQ(result.second.timeValue, testTime);
1244 EXPECT_TRUE(result.second.secretKey.empty());
1245 }
1246
1247 /**
1248 * @tc.name: Rdb_UnpackV2_Test_001
1249 * @tc.desc: unpackV2 test
1250 * @tc.type: FUNC
1251 */
1252 HWTEST_F(RdbRekeyTest, UnpackV2Test, TestSize.Level1)
1253 {
1254 RdbSecurityManager manager;
1255 std::vector<char> content;
1256 auto result = manager.UnpackV2(content);
1257 EXPECT_FALSE(result.first);
1258 EXPECT_EQ(result.second.nonce_.size(), 0);
1259 EXPECT_EQ(result.second.encrypt_.size(), 0);
1260
1261 uint32_t magicNum = RdbSecretContent::MAGIC_NUMBER_V2;
1262 char* magicPtr = reinterpret_cast<char*>(&magicNum);
1263 content.insert(content.end(), magicPtr, magicPtr + sizeof(magicNum));
1264
1265 const size_t nonceSize = RdbSecretContent::NONCE_VALUE_SIZE - 1;
1266 std::vector<char> nonce(nonceSize, 'N');
1267 content.insert(content.end(), nonce.begin(), nonce.end());
1268
1269 result = manager.UnpackV2(content);
1270
1271 EXPECT_FALSE(result.first);
1272 EXPECT_EQ(result.second.nonce_.size(), 0);
1273 EXPECT_EQ(result.second.encrypt_.size(), 0);
1274 }