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