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