• 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 #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 &params, 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> &params, 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