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 "event_listener_callback_service.h"
22 #include "load_mode_client_util.h"
23 #include "iam_check.h"
24 #include "iam_logger.h"
25 #include "ipc_client_utils.h"
26 #include "user_idm_callback_service.h"
27
28 #define LOG_TAG "USER_IDM_SDK"
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
OpenSession(int32_t userId)33 std::vector<uint8_t> UserIdmClientImpl::OpenSession(int32_t userId)
34 {
35 IAM_LOGI("start, userId:%{public}d", userId);
36 auto proxy = GetProxy();
37 if (!proxy) {
38 IAM_LOGE("proxy is nullptr");
39 return {};
40 }
41
42 std::vector<uint8_t> challenge;
43 auto ret = proxy->OpenSession(userId, challenge);
44 if (ret != SUCCESS) {
45 IAM_LOGE("OpenSession ret = %{public}d", ret);
46 }
47
48 return challenge;
49 }
50
CloseSession(int32_t userId)51 void UserIdmClientImpl::CloseSession(int32_t userId)
52 {
53 IAM_LOGI("start, userId:%{public}d", userId);
54 auto proxy = GetProxy();
55 if (!proxy) {
56 IAM_LOGE("proxy is nullptr");
57 return;
58 }
59
60 auto ret = proxy->CloseSession(userId);
61 if (ret != SUCCESS) {
62 IAM_LOGE("CloseSession ret = %{public}d", ret);
63 }
64 }
65
AddCredential(int32_t userId,const CredentialParameters & para,const std::shared_ptr<UserIdmClientCallback> & callback)66 void UserIdmClientImpl::AddCredential(int32_t userId, const CredentialParameters ¶,
67 const std::shared_ptr<UserIdmClientCallback> &callback)
68 {
69 IAM_LOGI("start, userId:%{public}d, authType:%{public}d, authSubType:%{public}d",
70 userId, para.authType, para.pinType.value_or(PIN_SIX));
71 if (!callback) {
72 IAM_LOGE("user idm client callback is nullptr");
73 return;
74 }
75 auto proxy = GetProxy();
76 if (!proxy) {
77 IAM_LOGE("proxy is nullptr");
78 Attributes extraInfo;
79 callback->OnResult(GENERAL_ERROR, extraInfo);
80 return;
81 }
82
83 sptr<IIamCallback> wrapper(new (std::nothrow) IdmCallbackService(callback));
84 if (wrapper == nullptr) {
85 IAM_LOGE("failed to create wrapper");
86 Attributes extraInfo;
87 callback->OnResult(GENERAL_ERROR, extraInfo);
88 return;
89 }
90 IpcCredentialPara credPara = {};
91 credPara.authType = static_cast<int32_t>(para.authType);
92 credPara.pinType = static_cast<int32_t>(para.pinType.value_or(PIN_SIX));
93 credPara.token = std::move(para.token);
94 auto ret = proxy->AddCredential(userId, credPara, wrapper, false);
95 if (ret != SUCCESS) {
96 IAM_LOGE("AddCredential fail, ret:%{public}d", ret);
97 return;
98 }
99 }
100
UpdateCredential(int32_t userId,const CredentialParameters & para,const std::shared_ptr<UserIdmClientCallback> & callback)101 void UserIdmClientImpl::UpdateCredential(int32_t userId, const CredentialParameters ¶,
102 const std::shared_ptr<UserIdmClientCallback> &callback)
103 {
104 IAM_LOGI("start, userId:%{public}d, authType:%{public}d, authSubType:%{public}d",
105 userId, para.authType, para.pinType.value_or(PIN_SIX));
106 if (!callback) {
107 IAM_LOGE("user idm client callback is nullptr");
108 return;
109 }
110 auto proxy = GetProxy();
111 if (!proxy) {
112 Attributes extraInfo;
113 int32_t result = LoadModeUtil::GetProxyNullResultCode(__func__, std::vector<std::string>({
114 MANAGE_USER_IDM_PERMISSION
115 }));
116 callback->OnResult(result, extraInfo);
117 return;
118 }
119
120 sptr<IIamCallback> wrapper(new (std::nothrow) IdmCallbackService(callback));
121 if (wrapper == nullptr) {
122 IAM_LOGE("failed to create wrapper");
123 Attributes extraInfo;
124 callback->OnResult(GENERAL_ERROR, extraInfo);
125 return;
126 }
127 IpcCredentialPara credPara = {};
128 credPara.authType = static_cast<int32_t>(para.authType);
129 credPara.pinType = static_cast<int32_t>(para.pinType.value_or(PIN_SIX));
130 credPara.token = std::move(para.token);
131 auto ret = proxy->UpdateCredential(userId, credPara, wrapper);
132 if (ret != SUCCESS) {
133 IAM_LOGE("UpdateCredential fail, ret:%{public}d", ret);
134 return;
135 }
136 }
137
Cancel(int32_t userId)138 int32_t UserIdmClientImpl::Cancel(int32_t userId)
139 {
140 IAM_LOGI("start, userId:%{public}d", userId);
141 auto proxy = GetProxy();
142 if (!proxy) {
143 IAM_LOGE("proxy is nullptr");
144 return GENERAL_ERROR;
145 }
146
147 return proxy->Cancel(userId);
148 }
149
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const std::shared_ptr<UserIdmClientCallback> & callback)150 void UserIdmClientImpl::DeleteCredential(int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken,
151 const std::shared_ptr<UserIdmClientCallback> &callback)
152 {
153 IAM_LOGI("start, userId:%{public}d", userId);
154 if (!callback) {
155 IAM_LOGE("user idm client callback is nullptr");
156 return;
157 }
158 auto proxy = GetProxy();
159 if (!proxy) {
160 IAM_LOGE("proxy is nullptr");
161 Attributes extraInfo;
162 callback->OnResult(GENERAL_ERROR, extraInfo);
163 return;
164 }
165
166 sptr<IIamCallback> wrapper(new (std::nothrow) IdmCallbackService(callback));
167 if (wrapper == nullptr) {
168 IAM_LOGE("failed to create wrapper");
169 Attributes extraInfo;
170 callback->OnResult(GENERAL_ERROR, extraInfo);
171 return;
172 }
173 auto ret = proxy->DelCredential(userId, credentialId, authToken, wrapper);
174 if (ret != SUCCESS) {
175 IAM_LOGE("DelCredential fail, ret:%{public}d", ret);
176 return;
177 }
178 }
179
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,const std::shared_ptr<UserIdmClientCallback> & callback)180 void UserIdmClientImpl::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
181 const std::shared_ptr<UserIdmClientCallback> &callback)
182 {
183 IAM_LOGI("start, userId:%{public}d", userId);
184 if (!callback) {
185 IAM_LOGE("user idm client callback is nullptr");
186 return;
187 }
188 auto proxy = GetProxy();
189 if (!proxy) {
190 IAM_LOGE("proxy is nullptr");
191 Attributes extraInfo;
192 callback->OnResult(GENERAL_ERROR, extraInfo);
193 return;
194 }
195
196 sptr<IIamCallback> wrapper(new (std::nothrow) IdmCallbackService(callback));
197 if (wrapper == nullptr) {
198 IAM_LOGE("failed to create wrapper");
199 Attributes extraInfo;
200 callback->OnResult(GENERAL_ERROR, extraInfo);
201 return;
202 }
203 auto ret = proxy->DelUser(userId, authToken, wrapper);
204 if (ret != SUCCESS) {
205 IAM_LOGE("DelUser fail, ret:%{public}d", ret);
206 return;
207 }
208 }
209
EraseUser(int32_t userId,const std::shared_ptr<UserIdmClientCallback> & callback)210 int32_t UserIdmClientImpl::EraseUser(int32_t userId, const std::shared_ptr<UserIdmClientCallback> &callback)
211 {
212 IAM_LOGI("start, userId:%{public}d", userId);
213 if (!callback) {
214 IAM_LOGE("user idm client callback is nullptr");
215 return GENERAL_ERROR;
216 }
217 auto proxy = GetProxy();
218 if (!proxy) {
219 IAM_LOGE("proxy is nullptr");
220 Attributes extraInfo;
221 callback->OnResult(GENERAL_ERROR, extraInfo);
222 return GENERAL_ERROR;
223 }
224 sptr<IIamCallback> wrapper(new (std::nothrow) IdmCallbackService(callback));
225 if (wrapper == nullptr) {
226 IAM_LOGE("failed to create wrapper");
227 Attributes extraInfo;
228 callback->OnResult(GENERAL_ERROR, extraInfo);
229 return GENERAL_ERROR;
230 }
231 return proxy->EnforceDelUser(userId, wrapper);
232 }
233
GetCredentialInfo(int32_t userId,AuthType authType,const std::shared_ptr<GetCredentialInfoCallback> & callback)234 int32_t UserIdmClientImpl::GetCredentialInfo(int32_t userId, AuthType authType,
235 const std::shared_ptr<GetCredentialInfoCallback> &callback)
236 {
237 IAM_LOGI("start, userId:%{public}d authType:%{public}d", userId, authType);
238 if (!callback) {
239 IAM_LOGE("get credential info callback is nullptr");
240 return GENERAL_ERROR;
241 }
242
243 auto proxy = GetProxy();
244 if (!proxy) {
245 std::vector<CredentialInfo> infoList;
246 callback->OnCredentialInfo(GENERAL_ERROR, infoList);
247 return GENERAL_ERROR;
248 }
249
250 sptr<IIdmGetCredInfoCallback> wrapper(new (std::nothrow) IdmGetCredInfoCallbackService(callback));
251 if (wrapper == nullptr) {
252 IAM_LOGE("failed to create wrapper");
253 std::vector<CredentialInfo> infoList;
254 callback->OnCredentialInfo(GENERAL_ERROR, infoList);
255 return GENERAL_ERROR;
256 }
257 int32_t funcResult = SUCCESS;
258 int32_t ret = proxy->GetCredentialInfo(userId, authType, wrapper, funcResult);
259 if (ret != SUCCESS) {
260 IAM_LOGE("ipc call return fail, ret:%{public}d", ret);
261 return GENERAL_ERROR;
262 }
263 if (funcResult != SUCCESS) {
264 IAM_LOGI("service call return fail, ret:%{public}d", funcResult);
265 return funcResult;
266 }
267 return SUCCESS;
268 }
269
GetSecUserInfo(int32_t userId,const std::shared_ptr<GetSecUserInfoCallback> & callback)270 int32_t UserIdmClientImpl::GetSecUserInfo(int32_t userId, const std::shared_ptr<GetSecUserInfoCallback> &callback)
271 {
272 IAM_LOGI("start, userId:%{public}d", userId);
273 if (!callback) {
274 IAM_LOGE("get secure info callback is nullptr");
275 return GENERAL_ERROR;
276 }
277
278 auto proxy = GetProxy();
279 if (!proxy) {
280 int32_t result = LoadModeUtil::GetProxyNullResultCode(__func__, std::vector<std::string>({
281 USE_USER_IDM_PERMISSION
282 }));
283 SecUserInfo info = {};
284 callback->OnSecUserInfo(result, info);
285 return result;
286 }
287
288 sptr<IIdmGetSecureUserInfoCallback> wrapper(
289 new (std::nothrow) IdmGetSecureUserInfoCallbackService(callback));
290 if (wrapper == nullptr) {
291 IAM_LOGE("failed to create wrapper");
292 SecUserInfo info = {};
293 callback->OnSecUserInfo(GENERAL_ERROR, info);
294 return GENERAL_ERROR;
295 }
296 return proxy->GetSecInfo(userId, wrapper);
297 }
298
GetProxy()299 sptr<IUserIdm> UserIdmClientImpl::GetProxy()
300 {
301 std::lock_guard<std::mutex> lock(mutex_);
302 if (proxy_ != nullptr) {
303 return proxy_;
304 }
305 sptr<IRemoteObject> obj = IpcClientUtils::GetRemoteObject(SUBSYS_USERIAM_SYS_ABILITY_USERIDM);
306 if (obj == nullptr) {
307 IAM_LOGE("remote object is null");
308 return proxy_;
309 }
310 sptr<IRemoteObject::DeathRecipient> dr(new (std::nothrow) UserIdmImplDeathRecipient());
311 if ((dr == nullptr) || (obj->IsProxyObject() && !obj->AddDeathRecipient(dr))) {
312 IAM_LOGE("add death recipient fail");
313 return proxy_;
314 }
315
316 proxy_ = iface_cast<IUserIdm>(obj);
317 deathRecipient_ = dr;
318 return proxy_;
319 }
320
ResetProxy(const wptr<IRemoteObject> & remote)321 void UserIdmClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
322 {
323 IAM_LOGI("start");
324 std::lock_guard<std::mutex> lock(mutex_);
325 if (proxy_ == nullptr) {
326 IAM_LOGE("proxy_ is null");
327 return;
328 }
329 auto serviceRemote = proxy_->AsObject();
330 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
331 IAM_LOGI("need reset");
332 serviceRemote->RemoveDeathRecipient(deathRecipient_);
333 proxy_ = nullptr;
334 deathRecipient_ = nullptr;
335 }
336 IAM_LOGI("end reset proxy");
337 }
338
ClearRedundancyCredential(const std::shared_ptr<UserIdmClientCallback> & callback)339 void UserIdmClientImpl::ClearRedundancyCredential(const std::shared_ptr<UserIdmClientCallback> &callback)
340 {
341 IAM_LOGI("start");
342 if (!callback) {
343 IAM_LOGE("ClearRedundancyCredential callback is nullptr");
344 return;
345 }
346
347 auto proxy = GetProxy();
348 if (!proxy) {
349 IAM_LOGE("proxy is nullptr");
350 Attributes extraInfo;
351 callback->OnResult(GENERAL_ERROR, extraInfo);
352 return;
353 }
354
355 sptr<IIamCallback> wrapper(new (std::nothrow) IdmCallbackService(callback));
356 if (wrapper == nullptr) {
357 IAM_LOGE("failed to create wrapper");
358 Attributes extraInfo;
359 callback->OnResult(GENERAL_ERROR, extraInfo);
360 return;
361 }
362
363 auto ret = proxy->ClearRedundancyCredential(wrapper);
364 if (ret != SUCCESS) {
365 IAM_LOGE("ClearRedundancyCredential fail, ret:%{public}d", ret);
366 return;
367 }
368 }
369
RegistCredChangeEventListener(const std::vector<AuthType> & authTypes,const std::shared_ptr<CredChangeEventListener> & listener)370 int32_t UserIdmClientImpl::RegistCredChangeEventListener(const std::vector<AuthType> &authTypes,
371 const std::shared_ptr<CredChangeEventListener> &listener)
372 {
373 IAM_LOGI("start");
374
375 auto proxy = GetProxy();
376 IF_FALSE_LOGE_AND_RETURN_VAL(proxy != nullptr, GENERAL_ERROR);
377
378 return EventListenerCallbackManager::GetInstance().AddCredChangeEventListener(proxy, authTypes, listener);
379 }
380
UnRegistCredChangeEventListener(const std::shared_ptr<CredChangeEventListener> & listener)381 int32_t UserIdmClientImpl::UnRegistCredChangeEventListener(const std::shared_ptr<CredChangeEventListener> &listener)
382 {
383 IAM_LOGI("start");
384
385 auto proxy = GetProxy();
386 IF_FALSE_LOGE_AND_RETURN_VAL(proxy != nullptr, GENERAL_ERROR);
387
388 return EventListenerCallbackManager::GetInstance().RemoveCredChangeEventListener(proxy, listener);
389 }
390
GetCredentialInfoSync(int32_t userId,AuthType authType,std::vector<CredentialInfo> & credentialInfoList)391 int32_t UserIdmClientImpl::GetCredentialInfoSync(int32_t userId, AuthType authType,
392 std::vector<CredentialInfo> &credentialInfoList)
393 {
394 IAM_LOGI("start, userId:%{public}d authType:%{public}d", userId, authType);
395 auto proxy = GetProxy();
396 if (!proxy) {
397 IAM_LOGE("proxy is nullptr");
398 return GENERAL_ERROR;
399 }
400
401 std::vector<IpcCredentialInfo> ipcCredInfoList;
402 auto ret = proxy->GetCredentialInfoSync(userId, authType, ipcCredInfoList);
403 if (ret != SUCCESS) {
404 IAM_LOGE("GetCredentialInfoSync fail, ret:%{public}d", ret);
405 return ret;
406 }
407
408 for (auto &iter : ipcCredInfoList) {
409 CredentialInfo credentialInfo;
410 credentialInfo.authType = static_cast<AuthType>(iter.authType);
411 credentialInfo.pinType = static_cast<PinSubType>(iter.pinType);
412 credentialInfo.credentialId = iter.credentialId;
413 credentialInfo.templateId = iter.credentialId;
414 credentialInfoList.push_back(credentialInfo);
415 }
416
417 IAM_LOGI("GetCredentialInfoSync success, credential num:%{public}zu", credentialInfoList.size());
418 return SUCCESS;
419 }
420
OnRemoteDied(const wptr<IRemoteObject> & remote)421 void UserIdmClientImpl::UserIdmImplDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
422 {
423 IAM_LOGI("start");
424 if (remote == nullptr) {
425 IAM_LOGE("remote is nullptr");
426 return;
427 }
428 CallbackManager::GetInstance().OnServiceDeath();
429 EventListenerCallbackManager::GetInstance().OnServiceDeath();
430 UserIdmClientImpl::Instance().ResetProxy(remote);
431 }
432
Instance()433 UserIdmClientImpl &UserIdmClientImpl::Instance()
434 {
435 static UserIdmClientImpl impl;
436 return impl;
437 }
438
GetInstance()439 UserIdmClient &UserIdmClient::GetInstance()
440 {
441 return UserIdmClientImpl::Instance();
442 }
443 } // namespace UserAuth
444 } // namespace UserIam
445 } // namespace OHOS