153c3577eSopenharmony_ci/* 253c3577eSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 353c3577eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 453c3577eSopenharmony_ci * you may not use this file except in compliance with the License. 553c3577eSopenharmony_ci * You may obtain a copy of the License at 653c3577eSopenharmony_ci * 753c3577eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 853c3577eSopenharmony_ci * 953c3577eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1053c3577eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1153c3577eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1253c3577eSopenharmony_ci * See the License for the specific language governing permissions and 1353c3577eSopenharmony_ci * limitations under the License. 1453c3577eSopenharmony_ci */ 1553c3577eSopenharmony_ci#define LOG_TAG "Upgrade" 1653c3577eSopenharmony_ci#include "upgrade.h" 1753c3577eSopenharmony_ci 1853c3577eSopenharmony_ci#include <chrono> 1953c3577eSopenharmony_ci#include <cinttypes> 2053c3577eSopenharmony_ci 2153c3577eSopenharmony_ci#include "accesstoken_kit.h" 2253c3577eSopenharmony_ci#include "crypto_manager.h" 2353c3577eSopenharmony_ci#include "device_manager_adapter.h" 2453c3577eSopenharmony_ci#include "directory/directory_manager.h" 2553c3577eSopenharmony_ci#include "kvdb_general_store.h" 2653c3577eSopenharmony_ci#include "log_print.h" 2753c3577eSopenharmony_ci#include "metadata/meta_data_manager.h" 2853c3577eSopenharmony_ci#include "metadata/secret_key_meta_data.h" 2953c3577eSopenharmony_cinamespace OHOS::DistributedKv { 3053c3577eSopenharmony_ciusing namespace OHOS::DistributedData; 3153c3577eSopenharmony_ciusing system_clock = std::chrono::system_clock; 3253c3577eSopenharmony_ciusing DMAdapter = DistributedData::DeviceManagerAdapter; 3353c3577eSopenharmony_ciusing DBKey = DistributedDB::Key; 3453c3577eSopenharmony_ci 3553c3577eSopenharmony_ciUpgrade &Upgrade::GetInstance() 3653c3577eSopenharmony_ci{ 3753c3577eSopenharmony_ci static Upgrade upgrade; 3853c3577eSopenharmony_ci return upgrade; 3953c3577eSopenharmony_ci} 4053c3577eSopenharmony_ci 4153c3577eSopenharmony_ciUpgrade::DBStatus Upgrade::UpdateStore(const StoreMeta &old, const StoreMeta &meta, const std::vector<uint8_t> &pwd) 4253c3577eSopenharmony_ci{ 4353c3577eSopenharmony_ci if (old.version < StoreMeta::UUID_CHANGED_TAG && old.storeType == DEVICE_COLLABORATION) { 4453c3577eSopenharmony_ci auto upStatus = Upgrade::GetInstance().UpdateUuid(old, meta, pwd); 4553c3577eSopenharmony_ci if (upStatus != DBStatus::OK) { 4653c3577eSopenharmony_ci return DBStatus::DB_ERROR; 4753c3577eSopenharmony_ci } 4853c3577eSopenharmony_ci } 4953c3577eSopenharmony_ci 5053c3577eSopenharmony_ci if (old.dataDir == meta.dataDir) { 5153c3577eSopenharmony_ci return DBStatus::OK; 5253c3577eSopenharmony_ci } 5353c3577eSopenharmony_ci 5453c3577eSopenharmony_ci if (!exporter_ || !cleaner_) { 5553c3577eSopenharmony_ci return DBStatus::NOT_SUPPORT; 5653c3577eSopenharmony_ci } 5753c3577eSopenharmony_ci 5853c3577eSopenharmony_ci DBPassword password; 5953c3577eSopenharmony_ci auto backupFile = exporter_(old, password); 6053c3577eSopenharmony_ci if (backupFile.empty()) { 6153c3577eSopenharmony_ci return DBStatus::NOT_FOUND; 6253c3577eSopenharmony_ci } 6353c3577eSopenharmony_ci 6453c3577eSopenharmony_ci auto kvStore = GetDBStore(meta, pwd); 6553c3577eSopenharmony_ci if (kvStore == nullptr) { 6653c3577eSopenharmony_ci return DBStatus::DB_ERROR; 6753c3577eSopenharmony_ci } 6853c3577eSopenharmony_ci 6953c3577eSopenharmony_ci cleaner_(old); 7053c3577eSopenharmony_ci return DBStatus::OK; 7153c3577eSopenharmony_ci} 7253c3577eSopenharmony_ci 7353c3577eSopenharmony_ciUpgrade::DBStatus Upgrade::ExportStore(const StoreMeta &old, const StoreMeta &meta) 7453c3577eSopenharmony_ci{ 7553c3577eSopenharmony_ci if (old.dataDir == meta.dataDir) { 7653c3577eSopenharmony_ci return DBStatus::OK; 7753c3577eSopenharmony_ci } 7853c3577eSopenharmony_ci 7953c3577eSopenharmony_ci if (!exporter_) { 8053c3577eSopenharmony_ci return DBStatus::NOT_SUPPORT; 8153c3577eSopenharmony_ci } 8253c3577eSopenharmony_ci 8353c3577eSopenharmony_ci DBPassword password; 8453c3577eSopenharmony_ci auto backupFile = exporter_(old, password); 8553c3577eSopenharmony_ci if (backupFile.empty()) { 8653c3577eSopenharmony_ci return DBStatus::NOT_FOUND; 8753c3577eSopenharmony_ci } 8853c3577eSopenharmony_ci return DBStatus::OK; 8953c3577eSopenharmony_ci} 9053c3577eSopenharmony_ci 9153c3577eSopenharmony_civoid Upgrade::UpdatePassword(const StoreMeta &meta, const std::vector<uint8_t> &password) 9253c3577eSopenharmony_ci{ 9353c3577eSopenharmony_ci if (!meta.isEncrypt) { 9453c3577eSopenharmony_ci return; 9553c3577eSopenharmony_ci } 9653c3577eSopenharmony_ci 9753c3577eSopenharmony_ci SecretKeyMetaData secretKey; 9853c3577eSopenharmony_ci secretKey.storeType = meta.storeType; 9953c3577eSopenharmony_ci secretKey.sKey = CryptoManager::GetInstance().Encrypt(password); 10053c3577eSopenharmony_ci auto time = system_clock::to_time_t(system_clock::now()); 10153c3577eSopenharmony_ci secretKey.time = { reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time) }; 10253c3577eSopenharmony_ci MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), secretKey, true); 10353c3577eSopenharmony_ci} 10453c3577eSopenharmony_ci 10553c3577eSopenharmony_ciUpgrade::DBStatus Upgrade::UpdateUuid(const StoreMeta &old, const StoreMeta &meta, const std::vector<uint8_t> &pwd) 10653c3577eSopenharmony_ci{ 10753c3577eSopenharmony_ci auto kvStore = GetDBStore(meta, pwd); 10853c3577eSopenharmony_ci if (kvStore == nullptr) { 10953c3577eSopenharmony_ci return DBStatus::DB_ERROR; 11053c3577eSopenharmony_ci } 11153c3577eSopenharmony_ci kvStore->RemoveDeviceData(); 11253c3577eSopenharmony_ci auto uuid = GetEncryptedUuidByMeta(meta); 11353c3577eSopenharmony_ci auto dbStatus = kvStore->UpdateKey([uuid](const DBKey &originKey, DBKey &newKey) { 11453c3577eSopenharmony_ci newKey = originKey; 11553c3577eSopenharmony_ci errno_t err = EOK; 11653c3577eSopenharmony_ci err = memcpy_s(newKey.data(), newKey.size(), uuid.data(), uuid.size()); 11753c3577eSopenharmony_ci if (err != EOK) { 11853c3577eSopenharmony_ci ZLOGE("memcpy_s failed, err:%{public}d", err); 11953c3577eSopenharmony_ci } 12053c3577eSopenharmony_ci }); 12153c3577eSopenharmony_ci if (dbStatus != DBStatus::OK) { 12253c3577eSopenharmony_ci ZLOGE("fail to update Uuid, status:%{public}d", dbStatus); 12353c3577eSopenharmony_ci } 12453c3577eSopenharmony_ci return dbStatus; 12553c3577eSopenharmony_ci} 12653c3577eSopenharmony_ci 12753c3577eSopenharmony_cibool Upgrade::RegisterExporter(uint32_t version, Exporter exporter) 12853c3577eSopenharmony_ci{ 12953c3577eSopenharmony_ci (void)version; 13053c3577eSopenharmony_ci exporter_ = std::move(exporter); 13153c3577eSopenharmony_ci return exporter_ != nullptr; 13253c3577eSopenharmony_ci} 13353c3577eSopenharmony_ci 13453c3577eSopenharmony_cibool Upgrade::RegisterCleaner(uint32_t version, Cleaner cleaner) 13553c3577eSopenharmony_ci{ 13653c3577eSopenharmony_ci (void)version; 13753c3577eSopenharmony_ci cleaner_ = std::move(cleaner); 13853c3577eSopenharmony_ci return cleaner_ != nullptr; 13953c3577eSopenharmony_ci} 14053c3577eSopenharmony_ci 14153c3577eSopenharmony_ciUpgrade::AutoStore Upgrade::GetDBStore(const StoreMeta &meta, const std::vector<uint8_t> &pwd) 14253c3577eSopenharmony_ci{ 14353c3577eSopenharmony_ci DBManager manager(meta.appId, meta.user, meta.instanceId); 14453c3577eSopenharmony_ci manager.SetKvStoreConfig({ DirectoryManager::GetInstance().GetStorePath(meta) }); 14553c3577eSopenharmony_ci auto release = [&manager](DBStore *store) { manager.CloseKvStore(store); }; 14653c3577eSopenharmony_ci DBPassword password; 14753c3577eSopenharmony_ci password.SetValue(pwd.data(), pwd.size()); 14853c3577eSopenharmony_ci AutoStore dbStore(nullptr, release); 14953c3577eSopenharmony_ci manager.GetKvStore(meta.storeId, KVDBGeneralStore::GetDBOption(meta, password), 15053c3577eSopenharmony_ci [&dbStore](auto dbStatus, auto *tmpStore) { 15153c3577eSopenharmony_ci dbStore.reset(tmpStore); 15253c3577eSopenharmony_ci }); 15353c3577eSopenharmony_ci return dbStore; 15453c3577eSopenharmony_ci} 15553c3577eSopenharmony_ci 15653c3577eSopenharmony_cistd::string Upgrade::GetEncryptedUuidByMeta(const StoreMeta &meta) 15753c3577eSopenharmony_ci{ 15853c3577eSopenharmony_ci std::string keyUuid = meta.appId + meta.deviceId; 15953c3577eSopenharmony_ci auto pair = calcUuid_.Find(keyUuid); 16053c3577eSopenharmony_ci if (pair.first) { 16153c3577eSopenharmony_ci return pair.second; 16253c3577eSopenharmony_ci } 16353c3577eSopenharmony_ci std::string uuid; 16453c3577eSopenharmony_ci if (OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(meta.tokenId) == 16553c3577eSopenharmony_ci OHOS::Security::AccessToken::TOKEN_HAP) { 16653c3577eSopenharmony_ci uuid = DMAdapter::GetInstance().CalcClientUuid(meta.appId, meta.deviceId); 16753c3577eSopenharmony_ci calcUuid_.Insert(keyUuid, uuid); 16853c3577eSopenharmony_ci return uuid; 16953c3577eSopenharmony_ci } 17053c3577eSopenharmony_ci uuid = DMAdapter::GetInstance().CalcClientUuid(" ", meta.deviceId); 17153c3577eSopenharmony_ci calcUuid_.Insert(keyUuid, uuid); 17253c3577eSopenharmony_ci return uuid; 17353c3577eSopenharmony_ci} 17453c3577eSopenharmony_ci} // namespace OHOS::DistributedKv