1 /*
2 * Copyright (c) 2021-2025 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 <mutex>
18 #include "accesstoken_common_log.h"
19 #include "access_token_error.h"
20 #include "data_validator.h"
21 #include "random.h"
22 #include "tokenid_attributes.h"
23
24 namespace OHOS {
25 namespace Security {
26 namespace AccessToken {
27 namespace {
28 std::recursive_mutex g_instanceMutex;
29 }
30
GetTokenIdType(AccessTokenID id)31 ATokenTypeEnum AccessTokenIDManager::GetTokenIdType(AccessTokenID id)
32 {
33 {
34 Utils::UniqueReadGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
35 if (tokenIdSet_.count(id) == 0) {
36 return TOKEN_INVALID;
37 }
38 }
39 return TokenIDAttributes::GetTokenIdTypeEnum(id);
40 }
41
RegisterTokenId(AccessTokenID id,ATokenTypeEnum type)42 int AccessTokenIDManager::RegisterTokenId(AccessTokenID id, ATokenTypeEnum type)
43 {
44 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
45 if (idInner->version != DEFAULT_TOKEN_VERSION || idInner->type != type) {
46 return ERR_PARAM_INVALID;
47 }
48
49 Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
50
51 for (std::set<AccessTokenID>::iterator it = tokenIdSet_.begin(); it != tokenIdSet_.end(); ++it) {
52 AccessTokenID tokenId = *it;
53 AccessTokenIDInner *idInnerExist = reinterpret_cast<AccessTokenIDInner *>(&tokenId);
54 if ((type == idInnerExist->type) && (idInnerExist->tokenUniqueID == idInner->tokenUniqueID)) {
55 return ERR_TOKENID_HAS_EXISTED;
56 }
57 }
58 tokenIdSet_.insert(id);
59 return RET_SUCCESS;
60 }
61
CreateTokenId(ATokenTypeEnum type,int32_t dlpFlag,int32_t cloneFlag) const62 AccessTokenID AccessTokenIDManager::CreateTokenId(ATokenTypeEnum type, int32_t dlpFlag, int32_t cloneFlag) const
63 {
64 uint32_t rand = GetRandomUint32FromUrandom();
65 if (rand == 0) {
66 LOGE(ATM_DOMAIN, ATM_TAG, "Get random failed");
67 return 0;
68 }
69
70 AccessTokenIDInner innerId = {0};
71 innerId.version = DEFAULT_TOKEN_VERSION;
72 innerId.type = type;
73 innerId.res = 0;
74 innerId.cloneFlag = static_cast<uint32_t>(cloneFlag);
75 innerId.renderFlag = 0;
76 innerId.dlpFlag = static_cast<uint32_t>(dlpFlag);
77 innerId.tokenUniqueID = rand & TOKEN_RANDOM_MASK;
78 AccessTokenID tokenId = *reinterpret_cast<AccessTokenID *>(&innerId);
79 return tokenId;
80 }
81
CreateAndRegisterTokenId(ATokenTypeEnum type,int32_t dlpFlag,int32_t cloneFlag)82 AccessTokenID AccessTokenIDManager::CreateAndRegisterTokenId(ATokenTypeEnum type, int32_t dlpFlag, int32_t cloneFlag)
83 {
84 AccessTokenID tokenId = 0;
85 // random maybe repeat, retry twice.
86 for (int i = 0; i < MAX_CREATE_TOKEN_ID_RETRY; i++) {
87 tokenId = CreateTokenId(type, dlpFlag, cloneFlag);
88 if (tokenId == INVALID_TOKENID) {
89 LOGE(ATM_DOMAIN, ATM_TAG, "Create tokenId failed");
90 return INVALID_TOKENID;
91 }
92
93 int ret = RegisterTokenId(tokenId, type);
94 if (ret == RET_SUCCESS) {
95 break;
96 } else if (i < MAX_CREATE_TOKEN_ID_RETRY - 1) {
97 LOGW(ATM_DOMAIN, ATM_TAG, "Reigster tokenId failed(error=%{public}d), maybe repeat, retry.", ret);
98 } else {
99 LOGE(ATM_DOMAIN, ATM_TAG, "Reigster tokenId finally failed(error=%{public}d).", ret);
100 tokenId = INVALID_TOKENID;
101 }
102 }
103 return tokenId;
104 }
105
ReleaseTokenId(AccessTokenID id)106 void AccessTokenIDManager::ReleaseTokenId(AccessTokenID id)
107 {
108 Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
109 if (tokenIdSet_.count(id) == 0) {
110 LOGI(ATM_DOMAIN, ATM_TAG, "Id %{public}x is not exist", id);
111 return;
112 }
113 tokenIdSet_.erase(id);
114 }
115
GetInstance()116 AccessTokenIDManager& AccessTokenIDManager::GetInstance()
117 {
118 static AccessTokenIDManager* instance = nullptr;
119 if (instance == nullptr) {
120 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
121 if (instance == nullptr) {
122 AccessTokenIDManager* tmp = new AccessTokenIDManager();
123 instance = std::move(tmp);
124 }
125 }
126 return *instance;
127 }
128 } // namespace AccessToken
129 } // namespace Security
130 } // namespace OHOS
131