• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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