1 /*
2 * Copyright (c) 2022-2023 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_auth_client_impl.h"
17
18 #include "system_ability_definition.h"
19
20 #include "auth_common.h"
21 #include "callback_manager.h"
22 #include "iam_check.h"
23 #include "iam_logger.h"
24 #include "iam_ptr.h"
25 #include "ipc_client_utils.h"
26 #include "user_auth_callback_service.h"
27 #include "widget_callback_service.h"
28
29 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SDK
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
33 namespace {
34 class NorthAuthenticationCallback : public AuthenticationCallback, public NoCopyable {
35 public:
36 explicit NorthAuthenticationCallback(std::shared_ptr<AuthenticationCallback> innerCallback);
37 void OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo) override;
38 void OnResult(int32_t result, const Attributes &extraInfo) override;
39
40 private:
41 std::shared_ptr<AuthenticationCallback> innerCallback_ = nullptr;
42 };
43
NorthAuthenticationCallback(std::shared_ptr<AuthenticationCallback> innerCallback)44 NorthAuthenticationCallback::NorthAuthenticationCallback(std::shared_ptr<AuthenticationCallback> innerCallback)
45 : innerCallback_(innerCallback) {};
46
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const Attributes & extraInfo)47 void NorthAuthenticationCallback::OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo)
48 {
49 if (innerCallback_ == nullptr) {
50 IAM_LOGE("callback is nullptr");
51 return;
52 }
53
54 if (module == AuthType::FACE) {
55 if (acquireInfo == 0 || acquireInfo > FACE_AUTH_TIP_MAX) {
56 IAM_LOGI("skip undefined face auth tip %{public}u", acquireInfo);
57 return;
58 }
59 } else if (module == AuthType::FINGERPRINT) {
60 if (acquireInfo > FINGERPRINT_AUTH_TIP_MAX) {
61 IAM_LOGI("skip undefined fingerprint auth tip %{public}u", acquireInfo);
62 return;
63 }
64 }
65
66 innerCallback_->OnAcquireInfo(module, acquireInfo, extraInfo);
67 }
68
OnResult(int32_t result,const Attributes & extraInfo)69 void NorthAuthenticationCallback::OnResult(int32_t result, const Attributes &extraInfo)
70 {
71 if (innerCallback_ == nullptr) {
72 IAM_LOGE("callback is nullptr");
73 return;
74 }
75
76 innerCallback_->OnResult(result, extraInfo);
77 }
78 } // namespace
79
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel)80 int32_t UserAuthClientImpl::GetAvailableStatus(AuthType authType, AuthTrustLevel authTrustLevel)
81 {
82 IAM_LOGI("start, authType:%{public}d authTrustLevel:%{public}u", authType, authTrustLevel);
83 return GetAvailableStatus(INT32_MAX, authType, authTrustLevel);
84 }
85
GetAvailableStatus(int32_t apiVersion,AuthType authType,AuthTrustLevel authTrustLevel)86 int32_t UserAuthClientImpl::GetAvailableStatus(int32_t apiVersion, AuthType authType, AuthTrustLevel authTrustLevel)
87 {
88 IAM_LOGI("start, apiVersion:%{public}d authType:%{public}d authTrustLevel:%{public}u",
89 apiVersion, authType, authTrustLevel);
90 auto proxy = GetProxy();
91 if (!proxy) {
92 IAM_LOGE("proxy is nullptr");
93 return GENERAL_ERROR;
94 }
95 return proxy->GetAvailableStatus(apiVersion, authType, authTrustLevel);
96 }
97
GetProperty(int32_t userId,const GetPropertyRequest & request,const std::shared_ptr<GetPropCallback> & callback)98 void UserAuthClientImpl::GetProperty(int32_t userId, const GetPropertyRequest &request,
99 const std::shared_ptr<GetPropCallback> &callback)
100 {
101 IAM_LOGI("start, userId:%{public}d authType:%{public}d", userId, request.authType);
102 if (!callback) {
103 IAM_LOGE("get prop callback is nullptr");
104 return;
105 }
106
107 auto proxy = GetProxy();
108 if (!proxy) {
109 IAM_LOGE("proxy is nullptr");
110 Attributes extraInfo;
111 callback->OnResult(GENERAL_ERROR, extraInfo);
112 return;
113 }
114
115 sptr<GetExecutorPropertyCallbackInterface> wrapper(
116 new (std::nothrow) GetExecutorPropertyCallbackService(callback));
117 if (wrapper == nullptr) {
118 IAM_LOGE("failed to create wrapper");
119 Attributes extraInfo;
120 callback->OnResult(GENERAL_ERROR, extraInfo);
121 return;
122 }
123 proxy->GetProperty(userId, request.authType, request.keys, wrapper);
124 }
125
SetPropertyInner(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<SetPropCallback> & callback)126 ResultCode UserAuthClientImpl::SetPropertyInner(int32_t userId, const SetPropertyRequest &request,
127 const std::shared_ptr<SetPropCallback> &callback)
128 {
129 auto proxy = GetProxy();
130 if (!proxy) {
131 IAM_LOGE("proxy is nullptr");
132 return GENERAL_ERROR;
133 }
134
135 auto keys = request.attrs.GetKeys();
136 IF_FALSE_LOGE_AND_RETURN_VAL(keys.size() == 1, GENERAL_ERROR);
137
138 Attributes::AttributeKey key = keys[0];
139 Attributes attr;
140
141 std::vector<uint8_t> extraInfo;
142 bool getArrayRet = request.attrs.GetUint8ArrayValue(static_cast<Attributes::AttributeKey>(key), extraInfo);
143 IF_FALSE_LOGE_AND_RETURN_VAL(getArrayRet, GENERAL_ERROR);
144
145 bool setModeRet = attr.SetUint32Value(Attributes::ATTR_PROPERTY_MODE, static_cast<uint32_t>(key));
146 IF_FALSE_LOGE_AND_RETURN_VAL(setModeRet, GENERAL_ERROR);
147
148 bool setArrayRet = attr.SetUint8ArrayValue(Attributes::ATTR_EXTRA_INFO, extraInfo);
149 IF_FALSE_LOGE_AND_RETURN_VAL(setArrayRet, GENERAL_ERROR);
150
151 sptr<SetExecutorPropertyCallbackInterface> wrapper(
152 new (std::nothrow) SetExecutorPropertyCallbackService(callback));
153 IF_FALSE_LOGE_AND_RETURN_VAL(wrapper != nullptr, GENERAL_ERROR);
154 proxy->SetProperty(userId, request.authType, attr, wrapper);
155 return SUCCESS;
156 }
157
SetProperty(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<SetPropCallback> & callback)158 void UserAuthClientImpl::SetProperty(int32_t userId, const SetPropertyRequest &request,
159 const std::shared_ptr<SetPropCallback> &callback)
160 {
161 IAM_LOGI("start, userId:%{public}d authType:%{public}d", userId, request.authType);
162 if (!callback) {
163 IAM_LOGE("set prop callback is nullptr");
164 return;
165 }
166
167 ResultCode result = SetPropertyInner(userId, request, callback);
168 if (result != SUCCESS) {
169 IAM_LOGE("result is not success");
170 Attributes retExtraInfo;
171 callback->OnResult(GENERAL_ERROR, retExtraInfo);
172 return;
173 }
174 }
175
BeginAuthentication(int32_t userId,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel atl,const std::shared_ptr<AuthenticationCallback> & callback)176 uint64_t UserAuthClientImpl::BeginAuthentication(int32_t userId, const std::vector<uint8_t> &challenge,
177 AuthType authType, AuthTrustLevel atl, const std::shared_ptr<AuthenticationCallback> &callback)
178 {
179 IAM_LOGI("start, userId:%{public}d authType:%{public}d atl:%{public}u", userId, authType, atl);
180 if (!callback) {
181 IAM_LOGE("auth callback is nullptr");
182 return INVALID_SESSION_ID;
183 }
184
185 auto proxy = GetProxy();
186 if (!proxy) {
187 IAM_LOGE("proxy is nullptr");
188 Attributes extraInfo;
189 callback->OnResult(GENERAL_ERROR, extraInfo);
190 return INVALID_SESSION_ID;
191 }
192
193 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(callback));
194 if (wrapper == nullptr) {
195 IAM_LOGE("failed to create wrapper");
196 Attributes extraInfo;
197 callback->OnResult(GENERAL_ERROR, extraInfo);
198 return INVALID_SESSION_ID;
199 }
200 return proxy->AuthUser(userId, challenge, authType, atl, wrapper);
201 }
202
BeginNorthAuthentication(int32_t apiVersion,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel atl,const std::shared_ptr<AuthenticationCallback> & callback)203 uint64_t UserAuthClientImpl::BeginNorthAuthentication(int32_t apiVersion, const std::vector<uint8_t> &challenge,
204 AuthType authType, AuthTrustLevel atl, const std::shared_ptr<AuthenticationCallback> &callback)
205 {
206 IAM_LOGI("start, apiVersion:%{public}d authType:%{public}d atl:%{public}u", apiVersion, authType, atl);
207 if (!callback) {
208 IAM_LOGE("auth callback is nullptr");
209 return INVALID_SESSION_ID;
210 }
211
212 auto northCallback = Common::MakeShared<NorthAuthenticationCallback>(callback);
213 if (!northCallback) {
214 IAM_LOGE("auth callback is nullptr");
215 Attributes extraInfo;
216 callback->OnResult(GENERAL_ERROR, extraInfo);
217 return INVALID_SESSION_ID;
218 }
219
220 auto proxy = GetProxy();
221 if (!proxy) {
222 IAM_LOGE("proxy is nullptr");
223 Attributes extraInfo;
224 callback->OnResult(GENERAL_ERROR, extraInfo);
225 return INVALID_SESSION_ID;
226 }
227
228 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(northCallback));
229 if (wrapper == nullptr) {
230 IAM_LOGE("failed to create wrapper");
231 Attributes extraInfo;
232 callback->OnResult(GENERAL_ERROR, extraInfo);
233 return INVALID_SESSION_ID;
234 }
235 return proxy->Auth(apiVersion, challenge, authType, atl, wrapper);
236 }
237
CancelAuthentication(uint64_t contextId)238 int32_t UserAuthClientImpl::CancelAuthentication(uint64_t contextId)
239 {
240 IAM_LOGI("start");
241 auto proxy = GetProxy();
242 if (!proxy) {
243 IAM_LOGE("proxy is nullptr");
244 return GENERAL_ERROR;
245 }
246
247 return proxy->CancelAuthOrIdentify(contextId);
248 }
249
BeginIdentification(const std::vector<uint8_t> & challenge,AuthType authType,const std::shared_ptr<IdentificationCallback> & callback)250 uint64_t UserAuthClientImpl::BeginIdentification(const std::vector<uint8_t> &challenge, AuthType authType,
251 const std::shared_ptr<IdentificationCallback> &callback)
252 {
253 IAM_LOGI("start, authType:%{public}d", authType);
254 if (!callback) {
255 IAM_LOGE("identify callback is nullptr");
256 return INVALID_SESSION_ID;
257 }
258
259 auto proxy = GetProxy();
260 if (!proxy) {
261 IAM_LOGE("proxy is nullptr");
262 Attributes extraInfo;
263 callback->OnResult(GENERAL_ERROR, extraInfo);
264 return INVALID_SESSION_ID;
265 }
266
267 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(callback));
268 if (wrapper == nullptr) {
269 IAM_LOGE("failed to create wrapper");
270 Attributes extraInfo;
271 callback->OnResult(GENERAL_ERROR, extraInfo);
272 return INVALID_SESSION_ID;
273 }
274 return proxy->Identify(challenge, authType, wrapper);
275 }
276
CancelIdentification(uint64_t contextId)277 int32_t UserAuthClientImpl::CancelIdentification(uint64_t contextId)
278 {
279 IAM_LOGI("start");
280 auto proxy = GetProxy();
281 if (!proxy) {
282 IAM_LOGE("proxy is nullptr");
283 return GENERAL_ERROR;
284 }
285
286 return proxy->CancelAuthOrIdentify(contextId);
287 }
288
GetVersion(int32_t & version)289 int32_t UserAuthClientImpl::GetVersion(int32_t &version)
290 {
291 IAM_LOGI("start");
292 auto proxy = GetProxy();
293 if (!proxy) {
294 IAM_LOGE("proxy is nullptr");
295 return GENERAL_ERROR;
296 }
297
298 return proxy->GetVersion(version);
299 }
300
GetProxy()301 sptr<UserAuthInterface> UserAuthClientImpl::GetProxy()
302 {
303 std::lock_guard<std::mutex> lock(mutex_);
304 if (proxy_ != nullptr) {
305 return proxy_;
306 }
307 sptr<IRemoteObject> obj = IpcClientUtils::GetRemoteObject(SUBSYS_USERIAM_SYS_ABILITY_USERAUTH);
308 if (obj == nullptr) {
309 IAM_LOGE("remote object is null");
310 return proxy_;
311 }
312 sptr<IRemoteObject::DeathRecipient> dr(new (std::nothrow) UserAuthImplDeathRecipient());
313 if ((dr == nullptr) || (obj->IsProxyObject() && !obj->AddDeathRecipient(dr))) {
314 IAM_LOGE("add death recipient fail");
315 return proxy_;
316 }
317
318 proxy_ = iface_cast<UserAuthInterface>(obj);
319 deathRecipient_ = dr;
320 return proxy_;
321 }
322
ResetProxy(const wptr<IRemoteObject> & remote)323 void UserAuthClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
324 {
325 IAM_LOGI("start");
326 std::lock_guard<std::mutex> lock(mutex_);
327 if (proxy_ == nullptr) {
328 IAM_LOGE("proxy_ is null");
329 return;
330 }
331 auto serviceRemote = proxy_->AsObject();
332 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
333 IAM_LOGI("need reset");
334 serviceRemote->RemoveDeathRecipient(deathRecipient_);
335 proxy_ = nullptr;
336 deathRecipient_ = nullptr;
337 }
338 IAM_LOGI("end reset proxy");
339 }
340
OnRemoteDied(const wptr<IRemoteObject> & remote)341 void UserAuthClientImpl::UserAuthImplDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
342 {
343 IAM_LOGI("start");
344 if (remote == nullptr) {
345 IAM_LOGE("remote is nullptr");
346 return;
347 }
348 CallbackManager::GetInstance().OnServiceDeath();
349 UserAuthClientImpl::Instance().ResetProxy(remote);
350 }
351
Instance()352 UserAuthClientImpl &UserAuthClientImpl::Instance()
353 {
354 static UserAuthClientImpl impl;
355 return impl;
356 }
357
GetInstance()358 UserAuthClient &UserAuthClient::GetInstance()
359 {
360 return UserAuthClientImpl::Instance();
361 }
362
BeginWidgetAuth(int32_t apiVersion,const AuthParam & authParam,const WidgetParam & widgetParam,const std::shared_ptr<AuthenticationCallback> & callback)363 uint64_t UserAuthClientImpl::BeginWidgetAuth(int32_t apiVersion, const AuthParam &authParam,
364 const WidgetParam &widgetParam, const std::shared_ptr<AuthenticationCallback> &callback)
365 {
366 IAM_LOGI("start, apiVersion:%{public}d authTypeSize:%{public}zu authTrustLevel:%{public}u",
367 apiVersion, authParam.authType.size(), authParam.authTrustLevel);
368 // parameter verification
369 if (!callback) {
370 IAM_LOGE("auth callback is nullptr");
371 return INVALID_SESSION_ID;
372 }
373 auto proxy = GetProxy();
374 if (!proxy) {
375 IAM_LOGE("proxy is nullptr");
376 Attributes extraInfo;
377 callback->OnResult(static_cast<int32_t>(ResultCode::GENERAL_ERROR), extraInfo);
378 return INVALID_SESSION_ID;
379 }
380
381 sptr<UserAuthCallbackInterface> wrapper(new (std::nothrow) UserAuthCallbackService(callback));
382 if (wrapper == nullptr) {
383 IAM_LOGE("failed to create wrapper");
384 Attributes extraInfo;
385 callback->OnResult(static_cast<int32_t>(ResultCode::GENERAL_ERROR), extraInfo);
386 return INVALID_SESSION_ID;
387 }
388 return proxy->AuthWidget(apiVersion, authParam, widgetParam, wrapper);
389 }
390
SetWidgetCallback(int32_t version,const std::shared_ptr<IUserAuthWidgetCallback> & callback)391 int32_t UserAuthClientImpl::SetWidgetCallback(int32_t version, const std::shared_ptr<IUserAuthWidgetCallback> &callback)
392 {
393 IAM_LOGI("start, version:%{public}d", version);
394 if (!callback) {
395 IAM_LOGE("widget callback is nullptr");
396 return GENERAL_ERROR;
397 }
398 auto proxy = GetProxy();
399 if (!proxy) {
400 IAM_LOGE("proxy is nullptr");
401 return GENERAL_ERROR;
402 }
403
404 sptr<WidgetCallbackInterface> wrapper(new (std::nothrow) WidgetCallbackService(callback));
405 if (wrapper == nullptr) {
406 IAM_LOGE("failed to create wrapper");
407 return GENERAL_ERROR;
408 }
409 return proxy->RegisterWidgetCallback(version, wrapper);
410 }
411
Notice(NoticeType noticeType,const std::string & eventData)412 int32_t UserAuthClientImpl::Notice(NoticeType noticeType, const std::string &eventData)
413 {
414 IAM_LOGI("start, noticeType:%{public}d", noticeType);
415 auto proxy = GetProxy();
416 if (!proxy) {
417 IAM_LOGE("proxy is nullptr");
418 return GENERAL_ERROR;
419 }
420 IAM_LOGI("UserAuthClientImpl::Notice noticeType:%{public}d, eventDat:%{public}s",
421 static_cast<int32_t>(noticeType), eventData.c_str());
422 return proxy->Notice(noticeType, eventData);
423 }
424 } // namespace UserAuth
425 } // namespace UserIam
426 } // namespace OHOS
427