• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 
16 #include "dlp_permission_serializer.h"
17 #include <cinttypes>
18 #include "domain_account_client.h"
19 #include "dlp_permission.h"
20 #include "dlp_permission_log.h"
21 #include "hex_string.h"
22 #include "ohos_account_kits.h"
23 #include "os_account_manager.h"
24 #include "permission_policy.h"
25 #include "securec.h"
26 
27 namespace OHOS {
28 namespace Security {
29 namespace DlpPermission {
30 namespace {
31 const std::string KIA_INDEX = "KIA";
32 const std::string OWNER_ACCOUNT_NAME = "ownerAccountName";
33 const std::string OWNER_ACCOUNT_ID = "ownerAccountId";
34 const std::string VERSION_INDEX = "version";
35 const std::string PERM_EXPIRY_TIME = "expireTime";
36 const std::string PERM_DOMAIN = "domain";
37 const std::string PARAMETER_KEY = "parameters";
38 const std::string TYPE_KEY = "type";
39 const std::string ACCOUNT_INDEX = "account";
40 const std::string AESKEY = "filekey";
41 const std::string AESKEY_LEN = "filekeyLen";
42 const std::string IV = "iv";
43 const std::string IV_LEN = "ivLen";
44 const std::string HMACKEY = "hmacKey";
45 const std::string HMACKEY_LEN = "hmacKeyLen";
46 const std::string DLP_VERSION_LOW_CAMEL_CASE = "dlpVersion";
47 const std::string DLP_FILE_DEBUG_FLAG = "debug";
48 const std::string ENC_DATA_LEN = "encDataLen";
49 const std::string ENC_DATA = "encData";
50 const std::string EXTRA_INFO_LEN = "extraInfoLen";
51 const std::string EXTRA_INFO = "extraInfo";
52 const std::string ENC_ACCOUNT_TYPE = "accountType";
53 const std::string ONLINE_POLICY_CONTENT = "plaintextPolicy";
54 const std::string NEED_ONLINE = "needOnline";
55 const std::string FILE_INDEX = "file";
56 const std::string POLICY_INDEX = "policy";
57 const std::string READ_INDEX = "read";
58 const std::string EDIT_INDEX = "edit";
59 const std::string FC_INDEX = "fullCtrl";
60 const std::string RIGHT_INDEX = "right";
61 const std::string EVERYONE_INDEX = "everyone";
62 const std::string ENC_POLICY_INDEX = "encPolicy";
63 const std::string POLICY_CERT_VERSION = "policyCertVersion";
64 const std::string ONLINE_CERT = "onlineCert";
65 const std::string ENC_POLICY = "encPolicy";
66 const std::string OFFLINE_CERT = "offlineCert";
67 const std::string ACCOUNT_TYPE = "accountType";
68 const std::string RECEIVER_ACCOUNT_INFO = "receiverAccountInfo";
69 const std::string OPEN_MODE = "openMode";
70 const std::string ACCOUNT_NAME = "accountName";
71 const std::string ACCOUNT_ID = "accountId";
72 const std::string ACTION_UPON_EXPIRY = "actionUponExpiry";
73 const std::string CUSTOM_PROPERTY = "customProperty";
74 const std::string ENTERPRISE = "enterprise";
75 constexpr uint64_t  VALID_TIME_STAMP = 2147483647;
76 static const uint32_t DOMAIN_VERSION = 2;
77 static const uint32_t CLOUD_VERSION = 1;
78 
79 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
80     LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpPermissionSerializer"};
81 }  // namespace
82 
GetInstance()83 DlpPermissionSerializer& DlpPermissionSerializer::GetInstance()
84 {
85     static DlpPermissionSerializer instance;
86     return instance;
87 }
88 
ReadUint8ArrayFromJson(const unordered_json & permJson,uint8_t ** buff,uint32_t & buffLen,const std::string & keyName,const std::string & lenName)89 static int32_t ReadUint8ArrayFromJson(const unordered_json& permJson, uint8_t** buff, uint32_t& buffLen,
90     const std::string& keyName, const std::string& lenName)
91 {
92     if (!lenName.empty() && permJson.find(lenName) != permJson.end() && permJson.at(lenName).is_number()) {
93         permJson.at(lenName).get_to(buffLen);
94     }
95 
96     if (permJson.find(keyName) != permJson.end() && permJson.at(keyName).is_string()) {
97         std::string tmp = permJson.at(keyName).get<std::string>();
98 
99         uint32_t length = tmp.size() / BYTE_TO_HEX_OPER_LENGTH;
100         if (length != buffLen) {
101             buffLen = length;
102         }
103         if (length == 0) {
104             DLP_LOG_ERROR(LABEL, "%{public}s length is 0", keyName.c_str());
105             return DLP_SERVICE_ERROR_VALUE_INVALID;
106         }
107         *buff = new (std::nothrow) uint8_t[length];
108         if (*buff == nullptr) {
109             DLP_LOG_ERROR(LABEL, "New memory fail");
110             return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
111         }
112         int32_t res = HexStringToByte(tmp.c_str(), tmp.length(), *buff, length);
113         if (res != DLP_OK) {
114             DLP_LOG_ERROR(LABEL, "Hexstring to byte fail");
115             memset_s(*buff, length, 0, length);
116             delete[] *buff;
117             *buff = nullptr;
118         }
119 
120         return res;
121     }
122     return DLP_OK;
123 }
124 
TransHexStringToByte(std::string & outer,const std::string & input)125 static void TransHexStringToByte(std::string& outer, const std::string& input)
126 {
127     uint32_t len = input.size() / BYTE_TO_HEX_OPER_LENGTH;
128     uint8_t* buff = new (std::nothrow) uint8_t[len + 1];
129     if (buff == nullptr) {
130         DLP_LOG_ERROR(LABEL, "New memory fail");
131         return;
132     }
133 
134     int32_t res = HexStringToByte(input.c_str(), input.length(), buff, len);
135     if (res != DLP_OK) {
136         DLP_LOG_ERROR(LABEL, "Hexstring to byte fail");
137         (void)memset_s(buff, len, 0, len);
138         delete[] buff;
139         buff = nullptr;
140         return;
141     }
142     buff[len] = '\0';
143     outer = reinterpret_cast<char *>(buff);
144     (void)memset_s(buff, len, 0, len);
145     delete[] buff;
146 }
147 
SerializeAuthUserInfo(unordered_json & authUsersJson,const AuthUserInfo & userInfo)148 static void SerializeAuthUserInfo(unordered_json& authUsersJson,
149     const AuthUserInfo& userInfo)
150 {
151     bool read = false;
152     bool edit = false;
153     bool fullCtrl = false;
154 
155     switch (userInfo.authPerm) {
156         case DLPFileAccess::READ_ONLY: {
157             read = true;
158             break;
159         }
160         case DLPFileAccess::CONTENT_EDIT: {
161             edit = true;
162             break;
163         }
164         case DLPFileAccess::FULL_CONTROL: {
165             read = true;
166             edit = true;
167             fullCtrl = true;
168             break;
169         }
170         default:
171             break;
172     }
173 
174     unordered_json rightInfoJson;
175     rightInfoJson[READ_INDEX] = read;
176     rightInfoJson[EDIT_INDEX] = edit;
177     rightInfoJson[FC_INDEX] = fullCtrl;
178     unordered_json accountRight;
179     accountRight[RIGHT_INDEX] = rightInfoJson;
180     authUsersJson[userInfo.authAccount.c_str()] = accountRight;
181     return;
182 }
183 
DeserializeAuthUserInfo(const unordered_json & accountInfoJson,AuthUserInfo & userInfo)184 int32_t DlpPermissionSerializer::DeserializeAuthUserInfo(const unordered_json& accountInfoJson,
185     AuthUserInfo& userInfo)
186 {
187     unordered_json rightInfoJson;
188     if (accountInfoJson.find(RIGHT_INDEX) != accountInfoJson.end() && accountInfoJson.at(RIGHT_INDEX).is_object()) {
189         accountInfoJson.at(RIGHT_INDEX).get_to(rightInfoJson);
190     }
191 
192     bool edit = false;
193     bool fullCtrl = false;
194 
195     if (rightInfoJson.find(EDIT_INDEX) != rightInfoJson.end() && rightInfoJson.at(EDIT_INDEX).is_boolean()) {
196         rightInfoJson.at(EDIT_INDEX).get_to(edit);
197     }
198 
199     if (rightInfoJson.find(FC_INDEX) != rightInfoJson.end() && rightInfoJson.at(FC_INDEX).is_boolean()) {
200         rightInfoJson.at(FC_INDEX).get_to(fullCtrl);
201     }
202 
203     if (fullCtrl) {
204         userInfo.authPerm = DLPFileAccess::FULL_CONTROL;
205     } else if (edit) {
206         userInfo.authPerm = DLPFileAccess::CONTENT_EDIT;
207     } else {
208         userInfo.authPerm = DLPFileAccess::READ_ONLY;
209     }
210 
211     userInfo.permExpiryTime = VALID_TIME_STAMP;
212     userInfo.authAccountType = CLOUD_ACCOUNT;
213 
214     return DLP_OK;
215 }
216 
SerializeAuthUserList(const std::vector<AuthUserInfo> & authUsers)217 static unordered_json SerializeAuthUserList(const std::vector<AuthUserInfo>& authUsers)
218 {
219     unordered_json authUsersJson;
220     for (auto it = authUsers.begin(); it != authUsers.end(); ++it) {
221         SerializeAuthUserInfo(authUsersJson, *it);
222     }
223     return authUsersJson;
224 }
225 
DeserializeAuthUserList(const unordered_json & authUsersJson,std::vector<AuthUserInfo> & userList)226 int32_t DlpPermissionSerializer::DeserializeAuthUserList(
227     const unordered_json& authUsersJson, std::vector<AuthUserInfo>& userList)
228 {
229     for (auto iter = authUsersJson.begin(); iter != authUsersJson.end(); ++iter) {
230         AuthUserInfo authInfo;
231         std::string name = iter.key();
232         authInfo.authAccount = name;
233         unordered_json accountInfo = iter.value();
234         int32_t res = DeserializeAuthUserInfo(accountInfo, authInfo);
235         if (res == DLP_OK) {
236             userList.emplace_back(authInfo);
237         } else {
238             userList.clear();
239             return res;
240         }
241     }
242     return DLP_OK;
243 }
244 
SerializeDomainInfo(const PermissionPolicy & policy,unordered_json & permInfoJson)245 static int32_t SerializeDomainInfo(const PermissionPolicy& policy, unordered_json& permInfoJson)
246 {
247     if (policy.ownerAccountType_ != DOMAIN_ACCOUNT) {
248         permInfoJson[VERSION_INDEX] = CLOUD_VERSION;
249         return DLP_OK;
250     }
251 
252     int32_t userId;
253     int32_t res = OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
254     if (res != DLP_OK) {
255         DLP_LOG_ERROR(LABEL, "GetForegroundOsAccountLocalId failed, res = %{public}d", res);
256         return DLP_PARSE_ERROR_ACCOUNT_INVALID;
257     }
258     AccountSA::OsAccountInfo osAccountInfo;
259     res = OHOS::AccountSA::OsAccountManager::QueryOsAccountById(userId, osAccountInfo);
260     if (res != DLP_OK) {
261         DLP_LOG_ERROR(LABEL, "QueryOsAccountById failed, res = %{public}d", res);
262         return DLP_PARSE_ERROR_ACCOUNT_INVALID;
263     }
264 
265     AccountSA::DomainAccountInfo domainInfo;
266     osAccountInfo.GetDomainInfo(domainInfo);
267     AccountSA::DomainServerConfig config;
268     res = AccountSA::DomainAccountClient::GetInstance().GetAccountServerConfig(domainInfo, config);
269     if (res != DLP_OK) {
270         DLP_LOG_ERROR(LABEL, "GetAccountServerConfig failed, res = %{public}d", res);
271         return DLP_PARSE_ERROR_ACCOUNT_INVALID;
272     }
273     auto serverConfigJsonObj = nlohmann::json::parse(config.parameters_, nullptr, false);
274     if (serverConfigJsonObj.is_discarded() || (!serverConfigJsonObj.is_object())) {
275         DLP_LOG_ERROR(LABEL, "JsonObj is discarded");
276         return DLP_SERVICE_ERROR_JSON_OPERATE_FAIL;
277     }
278     if (!serverConfigJsonObj.contains(PARAMETER_KEY) || !serverConfigJsonObj[PARAMETER_KEY].is_object()) {
279         DLP_LOG_ERROR(LABEL, "PARAMETER_KEY is missing or not an object");
280         return DLP_SERVICE_ERROR_JSON_OPERATE_FAIL;
281     }
282     auto parameterObj = serverConfigJsonObj[PARAMETER_KEY];
283     if (!parameterObj.contains(TYPE_KEY) || !parameterObj[TYPE_KEY].is_string()) {
284         DLP_LOG_ERROR(LABEL, "TYPE_KEY is missing or not a string");
285         return DLP_SERVICE_ERROR_JSON_OPERATE_FAIL;
286     }
287     std::string typeStr = parameterObj[TYPE_KEY];
288     permInfoJson[PERM_DOMAIN] = typeStr;
289     permInfoJson[VERSION_INDEX] = DOMAIN_VERSION;
290     return DLP_OK;
291 }
292 
SerializeEveryoneInfo(const PermissionPolicy & policy,unordered_json & permInfoJson)293 static void SerializeEveryoneInfo(const PermissionPolicy& policy, unordered_json& permInfoJson)
294 {
295     if (policy.supportEveryone_) {
296         bool read = false;
297         bool edit = false;
298         bool fullCtrl = false;
299 
300         switch (policy.everyonePerm_) {
301             case DLPFileAccess::READ_ONLY: {
302                 read = true;
303                 break;
304             }
305             case DLPFileAccess::CONTENT_EDIT: {
306                 edit = true;
307                 break;
308             }
309             case DLPFileAccess::FULL_CONTROL: {
310                 read = true;
311                 edit = true;
312                 fullCtrl = true;
313                 break;
314             }
315             default:
316                 break;
317         }
318 
319         unordered_json rightInfoJson;
320         rightInfoJson[READ_INDEX] = read;
321         rightInfoJson[EDIT_INDEX] = edit;
322         rightInfoJson[FC_INDEX] = fullCtrl;
323         unordered_json everyoneJson;
324         everyoneJson[RIGHT_INDEX] = rightInfoJson;
325         permInfoJson[EVERYONE_INDEX] = everyoneJson;
326         return;
327     }
328 }
329 
SerializeCustomProperty(const PermissionPolicy & policy,unordered_json & policyJson)330 static void SerializeCustomProperty(const PermissionPolicy& policy, unordered_json& policyJson)
331 {
332     unordered_json customProperty;
333     if (policy.customProperty_.empty()) {
334         return;
335     }
336     customProperty[ENTERPRISE] = policy.customProperty_;
337     policyJson[CUSTOM_PROPERTY] = customProperty.dump();
338 }
339 
SerializeFileEncInfo(const PermissionPolicy & policy,unordered_json & fileEnc)340 static int32_t SerializeFileEncInfo(const PermissionPolicy& policy, unordered_json& fileEnc)
341 {
342     uint32_t keyHexLen = policy.GetAeskeyLen() * BYTE_TO_HEX_OPER_LENGTH + 1;
343     auto keyHex = std::make_unique<char[]>(keyHexLen);
344     int32_t res = ByteToHexString(policy.GetAeskey(), policy.GetAeskeyLen(), keyHex.get(), keyHexLen);
345     if (res != DLP_OK) {
346         DLP_LOG_ERROR(LABEL, "Byte to hexstring fail");
347         return res;
348     }
349 
350     uint32_t ivHexLen = policy.GetIvLen() * BYTE_TO_HEX_OPER_LENGTH + 1;
351     auto ivHex = std::make_unique<char[]>(ivHexLen);
352     res = ByteToHexString(policy.GetIv(), policy.GetIvLen(), ivHex.get(), ivHexLen);
353     if (res != DLP_OK) {
354         DLP_LOG_ERROR(LABEL, "Byte to hexstring fail");
355         return res;
356     }
357 
358     uint32_t hmacKeyHexLen = policy.GetHmacKeyLen() * BYTE_TO_HEX_OPER_LENGTH + 1;
359     auto hmacKeyHex = std::make_unique<char[]>(hmacKeyHexLen);
360     res = ByteToHexString(policy.GetHmacKey(), policy.GetHmacKeyLen(), hmacKeyHex.get(), hmacKeyHexLen);
361     if (res != DLP_OK) {
362         DLP_LOG_ERROR(LABEL, "Byte to hexstring fail");
363         return res;
364     }
365     fileEnc[AESKEY] = keyHex.get();
366     fileEnc[AESKEY_LEN] = policy.GetAeskeyLen();
367     fileEnc[IV] = ivHex.get();
368     fileEnc[IV_LEN] = policy.GetIvLen();
369     fileEnc[HMACKEY] = hmacKeyHex.get();
370     fileEnc[HMACKEY_LEN] = policy.GetHmacKeyLen();
371     fileEnc[DLP_VERSION_LOW_CAMEL_CASE] = policy.dlpVersion_;
372     return DLP_OK;
373 }
374 
SerializeDlpPermission(const PermissionPolicy & policy,unordered_json & permInfoJson)375 int32_t DlpPermissionSerializer::SerializeDlpPermission(const PermissionPolicy& policy, unordered_json& permInfoJson)
376 {
377     unordered_json authUsersJson = SerializeAuthUserList(policy.authUsers_);
378     unordered_json policyJson;
379     policyJson[KIA_INDEX] = "";
380     policyJson[OWNER_ACCOUNT_NAME] = policy.ownerAccount_;
381     policyJson[OWNER_ACCOUNT_ID] = policy.ownerAccountId_;
382     int32_t res = SerializeDomainInfo(policy, policyJson);
383     if (res != DLP_OK) {
384         DLP_LOG_ERROR(LABEL, "Serialize domain info failed, res = %{public}d", res);
385         return res;
386     }
387     policyJson[PERM_EXPIRY_TIME] = policy.expireTime_;
388     policyJson[ACTION_UPON_EXPIRY] = policy.actionUponExpiry_;
389     policyJson[NEED_ONLINE] = policy.needOnline_;
390     policyJson[DLP_FILE_DEBUG_FLAG] = policy.debug_;
391     policyJson[ACCOUNT_INDEX] = authUsersJson;
392     SerializeCustomProperty(policy, policyJson);
393     SerializeEveryoneInfo(policy, policyJson);
394     permInfoJson[POLICY_INDEX] = policyJson;
395 
396     unordered_json fileEnc;
397     res = SerializeFileEncInfo(policy, fileEnc);
398     if (res != DLP_OK) {
399         DLP_LOG_ERROR(LABEL, "Serialize file enc info failed, res = %{public}d", res);
400         return res;
401     }
402     permInfoJson[FILE_INDEX] = fileEnc;
403 
404     DLP_LOG_INFO(LABEL, "Serialize successfully!");
405     return DLP_OK;
406 }
407 
GetPolicyJson(const unordered_json & permJson,unordered_json & plainPolicyJson)408 static int32_t GetPolicyJson(const unordered_json& permJson, unordered_json& plainPolicyJson)
409 {
410     if (permJson.find(ONLINE_POLICY_CONTENT) != permJson.end() && permJson.at(ONLINE_POLICY_CONTENT).is_string()) {
411         std::string plainHexPolicy;
412         permJson.at(ONLINE_POLICY_CONTENT).get_to(plainHexPolicy);
413         std::string plainPolicy;
414         TransHexStringToByte(plainPolicy, plainHexPolicy);
415         if (!unordered_json::accept(plainPolicy)) {
416             return DLP_PARSE_ERROR_VALUE_INVALID;
417         }
418         plainPolicyJson = unordered_json::parse(plainPolicy);
419         if (plainPolicyJson.is_discarded() || (!plainPolicyJson.is_object())) {
420             DLP_LOG_ERROR(LABEL, "JsonObj is discarded");
421             return DLP_PARSE_ERROR_VALUE_INVALID;
422         }
423     } else {
424         plainPolicyJson = permJson;
425     }
426     return DLP_OK;
427 }
428 
DeserializeEveryoneInfo(const unordered_json & policyJson,PermissionPolicy & policy)429 bool DlpPermissionSerializer::DeserializeEveryoneInfo(const unordered_json& policyJson, PermissionPolicy& policy)
430 {
431     if (policyJson.find(EVERYONE_INDEX) == policyJson.end() || !policyJson.at(EVERYONE_INDEX).is_object()) {
432         return false;
433     }
434 
435     policy.supportEveryone_ = true;
436     unordered_json everyoneInfoJson;
437     policyJson.at(EVERYONE_INDEX).get_to(everyoneInfoJson);
438 
439     unordered_json rightInfoJson;
440     if (everyoneInfoJson.find(RIGHT_INDEX) == everyoneInfoJson.end() ||
441         !everyoneInfoJson.at(RIGHT_INDEX).is_object()) {
442         return false;
443     }
444     everyoneInfoJson.at(RIGHT_INDEX).get_to(rightInfoJson);
445 
446     bool edit = false;
447     bool fullCtrl = false;
448 
449     if (rightInfoJson.find(EDIT_INDEX) != rightInfoJson.end() && rightInfoJson.at(EDIT_INDEX).is_boolean()) {
450         rightInfoJson.at(EDIT_INDEX).get_to(edit);
451     }
452 
453     if (rightInfoJson.find(FC_INDEX) != rightInfoJson.end() && rightInfoJson.at(FC_INDEX).is_boolean()) {
454         rightInfoJson.at(FC_INDEX).get_to(fullCtrl);
455     }
456 
457     if (fullCtrl) {
458         policy.everyonePerm_ = DLPFileAccess::FULL_CONTROL;
459     } else if (edit) {
460         policy.everyonePerm_ = DLPFileAccess::CONTENT_EDIT;
461     } else {
462         policy.everyonePerm_ = DLPFileAccess::READ_ONLY;
463     }
464     return true;
465 }
466 
InitPermissionAccountInfo(PermissionPolicy & policy,unordered_json policyJson)467 static void InitPermissionAccountInfo(PermissionPolicy& policy, unordered_json policyJson)
468 {
469     if (policyJson.find(OWNER_ACCOUNT_NAME) != policyJson.end() && policyJson.at(OWNER_ACCOUNT_NAME).is_string()) {
470         policyJson.at(OWNER_ACCOUNT_NAME).get_to(policy.ownerAccount_);
471     }
472     if (policyJson.find(OWNER_ACCOUNT_ID) != policyJson.end() && policyJson.at(OWNER_ACCOUNT_ID).is_string()) {
473         policyJson.at(OWNER_ACCOUNT_ID).get_to(policy.ownerAccountId_);
474     }
475     if (policyJson.find(ACCOUNT_TYPE) != policyJson.end() && policyJson.at(ACCOUNT_TYPE).is_number()) {
476         policyJson.at(ACCOUNT_TYPE).get_to(policy.acountType_);
477     }
478     if (policyJson.find(ACCOUNT_NAME) != policyJson.end() && policyJson.at(ACCOUNT_NAME).is_string()) {
479         policyJson.at(ACCOUNT_NAME).get_to(policy.accountName_);
480     }
481     if (policyJson.find(ACCOUNT_ID) != policyJson.end() && policyJson.at(ACCOUNT_ID).is_string()) {
482         policyJson.at(ACCOUNT_ID).get_to(policy.acountId_);
483     }
484 }
485 
InitPermissionPolicy(PermissionPolicy & policy,const std::vector<AuthUserInfo> & userList,unordered_json policyJson)486 static void InitPermissionPolicy(PermissionPolicy& policy, const std::vector<AuthUserInfo>& userList,
487     unordered_json policyJson)
488 {
489     policy.authUsers_ = userList;
490     InitPermissionAccountInfo(policy, policyJson);
491     if (policyJson.find(PERM_EXPIRY_TIME) != policyJson.end() && policyJson.at(PERM_EXPIRY_TIME).is_number()) {
492         policyJson.at(PERM_EXPIRY_TIME).get_to(policy.expireTime_);
493     }
494     if (policyJson.find(ACTION_UPON_EXPIRY) != policyJson.end() && policyJson.at(ACTION_UPON_EXPIRY).is_number()) {
495         policyJson.at(ACTION_UPON_EXPIRY).get_to(policy.actionUponExpiry_);
496     }
497     if (policyJson.find(NEED_ONLINE) != policyJson.end() && policyJson.at(NEED_ONLINE).is_number()) {
498         policyJson.at(NEED_ONLINE).get_to(policy.needOnline_);
499     }
500     if (policyJson.find(DLP_FILE_DEBUG_FLAG) != policyJson.end() && policyJson.at(DLP_FILE_DEBUG_FLAG).is_boolean()) {
501         policyJson.at(DLP_FILE_DEBUG_FLAG).get_to(policy.debug_);
502     }
503     if (policyJson.find(OPEN_MODE) != policyJson.end() && policyJson.at(OPEN_MODE).is_number()) {
504         policy.perm_ = DLPFileAccess::READ_ONLY;
505     }
506     if (policyJson.find(CUSTOM_PROPERTY) != policyJson.end() && policyJson.at(CUSTOM_PROPERTY).is_string()) {
507         policyJson.at(CUSTOM_PROPERTY).get_to(policy.customProperty_);
508     }
509     policy.ownerAccountType_ = CLOUD_ACCOUNT;
510 }
511 
DeserializeFileEncJson(PermissionPolicy & policy,unordered_json & plainPolicyJson)512 static int32_t DeserializeFileEncJson(PermissionPolicy& policy, unordered_json& plainPolicyJson)
513 {
514     unordered_json fileEncJson;
515     if (plainPolicyJson.find(FILE_INDEX) != plainPolicyJson.end() && plainPolicyJson.at(FILE_INDEX).is_object()) {
516         plainPolicyJson.at(FILE_INDEX).get_to(fileEncJson);
517     }
518     uint8_t* key = nullptr;
519     uint32_t keyLen = 0;
520     int32_t res = ReadUint8ArrayFromJson(fileEncJson, &key, keyLen, AESKEY, AESKEY_LEN);
521     if (res != DLP_OK) {
522         return res;
523     }
524     policy.SetAeskey(key, keyLen);
525     (void)memset_s(key, keyLen, 0, keyLen);
526     delete[] key;
527     key = nullptr;
528 
529     uint8_t* iv = nullptr;
530     uint32_t ivLen = 0;
531     res = ReadUint8ArrayFromJson(fileEncJson, &iv, ivLen, IV, IV_LEN);
532     if (res != DLP_OK) {
533         return res;
534     }
535     policy.SetIv(iv, ivLen);
536     (void)memset_s(iv, ivLen, 0, ivLen);
537     delete[] iv;
538     iv = nullptr;
539 
540     uint8_t* hmacKey = nullptr;
541     uint32_t hmacKeyLen = 0;
542     res = ReadUint8ArrayFromJson(fileEncJson, &hmacKey, hmacKeyLen, HMACKEY, HMACKEY_LEN);
543     if (res != DLP_OK) {
544         return res;
545     }
546     policy.SetHmacKey(hmacKey, hmacKeyLen);
547     (void)memset_s(hmacKey, hmacKeyLen, 0, hmacKeyLen);
548     delete[] hmacKey;
549     hmacKey = nullptr;
550 
551     policy.dlpVersion_ = 0;
552     if (fileEncJson.find(DLP_VERSION_LOW_CAMEL_CASE) != fileEncJson.end() &&
553         fileEncJson.at(DLP_VERSION_LOW_CAMEL_CASE).is_number()) {
554         fileEncJson.at(DLP_VERSION_LOW_CAMEL_CASE).get_to(policy.dlpVersion_);
555         DLP_LOG_DEBUG(LABEL, "set dlpVersion from DLP_CERT, dlpVersion = %{public}d", policy.dlpVersion_);
556     }
557     return DLP_OK;
558 }
559 
DeserializeDlpPermission(const unordered_json & permJson,PermissionPolicy & policy)560 int32_t DlpPermissionSerializer::DeserializeDlpPermission(const unordered_json& permJson, PermissionPolicy& policy)
561 {
562     unordered_json plainPolicyJson;
563     int32_t res = GetPolicyJson(permJson, plainPolicyJson);
564     if (res != DLP_OK) {
565         return res;
566     }
567     unordered_json policyJson;
568     if (plainPolicyJson.find(POLICY_INDEX) != plainPolicyJson.end() && plainPolicyJson.at(POLICY_INDEX).is_object()) {
569         plainPolicyJson.at(POLICY_INDEX).get_to(policyJson);
570     }
571 
572     unordered_json accountListJson;
573     if (policyJson.find(ACCOUNT_INDEX) != policyJson.end() && policyJson.at(ACCOUNT_INDEX).is_object()) {
574         policyJson.at(ACCOUNT_INDEX).get_to(accountListJson);
575     }
576     DeserializeEveryoneInfo(policyJson, policy);
577 
578     std::vector<AuthUserInfo> userList;
579     res = DeserializeAuthUserList(accountListJson, userList);
580     if (res != DLP_OK) {
581         return res;
582     }
583     InitPermissionPolicy(policy, userList, policyJson);
584 
585     res = DeserializeFileEncJson(policy, plainPolicyJson);
586     if (res != DLP_OK) {
587         return res;
588     }
589     return DLP_OK;
590 }
591 
SerializeEncPolicyData(const DLP_EncPolicyData & encData,unordered_json & encDataJson)592 int32_t DlpPermissionSerializer::SerializeEncPolicyData(const DLP_EncPolicyData& encData, unordered_json& encDataJson)
593 {
594     if (encData.dataLen == 0 || encData.dataLen > DLP_MAX_CERT_SIZE) {
595         DLP_LOG_ERROR(LABEL, "Cert lenth %{public}d is invalid", encData.dataLen);
596         return DLP_SERVICE_ERROR_VALUE_INVALID;
597     }
598 
599     uint32_t encDataHexLen = encData.dataLen * BYTE_TO_HEX_OPER_LENGTH + 1;
600     char* encDataHex = new (std::nothrow) char[encDataHexLen];
601     if (encDataHex == nullptr) {
602         DLP_LOG_ERROR(LABEL, "New memory fail");
603         return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
604     }
605     int32_t res = ByteToHexString(encData.data, encData.dataLen, encDataHex, encDataHexLen);
606     if (res != DLP_OK) {
607         DLP_LOG_ERROR(LABEL, "Byte to hexstring fail");
608         FreeCharBuffer(encDataHex, encDataHexLen);
609         return res;
610     }
611 
612     encDataJson = {
613         {ENC_DATA_LEN, encData.dataLen},
614         {ENC_DATA, encDataHex},
615         {ENC_ACCOUNT_TYPE, encData.accountType},
616     };
617     DLP_LOG_INFO(LABEL, "Serialize successfully!");
618     FreeCharBuffer(encDataHex, encDataHexLen);
619     return DLP_OK;
620 }
621 
DeserializeEncPolicyData(const unordered_json & encDataJson,DLP_EncPolicyData & encData,bool isNeedAdapter)622 int32_t DlpPermissionSerializer::DeserializeEncPolicyData(const unordered_json& encDataJson, DLP_EncPolicyData& encData,
623     bool isNeedAdapter)
624 {
625     if (encDataJson.find(ENC_ACCOUNT_TYPE) != encDataJson.end() && encDataJson.at(ENC_ACCOUNT_TYPE).is_number()) {
626         encDataJson.at(ENC_ACCOUNT_TYPE).get_to(encData.accountType);
627     }
628 
629     if (isNeedAdapter) {
630         DLP_LOG_INFO(LABEL, "open 4.0 Dlp File");
631         return DLP_OK;
632     }
633 
634     int32_t res = ReadUint8ArrayFromJson(encDataJson, &encData.data, encData.dataLen, ENC_DATA, ENC_DATA_LEN);
635     if (res != DLP_OK) {
636         return res;
637     }
638     DLP_LOG_INFO(LABEL, "Deserialize successfully!");
639     return DLP_OK;
640 }
641 
getEncJson(const unordered_json & encDataJson,unordered_json & certJson,std::string dataKey,std::string extraKey)642 int32_t getEncJson(const unordered_json& encDataJson, unordered_json& certJson, std::string dataKey,
643     std::string extraKey)
644 {
645     if (encDataJson.find(dataKey) == encDataJson.end() || !encDataJson.at(dataKey).is_string()) {
646         DLP_LOG_ERROR(LABEL, "key=%{public}s not found", dataKey.c_str());
647         return DLP_SERVICE_ERROR_VALUE_INVALID;
648     }
649     if (encDataJson.find(extraKey) == encDataJson.end() || !encDataJson.at(extraKey).is_string()) {
650         DLP_LOG_ERROR(LABEL, "key=%{public}s not found", extraKey.c_str());
651         return DLP_SERVICE_ERROR_VALUE_INVALID;
652     }
653     certJson[ENC_POLICY] = encDataJson.at(dataKey).get<std::string>();
654     certJson[EXTRA_INFO] = encDataJson.at(extraKey).get<std::string>();
655     return DLP_OK;
656 }
657 
DeserializeEncPolicyDataByFirstVersion(const unordered_json & encDataJson,const unordered_json & offlineEncDataJson,DLP_EncPolicyData & encData,std::string ownerAccountId)658 int32_t DlpPermissionSerializer::DeserializeEncPolicyDataByFirstVersion(const unordered_json& encDataJson,
659     const unordered_json& offlineEncDataJson, DLP_EncPolicyData& encData, std::string ownerAccountId)
660 {
661     unordered_json serverJson;
662     int res = getEncJson(encDataJson, serverJson, ENC_DATA, EXTRA_INFO);
663     if (res != DLP_OK) {
664         return res;
665     }
666     unordered_json data = { { POLICY_CERT_VERSION, 1 },
667                             { OWNER_ACCOUNT_ID, ownerAccountId },
668                             { ONLINE_CERT, serverJson } };
669     if (offlineEncDataJson != nullptr && !offlineEncDataJson.is_null()) {
670         unordered_json offlineServerJson;
671         if (offlineEncDataJson.find(ACCOUNT_TYPE) != offlineEncDataJson.end() &&
672             offlineEncDataJson.at(ACCOUNT_TYPE).is_number()) {
673             uint32_t accountType;
674             offlineEncDataJson.at(ACCOUNT_TYPE).get_to(accountType);
675             offlineServerJson[ACCOUNT_TYPE] = accountType;
676         }
677         res = getEncJson(offlineEncDataJson, offlineServerJson, ENC_POLICY, EXTRA_INFO);
678         if (res != DLP_OK) {
679             return res;
680         }
681         data[OFFLINE_CERT] = offlineServerJson;
682     }
683     std::string encDataStr = data.dump();
684     encData.data = new (std::nothrow) uint8_t[encDataStr.length()];
685     if (encData.data == nullptr) {
686         DLP_LOG_ERROR(LABEL, "New memory fail");
687         return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
688     }
689     encData.dataLen = encDataStr.length();
690     res = memcpy_s(encData.data, encDataStr.length(),
691         reinterpret_cast<const uint8_t*>(encDataStr.c_str()), encDataStr.length());
692     if (res != EOK) {
693         DLP_LOG_ERROR(LABEL, "Memcpy encData fill fail");
694         return DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL;
695     }
696     return DLP_OK;
697 }
698 }  // namespace DlpPermission
699 }  // namespace Security
700 }  // namespace OHOS
701