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 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 DLP_LOG_ERROR(LABEL, "Uint8 buffer is already nullptr.");
100 return;
101 }
102 if (*buff != nullptr) {
103 memset_s(*buff, buffLen, 0, buffLen);
104 delete[] *buff;
105 *buff = nullptr;
106 }
107 buffLen = 0;
108 }
109
FreePermissionPolicyMem()110 void PermissionPolicy::FreePermissionPolicyMem()
111 {
112 FreeUint8Buffer(&aeskey_, aeskeyLen_);
113 FreeUint8Buffer(&iv_, ivLen_);
114 FreeUint8Buffer(&hmacKey_, hmacKeyLen_);
115 ownerAccount_ = "";
116 ownerAccountId_ = "";
117 ownerAccountType_ = INVALID_ACCOUNT;
118 authUsers_.clear();
119 }
120
PermissionPolicy()121 PermissionPolicy::PermissionPolicy()
122 {
123 ownerAccount_ = "";
124 ownerAccountId_ = "";
125 ownerAccountType_ = INVALID_ACCOUNT;
126 authUsers_ = {};
127 expireTime_ = 0;
128 needOnline_ = 0;
129 aeskey_ = nullptr;
130 aeskeyLen_ = 0;
131 iv_ = nullptr;
132 ivLen_ = 0;
133 hmacKey_ = nullptr;
134 hmacKeyLen_ = 0;
135 dlpVersion_ = CURRENT_VERSION;
136 debug_ = false;
137 }
138
PermissionPolicy(const DlpProperty & property)139 PermissionPolicy::PermissionPolicy(const DlpProperty& property)
140 {
141 ownerAccount_ = property.ownerAccount;
142 ownerAccountId_ = property.ownerAccountId;
143 ownerAccountType_ = property.ownerAccountType;
144 authUsers_ = property.authUsers;
145 supportEveryone_ = property.supportEveryone;
146 everyonePerm_ = property.everyonePerm;
147 expireTime_ = property.expireTime;
148 needOnline_ = !property.offlineAccess;
149 aeskey_ = nullptr;
150 aeskeyLen_ = 0;
151 iv_ = nullptr;
152 ivLen_ = 0;
153 hmacKey_ = nullptr;
154 hmacKeyLen_ = 0;
155 dlpVersion_ = CURRENT_VERSION;
156 debug_ = false;
157 }
158
~PermissionPolicy()159 PermissionPolicy::~PermissionPolicy()
160 {
161 FreePermissionPolicyMem();
162 }
163
IsValid() const164 bool PermissionPolicy::IsValid() const
165 {
166 return (CheckAccount(this->ownerAccount_) && CheckAccount(this->ownerAccountId_) &&
167 CheckAccountType(this->ownerAccountType_) && CheckAesParam(this->aeskey_, this->aeskeyLen_) &&
168 CheckAesParam(this->iv_, this->ivLen_) && CheckAuthUserInfoList(this->authUsers_) &&
169 (this->hmacKeyLen_ == 0 || CheckAesParam(this->hmacKey_, this->hmacKeyLen_)));
170 }
171
SetDebug(bool debug)172 void PermissionPolicy::SetDebug(bool debug)
173 {
174 debug_ = debug;
175 }
176
SetKey(const uint8_t * originalKey,uint32_t originalKeyLen,uint8_t ** key,uint32_t & keyLen)177 static void SetKey(const uint8_t* originalKey, uint32_t originalKeyLen, uint8_t** key, uint32_t& keyLen)
178 {
179 if (key == nullptr) {
180 DLP_LOG_ERROR(LABEL, "key is null.");
181 return;
182 }
183 if (originalKey == nullptr) {
184 DLP_LOG_INFO(LABEL, "Set key to null");
185 FreeUint8Buffer(key, keyLen);
186 return;
187 }
188 if (!CheckAesParamLen(originalKeyLen)) {
189 DLP_LOG_ERROR(LABEL, "Key len invalid, len=%{public}u", keyLen);
190 return;
191 }
192 FreeUint8Buffer(key, keyLen);
193 *key = new (std::nothrow) uint8_t[originalKeyLen];
194 if (*key == nullptr) {
195 DLP_LOG_ERROR(LABEL, "Alloc %{public}u buff for key fail", keyLen);
196 return;
197 }
198 keyLen = originalKeyLen;
199 if (memcpy_s(*key, keyLen, originalKey, originalKeyLen) != EOK) {
200 DLP_LOG_ERROR(LABEL, "Memcpy key buff fail");
201 FreeUint8Buffer(key, keyLen);
202 return;
203 }
204 }
205
SetAeskey(const uint8_t * key,uint32_t keyLen)206 void PermissionPolicy::SetAeskey(const uint8_t* key, uint32_t keyLen)
207 {
208 DLP_LOG_DEBUG(LABEL, "Start set key.");
209 SetKey(key, keyLen, &aeskey_, aeskeyLen_);
210 }
211
GetAeskey() const212 uint8_t* PermissionPolicy::GetAeskey() const
213 {
214 return aeskey_;
215 }
216
GetAeskeyLen() const217 uint32_t PermissionPolicy::GetAeskeyLen() const
218 {
219 return aeskeyLen_;
220 }
221
SetIv(const uint8_t * iv,uint32_t ivLen)222 void PermissionPolicy::SetIv(const uint8_t* iv, uint32_t ivLen)
223 {
224 DLP_LOG_DEBUG(LABEL, "Start set offset.");
225 SetKey(iv, ivLen, &iv_, ivLen_);
226 }
227
GetIv() const228 uint8_t* PermissionPolicy::GetIv() const
229 {
230 return iv_;
231 }
232
GetIvLen() const233 uint32_t PermissionPolicy::GetIvLen() const
234 {
235 return ivLen_;
236 }
237
SetHmacKey(const uint8_t * key,uint32_t keyLen)238 void PermissionPolicy::SetHmacKey(const uint8_t* key, uint32_t keyLen)
239 {
240 DLP_LOG_DEBUG(LABEL, "Start set hmac key.");
241 SetKey(key, keyLen, &hmacKey_, hmacKeyLen_);
242 }
243
GetHmacKey() const244 uint8_t* PermissionPolicy::GetHmacKey() const
245 {
246 return hmacKey_;
247 }
248
GetHmacKeyLen() const249 uint32_t PermissionPolicy::GetHmacKeyLen() const
250 {
251 return hmacKeyLen_;
252 }
253
CopyPolicyHmac(const PermissionPolicy & srcPolicy)254 void PermissionPolicy::CopyPolicyHmac(const PermissionPolicy& srcPolicy)
255 {
256 if (srcPolicy.hmacKeyLen_ == 0 || srcPolicy.hmacKey_ == nullptr) {
257 return;
258 }
259 SetHmacKey(srcPolicy.hmacKey_, srcPolicy.hmacKeyLen_);
260 }
261
CopyPermissionPolicy(const PermissionPolicy & srcPolicy)262 void PermissionPolicy::CopyPermissionPolicy(const PermissionPolicy& srcPolicy)
263 {
264 if (!srcPolicy.IsValid()) {
265 return;
266 }
267 DLP_LOG_DEBUG(LABEL, "accountType %{public}u needOnline %{public}u expireTime %{private}" PRId64,
268 srcPolicy.ownerAccountType_, srcPolicy.needOnline_, srcPolicy.expireTime_);
269 ownerAccount_ = srcPolicy.ownerAccount_;
270 ownerAccountId_ = srcPolicy.ownerAccountId_;
271 ownerAccountType_ = srcPolicy.ownerAccountType_;
272 authUsers_ = srcPolicy.authUsers_;
273 supportEveryone_ = srcPolicy.supportEveryone_;
274 everyonePerm_ = srcPolicy.everyonePerm_;
275 expireTime_ = srcPolicy.expireTime_;
276 needOnline_ = srcPolicy.needOnline_;
277 SetAeskey(srcPolicy.aeskey_, srcPolicy.aeskeyLen_);
278 SetIv(srcPolicy.iv_, srcPolicy.ivLen_);
279 CopyPolicyHmac(srcPolicy);
280 dlpVersion_ = srcPolicy.dlpVersion_;
281 }
282
CheckAccountType(DlpAccountType accountType)283 bool CheckAccountType(DlpAccountType accountType)
284 {
285 if (accountType != CLOUD_ACCOUNT && accountType != DOMAIN_ACCOUNT && accountType != APPLICATION_ACCOUNT) {
286 DLP_LOG_ERROR(LABEL, "Account type is invalid, type=%{public}d", accountType);
287 return false;
288 }
289 return true;
290 }
291
FreeCharBuffer(char * buff,uint32_t buffLen)292 void FreeCharBuffer(char* buff, uint32_t buffLen)
293 {
294 if (buff != nullptr) {
295 memset_s(buff, buffLen, 0, buffLen);
296 delete[] buff;
297 }
298 }
299
CheckAesParamLen(uint32_t len)300 bool CheckAesParamLen(uint32_t len)
301 {
302 return VALID_AESPARAM_LEN.count(len) > 0;
303 }
304 } // namespace DlpPermission
305 } // namespace Security
306 } // namespace OHOS