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 <set>
19 #include "dlp_permission.h"
20 #include "dlp_permission_log.h"
21 #include "securec.h"
22
23 namespace OHOS {
24 namespace Security {
25 namespace DlpPermission {
26 namespace {
27 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpPolicyCheck"};
28 const uint32_t MAX_ACCOUNT_SIZE = 1024;
29 const uint32_t MAX_ACCOUNT_NUM = 100;
30 const std::set<uint32_t> VALID_AESPARAM_LEN = {16, 24, 32};
31 } // namespace
32
CheckAesParam(const uint8_t * buff,uint32_t len)33 static bool CheckAesParam(const uint8_t* buff, uint32_t len)
34 {
35 if (buff == nullptr) {
36 DLP_LOG_ERROR(LABEL, "Aes key or iv is null");
37 return false;
38 }
39 if (!CheckAesParamLen(len)) {
40 DLP_LOG_ERROR(LABEL, "Aes key or iv len invalid, len=%{public}u", len);
41 return false;
42 }
43 return true;
44 }
45
CheckAccount(const std::string & account)46 static bool CheckAccount(const std::string& account)
47 {
48 uint32_t accountSize = account.size();
49 if (accountSize == 0 || accountSize > MAX_ACCOUNT_SIZE) {
50 DLP_LOG_ERROR(LABEL, "Account len invalid, len=%{public}u", accountSize);
51 return false;
52 }
53 return true;
54 }
55
CheckPerm(uint32_t perm)56 static bool CheckPerm(uint32_t perm)
57 {
58 if (perm <= NO_PERMISSION || perm > FULL_CONTROL) {
59 DLP_LOG_ERROR(LABEL, "Auth Perm invalid, perm=%{public}u", perm);
60 return false;
61 }
62 return true;
63 }
64
CheckTime(uint64_t time)65 static bool CheckTime(uint64_t time)
66 {
67 uint64_t curTime = static_cast<uint64_t>(
68 std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count());
69 if (time < curTime) {
70 DLP_LOG_ERROR(LABEL, "Perm expiry time is earlier than current time, cur=%{public}s, set=%{public}s",
71 std::to_string(curTime).c_str(), std::to_string(time).c_str());
72 return false;
73 }
74 return true;
75 }
76
CheckAuthUserInfo(const AuthUserInfo & info)77 static bool CheckAuthUserInfo(const AuthUserInfo& info)
78 {
79 return (CheckAccount(info.authAccount) && CheckPerm(info.authPerm) && CheckTime(info.permExpiryTime) &&
80 CheckAccountType(info.authAccountType));
81 }
82
CheckAuthUserInfoList(const std::vector<AuthUserInfo> & authUsers_)83 static bool CheckAuthUserInfoList(const std::vector<AuthUserInfo>& authUsers_)
84 {
85 uint32_t userNum = authUsers_.size();
86 if (userNum > MAX_ACCOUNT_NUM) {
87 DLP_LOG_ERROR(LABEL, "Auth users number exceeds %{public}u, total=%{public}u", MAX_ACCOUNT_NUM, userNum);
88 return false;
89 }
90 return (std::none_of(authUsers_.begin(), authUsers_.end(),
91 [](const auto& iter) { return !CheckAuthUserInfo(iter); }));
92 }
93
FreeUint8Buffer(uint8_t ** buff,uint32_t & buffLen)94 static void FreeUint8Buffer(uint8_t** buff, uint32_t& buffLen)
95 {
96 if (*buff != nullptr) {
97 memset_s(*buff, buffLen, 0, buffLen);
98 delete[] *buff;
99 *buff = nullptr;
100 }
101 buffLen = 0;
102 }
103
FreePermissionPolicyMem()104 void PermissionPolicy::FreePermissionPolicyMem()
105 {
106 FreeUint8Buffer(&aeskey_, aeskeyLen_);
107 FreeUint8Buffer(&iv_, ivLen_);
108 ownerAccount_ = "";
109 ownerAccountId_ = "";
110 ownerAccountType_ = INVALID_ACCOUNT;
111 authUsers_.clear();
112 }
113
PermissionPolicy()114 PermissionPolicy::PermissionPolicy()
115 {
116 ownerAccount_ = "";
117 ownerAccountId_ = "";
118 ownerAccountType_ = INVALID_ACCOUNT;
119 authUsers_ = {};
120 aeskey_ = nullptr;
121 aeskeyLen_ = 0;
122 iv_ = nullptr;
123 ivLen_ = 0;
124 }
125
PermissionPolicy(const DlpProperty & property)126 PermissionPolicy::PermissionPolicy(const DlpProperty& property)
127 {
128 ownerAccount_ = property.ownerAccount;
129 ownerAccountId_ = property.ownerAccountId;
130 ownerAccountType_ = property.ownerAccountType;
131 authUsers_ = property.authUsers;
132 supportEveryone_ = property.supportEveryone;
133 everyonePerm_ = property.everyonePerm;
134 aeskey_ = nullptr;
135 aeskeyLen_ = 0;
136 iv_ = nullptr;
137 ivLen_ = 0;
138 }
139
~PermissionPolicy()140 PermissionPolicy::~PermissionPolicy()
141 {
142 FreePermissionPolicyMem();
143 }
144
IsValid() const145 bool PermissionPolicy::IsValid() const
146 {
147 return (CheckAccount(this->ownerAccount_) && CheckAccount(this->ownerAccountId_) &&
148 CheckAccountType(this->ownerAccountType_) && CheckAesParam(this->aeskey_, this->aeskeyLen_) &&
149 CheckAesParam(this->iv_, this->ivLen_) && CheckAuthUserInfoList(this->authUsers_));
150 }
151
SetAeskey(const uint8_t * key,uint32_t keyLen)152 void PermissionPolicy::SetAeskey(const uint8_t* key, uint32_t keyLen)
153 {
154 if (key == nullptr) {
155 DLP_LOG_INFO(LABEL, "Set aes key to null");
156 FreeUint8Buffer(&aeskey_, aeskeyLen_);
157 return;
158 }
159 if (!CheckAesParamLen(keyLen)) {
160 DLP_LOG_ERROR(LABEL, "Aes key len invalid, len=%{public}u", keyLen);
161 return;
162 }
163 FreeUint8Buffer(&aeskey_, aeskeyLen_);
164 if (keyLen < 1) {
165 DLP_LOG_ERROR(LABEL, "keyLen error");
166 return;
167 }
168 aeskey_ = new (std::nothrow) uint8_t[keyLen];
169 if (aeskey_ == nullptr) {
170 DLP_LOG_ERROR(LABEL, "Alloc %{public}u buff for aes key fail", keyLen);
171 return;
172 }
173 aeskeyLen_ = keyLen;
174 if (memcpy_s(aeskey_, aeskeyLen_, key, keyLen) != EOK) {
175 DLP_LOG_ERROR(LABEL, "Memcpy aes key buff fail");
176 FreeUint8Buffer(&aeskey_, aeskeyLen_);
177 return;
178 }
179 }
180
GetAeskey() const181 uint8_t* PermissionPolicy::GetAeskey() const
182 {
183 return aeskey_;
184 }
185
GetAeskeyLen() const186 uint32_t PermissionPolicy::GetAeskeyLen() const
187 {
188 return aeskeyLen_;
189 }
190
SetIv(const uint8_t * iv,uint32_t ivLen)191 void PermissionPolicy::SetIv(const uint8_t* iv, uint32_t ivLen)
192 {
193 if (iv == nullptr) {
194 DLP_LOG_INFO(LABEL, "Set iv to null");
195 FreeUint8Buffer(&iv_, ivLen_);
196 return;
197 }
198 if (!CheckAesParamLen(ivLen)) {
199 DLP_LOG_ERROR(LABEL, "Iv len invalid, len=%{public}u", ivLen);
200 return;
201 }
202 FreeUint8Buffer(&iv_, ivLen_);
203 if (ivLen < 1) {
204 DLP_LOG_ERROR(LABEL, "ivLen error %{public}u", ivLen);
205 return;
206 }
207 iv_ = new (std::nothrow) uint8_t[ivLen];
208 if (iv_ == nullptr) {
209 DLP_LOG_ERROR(LABEL, "Alloc %{public}u buff for iv fail", ivLen);
210 return;
211 }
212 ivLen_ = ivLen;
213 if (memcpy_s(iv_, ivLen_, iv, ivLen) != EOK) {
214 DLP_LOG_ERROR(LABEL, "Memcpy iv buff fail");
215 FreeUint8Buffer(&iv_, ivLen_);
216 return;
217 }
218 }
219
GetIv() const220 uint8_t* PermissionPolicy::GetIv() const
221 {
222 return iv_;
223 }
224
GetIvLen() const225 uint32_t PermissionPolicy::GetIvLen() const
226 {
227 return ivLen_;
228 }
229
CopyPermissionPolicy(const PermissionPolicy & srcPolicy)230 void PermissionPolicy::CopyPermissionPolicy(const PermissionPolicy& srcPolicy)
231 {
232 if (!srcPolicy.IsValid()) {
233 return;
234 }
235 DLP_LOG_DEBUG(LABEL, "ownerAccount_ %{private}s ownerAccountId %{private}s accountType %{public}u",
236 srcPolicy.ownerAccount_.c_str(), srcPolicy.ownerAccountId_.c_str(), srcPolicy.ownerAccountType_);
237 ownerAccount_ = srcPolicy.ownerAccount_;
238 ownerAccountId_ = srcPolicy.ownerAccountId_;
239 ownerAccountType_ = srcPolicy.ownerAccountType_;
240 authUsers_ = srcPolicy.authUsers_;
241 supportEveryone_ = srcPolicy.supportEveryone_;
242 everyonePerm_ = srcPolicy.everyonePerm_;
243 aeskeyLen_ = srcPolicy.aeskeyLen_;
244 aeskey_ = new (std::nothrow) uint8_t[aeskeyLen_];
245 if (aeskey_ == nullptr) {
246 DLP_LOG_ERROR(LABEL, "Alloc %{public}u buff for aes key fail", aeskeyLen_);
247 return;
248 }
249 if (memcpy_s(aeskey_, aeskeyLen_, srcPolicy.aeskey_, srcPolicy.aeskeyLen_) != EOK) {
250 DLP_LOG_ERROR(LABEL, "Memcpy aes key buff fail");
251 FreePermissionPolicyMem();
252 return;
253 }
254 ivLen_ = srcPolicy.ivLen_;
255 iv_ = new (std::nothrow) uint8_t[ivLen_];
256 if (iv_ == nullptr) {
257 DLP_LOG_ERROR(LABEL, "Alloc %{public}u buff for iv fail", ivLen_);
258 FreePermissionPolicyMem();
259 return;
260 }
261 if (memcpy_s(iv_, ivLen_, srcPolicy.iv_, srcPolicy.ivLen_) != EOK) {
262 DLP_LOG_ERROR(LABEL, "Memcpy iv buff fail");
263 FreePermissionPolicyMem();
264 return;
265 }
266 }
267
CheckAccountType(DlpAccountType accountType)268 bool CheckAccountType(DlpAccountType accountType)
269 {
270 if (accountType != CLOUD_ACCOUNT && accountType != DOMAIN_ACCOUNT && accountType != APPLICATION_ACCOUNT) {
271 DLP_LOG_ERROR(LABEL, "Account type is invalid, type=%{public}d", accountType);
272 return false;
273 }
274 return true;
275 }
276
FreeCharBuffer(char * buff,uint32_t buffLen)277 void FreeCharBuffer(char* buff, uint32_t buffLen)
278 {
279 if (buff != nullptr) {
280 memset_s(buff, buffLen, 0, buffLen);
281 delete[] buff;
282 buff = nullptr;
283 }
284 }
285
CheckAesParamLen(uint32_t len)286 bool CheckAesParamLen(uint32_t len)
287 {
288 return VALID_AESPARAM_LEN.count(len) > 0;
289 }
290 } // namespace DlpPermission
291 } // namespace Security
292 } // namespace OHOS