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