• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #define LOG_TAG "KvStoreMetaManager"
16 
17 #include "kvstore_meta_manager.h"
18 
19 #include <directory_ex.h>
20 #include <file_ex.h>
21 #include <unistd.h>
22 
23 #include <chrono>
24 #include <condition_variable>
25 #include <thread>
26 
27 #include "account_delegate.h"
28 #include "constant.h"
29 #include "device_kvstore_impl.h"
30 #include "directory_utils.h"
31 #include "executor_factory.h"
32 #include "hks_api.h"
33 #include "hks_param.h"
34 #include "kvstore_app_manager.h"
35 #include "kvstore_data_service.h"
36 #include "kvstore_utils.h"
37 #include "log_print.h"
38 #include "metadata/capability_meta_data.h"
39 #include "metadata/user_meta_data.h"
40 #include "rdb_types.h"
41 #include "reporter.h"
42 #include "serializable/serializable.h"
43 #include "user_delegate.h"
44 #include "utils/anonymous.h"
45 #include "utils/crypto.h"
46 
47 namespace OHOS {
48 namespace DistributedKv {
49 using json = nlohmann::json;
50 using namespace std::chrono;
51 using namespace OHOS::DistributedData;
52 
53 // APPID: distributeddata
54 // USERID: default
55 // STOREID: service_meta
56 // dataDir: /data/misc_de/0/mdds/Meta/${storeId}/sin_gen.db
57 std::condition_variable KvStoreMetaManager::cv_;
58 std::mutex KvStoreMetaManager::cvMutex_;
59 KvStoreMetaManager::MetaDeviceChangeListenerImpl KvStoreMetaManager::listener_;
60 
KvStoreMetaManager()61 KvStoreMetaManager::KvStoreMetaManager()
62     : metaDelegate_(nullptr,
63             [this](DistributedDB::KvStoreNbDelegate *delegate) {
64                 if (delegate == nullptr) {
65                     return;
66                 }
67                 auto result = kvStoreDelegateManager_.CloseKvStore(delegate);
68                 if (result != DistributedDB::DBStatus::OK) {
69                     ZLOGE("CloseMetaKvstore return error status: %d", static_cast<int>(result));
70                 }
71             }),
72       metaDBDirectory_("/data/service/el1/public/database/distributeddata/meta"),
73       kvStoreDelegateManager_(META_DB_APP_ID, Constant::GetDefaultHarmonyAccountName())
74 {
75     ZLOGI("begin.");
76 }
77 
~KvStoreMetaManager()78 KvStoreMetaManager::~KvStoreMetaManager()
79 {
80 }
81 
GetInstance()82 KvStoreMetaManager &KvStoreMetaManager::GetInstance()
83 {
84     static KvStoreMetaManager instance;
85     return instance;
86 }
87 
SubscribeMeta(const std::string & keyPrefix,const ChangeObserver & observer)88 void KvStoreMetaManager::SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer)
89 {
90     metaObserver_.handlerMap_[keyPrefix] = observer;
91 }
92 
InitMetaListener()93 void KvStoreMetaManager::InitMetaListener()
94 {
95     InitMetaData();
96     auto status = KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(&listener_, { "metaMgr" });
97     if (status != AppDistributedKv::Status::SUCCESS) {
98         ZLOGW("register failed.");
99         return;
100     }
101     ZLOGI("register meta device change success.");
102     SubscribeMetaKvStore();
103 }
104 
InitMetaData()105 void KvStoreMetaManager::InitMetaData()
106 {
107     ZLOGI("start.");
108     auto &metaDelegate = GetMetaKvStore();
109     if (metaDelegate == nullptr) {
110         ZLOGI("get meta failed.");
111         return;
112     }
113     auto uid = getuid();
114     const std::string accountId = AccountDelegate::GetInstance()->GetCurrentAccountId();
115     const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
116     auto metaKey = GetMetaKey(userId, "default", META_DB_APP_ID, Constant::SERVICE_META_DB_NAME);
117     struct KvStoreMetaData metaData {
118         .appId = META_DB_APP_ID,
119         .appType = "default",
120         .bundleName = META_DB_APP_ID,
121         .dataDir = metaDBDirectory_,
122         .deviceAccountId = userId,
123         .deviceId = DeviceKvStoreImpl::GetLocalDeviceId(),
124         .isAutoSync = false,
125         .isBackup = false,
126         .isEncrypt = false,
127         .kvStoreType = KvStoreType::SINGLE_VERSION,
128         .schema = "",
129         .storeId = Constant::SERVICE_META_DB_NAME,
130         .userId = accountId,
131         .uid = int32_t(uid),
132         .version = META_STORE_VERSION,
133         .securityLevel = SecurityLevel::S1,
134     };
135     std::string jsonStr = metaData.Marshal();
136     std::vector<uint8_t> value(jsonStr.begin(), jsonStr.end());
137     if (CheckUpdateServiceMeta(metaKey, UPDATE, value) != Status::SUCCESS) {
138         ZLOGW("CheckUpdateServiceMeta database failed.");
139     }
140 
141     ZLOGI("end.");
142 }
143 
InitMetaParameter()144 void KvStoreMetaManager::InitMetaParameter()
145 {
146     ZLOGI("start.");
147     bool ret = ForceCreateDirectory(metaDBDirectory_);
148     if (!ret) {
149         FaultMsg msg = {FaultType::SERVICE_FAULT, "user", __FUNCTION__, Fault::SF_CREATE_DIR};
150         Reporter::GetInstance()->ServiceFault()->Report(msg);
151         ZLOGE("create directories failed");
152         return;
153     }
154     ret = ForceCreateDirectory(metaDBDirectory_ + "/backup");
155 
156     DistributedDB::KvStoreConfig kvStoreConfig {metaDBDirectory_};
157     kvStoreDelegateManager_.SetKvStoreConfig(kvStoreConfig);
158 
159     vecRootKeyAlias_ = std::vector<uint8_t>(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS));
160     vecNonce_ = std::vector<uint8_t>(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE));
161     vecAad_ = std::vector<uint8_t>(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD));
162 }
163 
GetMetaKvStore()164 const KvStoreMetaManager::NbDelegate &KvStoreMetaManager::GetMetaKvStore()
165 {
166     if (metaDelegate_ != nullptr) {
167         return metaDelegate_;
168     }
169 
170     std::lock_guard<decltype(mutex_)> lock(mutex_);
171     if (metaDelegate_ == nullptr) {
172         metaDelegate_ = CreateMetaKvStore();
173     }
174     return metaDelegate_;
175 }
176 
CreateMetaKvStore()177 KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore()
178 {
179     DistributedDB::DBStatus dbStatusTmp = DistributedDB::DBStatus::NOT_SUPPORT;
180     DistributedDB::KvStoreNbDelegate::Option option;
181     option.createIfNecessary = true;
182     option.isMemoryDb = false;
183     option.createDirByStoreIdOnly = true;
184     option.isEncryptedDb = false;
185     DistributedDB::KvStoreNbDelegate *kvStoreNbDelegatePtr = nullptr;
186     kvStoreDelegateManager_.GetKvStore(
187         Constant::SERVICE_META_DB_NAME, option,
188         [&kvStoreNbDelegatePtr, &dbStatusTmp](DistributedDB::DBStatus dbStatus,
189                                               DistributedDB::KvStoreNbDelegate *kvStoreNbDelegate) {
190             kvStoreNbDelegatePtr = kvStoreNbDelegate;
191             dbStatusTmp = dbStatus;
192         });
193 
194     if (dbStatusTmp != DistributedDB::DBStatus::OK) {
195         ZLOGE("GetKvStore return error status: %d", static_cast<int>(dbStatusTmp));
196         return nullptr;
197     }
198     auto release = [this](DistributedDB::KvStoreNbDelegate *delegate) {
199         ZLOGI("release meta data  kv store");
200         if (delegate == nullptr) {
201             return;
202         }
203 
204         auto result = kvStoreDelegateManager_.CloseKvStore(delegate);
205         if (result != DistributedDB::DBStatus::OK) {
206             ZLOGE("CloseMetaKvStore return error status: %d", static_cast<int>(result));
207         }
208     };
209     return NbDelegate(kvStoreNbDelegatePtr, release);
210 }
211 
GetMetaKey(const std::string & deviceAccountId,const std::string & groupId,const std::string & bundleName,const std::string & storeId,const std::string & key)212 std::vector<uint8_t> KvStoreMetaManager::GetMetaKey(const std::string &deviceAccountId,
213                                                     const std::string &groupId, const std::string &bundleName,
214                                                     const std::string &storeId, const std::string &key)
215 {
216     std::string originKey;
217     if (key.empty()) {
218         originKey = DeviceKvStoreImpl::GetLocalDeviceId() + Constant::KEY_SEPARATOR +
219                     deviceAccountId + Constant::KEY_SEPARATOR +
220                     groupId + Constant::KEY_SEPARATOR +
221                     bundleName + Constant::KEY_SEPARATOR +
222                     storeId;
223         return KvStoreMetaRow::GetKeyFor(originKey);
224     }
225 
226     originKey = deviceAccountId + Constant::KEY_SEPARATOR +
227                 groupId + Constant::KEY_SEPARATOR +
228                 bundleName + Constant::KEY_SEPARATOR +
229                 storeId + Constant::KEY_SEPARATOR +
230                 key;
231     return SecretMetaRow::GetKeyFor(originKey);
232 }
233 
GetSecretKeyFile(const std::string & userId,const std::string & appId,const std::string & storeId,int pathType)234 std::string KvStoreMetaManager::GetSecretKeyFile(const std::string &userId, const std::string &appId,
235                                                  const std::string &storeId, int pathType)
236 {
237     std::string hashedStoreId;
238     DistributedDB::DBStatus result = DistributedDB::KvStoreDelegateManager::GetDatabaseDir(storeId, hashedStoreId);
239     if (DistributedDB::OK != result) {
240         ZLOGE("get data base directory by kvstore store id failed, result = %d.", result);
241         return "";
242     }
243     std::string miscPath = (pathType == KvStoreAppManager::PATH_DE) ? Constant::ROOT_PATH_DE : Constant::ROOT_PATH_CE;
244     return miscPath + "/" + Constant::SERVICE_NAME + "/" + userId + "/" + Constant::GetDefaultHarmonyAccountName()
245            + "/" + appId + "/" + hashedStoreId + ".mul.key";
246 }
247 
GetSecretSingleKeyFile(const std::string & userId,const std::string & appId,const std::string & storeId,int pathType)248 std::string KvStoreMetaManager::GetSecretSingleKeyFile(const std::string &userId, const std::string &appId,
249                                                        const std::string &storeId, int pathType)
250 {
251     std::string hashedStoreId;
252     DistributedDB::DBStatus result = DistributedDB::KvStoreDelegateManager::GetDatabaseDir(storeId, hashedStoreId);
253     if (DistributedDB::OK != result) {
254         ZLOGE("get data base directory by kvstore store id failed, result = %d.", result);
255         return "";
256     }
257     std::string miscPath = (pathType == KvStoreAppManager::PATH_DE) ? Constant::ROOT_PATH_DE : Constant::ROOT_PATH_CE;
258     return miscPath + "/" + Constant::SERVICE_NAME + "/" + userId + "/" + Constant::GetDefaultHarmonyAccountName()
259            + "/" + appId + "/" + hashedStoreId + ".sig.key";
260 }
261 
CheckUpdateServiceMeta(const std::vector<uint8_t> & metaKey,FLAG flag,const std::vector<uint8_t> & val)262 Status KvStoreMetaManager::CheckUpdateServiceMeta(const std::vector<uint8_t> &metaKey, FLAG flag,
263                                                   const std::vector<uint8_t> &val)
264 {
265     ZLOGD("begin.");
266     auto &metaDelegate = GetMetaKvStore();
267     if (metaDelegate == nullptr) {
268         ZLOGE("GetMetaKvStore return nullptr.");
269         return Status::DB_ERROR;
270     }
271 
272     DistributedDB::Key dbKey = metaKey;
273     DistributedDB::Value dbValue = val;
274     DistributedDB::DBStatus dbStatus;
275     DistributedDB::CipherPassword dbPassword;
276     std::initializer_list<std::string> backList = {META_DB_APP_ID, "_", Constant::SERVICE_META_DB_NAME};
277     std::string backupName = Constant::Concatenate(backList);
278     std::initializer_list<std::string> backFullList = {metaDBDirectory_, "/backup/",
279         BackupHandler::GetHashedBackupName(backupName)};
280     auto backupFullName = Constant::Concatenate(backFullList);
281 
282     switch (flag) {
283         case UPDATE:
284             dbStatus = metaDelegate->Put(dbKey, dbValue);
285             metaDelegate->Export(backupFullName, dbPassword);
286             break;
287         case DELETE:
288             dbStatus = metaDelegate->Delete(dbKey);
289             metaDelegate->Export(backupFullName, dbPassword);
290             break;
291         case CHECK_EXIST:
292             dbStatus = metaDelegate->Get(dbKey, dbValue);
293             break;
294         case UPDATE_LOCAL:
295             dbStatus = metaDelegate->PutLocal(dbKey, dbValue);
296             metaDelegate->Export(backupFullName, dbPassword);
297             break;
298         case DELETE_LOCAL:
299             dbStatus = metaDelegate->DeleteLocal(dbKey);
300             metaDelegate->Export(backupFullName, dbPassword);
301             break;
302         case CHECK_EXIST_LOCAL:
303             dbStatus = metaDelegate->GetLocal(dbKey, dbValue);
304             break;
305         default:
306             break;
307     }
308     ZLOGI("Flag: %{public}d status: %{public}d", static_cast<int>(flag), static_cast<int>(dbStatus));
309     SyncMeta();
310     return (dbStatus != DistributedDB::DBStatus::OK) ? Status::DB_ERROR : Status::SUCCESS;
311 }
312 
GenerateRootKey()313 Status KvStoreMetaManager::GenerateRootKey()
314 {
315     ZLOGI("GenerateRootKey.");
316     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) };
317     struct HksParamSet *paramSet = nullptr;
318     int32_t ret = HksInitParamSet(&paramSet);
319     if (ret != HKS_SUCCESS) {
320         ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
321         return Status::ERROR;
322     }
323 
324     struct HksParam genKeyParams[] = {
325         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
326         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
327         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
328         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
329         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
330         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
331     };
332 
333     ret = HksAddParams(paramSet, genKeyParams, sizeof(genKeyParams) / sizeof(genKeyParams[0]));
334     if (ret != HKS_SUCCESS) {
335         ZLOGE("HksAddParams failed with error %{public}d", ret);
336         HksFreeParamSet(&paramSet);
337         return Status::ERROR;
338     }
339 
340     ret = HksBuildParamSet(&paramSet);
341     if (ret != HKS_SUCCESS) {
342         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
343         HksFreeParamSet(&paramSet);
344         return Status::ERROR;
345     }
346 
347     ret = HksGenerateKey(&rootKeyName, paramSet, NULL);
348     if (ret != HKS_SUCCESS) {
349         ZLOGE("HksGenerateKey failed with error %{public}d", ret);
350         HksFreeParamSet(&paramSet);
351         return Status::ERROR;
352     }
353     HksFreeParamSet(&paramSet);
354 
355     auto &metaDelegate = GetMetaKvStore();
356     if (metaDelegate == nullptr) {
357         ZLOGE("GetMetaKvStore return nullptr.");
358         return Status::DB_ERROR;
359     }
360 
361     DistributedDB::Key dbKey = std::vector<uint8_t>(Constant::ROOT_KEY_GENERATED.begin(),
362         Constant::ROOT_KEY_GENERATED.end());
363     if (metaDelegate->PutLocal(dbKey, {ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS)}) !=
364         DistributedDB::DBStatus::OK) {
365         return Status::ERROR;
366     }
367     ZLOGI("GenerateRootKey Succeed.");
368     return Status::SUCCESS;
369 }
370 
CheckRootKeyExist()371 Status KvStoreMetaManager::CheckRootKeyExist()
372 {
373     ZLOGI("GenerateRootKey.");
374     auto &metaDelegate = GetMetaKvStore();
375     if (metaDelegate == nullptr) {
376         ZLOGE("GetMetaKvStore return nullptr.");
377         return Status::DB_ERROR;
378     }
379 
380     DistributedDB::Key dbKey = std::vector<uint8_t>(Constant::ROOT_KEY_GENERATED.begin(),
381                                                     Constant::ROOT_KEY_GENERATED.end());
382     DistributedDB::Value dbValue;
383     if (metaDelegate->GetLocal(dbKey, dbValue) == DistributedDB::DBStatus::OK) {
384         ZLOGI("root key exist.");
385         return Status::SUCCESS;
386     }
387     return Status::ERROR;
388 }
389 
EncryptWorkKey(const std::vector<uint8_t> & key)390 std::vector<uint8_t> KvStoreMetaManager::EncryptWorkKey(const std::vector<uint8_t> &key)
391 {
392     struct HksBlob blobAad = { uint32_t(vecAad_.size()), &(vecAad_[0]) };
393     struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), &(vecNonce_[0]) };
394     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) };
395     struct HksBlob plainKey = { uint32_t(key.size()), const_cast<uint8_t *>(&(key[0])) };
396     uint8_t cipherBuf[256] = { 0 };
397     struct HksBlob encryptedKey = { sizeof(cipherBuf), cipherBuf };
398     std::vector<uint8_t> encryptedKeyVec;
399     struct HksParamSet *encryptParamSet = nullptr;
400     int32_t ret = HksInitParamSet(&encryptParamSet);
401     if (ret != HKS_SUCCESS) {
402         ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
403         return {};
404     }
405     struct HksParam encryptParams[] = {
406         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
407         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
408         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
409         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
410         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
411         { .tag = HKS_TAG_NONCE, .blob = blobNonce },
412         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
413     };
414     ret = HksAddParams(encryptParamSet, encryptParams, sizeof(encryptParams) / sizeof(encryptParams[0]));
415     if (ret != HKS_SUCCESS) {
416         ZLOGE("HksAddParams failed with error %{public}d", ret);
417         HksFreeParamSet(&encryptParamSet);
418         return {};
419     }
420 
421     ret = HksBuildParamSet(&encryptParamSet);
422     if (ret != HKS_SUCCESS) {
423         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
424         HksFreeParamSet(&encryptParamSet);
425         return {};
426     }
427 
428     ret = HksEncrypt(&rootKeyName, encryptParamSet, &plainKey, &encryptedKey);
429     if (ret != HKS_SUCCESS) {
430         ZLOGE("HksEncrypt failed with error %{public}d", ret);
431         HksFreeParamSet(&encryptParamSet);
432         return {};
433     }
434     (void)HksFreeParamSet(&encryptParamSet);
435 
436     for (uint32_t i = 0; i < encryptedKey.size; i++) {
437         encryptedKeyVec.push_back(encryptedKey.data[i]);
438     }
439     return encryptedKeyVec;
440 }
441 
DecryptWorkKey(const std::vector<uint8_t> & encryptedKey,std::vector<uint8_t> & key)442 bool KvStoreMetaManager::DecryptWorkKey(const std::vector<uint8_t> &encryptedKey, std::vector<uint8_t> &key)
443 {
444     struct HksBlob blobAad = { uint32_t(vecAad_.size()), &(vecAad_[0]) };
445     struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), &(vecNonce_[0]) };
446     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) };
447     struct HksBlob encryptedKeyBlob = { uint32_t(encryptedKey.size()), const_cast<uint8_t *>(&(encryptedKey[0])) };
448     uint8_t plainBuf[256] = { 0 };
449     struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
450     struct HksParamSet *decryptParamSet = nullptr;
451     int32_t ret = HksInitParamSet(&decryptParamSet);
452     if (ret != HKS_SUCCESS) {
453         ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
454         return false;
455     }
456     struct HksParam decryptParams[] = {
457         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
458         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
459         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
460         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
461         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
462         { .tag = HKS_TAG_NONCE, .blob = blobNonce },
463         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
464     };
465     ret = HksAddParams(decryptParamSet, decryptParams, sizeof(decryptParams) / sizeof(decryptParams[0]));
466     if (ret !=  HKS_SUCCESS) {
467         ZLOGE("HksAddParams failed with error %{public}d", ret);
468         HksFreeParamSet(&decryptParamSet);
469         return false;
470     }
471 
472     ret = HksBuildParamSet(&decryptParamSet);
473     if (ret != HKS_SUCCESS) {
474         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
475         HksFreeParamSet(&decryptParamSet);
476         return false;
477     }
478 
479     ret = HksDecrypt(&rootKeyName, decryptParamSet, &encryptedKeyBlob, &plainKeyBlob);
480     if (ret != HKS_SUCCESS) {
481         ZLOGW("HksDecrypt failed with error %{public}d", ret);
482         HksFreeParamSet(&decryptParamSet);
483         return false;
484     }
485     (void)HksFreeParamSet(&decryptParamSet);
486 
487     for (uint32_t i = 0; i < plainKeyBlob.size; i++) {
488         key.push_back(plainKeyBlob.data[i]);
489     }
490     return true;
491 }
492 
WriteSecretKeyToMeta(const std::vector<uint8_t> & metaKey,const std::vector<uint8_t> & key)493 Status KvStoreMetaManager::WriteSecretKeyToMeta(const std::vector<uint8_t> &metaKey, const std::vector<uint8_t> &key)
494 {
495     ZLOGD("start");
496     auto &metaDelegate = GetMetaKvStore();
497     if (metaDelegate == nullptr) {
498         ZLOGE("GetMetaKvStore return nullptr.");
499         return Status::DB_ERROR;
500     }
501 
502     SecretKeyMetaData secretKey;
503     secretKey.kvStoreType = KvStoreType::DEVICE_COLLABORATION;
504     secretKey.timeValue = TransferTypeToByteArray<time_t>(system_clock::to_time_t(system_clock::now()));
505     secretKey.secretKey = EncryptWorkKey(key);
506     if (secretKey.secretKey.empty()) {
507         ZLOGE("encrypt work key error.");
508         return Status::CRYPT_ERROR;
509     }
510 
511     DistributedDB::DBStatus dbStatus = metaDelegate->PutLocal(metaKey, secretKey);
512     if (dbStatus != DistributedDB::DBStatus::OK) {
513         ZLOGE("end with %d", static_cast<int>(dbStatus));
514         return Status::DB_ERROR;
515     } else {
516         ZLOGD("normal end");
517         return Status::SUCCESS;
518     }
519 }
520 
WriteSecretKeyToFile(const std::string & secretKeyFile,const std::vector<uint8_t> & key)521 Status KvStoreMetaManager::WriteSecretKeyToFile(const std::string &secretKeyFile, const std::vector<uint8_t> &key)
522 {
523     ZLOGD("start");
524     std::vector<uint8_t> secretKey = EncryptWorkKey(key);
525     if (secretKey.empty()) {
526         ZLOGW("encrypt work key error.");
527         return Status::CRYPT_ERROR;
528     }
529     std::string dbDir = secretKeyFile.substr(0, secretKeyFile.find_last_of('/'));
530     if (!ForceCreateDirectory(dbDir)) {
531         return Status::ERROR;
532     }
533 
534     std::vector<uint8_t> secretKeyInByte =
535         TransferTypeToByteArray<time_t>(system_clock::to_time_t(system_clock::now()));
536     std::vector<char> secretKeyInChar;
537     secretKeyInChar.insert(secretKeyInChar.end(), secretKeyInByte.begin(), secretKeyInByte.end());
538     secretKeyInChar.insert(secretKeyInChar.end(), secretKey.begin(), secretKey.end());
539     if (SaveBufferToFile(secretKeyFile, secretKeyInChar)) {
540         ZLOGD("normal end");
541         return Status::SUCCESS;
542     }
543     ZLOGW("failure end");
544     return Status::ERROR;
545 }
546 
RemoveSecretKey(pid_t uid,const std::string & bundleName,const std::string & storeId)547 Status KvStoreMetaManager::RemoveSecretKey(pid_t uid, const std::string &bundleName, const std::string &storeId)
548 {
549     auto &metaDelegate = GetMetaKvStore();
550     if (metaDelegate == nullptr) {
551         ZLOGE("GetMetaKvStore return nullptr.");
552         return Status::DB_ERROR;
553     }
554     const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
555     Status status = Status::SUCCESS;
556     DistributedDB::Key secretDbKey = GetMetaKey(userId, "default", bundleName, storeId, "KEY");
557     DistributedDB::Key secretSingleDbKey = GetMetaKey(userId, "default", bundleName, storeId, "SINGLE_KEY");
558     DistributedDB::DBStatus dbStatus = metaDelegate->DeleteLocal(secretDbKey);
559     if (dbStatus != DistributedDB::DBStatus::OK) {
560         ZLOGE("delete secretDbKey fail Status %d", static_cast<int>(dbStatus));
561         status = Status::DB_ERROR;
562     }
563     dbStatus = metaDelegate->DeleteLocal(secretSingleDbKey);
564     if (dbStatus != DistributedDB::DBStatus::OK) {
565         ZLOGE("delete secretSingleDbKey fail Status %d", static_cast<int>(dbStatus));
566         status = Status::DB_ERROR;
567     }
568 
569     for (int32_t pathType = KvStoreAppManager::PATH_DE; pathType < KvStoreAppManager::PATH_TYPE_MAX; ++pathType) {
570         std::string keyFile = GetSecretKeyFile(userId, bundleName, storeId, pathType);
571         if (!RemoveFile(keyFile)) {
572             ZLOGW("remove secret key file %{public}s fail.", keyFile.c_str());
573             status = Status::DB_ERROR;
574         }
575         keyFile = GetSecretSingleKeyFile(userId, bundleName, storeId, pathType);
576         if (!RemoveFile(keyFile)) {
577             ZLOGW("remove secretKeyFile Single fail.");
578             status = Status::DB_ERROR;
579         }
580     }
581     return status;
582 }
583 
GetSecretKeyFromMeta(const std::vector<uint8_t> & metaSecretKey,std::vector<uint8_t> & key,bool & outdated)584 Status KvStoreMetaManager::GetSecretKeyFromMeta(const std::vector<uint8_t> &metaSecretKey, std::vector<uint8_t> &key,
585                                                 bool &outdated)
586 {
587     auto &metaDelegate = GetMetaKvStore();
588     if (metaDelegate == nullptr) {
589         ZLOGE("GetMetaKvStore return nullptr.");
590         return Status::DB_ERROR;
591     }
592 
593     DistributedDB::Key dbKey = metaSecretKey;
594     DistributedDB::Value dbValue;
595     DistributedDB::DBStatus dbStatus = metaDelegate->GetLocal(dbKey, dbValue);
596     if (dbStatus != DistributedDB::DBStatus::OK) {
597         return Status::DB_ERROR;
598     }
599     std::string jsonStr(dbValue.begin(), dbValue.end());
600     json jsonObj = json::parse(jsonStr, nullptr, false);
601     if (jsonObj.is_discarded()) {
602         ZLOGE("parse json error");
603         return Status::ERROR;
604     }
605     SecretKeyMetaData sKeyValue(jsonObj);
606     time_t createTime = TransferByteArrayToType<time_t>(sKeyValue.timeValue);
607     DecryptWorkKey(sKeyValue.secretKey, key);
608     system_clock::time_point createTimeChrono = system_clock::from_time_t(createTime);
609     outdated = ((createTimeChrono + hours(HOURS_PER_YEAR)) < system_clock::now()); // secretKey valid for 1 year.
610     return Status::SUCCESS;
611 }
612 
RecoverSecretKeyFromFile(const std::string & secretKeyFile,const std::vector<uint8_t> & metaSecretKey,std::vector<uint8_t> & key,bool & outdated)613 Status KvStoreMetaManager::RecoverSecretKeyFromFile(const std::string &secretKeyFile,
614                                                     const std::vector<uint8_t> &metaSecretKey,
615                                                     std::vector<uint8_t> &key, bool &outdated)
616 {
617     std::vector<char> fileBuffer;
618     if (!LoadBufferFromFile(secretKeyFile, fileBuffer)) {
619         return Status::ERROR;
620     }
621     if (fileBuffer.size() < sizeof(time_t) / sizeof(uint8_t) + KEY_SIZE) {
622         return Status::ERROR;
623     }
624     std::vector<uint8_t> timeVec;
625     auto iter = fileBuffer.begin();
626     for (int i = 0; i < static_cast<int>(sizeof(time_t) / sizeof(uint8_t)); i++) {
627         timeVec.push_back(*iter);
628         iter++;
629     }
630     time_t createTime = TransferByteArrayToType<time_t>(timeVec);
631     SecretKeyMetaData secretKey;
632     secretKey.secretKey.insert(secretKey.secretKey.end(), iter, fileBuffer.end());
633     if (!DecryptWorkKey(secretKey.secretKey, key)) {
634         return Status::ERROR;
635     }
636     system_clock::time_point createTimeChrono = system_clock::from_time_t(createTime);
637     outdated = ((createTimeChrono + hours(HOURS_PER_YEAR)) < system_clock::now()); // secretKey valid for 1 year.
638 
639     auto &metaDelegate = GetMetaKvStore();
640     if (metaDelegate == nullptr) {
641         ZLOGE("GetMetaKvStore return nullptr.");
642         return Status::DB_ERROR;
643     }
644 
645     secretKey.timeValue = TransferTypeToByteArray<time_t>(createTime);
646     secretKey.kvStoreType = KvStoreType::DEVICE_COLLABORATION;
647 
648     DistributedDB::DBStatus dbStatus = metaDelegate->PutLocal(metaSecretKey, secretKey);
649     if (dbStatus != DistributedDB::DBStatus::OK) {
650         ZLOGE("put work key failed.");
651         return Status::DB_ERROR;
652     }
653     return Status::SUCCESS;
654 }
655 
ReKey(const std::string & userId,const std::string & bundleName,const std::string & storeId,int32_t pathType,sptr<KvStoreImpl> store)656 void KvStoreMetaManager::ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId,
657     int32_t pathType, sptr<KvStoreImpl> store)
658 {
659     if (store == nullptr) {
660         return;
661     }
662     std::vector<uint8_t> key = Crypto::Random(KEY_SIZE);
663     WriteSecretKeyToMeta(GetMetaKey(userId, "default", bundleName, storeId, "KEY"), key);
664     Status status = store->ReKey(key);
665     if (status == Status::SUCCESS) {
666         WriteSecretKeyToFile(GetSecretKeyFile(userId, bundleName, storeId, pathType), key);
667     }
668     key.assign(key.size(), 0);
669 }
670 
ReKey(const std::string & userId,const std::string & bundleName,const std::string & storeId,int32_t pathType,sptr<SingleKvStoreImpl> store)671 void KvStoreMetaManager::ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId,
672     int32_t pathType, sptr<SingleKvStoreImpl> store)
673 {
674     if (store == nullptr) {
675         return;
676     }
677     std::vector<uint8_t> key = Crypto::Random(KEY_SIZE);
678     WriteSecretKeyToMeta(GetMetaKey(userId, "default", bundleName, storeId, "SINGLE_KEY"), key);
679     Status status = store->ReKey(key);
680     if (status == Status::SUCCESS) {
681         WriteSecretKeyToFile(GetSecretSingleKeyFile(userId, bundleName, storeId, pathType), key);
682     }
683     key.assign(key.size(), 0);
684 }
685 
686 // StrategyMetaData###deviceId###deviceAccountID###${groupId}###bundleName###storeId
GetStrategyMetaKey(const StrategyMeta & params,std::string & retVal)687 void KvStoreMetaManager::GetStrategyMetaKey(const StrategyMeta &params, std::string &retVal)
688 {
689     std::vector<std::string> keys = {STRATEGY_META_PREFIX, params.devId, params.devAccId, params.grpId,
690                                      params.bundleName, params.storeId};
691     ConcatWithSharps(keys, retVal);
692 }
693 
ConcatWithSharps(const std::vector<std::string> & params,std::string & retVal)694 void KvStoreMetaManager::ConcatWithSharps(const std::vector<std::string> &params, std::string &retVal)
695 {
696     int32_t len = static_cast<int32_t>(params.size());
697     for (int32_t i = 0; i < len; i++) {
698         retVal.append(params.at(i));
699         if (i != (len - 1)) {
700             retVal.append(Constant::KEY_SEPARATOR);
701         }
702     }
703 }
704 
SaveStrategyMetaEnable(const std::string & key,bool enable)705 Status KvStoreMetaManager::SaveStrategyMetaEnable(const std::string &key, bool enable)
706 {
707     ZLOGD("begin");
708     auto &metaDelegate = GetMetaKvStore();
709     if (metaDelegate == nullptr) {
710         return Status::ERROR;
711     }
712     auto dbkey = std::vector<uint8_t>(key.begin(), key.end());
713     std::vector<uint8_t> values;
714     auto dbStatus = metaDelegate->Get(dbkey, values);
715     if (dbStatus == DistributedDB::DBStatus::NOT_FOUND) {
716         json j;
717         j[CAPABILITY_ENABLED] = enable;
718         std::string json = j.dump();
719         if (metaDelegate->Put(dbkey, std::vector<uint8_t>(json.begin(), json.end())) != DistributedDB::OK) {
720             ZLOGE("save failed.");
721             return Status::DB_ERROR;
722         }
723         ZLOGD("save end");
724     } else if (dbStatus == DistributedDB::DBStatus::OK) {
725         std::string jsonStr(values.begin(), values.end());
726         auto jsonObj = json::parse(jsonStr, nullptr, false);
727         if (jsonObj.is_discarded()) {
728             ZLOGE("invalid json.");
729             return Status::ERROR;
730         }
731         jsonObj[CAPABILITY_ENABLED] = enable;
732         std::string json = jsonObj.dump();
733         if (metaDelegate->Put(dbkey, std::vector<uint8_t>(json.begin(), json.end())) != DistributedDB::OK) {
734             ZLOGE("save failed.");
735             return Status::DB_ERROR;
736         }
737         ZLOGD("update end");
738     } else {
739         ZLOGE("failed.");
740         return Status::DB_ERROR;
741     }
742     SyncMeta();
743     return Status::SUCCESS;
744 }
745 
SaveStrategyMetaLabels(const std::string & key,const std::vector<std::string> & localLabels,const std::vector<std::string> & remoteSupportLabels)746 Status KvStoreMetaManager::SaveStrategyMetaLabels(const std::string &key,
747                                                   const std::vector<std::string> &localLabels,
748                                                   const std::vector<std::string> &remoteSupportLabels)
749 {
750     auto &metaDelegate = GetMetaKvStore();
751     if (metaDelegate == nullptr) {
752         return Status::ERROR;
753     }
754     auto dbkey = std::vector<uint8_t>(key.begin(), key.end());
755     std::vector<uint8_t> values;
756     auto dbStatus = metaDelegate->Get(dbkey, values);
757     if (dbStatus == DistributedDB::DBStatus::NOT_FOUND) {
758         json j;
759         j[CAPABILITY_RANGE][LOCAL_LABEL] = localLabels;
760         j[CAPABILITY_RANGE][REMOTE_LABEL] = remoteSupportLabels;
761         std::string metaJson = j.dump();
762         if (metaDelegate->Put(dbkey, std::vector<uint8_t>(metaJson.begin(), metaJson.end())) != DistributedDB::OK) {
763             ZLOGE("save failed.");
764             return Status::DB_ERROR;
765         }
766     } else if (dbStatus == DistributedDB::DBStatus::OK) {
767         std::string jsonStr(values.begin(), values.end());
768         auto j = json::parse(jsonStr, nullptr, false);
769         if (j.is_discarded()) {
770             return Status::ERROR;
771         }
772         j[CAPABILITY_RANGE][LOCAL_LABEL] = localLabels;
773         j[CAPABILITY_RANGE][REMOTE_LABEL] = remoteSupportLabels;
774         std::string metaJson = j.dump();
775         if (metaDelegate->Put(dbkey, std::vector<uint8_t>(metaJson.begin(), metaJson.end())) != DistributedDB::OK) {
776             ZLOGE("save failed.");
777             return Status::DB_ERROR;
778         }
779     } else {
780         ZLOGE("failed.");
781         return Status::DB_ERROR;
782     }
783     SyncMeta();
784     return Status::SUCCESS;
785 }
786 
DeleteStrategyMeta(const std::string & bundleName,const std::string & storeId,const std::string & userId)787 Status KvStoreMetaManager::DeleteStrategyMeta(const std::string &bundleName, const std::string &storeId,
788                                               const std::string &userId)
789 {
790     ZLOGI("start");
791     std::string key;
792     std::string devId = DeviceKvStoreImpl::GetLocalDeviceId();
793     if (devId.empty()) {
794         ZLOGE("get device id empty.");
795         return Status::ERROR;
796     }
797     StrategyMeta params = {devId, userId, Constant::DEFAULT_GROUP_ID, bundleName, storeId};
798     GetStrategyMetaKey(params, key);
799 
800     auto &metaDelegate = GetMetaKvStore();
801     if (metaDelegate == nullptr) {
802         return Status::ERROR;
803     }
804     auto dbkey = std::vector<uint8_t>(key.begin(), key.end());
805     auto dbStatus = metaDelegate->Delete(dbkey);
806     if (dbStatus != DistributedDB::DBStatus::OK) {
807         ZLOGE("failed.");
808         return Status::DB_ERROR;
809     }
810     return Status::SUCCESS;
811 }
812 
SyncMeta()813 void KvStoreMetaManager::SyncMeta()
814 {
815     std::vector<std::string> devs;
816     auto deviceList = KvStoreUtils::GetProviderInstance().GetDeviceList();
817     for (auto const &dev : deviceList) {
818         devs.push_back(dev.deviceId);
819     }
820 
821     if (devs.empty()) {
822         ZLOGW("meta db sync fail, devices is empty.");
823         return;
824     }
825 
826     auto &metaDelegate = GetMetaKvStore();
827     if (metaDelegate == nullptr) {
828         ZLOGW("meta db sync failed.");
829         return;
830     }
831     auto onComplete = [this](const std::map<std::string, DistributedDB::DBStatus> &) {
832         ZLOGD("meta db sync complete.");
833         cv_.notify_all();
834         ZLOGD("meta db sync complete end.");
835     };
836     auto dbStatus = metaDelegate->Sync(devs, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, onComplete);
837     if (dbStatus != DistributedDB::OK) {
838         ZLOGW("meta db sync error %d.", dbStatus);
839     }
840 }
841 
SubscribeMetaKvStore()842 void KvStoreMetaManager::SubscribeMetaKvStore()
843 {
844     auto &metaDelegate = GetMetaKvStore();
845     if (metaDelegate == nullptr) {
846         ZLOGW("register meta observer failed.");
847         return;
848     }
849 
850     int mode = DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN;
851     auto dbStatus = metaDelegate->RegisterObserver(DistributedDB::Key(), mode, &metaObserver_);
852     if (dbStatus != DistributedDB::DBStatus::OK) {
853         ZLOGW("register meta observer failed :%{public}d.", dbStatus);
854     }
855 }
856 
CheckSyncPermission(const std::string & userId,const std::string & appId,const std::string & storeId,uint8_t flag,const std::string & remoteId)857 Status KvStoreMetaManager::CheckSyncPermission(const std::string &userId, const std::string &appId,
858                                                const std::string &storeId, uint8_t flag, const std::string &remoteId)
859 {
860     std::string localId = DeviceKvStoreImpl::GetLocalDeviceId();
861     if (localId.empty()) {
862         ZLOGE("get device id empty.");
863         return Status::ERROR;
864     }
865     KvStoreMetaData localMeta;
866     auto queryStatus = QueryKvStoreMetaDataByDeviceIdAndAppId(localId, appId, localMeta);
867     if (queryStatus != Status::SUCCESS) {
868         ZLOGE("get kvstore by deviceId and appId empty.");
869         return Status::ERROR;
870     }
871 
872     StrategyMeta params = {localId, localMeta.deviceAccountId, Constant::DEFAULT_GROUP_ID, localMeta.bundleName,
873                            storeId};
874     std::string localKey;
875     GetStrategyMetaKey(params, localKey);
876     if (localKey.empty()) {
877         ZLOGE("get key empty.");
878         return Status::ERROR;
879     }
880 
881     std::string remoteKey;
882     params.devId = remoteId;
883     GetStrategyMetaKey(params, remoteKey);
884     if (remoteKey.empty()) {
885         ZLOGE("get key empty.");
886         return Status::ERROR;
887     }
888 
889     std::map<std::string, std::vector<std::string>> localStrategies;
890     std::map<std::string, std::vector<std::string>> remoteStrategies;
891     GetStategyMeta(localKey, localStrategies);
892     GetStategyMeta(remoteKey, remoteStrategies);
893     if (localStrategies.empty() || remoteStrategies.empty()) {
894         ZLOGD("no range, sync permission success.");
895         return Status::SUCCESS;
896     }
897 
898     auto localSupportRemotes = localStrategies.find(REMOTE_LABEL);
899     auto remoteSupportLocals = remoteStrategies.find(LOCAL_LABEL);
900     if (localSupportRemotes != localStrategies.end() && remoteSupportLocals != remoteStrategies.end()) {
901         std::vector<std::string> lremotes = localSupportRemotes->second;
902         for (auto const &lremote : lremotes) {
903             std::vector<std::string> rlocals = remoteSupportLocals->second;
904             if (std::find(rlocals.begin(), rlocals.end(), lremote) != rlocals.end()) {
905                 ZLOGD("find range, sync permission success.");
906                 return Status::SUCCESS;
907             }
908         }
909     }
910     ZLOGD("check strategy failed, sync permission fail.");
911     return Status::ERROR;
912 }
913 
GetStategyMeta(const std::string & key,std::map<std::string,std::vector<std::string>> & strategies)914 Status KvStoreMetaManager::GetStategyMeta(const std::string &key,
915                                           std::map<std::string, std::vector<std::string>> &strategies)
916 {
917     ZLOGD("get meta key:%s.", key.c_str());
918     auto &metaDelegate = GetMetaKvStore();
919     if (metaDelegate == nullptr) {
920         ZLOGW("get delegate error.");
921         return Status::ERROR;
922     }
923 
924     DistributedDB::Value values;
925     auto dbStatus = metaDelegate->Get(DistributedDB::Key(key.begin(), key.end()), values);
926     if (dbStatus != DistributedDB::DBStatus::OK) {
927         ZLOGW("get meta error %d.", dbStatus);
928         return Status::DB_ERROR;
929     }
930 
931     std::string jsonStr(values.begin(), values.end());
932     auto jsonObj = json::parse(jsonStr, nullptr, false);
933     if (jsonObj.is_discarded()) {
934         jsonObj = json::parse(jsonStr.substr(1), nullptr, false); // 1 drop for a
935         if (jsonObj.is_discarded()) {
936             ZLOGW("get meta parse error.");
937             return Status::ERROR;
938         }
939     }
940 
941     auto range = jsonObj.find(CAPABILITY_RANGE);
942     if (range == jsonObj.end()) {
943         ZLOGW("get meta parse no range.");
944         return Status::ERROR;
945     }
946 
947     auto local = range->find(LOCAL_LABEL);
948     if (local != range->end()) {
949         json obj = *local;
950         if (obj.is_array()) {
951             std::vector<std::string> v;
952             obj.get_to(v);
953             strategies.insert({LOCAL_LABEL, v});
954         }
955     }
956     auto remote = range->find(REMOTE_LABEL);
957     if (remote != range->end()) {
958         json obj = *remote;
959         if (obj.is_array()) {
960             std::vector<std::string> v;
961             obj.get_to(v);
962             strategies.insert({REMOTE_LABEL, v});
963         }
964     }
965     return Status::SUCCESS;
966 }
967 
~KvStoreMetaObserver()968 KvStoreMetaManager::KvStoreMetaObserver::~KvStoreMetaObserver()
969 {
970     ZLOGW("meta observer destruct.");
971 }
972 
OnChange(const DistributedDB::KvStoreChangedData & data)973 void KvStoreMetaManager::KvStoreMetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data)
974 {
975     ZLOGD("on data change.");
976     HandleChanges(CHANGE_FLAG::INSERT, data.GetEntriesInserted());
977     HandleChanges(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated());
978     HandleChanges(CHANGE_FLAG::DELETE, data.GetEntriesDeleted());
979     KvStoreMetaManager::GetInstance().SyncMeta();
980 }
981 
HandleChanges(CHANGE_FLAG flag,const std::list<DistributedDB::Entry> & entries)982 void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges(
983     CHANGE_FLAG flag, const std::list<DistributedDB::Entry> &entries)
984 {
985     for (const auto &entry : entries) {
986         std::string key(entry.key.begin(), entry.key.end());
987         for (const auto &item : handlerMap_) {
988             ZLOGI("flag:%{public}d, key:%{public}s", flag, Anonymous::Change(key).c_str());
989             if (key.find(item.first) == 0) {
990                 item.second(entry.key, entry.value, flag);
991             }
992         }
993     }
994 }
995 
OnDeviceChanged(const AppDistributedKv::DeviceInfo & info,const AppDistributedKv::DeviceChangeType & type) const996 void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged(
997     const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const
998 {
999     if (type == AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE) {
1000         ZLOGD("offline ignore.");
1001         return;
1002     }
1003 
1004     ZLOGD("begin to sync.");
1005     KvStoreMetaManager::GetInstance().SyncMeta();
1006     ZLOGD("end.");
1007 }
1008 
GetChangeLevelType() const1009 AppDistributedKv::ChangeLevelType KvStoreMetaManager::MetaDeviceChangeListenerImpl::GetChangeLevelType() const
1010 {
1011     return AppDistributedKv::ChangeLevelType::HIGH;
1012 }
1013 
QueryKvStoreMetaDataByDeviceIdAndAppId(const std::string & devId,const std::string & appId,KvStoreMetaData & val)1014 Status KvStoreMetaManager::QueryKvStoreMetaDataByDeviceIdAndAppId(const std::string &devId, const std::string &appId,
1015                                                                   KvStoreMetaData &val)
1016 {
1017     ZLOGD("query meta start.");
1018     auto &metaDelegate = GetMetaKvStore();
1019     if (metaDelegate == nullptr) {
1020         ZLOGW("get delegate error.");
1021         return Status::ERROR;
1022     }
1023     std::string dbPrefixKey;
1024     std::string prefix = KvStoreMetaRow::KEY_PREFIX;
1025     ConcatWithSharps({prefix, devId}, dbPrefixKey);
1026     std::vector<DistributedDB::Entry> values;
1027     auto status = metaDelegate->GetEntries(DistributedDB::Key(dbPrefixKey.begin(), dbPrefixKey.end()), values);
1028     if (status != DistributedDB::DBStatus::OK) {
1029         status = metaDelegate->GetEntries(DistributedDB::Key(prefix.begin(), prefix.end()), values);
1030         if (status != DistributedDB::DBStatus::OK) {
1031             ZLOGW("query db failed key:%s, ret:%d.", dbPrefixKey.c_str(), static_cast<int>(status));
1032             return Status::ERROR;
1033         }
1034     }
1035 
1036     for (auto const &entry : values) {
1037         std::string str(entry.value.begin(), entry.value.end());
1038         json j = Serializable::ToJson(str);
1039         val.Unmarshal(j);
1040         if (val.appId == appId) {
1041             ZLOGD("query meta success.");
1042             return Status::SUCCESS;
1043         }
1044     }
1045 
1046     ZLOGW("find meta failed id: %{public}s", appId.c_str());
1047     return Status::ERROR;
1048 }
1049 
GetKvStoreMeta(const std::vector<uint8_t> & metaKey,KvStoreMetaData & metaData)1050 Status KvStoreMetaManager::GetKvStoreMeta(const std::vector<uint8_t> &metaKey, KvStoreMetaData &metaData)
1051 {
1052     ZLOGD("begin.");
1053     auto &metaDelegate = GetMetaKvStore();
1054     if (metaDelegate == nullptr) {
1055         ZLOGE("GetMetaKvStore return nullptr.");
1056         return Status::DB_ERROR;
1057     }
1058     DistributedDB::Value dbValue;
1059     DistributedDB::DBStatus dbStatus = metaDelegate->Get(metaKey, dbValue);
1060     ZLOGI("status: %{public}d", static_cast<int>(dbStatus));
1061     if (dbStatus == DistributedDB::DBStatus::NOT_FOUND) {
1062         ZLOGI("key not found.");
1063         return Status::KEY_NOT_FOUND;
1064     }
1065     if (dbStatus != DistributedDB::DBStatus::OK) {
1066         ZLOGE("GetKvStoreMeta failed.");
1067         return Status::DB_ERROR;
1068     }
1069 
1070     std::string jsonStr(dbValue.begin(), dbValue.end());
1071     metaData.Unmarshal(Serializable::ToJson(jsonStr));
1072     return Status::SUCCESS;
1073 }
1074 
Marshal() const1075 std::string KvStoreMetaData::Marshal() const
1076 {
1077     json jval = {
1078         {DEVICE_ID, deviceId},
1079         {USER_ID, userId},
1080         {APP_ID, appId},
1081         {STORE_ID, storeId},
1082         {BUNDLE_NAME, bundleName},
1083         {KVSTORE_TYPE, kvStoreType},
1084         {ENCRYPT, isEncrypt},
1085         {BACKUP, isBackup},
1086         {AUTO_SYNC, isAutoSync},
1087         {SCHEMA, schema},
1088         {DATA_DIR, dataDir}, // Reserved for kvstore data storage directory.
1089         {APP_TYPE, appType}, // Reserved for the APP type which used kvstore.
1090         {DEVICE_ACCOUNT_ID, deviceAccountId},
1091         {UID, uid},
1092         {VERSION, version},
1093         {SECURITY_LEVEL, securityLevel},
1094         {DIRTY_KEY, isDirty},
1095     };
1096     return jval.dump();
1097 }
1098 
ToJson(const std::string & jsonStr)1099 json Serializable::ToJson(const std::string &jsonStr)
1100 {
1101     json jsonObj = json::parse(jsonStr, nullptr, false);
1102     if (jsonObj.is_discarded()) {
1103         // if the string size is less than 1, means the string is invalid.
1104         if (jsonStr.empty()) {
1105             ZLOGE("empty jsonStr, error.");
1106             return {};
1107         }
1108         jsonObj = json::parse(jsonStr.substr(1), nullptr, false); // drop first char to adapt A's value;
1109         if (jsonObj.is_discarded()) {
1110             ZLOGE("parse jsonStr, error.");
1111             return {};
1112         }
1113     }
1114     return jsonObj;
1115 }
1116 
Unmarshal(const nlohmann::json & jObject)1117 void KvStoreMetaData::Unmarshal(const nlohmann::json &jObject)
1118 {
1119     kvStoreType = Serializable::GetVal<KvStoreType>(jObject, KVSTORE_TYPE, json::value_t::number_unsigned, kvStoreType);
1120     isBackup = Serializable::GetVal<bool>(jObject, BACKUP, json::value_t::boolean, isBackup);
1121     isEncrypt = Serializable::GetVal<bool>(jObject, ENCRYPT, json::value_t::boolean, isEncrypt);
1122     isAutoSync = Serializable::GetVal<bool>(jObject, AUTO_SYNC, json::value_t::boolean, isAutoSync);
1123     appId = Serializable::GetVal<std::string>(jObject, APP_ID, json::value_t::string, appId);
1124     userId = Serializable::GetVal<std::string>(jObject, USER_ID, json::value_t::string, userId);
1125     storeId = Serializable::GetVal<std::string>(jObject, STORE_ID, json::value_t::string, storeId);
1126     bundleName = Serializable::GetVal<std::string>(jObject, BUNDLE_NAME, json::value_t::string, bundleName);
1127     deviceAccountId = Serializable::GetVal<std::string>(jObject, DEVICE_ACCOUNT_ID, json::value_t::string,
1128                                                         deviceAccountId);
1129     dataDir = Serializable::GetVal<std::string>(jObject, DATA_DIR, json::value_t::string, dataDir);
1130     appType = Serializable::GetVal<std::string>(jObject, APP_TYPE, json::value_t::string, appType);
1131     deviceId = Serializable::GetVal<std::string>(jObject, DEVICE_ID, json::value_t::string, deviceId);
1132     schema = Serializable::GetVal<std::string>(jObject, SCHEMA, json::value_t::string, schema);
1133     uid = Serializable::GetVal<int32_t>(jObject, UID, json::value_t::number_unsigned, uid);
1134     version = Serializable::GetVal<uint32_t>(jObject, VERSION, json::value_t::number_unsigned, version);
1135     securityLevel = Serializable::GetVal<uint32_t>(jObject, SECURITY_LEVEL, json::value_t::number_unsigned,
1136                                                    securityLevel);
1137     isDirty = Serializable::GetVal<uint32_t>(jObject, DIRTY_KEY, json::value_t::boolean, isDirty);
1138 }
1139 
1140 template<typename T>
GetVal(const json & j,const std::string & name,json::value_t type,const T & val)1141 T Serializable::GetVal(const json &j, const std::string &name, json::value_t type, const T &val)
1142 {
1143     auto it = j.find(name);
1144     if (it != j.end() && it->type() == type) {
1145         return *it;
1146     }
1147     ZLOGW("not found name:%s.", name.c_str());
1148     return val;
1149 }
1150 
Marshal() const1151 std::vector<uint8_t> SecretKeyMetaData::Marshal() const
1152 {
1153     json jval = {
1154         {TIME, timeValue},
1155         {SKEY, secretKey},
1156         {KVSTORE_TYPE, kvStoreType}
1157     };
1158     auto value = jval.dump();
1159     return std::vector<uint8_t>(value.begin(), value.end());
1160 }
1161 
Unmarshal(const nlohmann::json & jObject)1162 void SecretKeyMetaData::Unmarshal(const nlohmann::json &jObject)
1163 {
1164     timeValue = Serializable::GetVal<std::vector<uint8_t>>(jObject, TIME, json::value_t::array, timeValue);
1165     secretKey = Serializable::GetVal<std::vector<uint8_t>>(jObject, SKEY, json::value_t::array, secretKey);
1166     kvStoreType = Serializable::GetVal<KvStoreType>(jObject, KVSTORE_TYPE, json::value_t::number_unsigned, kvStoreType);
1167 }
1168 
GetFullMetaData(std::map<std::string,MetaData> & entries,enum DatabaseType type)1169 bool KvStoreMetaManager::GetFullMetaData(std::map<std::string, MetaData> &entries, enum DatabaseType type)
1170 {
1171     ZLOGI("start");
1172     auto &metaDelegate = GetMetaKvStore();
1173     if (metaDelegate == nullptr) {
1174         return false;
1175     }
1176 
1177     std::vector<DistributedDB::Entry> kvStoreMetaEntries;
1178     const std::string &metaKey = KvStoreMetaRow::KEY_PREFIX;
1179     DistributedDB::DBStatus dbStatus = metaDelegate->GetEntries({metaKey.begin(), metaKey.end()}, kvStoreMetaEntries);
1180     if (dbStatus != DistributedDB::DBStatus::OK) {
1181         ZLOGE("Get kvstore meta data entries from metaDB failed, dbStatus: %d.", static_cast<int>(dbStatus));
1182         return false;
1183     }
1184 
1185     for (auto const &kvStoreMeta : kvStoreMetaEntries) {
1186         std::string jsonStr(kvStoreMeta.value.begin(), kvStoreMeta.value.end());
1187         ZLOGD("kvStoreMetaData get json: %s", jsonStr.c_str());
1188         auto metaObj = Serializable::ToJson(jsonStr);
1189         MetaData metaData {0};
1190         metaData.kvStoreType = MetaData::GetKvStoreType(metaObj);
1191         if (!(type == KVDB && metaData.kvStoreType < KvStoreType::INVALID_TYPE) &&
1192              !(type == RDB && metaData.kvStoreType >= DistributedRdb::RdbDistributedType::RDB_DEVICE_COLLABORATION)) {
1193             continue;
1194         }
1195 
1196         metaData.kvStoreMetaData.Unmarshal(metaObj);
1197         std::vector<uint8_t> decryptKey;
1198         if (metaData.kvStoreMetaData.isEncrypt) {
1199             ZLOGE("isEncrypt.");
1200             const std::string keyType = ((metaData.kvStoreType == KvStoreType::SINGLE_VERSION) ? "SINGLE_KEY" : "KEY");
1201             const std::vector<uint8_t> metaSecretKey = KvStoreMetaManager::GetInstance().GetMetaKey(
1202                 metaData.kvStoreMetaData.deviceAccountId, "default", metaData.kvStoreMetaData.bundleName,
1203                 metaData.kvStoreMetaData.storeId, keyType);
1204             DistributedDB::Value secretValue;
1205             metaDelegate->GetLocal(metaSecretKey, secretValue);
1206             auto secretObj = Serializable::ToJson({secretValue.begin(), secretValue.end()});
1207             if (secretObj.empty()) {
1208                 ZLOGE("Failed to find SKEY in SecretKeyMetaData.");
1209                 continue;
1210             }
1211             metaData.secretKeyMetaData.Unmarshal(secretObj);
1212             KvStoreMetaManager::GetInstance().DecryptWorkKey(metaData.secretKeyMetaData.secretKey, decryptKey);
1213         }
1214         entries.insert({{kvStoreMeta.key.begin(), kvStoreMeta.key.end()}, {metaData}});
1215         std::fill(decryptKey.begin(), decryptKey.end(), 0);
1216     }
1217 
1218     return true;
1219 }
1220 
GetKvStoreMetaByType(const std::string & name,const std::string & val,KvStoreMetaData & metaData)1221 bool KvStoreMetaManager::GetKvStoreMetaByType(const std::string &name, const std::string &val,
1222                                               KvStoreMetaData &metaData)
1223 {
1224     auto &metaDelegate = GetMetaKvStore();
1225     if (metaDelegate == nullptr) {
1226         return false;
1227     }
1228 
1229     DistributedDB::Key metaKeyPrefix = KvStoreMetaRow::GetKeyFor("");
1230     std::vector<DistributedDB::Entry> metaEntries;
1231     DistributedDB::DBStatus dbStatus = metaDelegate->GetEntries(metaKeyPrefix, metaEntries);
1232     if (dbStatus != DistributedDB::DBStatus::OK) {
1233         ZLOGE("Get meta entries from metaDB failed, dbStatus: %d.", static_cast<int>(dbStatus));
1234         return false;
1235     }
1236 
1237     for (auto const &metaEntry : metaEntries) {
1238         std::string jsonStr(metaEntry.value.begin(), metaEntry.value.end());
1239         ZLOGD("KvStore get json: %s", jsonStr.c_str());
1240         json jsonObj = json::parse(jsonStr, nullptr, false);
1241         if (jsonObj.is_discarded()) {
1242             ZLOGE("parse json error");
1243             continue;
1244         }
1245 
1246         std::string metaTypeVal;
1247         jsonObj[name].get_to(metaTypeVal);
1248         if (metaTypeVal == val) {
1249             metaData.Unmarshal(Serializable::ToJson(jsonStr));
1250         }
1251     }
1252     return true;
1253 }
1254 
GetKvStoreMetaDataByBundleName(const std::string & bundleName,KvStoreMetaData & metaData)1255 bool KvStoreMetaManager::GetKvStoreMetaDataByBundleName(const std::string &bundleName, KvStoreMetaData &metaData)
1256 {
1257     return GetKvStoreMetaByType(KvStoreMetaData::BUNDLE_NAME, bundleName, metaData);
1258 }
1259 
GetKvStoreMetaDataByAppId(const std::string & appId,KvStoreMetaData & metaData)1260 bool KvStoreMetaManager::GetKvStoreMetaDataByAppId(const std::string &appId, KvStoreMetaData &metaData)
1261 {
1262     return GetKvStoreMetaByType(KvStoreMetaData::APP_ID, appId, metaData);
1263 }
1264 } // namespace DistributedKv
1265 } // namespace OHOS
1266