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