* Copyright (c) 2025 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 "RdbRekeyExTest"
#include <gtest/gtest.h>
#include <securec.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <string>
#include <thread>
#include "rdb_test_common.h"
#include "logger.h"
#include "rdb_errno.h"
#include "rdb_helper.h"
#include "rdb_open_callback.h"
using namespace testing::ext;
using namespace OHOS::NativeRdb;
using namespace OHOS::Rdb;
namespace OHOS::RdbStoreRekeyExTest {
constexpr int AGE_VALUE = 18;
constexpr int64_t ITER_NUMS[2] = { 500, 5000 };
constexpr int CRYPTO_PAGE_SIZES[3] = { 1024, 2048, 4096 };
constexpr size_t ITER_NUMS_SIZE = sizeof(ITER_NUMS) / sizeof(ITER_NUMS[0]);
constexpr size_t CRYPTO_PAGE_SIZES_SIZE = sizeof(CRYPTO_PAGE_SIZES) / sizeof(CRYPTO_PAGE_SIZES[0]);
struct RekeyExTestParam {
RdbStoreConfig::CryptoParam srcCryptoParam;
RdbStoreConfig::CryptoParam dstCryptoParam;
};
std::vector<RekeyExTestParam> GenerateAllRekeyExParams()
{
std::vector<RdbStoreConfig::CryptoParam> allCryptoParams;
int index = 0;
for (int encrypt = 0; encrypt <= static_cast<int>(EncryptAlgo::PLAIN_TEXT); encrypt++) {
for (int hmac = 0; hmac < static_cast<int>(HmacAlgo::HMAC_BUTT); hmac++) {
for (int kdf = 0; kdf < static_cast<int>(KdfAlgo::KDF_BUTT); kdf++) {
RdbStoreConfig::CryptoParam param;
param.encryptAlgo = static_cast<EncryptAlgo>(encrypt);
param.hmacAlgo = static_cast<HmacAlgo>(hmac);
param.kdfAlgo = static_cast<KdfAlgo>(kdf);
param.iterNum = ITER_NUMS[index % ITER_NUMS_SIZE];
param.cryptoPageSize = CRYPTO_PAGE_SIZES[index % CRYPTO_PAGE_SIZES_SIZE];
allCryptoParams.push_back(param);
index++;
}
}
}
std::vector<RekeyExTestParam> allTestParams;
for (const auto &srcCryptoParam : allCryptoParams) {
for (const auto &dstCryptoParam : allCryptoParams) {
allTestParams.push_back({ srcCryptoParam, dstCryptoParam });
}
}
return allTestParams;
}
class RekeyTestOpenCallback : public RdbOpenCallback {
public:
int OnCreate(RdbStore &store) override;
int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
};
constexpr const char *CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test1 ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, "
"age INTEGER)";
int RekeyTestOpenCallback::OnCreate(RdbStore &store)
{
return store.ExecuteSql(CREATE_TABLE_TEST);
}
int RekeyTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
{
(void) oldVersion;
(void) newVersion;
return E_OK;
}
class RdbRekeyExTest : public testing::TestWithParam<RekeyExTestParam> {
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp(void);
void TearDown(void);
void VerifyResultSet(std::shared_ptr<ResultSet> resultSet);
const std::string BUNDLE_NAME = "com.example.test_rekey";
protected:
RekeyExTestParam currentParam_;
std::string encryptedDatabaseName_;
std::string encryptedDatabasePath_;
std::shared_ptr<RdbStore> store_;
};
void RdbRekeyExTest::SetUpTestCase(void)
{
}
void RdbRekeyExTest::TearDownTestCase(void)
{
}
void RdbRekeyExTest::SetUp(void)
{
currentParam_ = GetParam();
encryptedDatabaseName_ = "RekeyEx_test.db";
encryptedDatabasePath_ = RDB_TEST_PATH + encryptedDatabaseName_;
}
void RdbRekeyExTest::TearDown(void)
{
}
void RdbRekeyExTest::VerifyResultSet(std::shared_ptr<ResultSet> resultSet)
{
ASSERT_NE(resultSet, nullptr);
int32_t rowCount = 0;
int ret = resultSet->GetRowCount(rowCount);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(rowCount, 1);
ret = resultSet->GoToFirstRow();
ASSERT_EQ(ret, E_OK);
int columnIndex = -1;
ret = resultSet->GetColumnIndex("id", columnIndex);
ASSERT_EQ(ret, E_OK);
int idVal = -1;
ret = resultSet->GetInt(columnIndex, idVal);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(idVal, 1);
ret = resultSet->GetColumnIndex("name", columnIndex);
ASSERT_EQ(ret, E_OK);
std::string nameVal;
ret = resultSet->GetString(columnIndex, nameVal);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(nameVal, "zhangsan");
ret = resultSet->GetColumnIndex("age", columnIndex);
ASSERT_EQ(ret, E_OK);
int ageVal = -1;
ret = resultSet->GetInt(columnIndex, ageVal);
ASSERT_EQ(ret, E_OK);
ASSERT_EQ(ageVal, AGE_VALUE);
}
* @tc.name: RdbStore_RekeyEx_001
* @tc.desc: test rekeyex all crypto params
* @tc.type: FUNC
*/
HWTEST_P(RdbRekeyExTest, RdbStore_RekeyEx_001, TestSize.Level1)
{
int errCode = E_OK;
auto &srcParam = currentParam_.srcCryptoParam;
auto &dstParam = currentParam_.dstCryptoParam;
RdbStoreConfig config(encryptedDatabasePath_);
config.SetSecurityLevel(SecurityLevel::S1);
config.SetBundleName(BUNDLE_NAME);
config.SetName(encryptedDatabaseName_);
config.SetCryptoParam(srcParam);
config.SetEncryptStatus(true);
RekeyTestOpenCallback helper;
LOG_INFO("srcParam: [%{public}d,%{public}d,%{public}d,%{public}d,%{public}u]"
"-> dstParam: [%{public}d,%{public}d,%{public}d,%{public}d,%{public}u]",
srcParam.encryptAlgo, srcParam.hmacAlgo, srcParam.kdfAlgo, srcParam.iterNum, srcParam.cryptoPageSize,
dstParam.encryptAlgo, dstParam.hmacAlgo, dstParam.kdfAlgo, dstParam.iterNum, dstParam.cryptoPageSize);
store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store_, nullptr);
ASSERT_EQ(errCode, E_OK);
int64_t insertId = -1;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("name", "zhangsan");
values.PutInt("age", AGE_VALUE);
int ret = store_->Insert(insertId, "test1", values);
EXPECT_EQ(ret, E_OK);
EXPECT_EQ(insertId, 1);
errCode = store_->RekeyEx(dstParam);
ASSERT_EQ(errCode, E_OK);
store_ = nullptr;
config.SetCryptoParam(dstParam);
config.SetEncryptStatus(dstParam.encryptAlgo != EncryptAlgo::PLAIN_TEXT);
store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);
ASSERT_NE(store_, nullptr);
ASSERT_EQ(errCode, E_OK);
auto resultSet = store_->QueryByStep("SELECT * FROM test1");
VerifyResultSet(resultSet);
resultSet->Close();
RdbHelper::DeleteRdbStore(config);
}
INSTANTIATE_TEST_SUITE_P(RdbRekeyExTestSuite, RdbRekeyExTest, testing::ValuesIn(GenerateAllRekeyExParams()));
}