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