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_proxy.h"
17
18 #include <algorithm>
19 #include <cinttypes>
20
21 #include "iam_logger.h"
22
23 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SDK
24
25 namespace OHOS {
26 namespace UserIam {
27 namespace UserAuth {
28 namespace {
29 const uint64_t BAD_CONTEXT_ID = 0;
30 const uint32_t MAX_ATTR_COUNT = 512;
31 } // namespace
32
UserAuthProxy(const sptr<IRemoteObject> & object)33 UserAuthProxy::UserAuthProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<UserAuthInterface>(object)
34 {
35 }
36
GetAvailableStatus(int32_t apiVersion,AuthType authType,AuthTrustLevel authTrustLevel)37 int32_t UserAuthProxy::GetAvailableStatus(int32_t apiVersion, AuthType authType, AuthTrustLevel authTrustLevel)
38 {
39 MessageParcel data;
40 MessageParcel reply;
41
42 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
43 IAM_LOGE("failed to write descriptor");
44 return WRITE_PARCEL_ERROR;
45 }
46 if (!data.WriteInt32(authType)) {
47 IAM_LOGE("failed to write authType");
48 return WRITE_PARCEL_ERROR;
49 }
50 if (!data.WriteUint32(authTrustLevel)) {
51 IAM_LOGE("failed to write authTrustLevel");
52 return WRITE_PARCEL_ERROR;
53 }
54 if (!data.WriteInt32(apiVersion)) {
55 IAM_LOGE("failed to write apiVersion");
56 return WRITE_PARCEL_ERROR;
57 }
58
59 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_GET_AVAILABLE_STATUS, data, reply);
60 if (!ret) {
61 IAM_LOGE("failed to send get available status IPC request");
62 return GENERAL_ERROR;
63 }
64 int32_t result = SUCCESS;
65 if (!reply.ReadInt32(result)) {
66 IAM_LOGE("failed to read result");
67 return READ_PARCEL_ERROR;
68 }
69 return result;
70 }
71
GetProperty(int32_t userId,AuthType authType,const std::vector<Attributes::AttributeKey> & keys,sptr<GetExecutorPropertyCallbackInterface> & callback)72 void UserAuthProxy::GetProperty(int32_t userId, AuthType authType,
73 const std::vector<Attributes::AttributeKey> &keys, sptr<GetExecutorPropertyCallbackInterface> &callback)
74 {
75 if (callback == nullptr) {
76 IAM_LOGE("callback is nullptr");
77 return;
78 }
79 MessageParcel data;
80 MessageParcel reply;
81
82 std::vector<uint32_t> attrKeys;
83 if (keys.empty()) {
84 IAM_LOGE("the attribute key vector is empty");
85 return;
86 }
87 if (keys.size() > MAX_ATTR_COUNT) {
88 IAM_LOGE("the attribute key vector size exceed limit");
89 return;
90 }
91 attrKeys.resize(keys.size());
92 std::transform(keys.begin(), keys.end(), attrKeys.begin(), [](Attributes::AttributeKey key) {
93 return static_cast<uint32_t>(key);
94 });
95
96 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
97 IAM_LOGE("failed to write descriptor");
98 return;
99 }
100 if (!data.WriteInt32(userId)) {
101 IAM_LOGE("failed to write userId");
102 return;
103 }
104 if (!data.WriteInt32(authType)) {
105 IAM_LOGE("failed to write authType");
106 return;
107 }
108 if (!data.WriteUInt32Vector(attrKeys)) {
109 IAM_LOGE("failed to write keys");
110 return;
111 }
112 if (!data.WriteRemoteObject(callback->AsObject())) {
113 IAM_LOGE("failed to write callback");
114 return;
115 }
116
117 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_GET_PROPERTY, data, reply);
118 if (!ret) {
119 IAM_LOGE("failed to send get property IPC request");
120 Attributes attr;
121 callback->OnGetExecutorPropertyResult(GENERAL_ERROR, attr);
122 }
123 }
124
SetProperty(int32_t userId,AuthType authType,const Attributes & attributes,sptr<SetExecutorPropertyCallbackInterface> & callback)125 void UserAuthProxy::SetProperty(int32_t userId, AuthType authType, const Attributes &attributes,
126 sptr<SetExecutorPropertyCallbackInterface> &callback)
127 {
128 if (callback == nullptr) {
129 IAM_LOGE("callback is nullptr");
130 return;
131 }
132 MessageParcel data;
133 MessageParcel reply;
134
135 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
136 IAM_LOGE("failed to write descriptor");
137 return;
138 }
139 if (!data.WriteInt32(userId)) {
140 IAM_LOGE("failed to write userId");
141 return;
142 }
143 if (!data.WriteInt32(authType)) {
144 IAM_LOGE("failed to write authType");
145 return;
146 }
147 auto buffer = attributes.Serialize();
148 if (!data.WriteUInt8Vector(buffer)) {
149 IAM_LOGE("failed to write attributes");
150 return;
151 }
152 if (!data.WriteRemoteObject(callback->AsObject())) {
153 IAM_LOGE("failed to write callback");
154 return;
155 }
156
157 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_SET_PROPERTY, data, reply);
158 if (!ret) {
159 IAM_LOGE("failed to send set property IPC request");
160 callback->OnSetExecutorPropertyResult(GENERAL_ERROR);
161 }
162 }
163
WriteAuthParam(MessageParcel & data,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,sptr<UserAuthCallbackInterface> & callback)164 bool UserAuthProxy::WriteAuthParam(MessageParcel &data, const std::vector<uint8_t> &challenge,
165 AuthType authType, AuthTrustLevel authTrustLevel, sptr<UserAuthCallbackInterface> &callback)
166 {
167 if (!data.WriteUInt8Vector(challenge)) {
168 IAM_LOGE("failed to write challenge");
169 return false;
170 }
171 if (!data.WriteInt32(authType)) {
172 IAM_LOGE("failed to write authType");
173 return false;
174 }
175 if (!data.WriteUint32(authTrustLevel)) {
176 IAM_LOGE("failed to write authTrustLevel");
177 return false;
178 }
179 if (!data.WriteRemoteObject(callback->AsObject())) {
180 IAM_LOGE("failed to write callback");
181 return false;
182 }
183 return true;
184 }
185
Auth(int32_t apiVersion,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,sptr<UserAuthCallbackInterface> & callback)186 uint64_t UserAuthProxy::Auth(int32_t apiVersion, const std::vector<uint8_t> &challenge, AuthType authType,
187 AuthTrustLevel authTrustLevel, sptr<UserAuthCallbackInterface> &callback)
188 {
189 if (callback == nullptr) {
190 IAM_LOGE("callback is nullptr");
191 return BAD_CONTEXT_ID;
192 }
193 MessageParcel data;
194 MessageParcel reply;
195
196 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
197 IAM_LOGE("failed to write descriptor");
198 return BAD_CONTEXT_ID;
199 }
200 if (!WriteAuthParam(data, challenge, authType, authTrustLevel, callback)) {
201 IAM_LOGE("failed to write auth param");
202 return BAD_CONTEXT_ID;
203 }
204 if (!data.WriteInt32(apiVersion)) {
205 IAM_LOGE("failed to write apiVersion");
206 return BAD_CONTEXT_ID;
207 }
208 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_AUTH, data, reply);
209 if (!ret) {
210 IAM_LOGE("failed to send user auth IPC request");
211 return BAD_CONTEXT_ID;
212 }
213 uint64_t result = BAD_CONTEXT_ID;
214 if (!reply.ReadUint64(result)) {
215 IAM_LOGE("failed to read result");
216 }
217 return result;
218 }
219
AuthWidget(int32_t apiVersion,const AuthParam & authParam,const WidgetParam & widgetParam,sptr<UserAuthCallbackInterface> & callback)220 uint64_t UserAuthProxy::AuthWidget(int32_t apiVersion, const AuthParam &authParam,
221 const WidgetParam &widgetParam, sptr<UserAuthCallbackInterface> &callback)
222 {
223 if (callback == nullptr) {
224 IAM_LOGE("callback is nullptr");
225 return BAD_CONTEXT_ID;
226 }
227 MessageParcel data;
228 MessageParcel reply;
229
230 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
231 IAM_LOGE("failed to write descriptor");
232 return BAD_CONTEXT_ID;
233 }
234
235 if (!WriteWidgetParam(data, authParam, widgetParam)) {
236 IAM_LOGE("failed to write widget param");
237 return BAD_CONTEXT_ID;
238 }
239
240 if (!data.WriteRemoteObject(callback->AsObject())) {
241 IAM_LOGE("failed to write callback");
242 return BAD_CONTEXT_ID;
243 }
244
245 if (!data.WriteInt32(apiVersion)) {
246 IAM_LOGE("failed to write apiVersion");
247 return BAD_CONTEXT_ID;
248 }
249
250 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_AUTH_WIDGET, data, reply);
251 if (!ret) {
252 IAM_LOGE("failed to send auth widget IPC request");
253 return BAD_CONTEXT_ID;
254 }
255 uint64_t result = BAD_CONTEXT_ID;
256 if (!reply.ReadUint64(result)) {
257 IAM_LOGE("failed to read result");
258 }
259 return result;
260 }
261
WriteWidgetParam(MessageParcel & data,const AuthParam & authParam,const WidgetParam & widgetParam)262 bool UserAuthProxy::WriteWidgetParam(MessageParcel &data, const AuthParam &authParam, const WidgetParam &widgetParam)
263 {
264 if (!data.WriteUInt8Vector(authParam.challenge)) {
265 IAM_LOGE("failed to write challenge");
266 return false;
267 }
268 std::vector<int32_t> atList;
269 for (auto at : authParam.authType) {
270 atList.push_back(static_cast<int32_t>(at));
271 }
272 if (!data.WriteInt32Vector(atList)) {
273 IAM_LOGE("failed to write authTypeList");
274 return false;
275 }
276 if (!data.WriteUint32(authParam.authTrustLevel)) {
277 IAM_LOGE("failed to write authTrustLevel");
278 return false;
279 }
280
281 if (!data.WriteString(widgetParam.title)) {
282 IAM_LOGE("failed to write title");
283 return false;
284 }
285 if (!data.WriteString(widgetParam.navigationButtonText)) {
286 IAM_LOGE("failed to write navigation button text");
287 return false;
288 }
289 if (!data.WriteInt32(static_cast<int32_t>(widgetParam.windowMode))) {
290 IAM_LOGE("failed to write window mode");
291 return false;
292 }
293 return true;
294 }
295
AuthUser(int32_t userId,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,sptr<UserAuthCallbackInterface> & callback)296 uint64_t UserAuthProxy::AuthUser(int32_t userId, const std::vector<uint8_t> &challenge,
297 AuthType authType, AuthTrustLevel authTrustLevel, sptr<UserAuthCallbackInterface> &callback)
298 {
299 if (callback == nullptr) {
300 IAM_LOGE("callback is nullptr");
301 return BAD_CONTEXT_ID;
302 }
303 MessageParcel data;
304 MessageParcel reply;
305
306 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
307 IAM_LOGE("failed to write descriptor");
308 return BAD_CONTEXT_ID;
309 }
310 if (!data.WriteInt32(userId)) {
311 IAM_LOGE("failed to write userId");
312 return BAD_CONTEXT_ID;
313 }
314 if (!WriteAuthParam(data, challenge, authType, authTrustLevel, callback)) {
315 IAM_LOGE("failed to write auth param");
316 return BAD_CONTEXT_ID;
317 }
318
319 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_AUTH_USER, data, reply);
320 if (!ret) {
321 IAM_LOGE("failed to send auth user IPC request");
322 return BAD_CONTEXT_ID;
323 }
324 uint64_t result = BAD_CONTEXT_ID;
325 if (!reply.ReadUint64(result)) {
326 IAM_LOGE("failed to read result");
327 }
328 return result;
329 }
330
Identify(const std::vector<uint8_t> & challenge,AuthType authType,sptr<UserAuthCallbackInterface> & callback)331 uint64_t UserAuthProxy::Identify(const std::vector<uint8_t> &challenge, AuthType authType,
332 sptr<UserAuthCallbackInterface> &callback)
333 {
334 if (callback == nullptr) {
335 IAM_LOGE("callback is nullptr");
336 return BAD_CONTEXT_ID;
337 }
338 MessageParcel data;
339 MessageParcel reply;
340
341 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
342 IAM_LOGE("failed to write descriptor");
343 return BAD_CONTEXT_ID;
344 }
345 if (!data.WriteUInt8Vector(challenge)) {
346 IAM_LOGE("failed to write challenge");
347 return BAD_CONTEXT_ID;
348 }
349 if (!data.WriteInt32(authType)) {
350 IAM_LOGE("failed to write authType");
351 return BAD_CONTEXT_ID;
352 }
353 if (!data.WriteRemoteObject(callback->AsObject())) {
354 IAM_LOGE("failed to write callback");
355 return BAD_CONTEXT_ID;
356 }
357
358 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_IDENTIFY, data, reply);
359 if (!ret) {
360 IAM_LOGE("failed to send auth identify IPC request");
361 return BAD_CONTEXT_ID;
362 }
363 uint64_t result = BAD_CONTEXT_ID;
364 if (!reply.ReadUint64(result)) {
365 IAM_LOGE("failed to read result");
366 }
367 return result;
368 }
369
CancelAuthOrIdentify(uint64_t contextId)370 int32_t UserAuthProxy::CancelAuthOrIdentify(uint64_t contextId)
371 {
372 MessageParcel data;
373 MessageParcel reply;
374
375 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
376 IAM_LOGE("failed to write descriptor");
377 return GENERAL_ERROR;
378 }
379 if (!data.WriteUint64(contextId)) {
380 IAM_LOGE("failed to write contextId");
381 return GENERAL_ERROR;
382 }
383
384 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_CANCEL_AUTH, data, reply);
385 if (!ret) {
386 IAM_LOGE("failed to send cancel auth IPC request");
387 return GENERAL_ERROR;
388 }
389 int32_t result = GENERAL_ERROR;
390 if (!reply.ReadInt32(result)) {
391 IAM_LOGE("failed to read result");
392 }
393 return result;
394 }
395
GetVersion(int32_t & version)396 int32_t UserAuthProxy::GetVersion(int32_t &version)
397 {
398 version = 0;
399 MessageParcel data;
400 MessageParcel reply;
401
402 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
403 IAM_LOGE("failed to write descriptor");
404 return GENERAL_ERROR;
405 }
406
407 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_GET_VERSION, data, reply);
408 if (!ret) {
409 IAM_LOGE("failed to send get version IPC request");
410 return GENERAL_ERROR;
411 }
412 if (!reply.ReadInt32(version)) {
413 IAM_LOGE("failed to read version");
414 return GENERAL_ERROR;
415 }
416 int32_t result = GENERAL_ERROR;
417 if (!reply.ReadInt32(result)) {
418 IAM_LOGE("failed to read result");
419 }
420 return result;
421 }
422
SendRequest(uint32_t code,MessageParcel & data,MessageParcel & reply)423 bool UserAuthProxy::SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply)
424 {
425 IAM_LOGI("code = %{public}u", code);
426 sptr<IRemoteObject> remote = Remote();
427 if (remote == nullptr) {
428 IAM_LOGE("failed to get remote");
429 return false;
430 }
431 MessageOption option(MessageOption::TF_SYNC);
432 int32_t result = remote->SendRequest(code, data, reply, option);
433 if (result != OHOS::NO_ERROR) {
434 IAM_LOGE("failed to send request, result = %{public}d", result);
435 return false;
436 }
437 return true;
438 }
439
Notice(NoticeType noticeType,const std::string & eventData)440 int32_t UserAuthProxy::Notice(NoticeType noticeType, const std::string &eventData)
441 {
442 MessageParcel data;
443 MessageParcel reply;
444
445 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
446 IAM_LOGE("failed to write descriptor");
447 return ResultCode::WRITE_PARCEL_ERROR;
448 }
449
450 int32_t type = static_cast<int32_t>(noticeType);
451 if (!data.WriteInt32(type)) {
452 IAM_LOGE("failed to write noticeType");
453 return ResultCode::WRITE_PARCEL_ERROR;
454 }
455 if (!data.WriteString(eventData)) {
456 IAM_LOGE("failed to write eventData");
457 return ResultCode::WRITE_PARCEL_ERROR;
458 }
459
460 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_NOTICE, data, reply);
461 if (!ret) {
462 IAM_LOGE("failed to send user notice IPC request");
463 return ResultCode::GENERAL_ERROR;
464 }
465 int32_t result = ResultCode::GENERAL_ERROR;
466 if (!reply.ReadInt32(result)) {
467 IAM_LOGE("failed to read result");
468 return ResultCode::READ_PARCEL_ERROR;
469 }
470 return result;
471 }
472
RegisterWidgetCallback(int32_t version,sptr<WidgetCallbackInterface> & callback)473 int32_t UserAuthProxy::RegisterWidgetCallback(int32_t version, sptr<WidgetCallbackInterface> &callback)
474 {
475 if (callback == nullptr) {
476 IAM_LOGE("callback is nullptr");
477 return GENERAL_ERROR;
478 }
479 MessageParcel data;
480 MessageParcel reply;
481
482 if (!data.WriteInterfaceToken(UserAuthProxy::GetDescriptor())) {
483 IAM_LOGE("failed to write descriptor");
484 return GENERAL_ERROR;
485 }
486
487 if (!data.WriteInt32(version)) {
488 IAM_LOGE("failed to write version");
489 return WRITE_PARCEL_ERROR;
490 }
491
492 if (!data.WriteRemoteObject(callback->AsObject())) {
493 IAM_LOGE("failed to write callback");
494 return GENERAL_ERROR;
495 }
496
497 bool ret = SendRequest(UserAuthInterfaceCode::USER_AUTH_REG_WIDGET_CB, data, reply);
498 if (!ret) {
499 IAM_LOGE("failed to send register widget callback IPC request");
500 return GENERAL_ERROR;
501 }
502 int32_t result = GENERAL_ERROR;
503 if (!reply.ReadInt32(result)) {
504 IAM_LOGE("failed to read result");
505 return READ_PARCEL_ERROR;
506 }
507 return result;
508 }
509 } // namespace UserAuth
510 } // namespace UserIam
511 } // namespace OHOS