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 "permission_policy.h"
17 #include <chrono>
18 #include <cinttypes>
19 #include <set>
20 #include "dlp_permission.h"
21 #include "dlp_permission_log.h"
22 #include "dlp_permission_public_interface.h"
23 #include "securec.h"
24
25 namespace OHOS {
26 namespace Security {
27 namespace DlpPermission {
28 namespace {
29 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpPolicyCheck"};
30 const uint32_t MAX_ACCOUNT_SIZE = 1024;
31 const uint32_t MAX_ACCOUNT_NUM = 100;
32 const uint32_t NO_EXPIRATION_DATA = 0;
33 const std::set<uint32_t> VALID_AESPARAM_LEN = {16, 24, 32};
34 } // namespace
35
CheckAesParam(const uint8_t * buff,uint32_t len)36 static bool CheckAesParam(const uint8_t* buff, uint32_t len)
37 {
38 if (buff == nullptr) {
39 DLP_LOG_ERROR(LABEL, "Aes key or iv is null");
40 return false;
41 }
42 if (!CheckAesParamLen(len)) {
43 DLP_LOG_ERROR(LABEL, "Aes key or iv len invalid, len=%{public}u", len);
44 return false;
45 }
46 return true;
47 }
48
CheckAccount(const std::string & account)49 static bool CheckAccount(const std::string& account)
50 {
51 uint32_t accountSize = account.size();
52 if (accountSize == 0 || accountSize > MAX_ACCOUNT_SIZE) {
53 DLP_LOG_ERROR(LABEL, "Account len invalid, len=%{public}u", accountSize);
54 return false;
55 }
56 return true;
57 }
58
CheckPerm(uint32_t perm)59 static bool CheckPerm(uint32_t perm)
60 {
61 if (perm <= static_cast<uint32_t>(DLPFileAccess::NO_PERMISSION) ||
62 perm > static_cast<uint32_t>(DLPFileAccess::FULL_CONTROL)) {
63 DLP_LOG_ERROR(LABEL, "Auth Perm invalid, perm=%{public}u", perm);
64 return false;
65 }
66 return true;
67 }
68
CheckTime(uint64_t time)69 static bool CheckTime(uint64_t time)
70 {
71 uint64_t curTime = static_cast<uint64_t>(
72 std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count());
73 if (time < curTime) {
74 DLP_LOG_ERROR(LABEL, "Perm expiry time is earlier than current time, cur=%{public}s, set=%{public}s",
75 std::to_string(curTime).c_str(), std::to_string(time).c_str());
76 return false;
77 }
78 return true;
79 }
80
CheckAuthUserInfo(const AuthUserInfo & info)81 static bool CheckAuthUserInfo(const AuthUserInfo& info)
82 {
83 return (CheckAccount(info.authAccount) &&
84 CheckPerm(static_cast<uint32_t>(info.authPerm)) &&
85 CheckTime(info.permExpiryTime) &&
86 CheckAccountType(info.authAccountType));
87 }
88
CheckAuthUserInfoList(const std::vector<AuthUserInfo> & authUsers)89 static bool CheckAuthUserInfoList(const std::vector<AuthUserInfo>& authUsers)
90 {
91 uint32_t userNum = authUsers.size();
92 if (userNum > MAX_ACCOUNT_NUM) {
93 DLP_LOG_ERROR(LABEL, "Auth users number exceeds %{public}u, total=%{public}u", MAX_ACCOUNT_NUM, userNum);
94 return false;
95 }
96 return (std::none_of(authUsers.begin(), authUsers.end(),
97 [](const auto& iter) { return !CheckAuthUserInfo(iter); }));
98 }
99
FreeUint8Buffer(uint8_t ** buff,uint32_t & buffLen)100 static void FreeUint8Buffer(uint8_t** buff, uint32_t& buffLen)
101 {
102 if (buff == nullptr) {
103 DLP_LOG_ERROR(LABEL, "Uint8 buffer is already nullptr.");
104 return;
105 }
106 if (*buff != nullptr) {
107 memset_s(*buff, buffLen, 0, buffLen);
108 delete[] *buff;
109 *buff = nullptr;
110 }
111 buffLen = 0;
112 }
113
FreePermissionPolicyMem()114 void PermissionPolicy::FreePermissionPolicyMem()
115 {
116 FreeUint8Buffer(&aeskey_, aeskeyLen_);
117 FreeUint8Buffer(&iv_, ivLen_);
118 FreeUint8Buffer(&hmacKey_, hmacKeyLen_);
119 ownerAccount_ = "";
120 ownerAccountId_ = "";
121 ownerAccountType_ = INVALID_ACCOUNT;
122 customProperty_ = "";
123 authUsers_.clear();
124 }
125
PermissionPolicy()126 PermissionPolicy::PermissionPolicy()
127 {
128 ownerAccount_ = "";
129 ownerAccountId_ = "";
130 ownerAccountType_ = INVALID_ACCOUNT;
131 authUsers_ = {};
132 expireTime_ = 0;
133 actionUponExpiry_ = 0;
134 needOnline_ = 0;
135 aeskey_ = nullptr;
136 aeskeyLen_ = 0;
137 iv_ = nullptr;
138 ivLen_ = 0;
139 hmacKey_ = nullptr;
140 hmacKeyLen_ = 0;
141 dlpVersion_ = CURRENT_VERSION;
142 debug_ = false;
143 customProperty_ = "";
144 }
145
PermissionPolicy(const DlpProperty & property)146 PermissionPolicy::PermissionPolicy(const DlpProperty& property)
147 {
148 ownerAccount_ = property.ownerAccount;
149 ownerAccountId_ = property.ownerAccountId;
150 ownerAccountType_ = property.ownerAccountType;
151 authUsers_ = property.authUsers;
152 supportEveryone_ = property.supportEveryone;
153 everyonePerm_ = property.everyonePerm;
154 expireTime_ = property.expireTime;
155 needOnline_ = !property.offlineAccess;
156 actionUponExpiry_ = static_cast<uint32_t>(property.actionUponExpiry);
157 aeskey_ = nullptr;
158 aeskeyLen_ = 0;
159 iv_ = nullptr;
160 ivLen_ = 0;
161 hmacKey_ = nullptr;
162 hmacKeyLen_ = 0;
163 dlpVersion_ = CURRENT_VERSION;
164 debug_ = false;
165 customProperty_ = property.customProperty.enterprise;
166 }
167
~PermissionPolicy()168 PermissionPolicy::~PermissionPolicy()
169 {
170 FreePermissionPolicyMem();
171 }
172
IsValid() const173 bool PermissionPolicy::IsValid() const
174 {
175 return (CheckAccount(this->ownerAccount_) && CheckAccount(this->ownerAccountId_) &&
176 CheckAccountType(this->ownerAccountType_) && CheckAesParam(this->aeskey_, this->aeskeyLen_) &&
177 CheckAesParam(this->iv_, this->ivLen_) && CheckAuthUserInfoList(this->authUsers_) &&
178 (this->hmacKeyLen_ == 0 || CheckAesParam(this->hmacKey_, this->hmacKeyLen_)));
179 }
180
SetDebug(bool debug)181 void PermissionPolicy::SetDebug(bool debug)
182 {
183 debug_ = debug;
184 }
185
SetKey(const uint8_t * originalKey,uint32_t originalKeyLen,uint8_t ** key,uint32_t & keyLen)186 static void SetKey(const uint8_t* originalKey, uint32_t originalKeyLen, uint8_t** key, uint32_t& keyLen)
187 {
188 if (key == nullptr) {
189 DLP_LOG_ERROR(LABEL, "key is null.");
190 return;
191 }
192 if (originalKey == nullptr) {
193 DLP_LOG_INFO(LABEL, "Set key to null");
194 FreeUint8Buffer(key, keyLen);
195 return;
196 }
197 if (!CheckAesParamLen(originalKeyLen)) {
198 DLP_LOG_ERROR(LABEL, "Key len invalid, len=%{public}u", originalKeyLen);
199 return;
200 }
201 FreeUint8Buffer(key, keyLen);
202 *key = new (std::nothrow) uint8_t[originalKeyLen];
203 if (*key == nullptr) {
204 DLP_LOG_ERROR(LABEL, "Alloc %{public}u buff for key fail", originalKeyLen);
205 return;
206 }
207 keyLen = originalKeyLen;
208 if (memcpy_s(*key, keyLen, originalKey, originalKeyLen) != EOK) {
209 DLP_LOG_ERROR(LABEL, "Memcpy key buff fail");
210 FreeUint8Buffer(key, keyLen);
211 return;
212 }
213 }
214
SetAeskey(const uint8_t * key,uint32_t keyLen)215 void PermissionPolicy::SetAeskey(const uint8_t* key, uint32_t keyLen)
216 {
217 DLP_LOG_DEBUG(LABEL, "Start set key.");
218 SetKey(key, keyLen, &aeskey_, aeskeyLen_);
219 }
220
GetAeskey() const221 uint8_t* PermissionPolicy::GetAeskey() const
222 {
223 return aeskey_;
224 }
225
GetAeskeyLen() const226 uint32_t PermissionPolicy::GetAeskeyLen() const
227 {
228 return aeskeyLen_;
229 }
230
SetIv(const uint8_t * iv,uint32_t ivLen)231 void PermissionPolicy::SetIv(const uint8_t* iv, uint32_t ivLen)
232 {
233 DLP_LOG_DEBUG(LABEL, "Start set offset.");
234 SetKey(iv, ivLen, &iv_, ivLen_);
235 }
236
GetIv() const237 uint8_t* PermissionPolicy::GetIv() const
238 {
239 return iv_;
240 }
241
GetIvLen() const242 uint32_t PermissionPolicy::GetIvLen() const
243 {
244 return ivLen_;
245 }
246
SetHmacKey(const uint8_t * key,uint32_t keyLen)247 void PermissionPolicy::SetHmacKey(const uint8_t* key, uint32_t keyLen)
248 {
249 DLP_LOG_DEBUG(LABEL, "Start set hmac key.");
250 SetKey(key, keyLen, &hmacKey_, hmacKeyLen_);
251 }
252
GetHmacKey() const253 uint8_t* PermissionPolicy::GetHmacKey() const
254 {
255 return hmacKey_;
256 }
257
GetHmacKeyLen() const258 uint32_t PermissionPolicy::GetHmacKeyLen() const
259 {
260 return hmacKeyLen_;
261 }
262
CopyPolicyHmac(const PermissionPolicy & srcPolicy)263 void PermissionPolicy::CopyPolicyHmac(const PermissionPolicy& srcPolicy)
264 {
265 if (srcPolicy.hmacKeyLen_ == 0 || srcPolicy.hmacKey_ == nullptr) {
266 return;
267 }
268 SetHmacKey(srcPolicy.hmacKey_, srcPolicy.hmacKeyLen_);
269 }
270
CopyPermissionPolicy(const PermissionPolicy & srcPolicy)271 void PermissionPolicy::CopyPermissionPolicy(const PermissionPolicy& srcPolicy)
272 {
273 if (!srcPolicy.IsValid()) {
274 return;
275 }
276 DLP_LOG_DEBUG(LABEL, "accountType %{public}u needOnline %{public}u expireTime %{private}" PRId64,
277 srcPolicy.ownerAccountType_, srcPolicy.needOnline_, srcPolicy.expireTime_);
278 ownerAccount_ = srcPolicy.ownerAccount_;
279 ownerAccountId_ = srcPolicy.ownerAccountId_;
280 ownerAccountType_ = srcPolicy.ownerAccountType_;
281 authUsers_ = srcPolicy.authUsers_;
282 supportEveryone_ = srcPolicy.supportEveryone_;
283 everyonePerm_ = srcPolicy.everyonePerm_;
284 expireTime_ = srcPolicy.expireTime_;
285 actionUponExpiry_ = srcPolicy.actionUponExpiry_;
286 needOnline_ = srcPolicy.needOnline_;
287 customProperty_ = srcPolicy.customProperty_;
288 SetAeskey(srcPolicy.aeskey_, srcPolicy.aeskeyLen_);
289 SetIv(srcPolicy.iv_, srcPolicy.ivLen_);
290 CopyPolicyHmac(srcPolicy);
291 dlpVersion_ = srcPolicy.dlpVersion_;
292 }
293
CheckActionUponExpiry()294 int32_t PermissionPolicy::CheckActionUponExpiry()
295 {
296 if (expireTime_ != NO_EXPIRATION_DATA) {
297 if (actionUponExpiry_ > static_cast<uint32_t>(ActionType::OPEN) ||
298 actionUponExpiry_ < static_cast<uint32_t>(ActionType::NOTOPEN)) {
299 return DLP_PARSE_ERROR_VALUE_INVALID;
300 }
301 } else {
302 actionUponExpiry_ = static_cast<uint32_t>(ActionType::NOTOPEN);
303 }
304 return DLP_OK;
305 }
306
CheckAccountType(DlpAccountType accountType)307 bool CheckAccountType(DlpAccountType accountType)
308 {
309 if (accountType != CLOUD_ACCOUNT && accountType != DOMAIN_ACCOUNT && accountType != APPLICATION_ACCOUNT) {
310 DLP_LOG_ERROR(LABEL, "Account type is invalid, type=%{public}d", accountType);
311 return false;
312 }
313 return true;
314 }
315
FreeCharBuffer(char * buff,uint32_t buffLen)316 void FreeCharBuffer(char* buff, uint32_t buffLen)
317 {
318 if (buff != nullptr) {
319 memset_s(buff, buffLen, 0, buffLen);
320 delete[] buff;
321 }
322 }
323
CheckAesParamLen(uint32_t len)324 bool CheckAesParamLen(uint32_t len)
325 {
326 return VALID_AESPARAM_LEN.count(len) > 0;
327 }
328
Marshalling(Parcel & out) const329 bool SandboxInfo::Marshalling(Parcel &out) const
330 {
331 if (!(out.WriteInt32(appIndex))) {
332 DLP_LOG_ERROR(LABEL, "Write appIndex fail");
333 return false;
334 }
335 if (!(out.WriteUint32(tokenId))) {
336 DLP_LOG_ERROR(LABEL, "Write tokenId fail");
337 return false;
338 }
339 return true;
340 }
341
Unmarshalling(Parcel & in)342 SandboxInfo* SandboxInfo::Unmarshalling(Parcel &in)
343 {
344 auto *parcel = new (std::nothrow) SandboxInfo();
345 if (parcel == nullptr) {
346 DLP_LOG_ERROR(LABEL, "Alloc buff for parcel fail");
347 return nullptr;
348 }
349 if (!(in.ReadInt32(parcel->appIndex))) {
350 DLP_LOG_ERROR(LABEL, "Read appIndex fail");
351 delete parcel;
352 return nullptr;
353 }
354 if (!(in.ReadUint32(parcel->tokenId))) {
355 DLP_LOG_ERROR(LABEL, "Read tokenId fail");
356 delete parcel;
357 return nullptr;
358 }
359 return parcel;
360 }
361 } // namespace DlpPermission
362 } // namespace Security
363 } // namespace OHOS