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