• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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