• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "accesstoken_id_manager.h"
17 #include "accesstoken_log.h"
18 #include "access_token_error.h"
19 #include "data_validator.h"
20 #include "random.h"
21 
22 namespace OHOS {
23 namespace Security {
24 namespace AccessToken {
25 namespace {
26 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenIDManager"};
27 }
28 
GetTokenIdTypeEnum(AccessTokenID id)29 ATokenTypeEnum AccessTokenIDManager::GetTokenIdTypeEnum(AccessTokenID id)
30 {
31     AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
32     return static_cast<ATokenTypeEnum>(idInner->type);
33 }
34 
GetTokenIdDlpFlag(AccessTokenID id)35 int AccessTokenIDManager::GetTokenIdDlpFlag(AccessTokenID id)
36 {
37     AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
38     return idInner->dlpFlag;
39 }
40 
GetTokenIdType(AccessTokenID id)41 ATokenTypeEnum AccessTokenIDManager::GetTokenIdType(AccessTokenID id)
42 {
43     {
44         Utils::UniqueReadGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
45         if (tokenIdSet_.count(id) == 0) {
46             return TOKEN_INVALID;
47         }
48     }
49     return GetTokenIdTypeEnum(id);
50 }
51 
RegisterTokenId(AccessTokenID id,ATokenTypeEnum type)52 int AccessTokenIDManager::RegisterTokenId(AccessTokenID id, ATokenTypeEnum type)
53 {
54     AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
55     if (idInner->version != DEFAULT_TOKEN_VERSION || idInner->type != type) {
56         return ERR_PARAM_INVALID;
57     }
58 
59     Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
60 
61     for (std::set<AccessTokenID>::iterator it = tokenIdSet_.begin(); it != tokenIdSet_.end(); ++it) {
62         AccessTokenID tokenId = *it;
63         AccessTokenIDInner *idInnerExist = reinterpret_cast<AccessTokenIDInner *>(&tokenId);
64         if (idInnerExist->tokenUniqueID == idInner->tokenUniqueID) {
65             return ERR_TOKENID_HAS_EXISTED;
66         }
67     }
68     tokenIdSet_.insert(id);
69     return RET_SUCCESS;
70 }
71 
GetHapTokenIdList(std::vector<AccessTokenID> & idList)72 void AccessTokenIDManager::GetHapTokenIdList(std::vector<AccessTokenID>& idList)
73 {
74     Utils::UniqueReadGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
75 
76     for (std::set<AccessTokenID>::iterator it = tokenIdSet_.begin(); it != tokenIdSet_.end(); ++it) {
77         idList.emplace_back(*it);
78     }
79 }
80 
CreateTokenId(ATokenTypeEnum type,int dlpType) const81 AccessTokenID AccessTokenIDManager::CreateTokenId(ATokenTypeEnum type, int dlpType) const
82 {
83     unsigned int rand = GetRandomUint32();
84     if (rand == 0) {
85         ACCESSTOKEN_LOG_ERROR(LABEL, "get random failed");
86         return 0;
87     }
88 
89     AccessTokenIDInner innerId = {0};
90     innerId.version = DEFAULT_TOKEN_VERSION;
91     innerId.type = type;
92     innerId.res = 0;
93     innerId.renderFlag = 0;
94     innerId.dlpFlag = (dlpType == 0) ? 0 : 1;
95     innerId.tokenUniqueID = rand & TOKEN_RANDOM_MASK;
96     AccessTokenID tokenId = *reinterpret_cast<AccessTokenID *>(&innerId);
97     return tokenId;
98 }
99 
CreateAndRegisterTokenId(ATokenTypeEnum type,int dlpType)100 AccessTokenID AccessTokenIDManager::CreateAndRegisterTokenId(ATokenTypeEnum type, int dlpType)
101 {
102     AccessTokenID tokenId = 0;
103     // random maybe repeat, retry twice.
104     for (int i = 0; i < MAX_CREATE_TOKEN_ID_RETRY; i++) {
105         tokenId = CreateTokenId(type, dlpType);
106         if (tokenId == INVALID_TOKENID) {
107             ACCESSTOKEN_LOG_ERROR(LABEL, "create tokenId failed");
108             return INVALID_TOKENID;
109         }
110 
111         int ret = RegisterTokenId(tokenId, type);
112         if (ret == RET_SUCCESS) {
113             break;
114         } else if (i < MAX_CREATE_TOKEN_ID_RETRY - 1) {
115             ACCESSTOKEN_LOG_WARN(LABEL, "reigster tokenId failed, maybe repeat, retry");
116         } else {
117             ACCESSTOKEN_LOG_ERROR(LABEL, "reigster tokenId finally failed");
118             tokenId = INVALID_TOKENID;
119         }
120     }
121     return tokenId;
122 }
123 
ReleaseTokenId(AccessTokenID id)124 void AccessTokenIDManager::ReleaseTokenId(AccessTokenID id)
125 {
126     Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
127     if (tokenIdSet_.count(id) == 0) {
128         ACCESSTOKEN_LOG_INFO(LABEL, "id %{public}x is not exist", id);
129         return;
130     }
131     tokenIdSet_.erase(id);
132 }
133 
GetInstance()134 AccessTokenIDManager& AccessTokenIDManager::GetInstance()
135 {
136     static AccessTokenIDManager instance;
137     return instance;
138 }
139 } // namespace AccessToken
140 } // namespace Security
141 } // namespace OHOS
142