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(¶mSet);
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(¶mSet);
337 return Status::ERROR;
338 }
339
340 ret = HksBuildParamSet(¶mSet);
341 if (ret != HKS_SUCCESS) {
342 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
343 HksFreeParamSet(¶mSet);
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(¶mSet);
351 return Status::ERROR;
352 }
353 HksFreeParamSet(¶mSet);
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 ¶ms, 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> ¶ms, 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