* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "RdbRekeyTest"
#include <gtest/gtest.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <securec.h>
#include <fstream>
#include <iostream>
#include <string>
#include <thread>
#include "block_data.h"
#include "rdb_test_common.h"
#include "file_ex.h"
#include "logger.h"
#include "rdb_errno.h"
#include "rdb_helper.h"
#include "rdb_open_callback.h"
#include "rdb_security_manager.h"
#include "sqlite_connection.h"
#include "sqlite_utils.h"
using namespace testing::ext;
using namespace OHOS::NativeRdb;
using namespace OHOS::Rdb;
class RdbInterfaceRekeyTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
static std::string RemoveSuffix(const std::string &name);
static std::chrono::system_clock::time_point GetKeyFileDate(const std::string &dbName);
static bool ChangeKeyFileDate(const std::string &dbName, int rep);
static bool SaveNewKey(const std::string &dbName);
static RdbStoreConfig GetRdbConfig(const std::string &name);
static RdbStoreConfig GetRdbNotRekeyConfig(const std::string &name);
static void InsertData(std::shared_ptr<RdbStore> &store);
static void CheckQueryData(std::shared_ptr<RdbStore> &store);
static const std::string encryptedDatabaseName;
static const std::string encryptedDatabasePath;
static const std::string encryptedDatabaseKeyDir;
static const std::string encryptedDatabaseMockName;
static const std::string encryptedDatabaseMockPath;
static constexpr int HOURS_EXPIRED = (24 * 365) + 1;
static constexpr int HOURS_LONG_LONG_AGO = 30 * (24 * 365);
static constexpr int HOURS_NOT_EXPIRED = (24 * 30);
};
const std::string RdbInterfaceRekeyTest::encryptedDatabaseName = "encrypted.db";
const std::string RdbInterfaceRekeyTest::encryptedDatabasePath = RDB_TEST_PATH + encryptedDatabaseName;
const std::string RdbInterfaceRekeyTest::encryptedDatabaseKeyDir = RDB_TEST_PATH + "key/";
const std::string RdbInterfaceRekeyTest::encryptedDatabaseMockName = "encrypted_mock.db";
const std::string RdbInterfaceRekeyTest::encryptedDatabaseMockPath = RDB_TEST_PATH + encryptedDatabaseMockName;
class RekeyTestOpenCallback : public RdbOpenCallback {
public:
int OnCreate(RdbStore &store) override;
int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
static const std::string createTableTest;
};
std::string const RekeyTestOpenCallback::createTableTest = "CREATE TABLE IF NOT EXISTS test "
"(id INTEGER PRIMARY KEY "
"AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, "
"salary "
"REAL, blobType BLOB)";
int RekeyTestOpenCallback::OnCreate(RdbStore &store)
{
return store.ExecuteSql(createTableTest);
}
int RekeyTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
{
return E_OK;
}
void RdbInterfaceRekeyTest::SetUpTestCase()
{
}
void RdbInterfaceRekeyTest::TearDownTestCase()
{
}
void RdbInterfaceRekeyTest::SetUp()
{
RdbHelper::ClearCache();
RdbHelper::DeleteRdbStore(RdbInterfaceRekeyTest::encryptedDatabasePath);
RdbStoreConfig config = GetRdbConfig(encryptedDatabasePath);
RekeyTestOpenCallback helper;
int errCode;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
EXPECT_NE(store, nullptr);
InsertData(store);
store.reset();
RdbHelper::ClearCache();
}
void RdbInterfaceRekeyTest::TearDown()
{
RdbHelper::ClearCache();
RdbHelper::DeleteRdbStore(RdbInterfaceRekeyTest::encryptedDatabasePath);
}
std::string RdbInterfaceRekeyTest::RemoveSuffix(const std::string &name)
{
std::string suffix(".db");
auto pos = name.rfind(suffix);
if (pos == std::string::npos || pos < name.length() - suffix.length()) {
return name;
}
return { name, 0, pos };
}
std::chrono::system_clock::time_point RdbInterfaceRekeyTest::GetKeyFileDate(const std::string &dbName)
{
std::chrono::system_clock::time_point timePoint;
std::string name = RemoveSuffix(dbName);
auto keyPath = RDB_TEST_PATH + "key/" + name + ".pub_key_v2";
if (!OHOS::FileExists(keyPath)) {
return timePoint;
}
std::vector<char> content;
auto loaded = OHOS::LoadBufferFromFile(keyPath, content);
if (!loaded) {
return timePoint;
}
auto iter = content.begin();
iter++;
constexpr uint32_t dateFileLength = sizeof(time_t) / sizeof(uint8_t);
std::vector<uint8_t> date;
date.assign(iter, iter + dateFileLength);
timePoint = std::chrono::system_clock::from_time_t(*reinterpret_cast<time_t *>(const_cast<uint8_t *>(&date[0])));
return timePoint;
}
bool RdbInterfaceRekeyTest::ChangeKeyFileDate(const std::string &dbName, int rep)
{
std::string name = RemoveSuffix(dbName);
auto keyPath = RDB_TEST_PATH + "key/" + name + ".pub_key_v2";
if (!OHOS::FileExists(keyPath)) {
return false;
}
std::vector<char> content;
auto loaded = OHOS::LoadBufferFromFile(keyPath, content);
if (!loaded) {
return false;
}
auto time =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::system_clock::now() - std::chrono::hours(rep));
std::vector<char> date(reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time));
std::copy(date.begin(), date.end(), ++content.begin());
auto saved = OHOS::SaveBufferToFile(keyPath, content);
return saved;
}
bool RdbInterfaceRekeyTest::SaveNewKey(const string &dbName)
{
std::string name = RemoveSuffix(dbName);
auto keyPath = RDB_TEST_PATH + "key/" + name + ".pub_key_v2";
auto newKeyPath = RDB_TEST_PATH + "key/" + name + ".pub_key_v2.new";
if (!OHOS::FileExists(keyPath)) {
return false;
}
std::vector<char> content;
auto loaded = OHOS::LoadBufferFromFile(keyPath, content);
if (!loaded) {
return false;
}
OHOS::SaveBufferToFile(newKeyPath, content);
content[content.size() - 1] = 'E';
return OHOS::SaveBufferToFile(keyPath, content);
}
RdbStoreConfig RdbInterfaceRekeyTest::GetRdbConfig(const std::string &name)
{
RdbStoreConfig config(name);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
config.EnableRekey(true);
return config;
}
RdbStoreConfig RdbInterfaceRekeyTest::GetRdbNotRekeyConfig(const std::string &name)
{
RdbStoreConfig config(name);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
config.EnableRekey(false);
return config;
}
void RdbInterfaceRekeyTest::InsertData(std::shared_ptr<RdbStore> &store)
{
int64_t id;
ValuesBucket values;
std::string name = "zhangsan";
int age = 18;
double salary = 100.5;
std::vector<uint8_t> blob{ 1, 2, 3 };
values.PutString("name", name);
values.PutInt("age", age);
values.PutDouble("salary", salary);
values.PutBlob("blobType", blob);
int insertRet = store->Insert(id, "test", values);
EXPECT_EQ(insertRet, E_OK);
}
void RdbInterfaceRekeyTest::CheckQueryData(std::shared_ptr<RdbStore> &store)
{
std::shared_ptr<ResultSet> resultSet =
store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector<std::string>{ "zhangsan" });
EXPECT_NE(resultSet, nullptr);
int result = resultSet->GoToFirstRow();
EXPECT_EQ(result, E_OK);
int columnIndex;
std::string strVal;
ColumnType columnType;
result = resultSet->GetColumnIndex("name", columnIndex);
EXPECT_EQ(result, E_OK);
result = resultSet->GetColumnType(columnIndex, columnType);
EXPECT_EQ(result, E_OK);
EXPECT_EQ(columnType, ColumnType::TYPE_STRING);
result = resultSet->GetString(columnIndex, strVal);
EXPECT_EQ(result, E_OK);
EXPECT_EQ("zhangsan", strVal);
result = resultSet->Close();
EXPECT_EQ(result, E_OK);
}
* @tc.name: Rdb_Rekey_Test_001
* @tc.desc: test automatic rekey when database key is expired (over 365 days)
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_01, TestSize.Level1)
{
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2.new";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbInterfaceRekeyTest::HOURS_EXPIRED);
ASSERT_TRUE(isFileDateChanged);
RdbStoreConfig config = GetRdbConfig(RdbInterfaceRekeyTest::encryptedDatabasePath);
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
isFileExists = OHOS::FileExists(newKeyPath);
ASSERT_FALSE(isFileExists);
CheckQueryData(store);
}
* @tc.name: Rdb_Rekey_Test_002
* @tc.desc: test RdbStore with not outdated password
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_02, TestSize.Level1)
{
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbInterfaceRekeyTest::HOURS_NOT_EXPIRED);
ASSERT_TRUE(isFileDateChanged);
auto changedDate = GetKeyFileDate(encryptedDatabaseName);
ASSERT_TRUE(
std::chrono::system_clock::now() - changedDate > std::chrono::hours(RdbInterfaceRekeyTest::HOURS_NOT_EXPIRED));
RdbStoreConfig config = GetRdbConfig(RdbInterfaceRekeyTest::encryptedDatabasePath);
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
CheckQueryData(store);
}
* @tc.name: Rdb_Rekey_Test_004
* @tc.desc: try to open store and modify create date to a future time.
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_04, TestSize.Level1)
{
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2.new";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, -RdbInterfaceRekeyTest::HOURS_EXPIRED);
ASSERT_TRUE(isFileDateChanged);
RdbStoreConfig config = GetRdbConfig(RdbInterfaceRekeyTest::encryptedDatabasePath);
RekeyTestOpenCallback helper;
int errCode;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
isFileExists = OHOS::FileExists(newKeyPath);
ASSERT_FALSE(isFileExists);
CheckQueryData(store);
}
* @tc.name: Rdb_Rekey_RenameFailed_05
* @tc.desc: test rekey when rename operation fails due to .new key file already existing
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_RenameFailed_05, TestSize.Level1)
{
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2.new";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbInterfaceRekeyTest::HOURS_LONG_LONG_AGO);
ASSERT_TRUE(isFileDateChanged);
RdbStoreConfig config = GetRdbConfig(RdbInterfaceRekeyTest::encryptedDatabasePath);
RekeyTestOpenCallback helper;
int errCode = E_OK;
for (int i = 0; i < 50; ++i) {
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store = nullptr;
SaveNewKey(encryptedDatabaseName);
}
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
CheckQueryData(store);
}
* @tc.name: Rdb_Delete_Rekey_Test_06
* @tc.desc: test that rekey is skipped when rekey is disabled in config
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_06, TestSize.Level1)
{
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
std::string newKeyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2.new";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
bool isFileDateChanged = ChangeKeyFileDate(encryptedDatabaseName, RdbInterfaceRekeyTest::HOURS_EXPIRED);
ASSERT_TRUE(isFileDateChanged);
auto changedDate = GetKeyFileDate(encryptedDatabaseName);
ASSERT_TRUE(
std::chrono::system_clock::now() - changedDate > std::chrono::hours(RdbInterfaceRekeyTest::HOURS_EXPIRED));
RdbStoreConfig config = GetRdbNotRekeyConfig(RdbInterfaceRekeyTest::encryptedDatabasePath);
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
isFileExists = OHOS::FileExists(newKeyPath);
ASSERT_FALSE(isFileExists);
ASSERT_TRUE(
std::chrono::system_clock::now() - changedDate > std::chrono::hours(RdbInterfaceRekeyTest::HOURS_EXPIRED));
CheckQueryData(store);
}
* @tc.name: Rdb_Delete_Rekey_Test_07
* @tc.desc: test deleting the key file of the encrypted database
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_07, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetAllowRebuild(true);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
struct stat fileStat;
ino_t inodeNumber1 = -1;
if (stat(keyPath.c_str(), &fileStat) == 0) {
inodeNumber1 = fileStat.st_ino;
}
store = nullptr;
{
std::ofstream fsDb(encryptedDatabasePath, std::ios_base::binary | std::ios_base::out);
fsDb.seekp(64);
fsDb.write("hello", 5);
fsDb.close();
}
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
ino_t inodeNumber2 = -1;
if (stat(keyPath.c_str(), &fileStat) == 0) {
inodeNumber2 = fileStat.st_ino;
}
ASSERT_NE(inodeNumber1, inodeNumber2);
}
* @tc.name: Rdb_Delete_Rekey_Test_08
* @tc.desc: test key file is NOT regenerated when database is corrupted and AllowRebuild is false
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_08, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetAllowRebuild(false);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
struct stat fileStat;
ino_t inodeNumber1 = -1;
if (stat(keyPath.c_str(), &fileStat) == 0) {
inodeNumber1 = fileStat.st_ino;
}
store = nullptr;
{
std::ofstream fsDb(encryptedDatabasePath, std::ios_base::binary | std::ios_base::out);
fsDb.seekp(64);
fsDb.write("hello", 5);
fsDb.close();
}
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
ino_t inodeNumber2 = -1;
if (stat(keyPath.c_str(), &fileStat) == 0) {
inodeNumber2 = fileStat.st_ino;
}
ASSERT_EQ(inodeNumber1, inodeNumber2);
}
* @tc.name: Rdb_Delete_Rekey_Test_009
* @tc.desc: test Rekey with invalid CryptoParam parameters returns E_INVALID_ARGS_NEW
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_009, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetAllowRebuild(false);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam1;
cryptoParam1.iterNum = -1;
errCode = store->Rekey(cryptoParam1);
ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
RdbStoreConfig::CryptoParam cryptoParam2;
cryptoParam2.encryptAlgo = -1;
errCode = store->Rekey(cryptoParam2);
ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
RdbStoreConfig::CryptoParam cryptoParam3;
cryptoParam3.hmacAlgo = -1;
errCode = store->Rekey(cryptoParam3);
ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
RdbStoreConfig::CryptoParam cryptoParam4;
cryptoParam4.kdfAlgo = -1;
errCode = store->Rekey(cryptoParam4);
ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
RdbStoreConfig::CryptoParam cryptoParam5;
cryptoParam5.cryptoPageSize = -1;
errCode = store->Rekey(cryptoParam5);
ASSERT_EQ(errCode, E_INVALID_ARGS_NEW);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
}
* @tc.name: Rdb_Delete_Rekey_Test_010
* @tc.desc: test Rekey on non-encrypted database returns E_NOT_SUPPORT
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_010, TestSize.Level1)
{
const std::string encryptedDatabaseName1 = "encrypted1.db";
const std::string encryptedDatabasePath1 = RDB_TEST_PATH + encryptedDatabaseName1;
RdbStoreConfig config(encryptedDatabasePath1);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan1"));
values.PutInt("age", 50);
values.PutDouble("salary", 263);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3, 4, 5});
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam;
auto isEncrypt = config.IsEncrypt();
ASSERT_EQ(isEncrypt, false);
errCode = store->Rekey(cryptoParam);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
errCode = store->Rekey(cryptoParam);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi1"));
values.PutInt("age", 191);
values.PutDouble("salary", 2001.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6, 7 });
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_011
* @tc.desc: test Rekey with modified CryptoParam parameters returns E_NOT_SUPPORT for default encrypted database
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_011, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetBundleName("com.example.test_rekey");
config.SetEncryptStatus(true);
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("1zhangsan"));
values.PutInt("age", 118);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam1;
cryptoParam1.iterNum = 500;
errCode = store->Rekey(cryptoParam1);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
RdbStoreConfig::CryptoParam cryptoParam2;
cryptoParam2.encryptAlgo = EncryptAlgo::AES_256_CBC;
errCode = store->Rekey(cryptoParam2);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
RdbStoreConfig::CryptoParam cryptoParam3;
cryptoParam3.hmacAlgo = HmacAlgo::SHA512;
errCode = store->Rekey(cryptoParam3);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
RdbStoreConfig::CryptoParam cryptoParam4;
cryptoParam4.kdfAlgo = KdfAlgo::KDF_SHA512;
errCode = store->Rekey(cryptoParam4);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
RdbStoreConfig::CryptoParam cryptoParam5;
cryptoParam5.cryptoPageSize = 2048;
errCode = store->Rekey(cryptoParam5);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_012
* @tc.desc: test Rekey successfully changes custom encryption key and data remains accessible
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_012, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam newCryptoParam;
newCryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 2, 3, 4, 5, 1 };
errCode = store->Rekey(newCryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(newCryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_013
* @tc.desc: test Rekey from default encrypted to custom encrypted returns E_NOT_SUPPORT
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_013, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
int changedRows;
values.Clear();
values.PutInt("age", 30);
ret = store->Update(changedRows, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, changedRows);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
errCode = store->Rekey(cryptoParam);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
values.Clear();
values.PutInt("age", 60);
ret = store->Update(changedRows, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, changedRows);
ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_014
* @tc.desc: test Rekey from default encrypted to default encrypted with rekey operation
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_014, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam;
errCode = store->Rekey(cryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
int changedRows = 0;
AbsRdbPredicates predicates("test1");
predicates.EqualTo("id", 1);
ret = store->Delete(changedRows, predicates);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(changedRows, 1);
store = nullptr;
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 1);
}
* @tc.name: Rdb_Delete_Rekey_Test_015
* @tc.desc: test Rekey from custom encrypted to default encrypted returns E_NOT_SUPPORT
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_015, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
RdbHelper::DeleteRdbStore(config);
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam newCryptoParam;
errCode = store->Rekey(newCryptoParam);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_016
* @tc.desc: test Rekey during EXCLUSIVE transaction returns E_DATABASE_BUSY
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_016, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetAllowRebuild(false);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
RdbHelper::DeleteRdbStore(config);
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
ASSERT_EQ(ret, E_OK);
ASSERT_NE(transaction, nullptr);
auto result = transaction->Insert("test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]));
ASSERT_EQ(result.first, E_OK);
ASSERT_EQ(1, result.second);
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_FALSE(isFileExists);
RdbStoreConfig::CryptoParam newCryptoParam;
newCryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 5, 4, 3, 2, 1 };
errCode = store->Rekey(newCryptoParam);
ASSERT_EQ(errCode, E_DATABASE_BUSY);
result = transaction->Insert("test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[1]));
ASSERT_EQ(result.first, E_OK);
ASSERT_EQ(2, result.second);
auto resultSet = transaction->QueryByStep("SELECT * FROM test");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
ret = transaction->Commit();
ASSERT_EQ(ret, E_OK);
resultSet = store->QueryByStep("SELECT * FROM test");
ASSERT_NE(resultSet, nullptr);
resultSet->GetRowCount(rowCount);
EXPECT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_017
* @tc.desc: test Rekey during DEFERRED transaction returns E_DATABASE_BUSY
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_017, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetAllowRebuild(false);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
RdbHelper::DeleteRdbStore(config);
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
ASSERT_EQ(ret, E_OK);
ASSERT_NE(transaction, nullptr);
auto result = transaction->Insert("test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]));
ASSERT_EQ(result.first, E_OK);
ASSERT_EQ(1, result.second);
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_TRUE(isFileExists);
RdbStoreConfig::CryptoParam newCryptoParam;
errCode = store->Rekey(newCryptoParam);
ASSERT_EQ(errCode, E_DATABASE_BUSY);
result = transaction->Insert("test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[1]));
ASSERT_EQ(result.first, E_OK);
ASSERT_EQ(2, result.second);
auto resultSet = transaction->QueryByStep("SELECT * FROM test");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
ret = transaction->Commit();
ASSERT_EQ(ret, E_OK);
resultSet = store->QueryByStep("SELECT * FROM test");
ASSERT_NE(resultSet, nullptr);
resultSet->GetRowCount(rowCount);
EXPECT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_018
* @tc.desc: test Rekey on read-only database returns E_NOT_SUPPORT
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_018, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetEncryptStatus(true);
config.SetReadOnly(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
RdbStoreConfig::CryptoParam cryptoParam1;
errCode = store->Rekey(cryptoParam1);
ASSERT_EQ(errCode, E_NOT_SUPPORT);
int ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Delete_Rekey_Test_019
* @tc.desc: test multi-threaded Rekey operations for thread safety
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_019, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
config.SetEncryptStatus(true);
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto blockResult = std::make_shared<OHOS::BlockData<bool>>(3, false);
std::thread thread([store, blockResult]() {
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 2, 3, 4, 5, 1 };
int ret1 = store->Rekey(cryptoParam);
LOG_INFO("Rdb_Rekey_019 thread Rekey finish, code:%{public}d", ret1);
blockResult->SetValue(true);
});
thread.detach();
RdbStoreConfig::CryptoParam cryptoParam2;
cryptoParam2.encryptKey_ = std::vector<uint8_t>{ 6, 5, 3, 4, 2, 1 };
int ret2 = store->Rekey(cryptoParam2);
LOG_INFO("Rdb_Rekey_019 main Rekey finish, code:%{public}d", ret2);
EXPECT_TRUE(blockResult->GetValue());
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan1"));
values.PutInt("age", 50);
values.PutDouble("salary", 263);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3, 4, 5 });
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
int changedRows;
values.Clear();
values.PutInt("age", 30);
ret = store->Update(changedRows, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, changedRows);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 1);
}
* @tc.name: Rdb_Rekey_020
* @tc.desc: test RekeyEx converts non-encrypted database to encrypted database
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_020, TestSize.Level1)
{
const std::string encryptedDatabaseName1 = "encrypted1.db";
const std::string encryptedDatabasePath1 = RDB_TEST_PATH + encryptedDatabaseName1;
RdbStoreConfig config(encryptedDatabasePath1);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan1"));
values.PutInt("age", 50);
values.PutDouble("salary", 263);
values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3, 4, 5 });
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam;
auto isEncrypt = config.IsEncrypt();
ASSERT_EQ(isEncrypt, false);
errCode = store->RekeyEx(cryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi1"));
values.PutInt("age", 191);
values.PutDouble("salary", 2001.5);
values.PutBlob("blobType", std::vector<uint8_t>{ 4, 5, 6, 7 });
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetEncryptStatus(true);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Rekey_021
* @tc.desc: test RekeyEx successfully modifies encryption parameters (iterNum, encryptAlgo, etc.)
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_021, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetBundleName("com.example.test_rekey");
config.SetEncryptStatus(true);
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("1zhangsan"));
values.PutInt("age", 118);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam1;
cryptoParam1.iterNum = 500;
cryptoParam1.encryptAlgo = EncryptAlgo::AES_256_CBC;
errCode = store->RekeyEx(cryptoParam1);
ASSERT_EQ(errCode, E_OK);
RdbStoreConfig::CryptoParam cryptoParam2;
cryptoParam2.hmacAlgo = HmacAlgo::SHA512;
cryptoParam2.kdfAlgo = KdfAlgo::KDF_SHA512;
cryptoParam2.cryptoPageSize = 2048;
errCode = store->RekeyEx(cryptoParam2);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(cryptoParam2);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
}
* @tc.name: Rdb_Rekey_022
* @tc.desc: test RekeyEx successfully changes custom encryption key to new custom key
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_022, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
errCode = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(errCode, E_OK);
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam newCryptoParam;
newCryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 2, 3, 4, 5, 1 };
errCode = store->RekeyEx(newCryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(newCryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Rekey_023
* @tc.desc: test RekeyEx converts default encrypted database to custom encrypted database
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_023, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
int changedRows;
values.Clear();
values.PutInt("age", 30);
ret = store->Update(changedRows, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, changedRows);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
errCode = store->RekeyEx(cryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(cryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
values.Clear();
values.PutInt("age", 60);
ret = store->Update(changedRows, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, changedRows);
ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Rekey_024
* @tc.desc: test RekeyEx performs rekey operation on default encrypted database
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_024, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam;
errCode = store->RekeyEx(cryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
int changedRows = 0;
AbsRdbPredicates predicates("test1");
predicates.EqualTo("id", 1);
ret = store->Delete(changedRows, predicates);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(changedRows, 1);
store = nullptr;
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 1);
}
* @tc.name: Rdb_Rekey_025
* @tc.desc: test RekeyEx converts custom encrypted database to default encrypted database
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_025, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
RdbHelper::DeleteRdbStore(config);
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam newCryptoParam;
errCode = store->RekeyEx(newCryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(newCryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Rekey_026
* @tc.desc: test RekeyEx converts encrypted database to non-encrypted (PLAIN_TEXT) database
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_026, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptAlgo = EncryptAlgo::PLAIN_TEXT;
errCode = store->RekeyEx(cryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
int changedRows = 0;
AbsRdbPredicates predicates("test1");
predicates.EqualTo("id", 1);
ret = store->Delete(changedRows, predicates);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(changedRows, 1);
store = nullptr;
config.SetEncryptStatus(false);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 1);
}
* @tc.name: Rdb_Rekey_027
* @tc.desc: test RekeyEx successfully modifies iteration count (iterNum) parameter
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_027, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetBundleName("com.example.test_rekey");
config.SetEncryptStatus(true);
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("1zhangsan"));
values.PutInt("age", 118);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam1;
cryptoParam1.iterNum = 500;
errCode = store->RekeyEx(cryptoParam1);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_EQ(store, nullptr);
config.SetCryptoParam(cryptoParam1);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Rekey_028
* @tc.desc: test RekeyEx successfully modifies encryption algorithm and iteration count
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_028, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam newCryptoParam;
newCryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 2, 3, 4, 5, 1 };
newCryptoParam.encryptAlgo = EncryptAlgo::AES_256_CBC;
newCryptoParam.iterNum = 500;
errCode = store->RekeyEx(newCryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(newCryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
}
* @tc.name: Rdb_Rekey_029
* @tc.desc: test RekeyEx successfully modifies HMAC algorithm parameter
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_029, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
int changedRows;
values.Clear();
values.PutInt("age", 30);
ret = store->Update(changedRows, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, changedRows);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
cryptoParam.hmacAlgo = HmacAlgo::SHA512;
errCode = store->RekeyEx(cryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(cryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
values.Clear();
values.PutInt("age", 60);
ret = store->Update(changedRows, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, changedRows);
ret = RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Rekey_030
* @tc.desc: test RekeyEx successfully modifies key derivation function (KDF) algorithm parameter
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_030, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.kdfAlgo = KdfAlgo::KDF_SHA512;
errCode = store->RekeyEx(cryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
int changedRows = 0;
AbsRdbPredicates predicates("test1");
predicates.EqualTo("id", 1);
ret = store->Delete(changedRows, predicates);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(changedRows, 1);
store = nullptr;
config.SetCryptoParam(cryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 1);
}
* @tc.name: Rdb_Rekey_031
* @tc.desc: test RekeyEx successfully modifies crypto page size parameter
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_031, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
RdbHelper::DeleteRdbStore(config);
int errCode = E_OK;
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER)");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", std::string("zhangsan"));
values.PutInt("age", 18);
int ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(1, id);
RdbStoreConfig::CryptoParam newCryptoParam;
newCryptoParam.cryptoPageSize = 2048;
errCode = store->RekeyEx(newCryptoParam);
ASSERT_EQ(errCode, E_OK);
values.Clear();
values.PutInt("id", 2);
values.PutString("name", std::string("lisi"));
values.PutInt("age", 19);
ret = store->Insert(id, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(2, id);
store = nullptr;
config.SetCryptoParam(newCryptoParam);
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store->QueryByStep("SELECT * FROM test1");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}
* @tc.name: Rdb_Rekey_032
* @tc.desc: test RekeyEx during EXCLUSIVE transaction returns E_SQLITE_BUSY
* @tc.type: FUNC
*/
HWTEST_F(RdbInterfaceRekeyTest, Rdb_Rekey_032, TestSize.Level1)
{
RdbStoreConfig config(RdbInterfaceRekeyTest::encryptedDatabasePath);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetAllowRebuild(false);
config.SetEncryptStatus(true);
RdbStoreConfig::CryptoParam cryptoParam;
cryptoParam.encryptKey_ = std::vector<uint8_t>{ 1, 2, 3, 4, 5, 6 };
config.SetCryptoParam(cryptoParam);
config.SetBundleName("com.example.test_rekey");
RekeyTestOpenCallback helper;
int errCode = E_OK;
RdbHelper::DeleteRdbStore(config);
std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store, nullptr);
ASSERT_EQ(errCode, E_OK);
store->ExecuteSql("CREATE TABLE IF NOT EXISTS test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
auto [ret, transaction] = store->CreateTransaction(Transaction::EXCLUSIVE);
ASSERT_EQ(ret, E_OK);
ASSERT_NE(transaction, nullptr);
auto result = transaction->Insert("test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[0]));
ASSERT_EQ(result.first, E_OK);
ASSERT_EQ(1, result.second);
std::string keyPath = encryptedDatabaseKeyDir + RemoveSuffix(encryptedDatabaseName) + ".pub_key_v2";
bool isFileExists = OHOS::FileExists(keyPath);
ASSERT_FALSE(isFileExists);
RdbStoreConfig::CryptoParam newCryptoParam;
newCryptoParam.encryptKey_ = std::vector<uint8_t>{ 6, 5, 4, 3, 2, 1 };
errCode = store->RekeyEx(newCryptoParam);
ASSERT_EQ(errCode, E_SQLITE_BUSY);
result = transaction->Insert("test", RdbTestUtils::SetRowData(RdbTestUtils::g_rowData[1]));
ASSERT_EQ(result.first, E_OK);
ASSERT_EQ(2, result.second);
auto resultSet = transaction->QueryByStep("SELECT * FROM test");
ASSERT_NE(resultSet, nullptr);
int32_t rowCount{};
ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 2);
ret = transaction->Commit();
ASSERT_EQ(ret, E_OK);
resultSet = store->QueryByStep("SELECT * FROM test");
ASSERT_NE(resultSet, nullptr);
resultSet->GetRowCount(rowCount);
EXPECT_EQ(rowCount, 2);
RdbHelper::DeleteRdbStore(config);
EXPECT_EQ(ret, E_OK);
}