From ded6f44365ae5bec118940f9e1d3f6e95d159648 Mon Sep 17 00:00:00 2001 From: ZhaoJinghui Date: Sat, 28 Jun 2025 18:05:35 +0800 Subject: [PATCH] add testcase Signed-off-by: ZhaoJinghui Change-Id: I69bd0c742f8d396aeb933a4e8253eebf16f721ef --- .../app/src/kvstore_data_service.cpp | 5 +- .../unittest/kvstore_data_service_test.cpp | 300 ++++++++++++++++++ 2 files changed, 301 insertions(+), 4 deletions(-) diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index aff30c73f..d3ec757ed 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -525,10 +525,7 @@ int32_t KvStoreDataService::OnBackup(MessageParcel &data, MessageParcel &reply) } std::string content; - if (!GetSecretKeyBackup(backupInfo.bundleInfos, backupInfo.userId, iv, content)) { - DeleteCloneKey(); - return -1; - }; + GetSecretKeyBackup(backupInfo.bundleInfos, backupInfo.userId, iv, content); DeleteCloneKey(); std::string backupPath = DirectoryManager::GetInstance().GetClonePath(backupInfo.userId); diff --git a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp index beee71e60..83e0acf56 100644 --- a/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp +++ b/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp @@ -30,6 +30,7 @@ #include "system_ability.h" #include "system_ability_definition.h" #include "upgrade_manager.h" +#include "utils/base64_utils.h" using namespace testing::ext; using namespace OHOS; @@ -703,6 +704,22 @@ HWTEST_F(KvStoreDataServiceTest, DumpBundleInfo001, TestSize.Level0) EXPECT_NO_FATAL_FAILURE(kvStoreDataServiceTest.DumpBundleInfo(fd, params)); } +/** +* @tc.name: OnExtensionRestore001 +* @tc.desc: restore with invalid fd +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(KvStoreDataServiceTest, OnExtension001, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + data.WriteFileDescriptor(-1); + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("invalid", data, reply), 0); +} + /** * @tc.name: OnExtensionRestore001 * @tc.desc: restore with invalid fd @@ -1057,4 +1074,287 @@ HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup008, TestSize.Level0) { EXPECT_TRUE(backupData.infos.size() == 1); } + +/** + * @tc.name: OnExtensionBackup009 + * @tc.desc: test OnExtension function backup secret iv length invalid + * @tc.type: FUNC + * @tc.require: + * @tc.author: SQL + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionBackup009, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + std::string cloneInfoStr = "[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"27," + "145,118,212,62,156,133,135,50,68,188,239,20,170,227,190,37,142,218," + "158,177,32,5,160,13,114,186,141,59,91,44,200\",\"encryption_algname\":" + "\"AES256\",\"gcmParams_iv\":\"97,160,201,177,46,37,129,18,112,220,107," + "106,25,231,15,15,58,85,31,83,123,216,211,2,222,49,122,72,21,251,83," + "16\"}},{\"type\":\"application_selection\",\"detail\":[{" + "\"bundleName\":\"com.example.restore_test\",\"accessTokenId\":" + "536973769}]},{\"type\":\"userId\",\"detail\":\"100\"}]"; + data.WriteString(cloneInfoStr); + + std::string chAttrAddICmd = "chattr +i /data/service/el2/100/database/distributeddata/secret_key_backup.conf"; + ASSERT_EQ(E_OK, system(chAttrAddICmd.c_str())); + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("backup", data, reply), -1); + std::string chAttrSubICmd = "chattr -i /data/service/el2/100/database/distributeddata/secret_key_backup.conf"; + ASSERT_EQ(E_OK, system(chAttrSubICmd.c_str())); +} + +/** + * @tc.name: ReEncryptKey001 + * @tc.desc: test ReEncryptKey load meta failed + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(KvStoreDataServiceTest, ReEncryptKey001, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + SecretKeyMetaData secretKeyMeta; + StoreMetaData storeMeta; + std::vector iv; + auto ret = kvStoreDataServiceTest.ReEncryptKey("", secretKeyMeta, storeMeta, iv); + EXPECT_TRUE(ret.empty()); +} +/** + * @tc.name: ReEncryptKey002 + * @tc.desc: test ReEncryptKey password empty + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(KvStoreDataServiceTest, ReEncryptKey002, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + StoreMetaData testMeta; + testMeta.bundleName = "com.example.restore_test"; + testMeta.storeId = "Source"; + testMeta.user = "100"; + testMeta.area = CryptoManager::Area::EL1; + testMeta.instanceId = 0; + testMeta.deviceId = + DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + testMeta.isEncrypt = true; + testMeta.dataDir = "TEST_DIR"; + SecretKeyMetaData testSecret; + CryptoManager::CryptoParams encryptParams = { .area = testMeta.area }; + testSecret.storeType = 10; + testSecret.time = std::vector{233, 39, 137, 103, 0, 0, 0, 0}; + testSecret.nonce = encryptParams.nonce; + testSecret.area = encryptParams.area; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetKey(), testMeta, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetSecretKey(), testSecret, true), true); + + SecretKeyMetaData secretKeyMeta; + std::vector iv; + auto ret = kvStoreDataServiceTest.ReEncryptKey(testMeta.GetSecretKey(), secretKeyMeta, testMeta, iv); + EXPECT_TRUE(ret.empty()); +} + +/** + * @tc.name: ReEncryptKey003 + * @tc.desc: test ReEncryptKey reEncryptedKey empty + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(KvStoreDataServiceTest, ReEncryptKey003, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + StoreMetaData testMeta; + testMeta.bundleName = "com.example.restore_test"; + testMeta.storeId = "Source"; + testMeta.user = "100"; + testMeta.area = CryptoManager::Area::EL1; + testMeta.instanceId = 0; + testMeta.deviceId = + DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + testMeta.isEncrypt = true; + testMeta.dataDir = "TEST_DIR"; + std::vector sKey{2, 249, 221, 119, 177, 216, 217, 134, 185, 139, + 114, 38, 140, 64, 165, 35, 77, 169, 0, 226, + 226, 166, 37, 73, 181, 229, 42, 88, 108, 111, + 131, 104, 141, 43, 96, 119, 214, 34, 177, 129, + 233, 96, 98, 164, 87, 115, 187, 170}; + SecretKeyMetaData testSecret; + CryptoManager::CryptoParams encryptParams = { .area = testMeta.area }; + testSecret.sKey = CryptoManager::GetInstance().Encrypt(sKey, encryptParams); + testSecret.storeType = 10; + testSecret.time = std::vector{233, 39, 137, 103, 0, 0, 0, 0}; + testSecret.nonce = encryptParams.nonce; + testSecret.area = encryptParams.area; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetKey(), testMeta, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetSecretKey(), testSecret, true), true); + + SecretKeyMetaData secretKeyMeta; + std::vector iv; + auto ret = kvStoreDataServiceTest.ReEncryptKey(testMeta.GetSecretKey(), secretKeyMeta, testMeta, iv); + EXPECT_TRUE(ret.empty()); +} + +/** + * @tc.name: OnExtensionRestore_InvalidUserId + * @tc.desc: Test OnRestore returns -1 when userId is empty + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_InvalidUserId, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + // Prepare a valid backup file (content doesn't matter, as IV size will fail first) + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, NORMAL_BACKUP_DATA), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + std::string cloneInfoStr = + "[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"27," + "145,118,212,62,156,133,135,50,68,188,239,20,170,227,190,37,142,218," + "158,177,32,5,160,13,114,186,141,59,91,44,200\",\"encryption_algname\":" + "\"AES256\",\"gcmParams_iv\":\"1,2,3,4,5,6,7,8,9,10\"}},{\"type\":\"userId\",\"detail\":\"\"}]"; + data.WriteString(cloneInfoStr); + + // Should return -1 due to IV size error + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), -1); + close(fd); +} + +/** + * @tc.name: OnExtensionRestore_InvalidIvSize + * @tc.desc: Test OnRestore returns -1 when IV size is incorrect + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_InvalidIvSize, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, NORMAL_BACKUP_DATA), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + // Prepare cloneInfoStr with invalid IV (length != AES_256_NONCE_SIZE) + std::string cloneInfoStr = + "[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"27," + "145,118,212,62,156,133,135,50,68,188,239,20,170,227,190,37,142,218," + "158,177,32,5,160,13,114,186,141,59,91,44,200\",\"encryption_algname\":" + "\"AES256\",\"gcmParams_iv\":\"1,2,3,4,5,6,7,8,9,10\"}},{\"type\":\"userId\",\"detail\":\"100\"}]"; + data.WriteString(cloneInfoStr); + + // Should return -1 due to IV size error + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), -1); + close(fd); +} + +/** + * @tc.name: OnExtensionRestore_ImportCloneKeyFailed + * @tc.desc: Test OnRestore returns -1 when ImportCloneKey fails (invalid key size) + * @tc.type: FUNC + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_ImportCloneKeyFailed, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + // Prepare a valid backup file (content doesn't matter, as ImportCloneKey will fail first) + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, NORMAL_BACKUP_DATA), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + // Prepare cloneInfoStr with invalid encryption_symkey (too short, so ImportCloneKey fails) + std::string cloneInfoStr = + "[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"1,2,3\",\"encryption_algname\":\"AES256\"," + "\"gcmParams_iv\":\"97,160,201,177,46,37,129,18,112,220,107,106,25,231,15,15,""58,85,31,83,123,216,211,2,222," + "49,122,72,21,251,83,16\"}},{\"type\":\"userId\",\"detail\":\"100\"}]"; + data.WriteString(cloneInfoStr); + + // Should return -1 due to ImportCloneKey failure + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), -1); + close(fd); +} + +/** + * @tc.name: OnExtensionRestore_RestoreSuccess + * @tc.desc: Test OnRestore returns 0 when ImportCloneKey succeeds + * @tc.type: FUNC + */ +HWTEST_F(KvStoreDataServiceTest, OnExtensionRestore_RestoreSuccess, TestSize.Level0) +{ + KvStoreDataService kvStoreDataServiceTest; + MessageParcel data; + MessageParcel reply; + + StoreMetaData testMeta; + testMeta.bundleName = "com.myapp.example"; + testMeta.storeId = "storeId"; + testMeta.user = "100"; + testMeta.area = CryptoManager::Area::EL1; + testMeta.instanceId = 0; + testMeta.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + testMeta.isEncrypt = true; + testMeta.dataDir = "TEST_DIR"; + std::vector sKey(32, 0); + SecretKeyMetaData testSecret; + CryptoManager::CryptoParams encryptParams = { .area = testMeta.area }; + testSecret.sKey = CryptoManager::GetInstance().Encrypt(sKey, encryptParams); + testSecret.storeType = 10; + testSecret.time = std::vector{ 233, 39, 137, 103, 0, 0, 0, 0 }; + testSecret.nonce = encryptParams.nonce; + testSecret.area = encryptParams.area; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetKey(), testMeta, true), true); + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(testMeta.GetSecretKey(), testSecret, true), true); + + std::string symKey = "27,145,118,212,62,156,133,135,50,68,188,239,20,170,227,190,37,142," + "218,158,177,32,5,160,13,114,186,141,59,91,44,200"; + std::vector iv{ 97, 160, 201, 177, 46, 37, 129, 18, 112, 220, 107, 106, 25, 231, 15, 15, 58, 85, 31, 83, + 123, 216, 211, 2, 222, 49, 122, 72, 21, 251, 83, 16 }; + + ASSERT_EQ(kvStoreDataServiceTest.ImportCloneKey(symKey), true); + + SecretKeyMetaData secretKeyMeta; + auto reEncryptedKey = kvStoreDataServiceTest.ReEncryptKey(testMeta.GetSecretKey(), secretKeyMeta, testMeta, iv); + kvStoreDataServiceTest.DeleteCloneKey(); + auto encodeEncryptedKey = DistributedData::Base64::Encode(reEncryptedKey); + + const std::string backupData = + std::string("{\"infos\":[{\"bundleName\":\"com.myapp.example\",\"dbName\":\"storeId\"," + "\"instanceId\":0,\"storeType\":\"10\",\"user\":\"100\",\"sKey\":\"") + + encodeEncryptedKey + std::string("\",\"time\":[50,180,137,103,0,0,0,0]}]}"); + + EXPECT_EQ(WriteContentToFile(SECRETKEY_BACKUP_FILE, backupData), 0); + int32_t fd = open(SECRETKEY_BACKUP_FILE.c_str(), O_RDONLY); + ASSERT_GE(fd, 0); + data.WriteFileDescriptor(fd); + + std::string cloneInfoStr = + std::string("[{\"type\":\"encryption_info\",\"detail\":{\"encryption_symkey\":\"") + symKey + + std::string("\",\"encryption_algname\":\"AES256\",\"gcmParams_iv\":\"97,160,201,177,46,37,129,18,112,220,107," + "106,25,231,15,15,58,85,31,83,123,216,211,2,222,49,122,72,21,251,83,16\"}}," + "{\"type\":\"userId\",\"detail\":\"100\"}]"); + data.WriteString(cloneInfoStr); + + EXPECT_EQ(kvStoreDataServiceTest.OnExtension("restore", data, reply), 0); + close(fd); +} } // namespace OHOS::Test \ No newline at end of file -- Gitee