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 #ifndef KVSTORE_META_MANAGER_H 16 #define KVSTORE_META_MANAGER_H 17 18 #include <mutex> 19 #include <nlohmann/json.hpp> 20 21 #include "app_device_status_change_listener.h" 22 #include "kv_store_delegate.h" 23 #include "kv_store_delegate_manager.h" 24 #include "kv_store_task.h" 25 #include "kvstore_impl.h" 26 #include "single_kvstore_impl.h" 27 #include "system_ability.h" 28 #include "types.h" 29 30 namespace OHOS { 31 namespace DistributedKv { 32 enum FLAG { 33 UPDATE, 34 DELETE, 35 CHECK_EXIST, 36 UPDATE_LOCAL, 37 DELETE_LOCAL, 38 CHECK_EXIST_LOCAL, 39 }; 40 41 enum class CHANGE_FLAG { 42 INSERT, 43 UPDATE, 44 DELETE 45 }; 46 47 struct Serializable { 48 using json = nlohmann::json; 49 template<typename T> 50 static T GetVal(const json &j, const std::string &name, json::value_t type, const T &def); 51 static json ToJson(const std::string &jsonStr); 52 }; 53 54 struct StrategyMeta { 55 std::string devId; 56 std::string devAccId; 57 std::string grpId; 58 std::string bundleName; 59 std::string storeId; 60 }; 61 62 struct SecretKeyMetaData { 63 static constexpr const char *SKEY = "skey"; 64 std::vector<uint8_t> timeValue {}; 65 std::vector<uint8_t> secretKey {}; 66 KvStoreType kvStoreType = KvStoreType::INVALID_TYPE; SecretKeyMetaDataSecretKeyMetaData67 SecretKeyMetaData() {} ~SecretKeyMetaDataSecretKeyMetaData68 ~SecretKeyMetaData() 69 { 70 secretKey.assign(secretKey.size(), 0); 71 } SecretKeyMetaDataSecretKeyMetaData72 explicit SecretKeyMetaData(const nlohmann::json &jObject) 73 { 74 Unmarshal(jObject); 75 } 76 77 std::vector<uint8_t> Marshal() const; 78 void Unmarshal(const nlohmann::json &jObject); 79 operator std::vector<uint8_t>() const 80 { 81 return Marshal(); 82 } 83 private: 84 static constexpr const char *TIME = "time"; 85 static constexpr const char *KVSTORE_TYPE = "kvStoreType"; 86 }; 87 88 struct KvStoreMetaData { 89 static constexpr const char *APP_ID = "appId"; 90 static constexpr const char *BUNDLE_NAME = "bundleName"; 91 using json = nlohmann::json; 92 std::string appId = ""; 93 std::string appType = ""; 94 std::string bundleName = ""; 95 std::string dataDir = ""; 96 std::string deviceAccountId = ""; 97 std::string deviceId = ""; 98 bool isAutoSync = false; 99 bool isBackup = false; 100 bool isEncrypt = false; 101 KvStoreType kvStoreType = KvStoreType::DEVICE_COLLABORATION; 102 std::string schema = ""; 103 std::string storeId = ""; 104 std::string userId = ""; 105 std::int32_t uid = -1; 106 std::uint32_t version = 0; 107 int securityLevel = 0; 108 bool isDirty = false; 109 std::string Marshal() const; 110 void Unmarshal(const json &jObject); 111 GetAppIdKvStoreMetaData112 static inline std::string GetAppId(const json &jObject) 113 { 114 return Serializable::GetVal<std::string>(jObject, APP_ID, json::value_t::string, ""); 115 } 116 GetStoreIdKvStoreMetaData117 static inline std::string GetStoreId(const json &jObject) 118 { 119 return Serializable::GetVal<std::string>(jObject, STORE_ID, json::value_t::string, ""); 120 } 121 private: 122 static constexpr const char *KVSTORE_TYPE = "kvStoreType"; 123 static constexpr const char *DEVICE_ID = "deviceId"; 124 static constexpr const char *USER_ID = "userId"; 125 static constexpr const char *STORE_ID = "storeId"; 126 static constexpr const char *ENCRYPT = "isEncrypt"; 127 static constexpr const char *BACKUP = "isBackup"; 128 static constexpr const char *AUTO_SYNC = "isAutoSync"; 129 static constexpr const char *SCHEMA = "schema"; 130 static constexpr const char *DATA_DIR = "dataDir"; 131 static constexpr const char *APP_TYPE = "appType"; 132 static constexpr const char *DEVICE_ACCOUNT_ID = "deviceAccountID"; 133 static constexpr const char *UID = "UID"; 134 static constexpr const char *VERSION = "version"; 135 static constexpr const char *SECURITY_LEVEL = "securityLevel"; 136 static constexpr const char *DIRTY_KEY = "isDirty"; 137 }; 138 139 struct MetaData { 140 std::int32_t kvStoreType; 141 KvStoreMetaData kvStoreMetaData; 142 SecretKeyMetaData secretKeyMetaData; 143 GetKvStoreTypeMetaData144 static inline KvStoreType GetKvStoreType(const nlohmann::json &jObject) 145 { 146 return Serializable::GetVal<KvStoreType>(jObject, KVSTORE_TYPE, nlohmann::json::value_t::number_unsigned, 147 KvStoreType::INVALID_TYPE); 148 } 149 private: 150 static constexpr const char *KVSTORE_TYPE = "kvStoreType"; 151 }; 152 153 class KvStoreMetaManager { 154 public: 155 static constexpr uint32_t META_STORE_VERSION = 0x03000001; 156 static const inline std::string META_DB_APP_ID = "distributeddata"; 157 enum DatabaseType { 158 KVDB, 159 RDB, 160 }; 161 using NbDelegate = std::unique_ptr<DistributedDB::KvStoreNbDelegate, 162 std::function<void(DistributedDB::KvStoreNbDelegate *)>>; 163 using ChangeObserver = std::function<void(const std::vector<uint8_t> &, const std::vector<uint8_t> &, CHANGE_FLAG)>; 164 165 class MetaDeviceChangeListenerImpl : public AppDistributedKv::AppDeviceStatusChangeListener { 166 void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, 167 const AppDistributedKv::DeviceChangeType &type) const override; 168 169 AppDistributedKv::ChangeLevelType GetChangeLevelType() const override; 170 }; 171 172 ~KvStoreMetaManager(); 173 174 static KvStoreMetaManager &GetInstance(); 175 176 void InitMetaParameter(); 177 void InitMetaListener(); 178 void SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer); 179 const NbDelegate &GetMetaKvStore(); 180 181 Status CheckUpdateServiceMeta(const std::vector<uint8_t> &metaKey, FLAG flag, const std::vector<uint8_t> &val = {}); 182 183 Status GenerateRootKey(); 184 185 Status CheckRootKeyExist(); 186 187 static std::vector<uint8_t> GetMetaKey( 188 const std::string &deviceAccountId, const std::string &groupId, const std::string &bundleName, 189 const std::string &storeId, const std::string &key = ""); 190 191 static std::string GetSecretKeyFile(const std::string &userId, const std::string &appId, 192 const std::string &storeId, int pathType); 193 194 static std::string GetSecretSingleKeyFile(const std::string &userId, const std::string &appId, 195 const std::string &storeId, int pathType); 196 197 Status GetSecretKeyFromMeta(const std::vector<uint8_t> &metaSecretKey, 198 std::vector<uint8_t> &key, bool &outdated); 199 200 std::vector<uint8_t> EncryptWorkKey(const std::vector<uint8_t> &key); 201 202 bool DecryptWorkKey(const std::vector<uint8_t> &encryptedKey, std::vector<uint8_t> &key); 203 204 Status WriteSecretKeyToMeta(const std::vector<uint8_t> &metaKey, const std::vector<uint8_t> &key); 205 206 Status WriteSecretKeyToFile(const std::string &secretKeyFile, const std::vector<uint8_t> &key); 207 208 Status 209 RemoveSecretKey(pid_t uid, const std::string &bundleName, const std::string &storeId); 210 211 Status 212 RecoverSecretKeyFromFile(const std::string &secretKeyFile, const std::vector<uint8_t> &metaSecretKey, 213 std::vector<uint8_t> &key, bool &outdated); 214 215 void ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId, int32_t pathType, 216 sptr<KvStoreImpl> store); 217 218 void ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId, int32_t pathType, 219 sptr<SingleKvStoreImpl> store); 220 221 void GetStrategyMetaKey(const StrategyMeta ¶ms, std::string &retVal); 222 223 Status DeleteStrategyMeta(const std::string &bundleName, const std::string &storeId, const std::string &userId); 224 225 Status SaveStrategyMetaEnable(const std::string &key, bool enable); 226 227 Status SaveStrategyMetaLabels(const std::string &key, 228 const std::vector<std::string> &localLabels, 229 const std::vector<std::string> &remoteSupportLabels); 230 231 Status CheckSyncPermission(const std::string &userId, const std::string &appId, const std::string &storeId, 232 uint8_t flag, const std::string &remoteId); 233 234 Status QueryKvStoreMetaDataByDeviceIdAndAppId(const std::string &devId, const std::string &appId, 235 KvStoreMetaData &val); 236 237 Status GetKvStoreMeta(const std::vector<uint8_t> &metaKey, KvStoreMetaData &kvStoreMetaData); 238 239 bool GetKvStoreMetaDataByBundleName(const std::string &bundleName, KvStoreMetaData &metaData); 240 241 bool GetKvStoreMetaDataByAppId(const std::string &appId, KvStoreMetaData &metaData); 242 243 bool GetFullMetaData(std::map<std::string, MetaData> &entries, enum DatabaseType type = KVDB); 244 private: 245 NbDelegate CreateMetaKvStore(); 246 247 KvStoreMetaManager(); 248 249 void InitMetaData(); 250 251 void SubscribeMetaKvStore(); 252 253 void SyncMeta(); 254 255 void ConcatWithSharps(const std::vector<std::string> ¶ms, std::string &retVal); 256 257 Status GetStategyMeta(const std::string &key, std::map<std::string, std::vector<std::string>> &strategies); 258 259 bool GetKvStoreMetaByType(const std::string &name, const std::string &val, KvStoreMetaData &metaData); 260 261 class KvStoreMetaObserver : public DistributedDB::KvStoreObserver { 262 public: 263 virtual ~KvStoreMetaObserver(); 264 265 // Database change callback 266 void OnChange(const DistributedDB::KvStoreChangedData &data) override; 267 std::map<std::string, ChangeObserver> handlerMap_; 268 private: 269 void HandleChanges(CHANGE_FLAG flag, const std::list<DistributedDB::Entry> &list); 270 }; 271 272 static constexpr const char *ROOT_KEY_ALIAS = "distributed_db_root_key"; 273 static constexpr const char *STRATEGY_META_PREFIX = "StrategyMetaData"; 274 static constexpr const char *CAPABILITY_ENABLED = "capabilityEnabled"; 275 static constexpr const char *CAPABILITY_RANGE = "capabilityRange"; 276 static constexpr const char *LOCAL_LABEL = "localLabel"; 277 static constexpr const char *REMOTE_LABEL = "remoteLabel"; 278 static constexpr const char *HARMONY_APP = "harmony"; 279 static constexpr const char *HKS_BLOB_TYPE_NONCE = "Z5s0Bo571KoqwIi6"; 280 static constexpr const char *HKS_BLOB_TYPE_AAD = "distributeddata"; 281 static constexpr int KEY_SIZE = 32; 282 static constexpr int HOURS_PER_YEAR = (24 * 365); 283 284 NbDelegate metaDelegate_; 285 std::string metaDBDirectory_; 286 DistributedDB::KvStoreDelegateManager kvStoreDelegateManager_; 287 std::vector<uint8_t> vecRootKeyAlias_ {}; 288 std::vector<uint8_t> vecNonce_ {}; 289 std::vector<uint8_t> vecAad_ {}; 290 static std::condition_variable cv_; 291 static std::mutex cvMutex_; 292 static MetaDeviceChangeListenerImpl listener_; 293 KvStoreMetaObserver metaObserver_; 294 std::recursive_mutex mutex_; 295 }; 296 } // namespace DistributedKv 297 } // namespace OHOS 298 #endif // KVSTORE_META_MANAGER_H 299