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