1 /*
2  * Copyright (c) 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 "user_idm_client_impl.h"
17 
18 #include "system_ability_definition.h"
19 
20 #include "callback_manager.h"
21 #include "iam_logger.h"
22 #include "ipc_client_utils.h"
23 #include "user_idm_callback_service.h"
24 
25 #define LOG_TAG "USER_IDM_SDK"
26 
27 namespace OHOS {
28 namespace UserIam {
29 namespace UserAuth {
OpenSession(int32_t userId)30 std::vector<uint8_t> UserIdmClientImpl::OpenSession(int32_t userId)
31 {
32     IAM_LOGI("start, userId:%{public}d", userId);
33     auto proxy = GetProxy();
34     if (!proxy) {
35         IAM_LOGE("proxy is nullptr");
36         return {};
37     }
38 
39     std::vector<uint8_t> challenge;
40     auto success = proxy->OpenSession(userId, challenge);
41     if (success != SUCCESS) {
42         IAM_LOGE("OpenSession ret = %{public}d", success);
43     }
44 
45     return challenge;
46 }
47 
CloseSession(int32_t userId)48 void UserIdmClientImpl::CloseSession(int32_t userId)
49 {
50     IAM_LOGI("start, userId:%{public}d", userId);
51     auto proxy = GetProxy();
52     if (!proxy) {
53         IAM_LOGE("proxy is nullptr");
54         return;
55     }
56 
57     proxy->CloseSession(userId);
58 }
59 
AddCredential(int32_t userId,const CredentialParameters & para,const std::shared_ptr<UserIdmClientCallback> & callback)60 void UserIdmClientImpl::AddCredential(int32_t userId, const CredentialParameters &para,
61     const std::shared_ptr<UserIdmClientCallback> &callback)
62 {
63     IAM_LOGI("start, userId:%{public}d, authType:%{public}d, authSubType:%{public}d",
64         userId, para.authType, para.pinType.value_or(PIN_SIX));
65     if (!callback) {
66         IAM_LOGE("user idm client callback is nullptr");
67         return;
68     }
69     auto proxy = GetProxy();
70     if (!proxy) {
71         IAM_LOGE("proxy is nullptr");
72         Attributes extraInfo;
73         callback->OnResult(GENERAL_ERROR, extraInfo);
74         return;
75     }
76 
77     sptr<IdmCallbackInterface> wrapper(new (std::nothrow) IdmCallbackService(callback));
78     if (wrapper == nullptr) {
79         IAM_LOGE("failed to create wrapper");
80         Attributes extraInfo;
81         callback->OnResult(GENERAL_ERROR, extraInfo);
82         return;
83     }
84     UserIdmInterface::CredentialPara credPara = {};
85     credPara.authType = para.authType;
86     credPara.pinType = para.pinType.value_or(PIN_SIX);
87     credPara.token = std::move(para.token);
88     proxy->AddCredential(userId, credPara, wrapper, false);
89 }
90 
UpdateCredential(int32_t userId,const CredentialParameters & para,const std::shared_ptr<UserIdmClientCallback> & callback)91 void UserIdmClientImpl::UpdateCredential(int32_t userId, const CredentialParameters &para,
92     const std::shared_ptr<UserIdmClientCallback> &callback)
93 {
94     IAM_LOGI("start, userId:%{public}d, authType:%{public}d, authSubType:%{public}d",
95         userId, para.authType, para.pinType.value_or(PIN_SIX));
96     if (!callback) {
97         IAM_LOGE("user idm client callback is nullptr");
98         return;
99     }
100     auto proxy = GetProxy();
101     if (!proxy) {
102         IAM_LOGE("proxy is nullptr");
103         Attributes extraInfo;
104         callback->OnResult(GENERAL_ERROR, extraInfo);
105         return;
106     }
107 
108     sptr<IdmCallbackInterface> wrapper(new (std::nothrow) IdmCallbackService(callback));
109     if (wrapper == nullptr) {
110         IAM_LOGE("failed to create wrapper");
111         Attributes extraInfo;
112         callback->OnResult(GENERAL_ERROR, extraInfo);
113         return;
114     }
115     UserIdmInterface::CredentialPara credPara = {};
116     credPara.authType = para.authType;
117     credPara.pinType = para.pinType.value_or(PIN_SIX);
118     credPara.token = std::move(para.token);
119     proxy->UpdateCredential(userId, credPara, wrapper);
120 }
121 
Cancel(int32_t userId)122 int32_t UserIdmClientImpl::Cancel(int32_t userId)
123 {
124     IAM_LOGI("start, userId:%{public}d", userId);
125     auto proxy = GetProxy();
126     if (!proxy) {
127         IAM_LOGE("proxy is nullptr");
128         return GENERAL_ERROR;
129     }
130 
131     return proxy->Cancel(userId);
132 }
133 
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const std::shared_ptr<UserIdmClientCallback> & callback)134 void UserIdmClientImpl::DeleteCredential(int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken,
135     const std::shared_ptr<UserIdmClientCallback> &callback)
136 {
137     IAM_LOGI("start, userId:%{public}d", userId);
138     if (!callback) {
139         IAM_LOGE("user idm client callback is nullptr");
140         return;
141     }
142     auto proxy = GetProxy();
143     if (!proxy) {
144         IAM_LOGE("proxy is nullptr");
145         Attributes extraInfo;
146         callback->OnResult(GENERAL_ERROR, extraInfo);
147         return;
148     }
149 
150     sptr<IdmCallbackInterface> wrapper(new (std::nothrow) IdmCallbackService(callback));
151     if (wrapper == nullptr) {
152         IAM_LOGE("failed to create wrapper");
153         Attributes extraInfo;
154         callback->OnResult(GENERAL_ERROR, extraInfo);
155         return;
156     }
157     proxy->DelCredential(userId, credentialId, authToken, wrapper);
158 }
159 
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,const std::shared_ptr<UserIdmClientCallback> & callback)160 void UserIdmClientImpl::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
161     const std::shared_ptr<UserIdmClientCallback> &callback)
162 {
163     IAM_LOGI("start, userId:%{public}d", userId);
164     if (!callback) {
165         IAM_LOGE("user idm client callback is nullptr");
166         return;
167     }
168     auto proxy = GetProxy();
169     if (!proxy) {
170         IAM_LOGE("proxy is nullptr");
171         Attributes extraInfo;
172         callback->OnResult(GENERAL_ERROR, extraInfo);
173         return;
174     }
175 
176     sptr<IdmCallbackInterface> wrapper(new (std::nothrow) IdmCallbackService(callback));
177     if (wrapper == nullptr) {
178         IAM_LOGE("failed to create wrapper");
179         Attributes extraInfo;
180         callback->OnResult(GENERAL_ERROR, extraInfo);
181         return;
182     }
183     proxy->DelUser(userId, authToken, wrapper);
184 }
185 
EraseUser(int32_t userId,const std::shared_ptr<UserIdmClientCallback> & callback)186 int32_t UserIdmClientImpl::EraseUser(int32_t userId, const std::shared_ptr<UserIdmClientCallback> &callback)
187 {
188     IAM_LOGI("start, userId:%{public}d", userId);
189     if (!callback) {
190         IAM_LOGE("user idm client callback is nullptr");
191         return GENERAL_ERROR;
192     }
193     auto proxy = GetProxy();
194     if (!proxy) {
195         IAM_LOGE("proxy is nullptr");
196         Attributes extraInfo;
197         callback->OnResult(GENERAL_ERROR, extraInfo);
198         return GENERAL_ERROR;
199     }
200     sptr<IdmCallbackInterface> wrapper(new (std::nothrow) IdmCallbackService(callback));
201     if (wrapper == nullptr) {
202         IAM_LOGE("failed to create wrapper");
203         Attributes extraInfo;
204         callback->OnResult(GENERAL_ERROR, extraInfo);
205         return GENERAL_ERROR;
206     }
207     return proxy->EnforceDelUser(userId, wrapper);
208 }
209 
GetCredentialInfo(int32_t userId,AuthType authType,const std::shared_ptr<GetCredentialInfoCallback> & callback)210 int32_t UserIdmClientImpl::GetCredentialInfo(int32_t userId, AuthType authType,
211     const std::shared_ptr<GetCredentialInfoCallback> &callback)
212 {
213     IAM_LOGI("start, userId:%{public}d authType:%{public}d", userId, authType);
214     if (!callback) {
215         IAM_LOGE("get credential info callback is nullptr");
216         return GENERAL_ERROR;
217     }
218 
219     auto proxy = GetProxy();
220     if (!proxy) {
221         IAM_LOGE("proxy is nullptr");
222         std::vector<CredentialInfo> infoList;
223         callback->OnCredentialInfo(infoList);
224         return GENERAL_ERROR;
225     }
226 
227     sptr<IdmGetCredInfoCallbackInterface> wrapper(new (std::nothrow) IdmGetCredInfoCallbackService(callback));
228     if (wrapper == nullptr) {
229         IAM_LOGE("failed to create wrapper");
230         std::vector<CredentialInfo> infoList;
231         callback->OnCredentialInfo(infoList);
232         return GENERAL_ERROR;
233     }
234     return proxy->GetCredentialInfo(userId, authType, wrapper);
235 }
236 
GetSecUserInfo(int32_t userId,const std::shared_ptr<GetSecUserInfoCallback> & callback)237 int32_t UserIdmClientImpl::GetSecUserInfo(int32_t userId, const std::shared_ptr<GetSecUserInfoCallback> &callback)
238 {
239     IAM_LOGI("start, userId:%{public}d", userId);
240     if (!callback) {
241         IAM_LOGE("get secure info callback is nullptr");
242         return GENERAL_ERROR;
243     }
244 
245     auto proxy = GetProxy();
246     if (!proxy) {
247         IAM_LOGE("proxy is nullptr");
248         SecUserInfo info = {};
249         callback->OnSecUserInfo(info);
250         return GENERAL_ERROR;
251     }
252 
253     sptr<IdmGetSecureUserInfoCallbackInterface> wrapper(
254         new (std::nothrow) IdmGetSecureUserInfoCallbackService(callback));
255     if (wrapper == nullptr) {
256         IAM_LOGE("failed to create wrapper");
257         SecUserInfo info = {};
258         callback->OnSecUserInfo(info);
259         return GENERAL_ERROR;
260     }
261     return proxy->GetSecInfo(userId, wrapper);
262 }
263 
GetProxy()264 sptr<UserIdmInterface> UserIdmClientImpl::GetProxy()
265 {
266     std::lock_guard<std::mutex> lock(mutex_);
267     if (proxy_ != nullptr) {
268         return proxy_;
269     }
270     sptr<IRemoteObject> obj = IpcClientUtils::GetRemoteObject(SUBSYS_USERIAM_SYS_ABILITY_USERIDM);
271     if (obj == nullptr) {
272         IAM_LOGE("remote object is null");
273         return proxy_;
274     }
275     sptr<IRemoteObject::DeathRecipient> dr(new (std::nothrow) UserIdmImplDeathRecipient());
276     if ((dr == nullptr) || (obj->IsProxyObject() && !obj->AddDeathRecipient(dr))) {
277         IAM_LOGE("add death recipient fail");
278         return proxy_;
279     }
280 
281     proxy_ = iface_cast<UserIdmInterface>(obj);
282     deathRecipient_ = dr;
283     return proxy_;
284 }
285 
ResetProxy(const wptr<IRemoteObject> & remote)286 void UserIdmClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
287 {
288     IAM_LOGI("start");
289     std::lock_guard<std::mutex> lock(mutex_);
290     if (proxy_ == nullptr) {
291         IAM_LOGE("proxy_ is null");
292         return;
293     }
294     auto serviceRemote = proxy_->AsObject();
295     if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
296         IAM_LOGI("need reset");
297         serviceRemote->RemoveDeathRecipient(deathRecipient_);
298         proxy_ = nullptr;
299         deathRecipient_ = nullptr;
300     }
301     IAM_LOGI("end reset proxy");
302 }
303 
ClearRedundancyCredential(const std::shared_ptr<UserIdmClientCallback> & callback)304 void UserIdmClientImpl::ClearRedundancyCredential(const std::shared_ptr<UserIdmClientCallback> &callback)
305 {
306     IAM_LOGI("start");
307     if (!callback) {
308         IAM_LOGE("ClearRedundancyCredential callback is nullptr");
309         return;
310     }
311 
312     auto proxy = GetProxy();
313     if (!proxy) {
314         IAM_LOGE("proxy is nullptr");
315         Attributes extraInfo;
316         callback->OnResult(GENERAL_ERROR, extraInfo);
317         return;
318     }
319 
320     sptr<IdmCallbackInterface> wrapper(new (std::nothrow) IdmCallbackService(callback));
321     if (wrapper == nullptr) {
322         IAM_LOGE("failed to create wrapper");
323         Attributes extraInfo;
324         callback->OnResult(GENERAL_ERROR, extraInfo);
325         return;
326     }
327 
328     proxy->ClearRedundancyCredential(wrapper);
329 }
330 
OnRemoteDied(const wptr<IRemoteObject> & remote)331 void UserIdmClientImpl::UserIdmImplDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
332 {
333     IAM_LOGI("start");
334     if (remote == nullptr) {
335         IAM_LOGE("remote is nullptr");
336         return;
337     }
338     CallbackManager::GetInstance().OnServiceDeath();
339     UserIdmClientImpl::Instance().ResetProxy(remote);
340 }
341 
Instance()342 UserIdmClientImpl &UserIdmClientImpl::Instance()
343 {
344     static UserIdmClientImpl impl;
345     return impl;
346 }
347 
GetInstance()348 UserIdmClient &UserIdmClient::GetInstance()
349 {
350     return UserIdmClientImpl::Instance();
351 }
352 } // namespace UserAuth
353 } // namespace UserIam
354 } // namespace OHOS