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