1 /*
2 * Copyright (c) 2024-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 "el5_filekey_manager_client.h"
17
18 #include "el5_filekey_manager_log.h"
19 #include "el5_filekey_manager_interface_proxy.h"
20 #include "el5_filekey_manager_error.h"
21 #include "app_key_load_info.h"
22 #include "user_app_key_info.h"
23 #include "iservice_registry.h"
24 #include "refbase.h"
25 #include "system_ability_definition.h"
26 #include "sys_binder.h"
27
28 namespace OHOS {
29 namespace Security {
30 namespace AccessToken {
31 namespace {
32 constexpr int32_t LOAD_SA_TIMEOUT_SECOND = 4;
33 constexpr int32_t LOAD_SA_RETRY_TIMES = 5;
34 constexpr int32_t SA_REQUEST_RETRY_TIMES = 3;
35 static const int32_t SENDREQ_FAIL_ERR = 32;
36 static const std::vector<int32_t> RETRY_CODE_LIST = { BR_DEAD_REPLY, BR_FAILED_REPLY, SENDREQ_FAIL_ERR };
37 }
El5FilekeyManagerClient()38 El5FilekeyManagerClient::El5FilekeyManagerClient() {}
39
~El5FilekeyManagerClient()40 El5FilekeyManagerClient::~El5FilekeyManagerClient() {}
41
GetInstance()42 El5FilekeyManagerClient &El5FilekeyManagerClient::GetInstance()
43 {
44 static El5FilekeyManagerClient instance;
45 return instance;
46 }
47
AcquireAccess(DataLockType type)48 int32_t El5FilekeyManagerClient::AcquireAccess(DataLockType type)
49 {
50 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
51 return proxy->AcquireAccess(type);
52 };
53 return CallProxyWithRetry(func, __FUNCTION__);
54 }
55
ReleaseAccess(DataLockType type)56 int32_t El5FilekeyManagerClient::ReleaseAccess(DataLockType type)
57 {
58 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
59 return proxy->ReleaseAccess(type);
60 };
61 return CallProxyWithRetry(func, __FUNCTION__);
62 }
63
GenerateAppKey(uint32_t uid,const std::string & bundleName,std::string & keyId)64 int32_t El5FilekeyManagerClient::GenerateAppKey(uint32_t uid, const std::string &bundleName, std::string &keyId)
65 {
66 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
67 return proxy->GenerateAppKey(uid, bundleName, keyId);
68 };
69 return CallProxyWithRetry(func, __FUNCTION__);
70 }
71
DeleteAppKey(const std::string & bundleName,int32_t userId)72 int32_t El5FilekeyManagerClient::DeleteAppKey(const std::string &bundleName, int32_t userId)
73 {
74 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
75 return proxy->DeleteAppKey(bundleName, userId);
76 };
77 return CallProxyWithRetry(func, __FUNCTION__);
78 }
79
GetUserAppKey(int32_t userId,bool getAllFlag,std::vector<std::pair<int32_t,std::string>> & keyInfos)80 int32_t El5FilekeyManagerClient::GetUserAppKey(int32_t userId, bool getAllFlag,
81 std::vector<std::pair<int32_t, std::string>> &keyInfos)
82 {
83 std::vector<UserAppKeyInfo> userAppKeyInfos;
84 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
85 return proxy->GetUserAppKey(userId, getAllFlag, userAppKeyInfos);
86 };
87 int32_t ret = CallProxyWithRetry(func, __FUNCTION__, SA_REQUEST_RETRY_TIMES);
88 for (auto const &it : userAppKeyInfos) {
89 keyInfos.emplace_back(std::make_pair(it.first, it.second));
90 }
91 return ret;
92 }
93
ChangeUserAppkeysLoadInfo(int32_t userId,std::vector<std::pair<std::string,bool>> & loadInfos)94 int32_t El5FilekeyManagerClient::ChangeUserAppkeysLoadInfo(int32_t userId,
95 std::vector<std::pair<std::string, bool>> &loadInfos)
96 {
97 std::vector<AppKeyLoadInfo> appKeyLoadInfos;
98 for (auto &it : loadInfos) {
99 appKeyLoadInfos.emplace_back(AppKeyLoadInfo(it.first, it.second));
100 }
101 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
102 return proxy->ChangeUserAppkeysLoadInfo(userId, appKeyLoadInfos);
103 };
104 return CallProxyWithRetry(func, __FUNCTION__);
105 }
106
SetFilePathPolicy()107 int32_t El5FilekeyManagerClient::SetFilePathPolicy()
108 {
109 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
110 return proxy->SetFilePathPolicy();
111 };
112 return CallProxyWithRetry(func, __FUNCTION__);
113 }
114
RegisterCallback(const sptr<El5FilekeyCallbackInterface> & callback)115 int32_t El5FilekeyManagerClient::RegisterCallback(const sptr<El5FilekeyCallbackInterface> &callback)
116 {
117 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
118 return proxy->RegisterCallback(callback);
119 };
120 return CallProxyWithRetry(func, __FUNCTION__);
121 }
122
GenerateGroupIDKey(uint32_t uid,const std::string & groupID,std::string & keyId)123 int32_t El5FilekeyManagerClient::GenerateGroupIDKey(uint32_t uid, const std::string &groupID, std::string &keyId)
124 {
125 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
126 return proxy->GenerateGroupIDKey(uid, groupID, keyId);
127 };
128 return CallProxyWithRetry(func, __FUNCTION__);
129 }
130
DeleteGroupIDKey(uint32_t uid,const std::string & groupID)131 int32_t El5FilekeyManagerClient::DeleteGroupIDKey(uint32_t uid, const std::string &groupID)
132 {
133 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
134 return proxy->DeleteGroupIDKey(uid, groupID);
135 };
136 return CallProxyWithRetry(func, __FUNCTION__);
137 }
138
QueryAppKeyState(DataLockType type)139 int32_t El5FilekeyManagerClient::QueryAppKeyState(DataLockType type)
140 {
141 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
142 return proxy->QueryAppKeyState(type);
143 };
144 return CallProxyWithRetry(func, __FUNCTION__);
145 }
146
GetProxy()147 sptr<El5FilekeyManagerInterface> El5FilekeyManagerClient::GetProxy()
148 {
149 std::unique_lock<std::mutex> lock(proxyMutex_);
150 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
151 if (systemAbilityManager == nullptr) {
152 LOG_ERROR("Get system ability manager failed.");
153 return nullptr;
154 }
155
156 auto el5FilekeyService = systemAbilityManager->CheckSystemAbility(EL5_FILEKEY_MANAGER_SERVICE_ID);
157 if (el5FilekeyService != nullptr) {
158 LOG_INFO("get el5 filekey manager proxy success");
159 return iface_cast<El5FilekeyManagerInterface>(el5FilekeyService);
160 }
161
162 for (int i = 0; i <= LOAD_SA_RETRY_TIMES; i++) {
163 el5FilekeyService =
164 systemAbilityManager->LoadSystemAbility(EL5_FILEKEY_MANAGER_SERVICE_ID, LOAD_SA_TIMEOUT_SECOND);
165 if (el5FilekeyService != nullptr) {
166 LOG_INFO("load el5 filekey manager success");
167 return iface_cast<El5FilekeyManagerInterface>(el5FilekeyService);
168 }
169 LOG_INFO("load el5 filekey manager failed, retry count:%{public}d", i);
170 }
171 LOG_ERROR("get el5 filekey manager proxy failed");
172 return nullptr;
173 }
174
CallProxyWithRetry(const std::function<int32_t (sptr<El5FilekeyManagerInterface> &)> & func,const char * funcName,int32_t retryTimes)175 int32_t El5FilekeyManagerClient::CallProxyWithRetry(
176 const std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> &func, const char *funcName, int32_t retryTimes)
177 {
178 LOG_INFO("call proxy with retry function:%s", funcName);
179 auto proxy = GetProxy();
180 if (proxy != nullptr) {
181 int32_t ret = func(proxy);
182 if (!IsRequestNeedRetry(ret)) {
183 return ret;
184 }
185 LOG_WARN("First try cal %{public}s failed ret:%{public}d. Begin retry", funcName, ret);
186 } else {
187 LOG_WARN("First try call %{public}s failed, proxy is NULL. Begin retry.", funcName);
188 }
189
190 for (int32_t i = 0; i < retryTimes; i++) {
191 proxy = GetProxy();
192 if (proxy == nullptr) {
193 LOG_WARN("Get proxy %{public}s failed, retry time = %{public}d.", funcName, i);
194 continue;
195 }
196 int32_t ret = func(proxy);
197 if (!IsRequestNeedRetry(ret)) {
198 return ret;
199 }
200 LOG_WARN("Call %{public}s failed, retry time = %{public}d, result = %{public}d", funcName, i, ret);
201 }
202 LOG_ERROR("Retry call service %{public}s error, tried %{public}d times.", funcName, retryTimes);
203 return EFM_ERR_REMOTE_CONNECTION;
204 }
205
IsRequestNeedRetry(int32_t ret)206 bool El5FilekeyManagerClient::IsRequestNeedRetry(int32_t ret)
207 {
208 auto it = std::find(RETRY_CODE_LIST.begin(), RETRY_CODE_LIST.end(), ret);
209 return it != RETRY_CODE_LIST.end();
210 }
211 } // namespace AccessToken
212 } // namespace Security
213 } // namespace OHOS
214