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 "v1_0/user_auth_interface_service.h"
17
18 #include <mutex>
19 #include <hdf_base.h>
20 #include "securec.h"
21
22 #include "iam_logger.h"
23 #include "iam_ptr.h"
24
25 #include "useriam_common.h"
26 #include "auth_level.h"
27 #include "buffer.h"
28 #include "coauth_funcs.h"
29 #include "identify_funcs.h"
30 #include "idm_database.h"
31 #include "idm_session.h"
32 #include "ed25519_key.h"
33 #include "user_auth_funcs.h"
34 #include "user_idm_funcs.h"
35 #include "enroll_specification_check.h"
36
37 #define LOG_LABEL OHOS::UserIam::Common::LABEL_USER_AUTH_HDI
38
39 namespace OHOS {
40 namespace HDI {
41 namespace UserAuth {
42 namespace V1_0 {
43 namespace {
44 static std::mutex g_mutex;
45 }
46
UserAuthInterfaceImplGetInstance(void)47 extern "C" IUserAuthInterface *UserAuthInterfaceImplGetInstance(void)
48 {
49 auto userAuthInterfaceService = new (std::nothrow) UserAuthInterfaceService();
50 if (userAuthInterfaceService == nullptr) {
51 IAM_LOGE("userAuthInterfaceService is nullptr");
52 return nullptr;
53 }
54 std::lock_guard<std::mutex> lock(g_mutex);
55 OHOS::UserIam::Common::Init();
56 return userAuthInterfaceService;
57 }
58
Init()59 int32_t UserAuthInterfaceService::Init()
60 {
61 IAM_LOGI("start");
62 std::lock_guard<std::mutex> lock(g_mutex);
63 OHOS::UserIam::Common::Close();
64 return OHOS::UserIam::Common::Init();
65 }
66
CopyScheduleInfo(const CoAuthSchedule * in,ScheduleInfo * out)67 static bool CopyScheduleInfo(const CoAuthSchedule *in, ScheduleInfo *out)
68 {
69 IAM_LOGI("start");
70 if (in->executorSize == 0) {
71 IAM_LOGE("executorSize is zero");
72 return false;
73 }
74 out->executors.clear();
75 out->templateIds.clear();
76 out->scheduleId = in->scheduleId;
77 out->authType = static_cast<AuthType>(in->authType);
78 for (uint32_t i = 0; i < in->templateIds.num; ++i) {
79 out->templateIds.push_back(in->templateIds.value[i]);
80 }
81 out->executorMatcher = static_cast<uint32_t>(in->executors[0].executorMatcher);
82 out->scheduleMode = static_cast<ScheduleMode>(in->scheduleMode);
83 for (uint32_t i = 0; i < in->executorSize; ++i) {
84 ExecutorInfo temp = {};
85 temp.executorIndex = in->executors[i].executorIndex;
86 temp.info.authType = static_cast<AuthType>(in->executors[i].authType);
87 temp.info.executorRole = static_cast<ExecutorRole>(in->executors[i].executorRole);
88 temp.info.executorSensorHint = in->executors[i].executorSensorHint;
89 temp.info.executorMatcher = static_cast<uint32_t>(in->executors[i].executorMatcher);
90 temp.info.esl = static_cast<ExecutorSecureLevel>(in->executors[i].esl);
91 temp.info.publicKey.resize(PUBLIC_KEY_LEN);
92 if (memcpy_s(&temp.info.publicKey[0], temp.info.publicKey.size(),
93 in->executors[i].pubKey, PUBLIC_KEY_LEN) != EOK) {
94 IAM_LOGE("copy failed");
95 out->executors.clear();
96 out->templateIds.clear();
97 return false;
98 }
99 out->executors.push_back(temp);
100 }
101 return true;
102 }
103
BeginAuthentication(uint64_t contextId,const AuthSolution & param,std::vector<ScheduleInfo> & infos)104 int32_t UserAuthInterfaceService::BeginAuthentication(uint64_t contextId, const AuthSolution ¶m,
105 std::vector<ScheduleInfo> &infos)
106 {
107 IAM_LOGI("start");
108 infos.clear();
109 AuthSolutionHal solutionIn = {};
110 solutionIn.contextId = contextId;
111 solutionIn.userId = param.userId;
112 solutionIn.authType = static_cast<uint32_t>(param.authType);
113 solutionIn.authTrustLevel = param.authTrustLevel;
114 if (!param.challenge.empty() && memcpy_s(solutionIn.challenge, CHALLENGE_LEN, param.challenge.data(),
115 param.challenge.size()) != EOK) {
116 IAM_LOGE("challenge copy failed");
117 return RESULT_BAD_COPY;
118 }
119 std::lock_guard<std::mutex> lock(g_mutex);
120 LinkedList *schedulesGet = nullptr;
121 int32_t ret = GenerateSolutionFunc(solutionIn, &schedulesGet);
122 if (ret != RESULT_SUCCESS) {
123 IAM_LOGE("generate solution failed %{public}d", ret);
124 return ret;
125 }
126 if (schedulesGet == nullptr) {
127 IAM_LOGE("get null schedule");
128 return RESULT_GENERAL_ERROR;
129 }
130 LinkedListNode *tempNode = schedulesGet->head;
131 while (tempNode != nullptr) {
132 if (tempNode->data == nullptr) {
133 IAM_LOGE("node data is invalid");
134 DestroyLinkedList(schedulesGet);
135 return RESULT_UNKNOWN;
136 }
137 ScheduleInfo temp = {};
138 auto coAuthSchedule = static_cast<CoAuthSchedule *>(tempNode->data);
139 if (!CopyScheduleInfo(coAuthSchedule, &temp)) {
140 infos.clear();
141 ret = RESULT_GENERAL_ERROR;
142 break;
143 }
144 infos.push_back(temp);
145 tempNode = tempNode->next;
146 }
147 DestroyLinkedList(schedulesGet);
148 return ret;
149 }
150
CreateExecutorCommand(AuthResultInfo & info)151 static int32_t CreateExecutorCommand(AuthResultInfo &info)
152 {
153 LinkedList *executorSendMsg = nullptr;
154 int32_t ret = RESULT_GENERAL_ERROR;
155 if (info.result == RESULT_SUCCESS) {
156 ret = GetExecutorMsgList(PROPERMODE_UNLOCK, &executorSendMsg);
157 if (ret != RESULT_SUCCESS) {
158 IAM_LOGE("get unlock msg failed");
159 return ret;
160 }
161 } else if (info.remainAttempts == 0) {
162 ret = GetExecutorMsgList(PROPERMODE_LOCK, &executorSendMsg);
163 if (ret != RESULT_SUCCESS) {
164 IAM_LOGE("get lock msg failed");
165 return ret;
166 }
167 } else {
168 return RESULT_SUCCESS;
169 }
170 LinkedListNode *temp = executorSendMsg->head;
171 while (temp != NULL) {
172 if (temp->data == NULL) {
173 IAM_LOGE("list node is invalid");
174 DestroyLinkedList(executorSendMsg);
175 return RESULT_UNKNOWN;
176 }
177 auto nodeData = static_cast<ExecutorMsg *>(temp->data);
178 Buffer *nodeMsgBuffer = nodeData->msg;
179 if (!IsBufferValid(nodeMsgBuffer)) {
180 IAM_LOGE("node's buffer invalid");
181 DestroyLinkedList(executorSendMsg);
182 return RESULT_UNKNOWN;
183 }
184 ExecutorSendMsg msg = {};
185 msg.executorIndex = nodeData->executorIndex;
186 msg.msg.resize(nodeMsgBuffer->contentSize);
187 if (memcpy_s(msg.msg.data(), msg.msg.size(), nodeMsgBuffer->buf, nodeMsgBuffer->contentSize) != EOK) {
188 IAM_LOGE("copy failed");
189 msg.msg.clear();
190 DestroyLinkedList(executorSendMsg);
191 return RESULT_BAD_COPY;
192 }
193 info.msgs.push_back(msg);
194 temp = temp->next;
195 }
196 DestroyLinkedList(executorSendMsg);
197 return RESULT_SUCCESS;
198 }
199
UpdateAuthenticationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,AuthResultInfo & info)200 int32_t UserAuthInterfaceService::UpdateAuthenticationResult(uint64_t contextId,
201 const std::vector<uint8_t> &scheduleResult, AuthResultInfo &info)
202 {
203 IAM_LOGI("start");
204 if (scheduleResult.size() == 0) {
205 IAM_LOGE("param is invalid");
206 DestoryContextbyId(contextId);
207 return RESULT_BAD_PARAM;
208 }
209 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
210 if (!IsBufferValid(scheduleResultBuffer)) {
211 IAM_LOGE("scheduleTokenBuffer is invalid");
212 DestoryContextbyId(contextId);
213 return RESULT_NO_MEMORY;
214 }
215 std::lock_guard<std::mutex> lock(g_mutex);
216 UserAuthTokenHal authTokenHal = {};
217 AuthResult authResult = {};
218 int32_t ret = RequestAuthResultFunc(contextId, scheduleResultBuffer, &authTokenHal, &authResult);
219 DestoryBuffer(scheduleResultBuffer);
220 if (ret != RESULT_SUCCESS) {
221 IAM_LOGE("execute func failed");
222 return ret;
223 }
224 info.result = authResult.result;
225 info.remainAttempts = authResult.remainTimes;
226 info.lockoutDuration = authResult.freezingTime;
227 if (info.result == RESULT_SUCCESS) {
228 info.token.resize(sizeof(UserAuthTokenHal));
229 if (memcpy_s(info.token.data(), info.token.size(), &authTokenHal, sizeof(authTokenHal)) != EOK) {
230 IAM_LOGE("copy authToken failed");
231 info.token.clear();
232 return RESULT_BAD_COPY;
233 }
234 if (authResult.rootSecret != NULL) {
235 info.rootSecret.resize(authResult.rootSecret->contentSize);
236 if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(),
237 authResult.rootSecret->buf, authResult.rootSecret->contentSize) != EOK) {
238 IAM_LOGE("copy secret failed");
239 info.rootSecret.clear();
240 info.token.clear();
241 return RESULT_BAD_COPY;
242 }
243 }
244 }
245 DestoryBuffer(authResult.rootSecret);
246 if (authTokenHal.authType != PIN_AUTH) {
247 IAM_LOGI("type not pin");
248 return RESULT_SUCCESS;
249 }
250 IAM_LOGI("type pin");
251 return CreateExecutorCommand(info);
252 }
253
CancelAuthentication(uint64_t contextId)254 int32_t UserAuthInterfaceService::CancelAuthentication(uint64_t contextId)
255 {
256 IAM_LOGI("start");
257 std::lock_guard<std::mutex> lock(g_mutex);
258 return DestoryContextbyId(contextId);
259 }
260
BeginIdentification(uint64_t contextId,AuthType authType,const std::vector<uint8_t> & challenge,uint32_t executorSensorHint,ScheduleInfo & scheduleInfo)261 int32_t UserAuthInterfaceService::BeginIdentification(uint64_t contextId, AuthType authType,
262 const std::vector<uint8_t> &challenge, uint32_t executorSensorHint, ScheduleInfo &scheduleInfo)
263 {
264 IAM_LOGI("start");
265 if (authType == PIN) {
266 IAM_LOGE("param is invalid");
267 return RESULT_BAD_PARAM;
268 }
269 IdentifyParam param = {};
270 param.contextId = contextId;
271 param.authType = static_cast<uint32_t>(authType);
272 param.executorSensorHint = executorSensorHint;
273 if (!challenge.empty() && memcpy_s(param.challenge, CHALLENGE_LEN, challenge.data(), challenge.size()) != EOK) {
274 IAM_LOGE("challenge copy failed");
275 return RESULT_BAD_COPY;
276 }
277 std::lock_guard<std::mutex> lock(g_mutex);
278 LinkedList *scheduleGet = nullptr;
279 int32_t ret = DoIdentify(param, &scheduleGet);
280 if (ret != RESULT_SUCCESS) {
281 IAM_LOGE("generate solution failed");
282 return ret;
283 }
284 if (scheduleGet == nullptr) {
285 IAM_LOGE("get null schedule");
286 return RESULT_GENERAL_ERROR;
287 }
288 if (scheduleGet->head == nullptr || scheduleGet->head->data == nullptr) {
289 IAM_LOGE("scheduleGet is invalid");
290 DestroyLinkedList(scheduleGet);
291 return RESULT_UNKNOWN;
292 }
293 auto data = static_cast<CoAuthSchedule *>(scheduleGet->head->data);
294 if (!CopyScheduleInfo(data, &scheduleInfo)) {
295 IAM_LOGE("copy schedule failed");
296 ret = RESULT_BAD_COPY;
297 }
298 DestroyLinkedList(scheduleGet);
299 return ret;
300 }
301
UpdateIdentificationResult(uint64_t contextId,const std::vector<uint8_t> & scheduleResult,IdentifyResultInfo & info)302 int32_t UserAuthInterfaceService::UpdateIdentificationResult(uint64_t contextId,
303 const std::vector<uint8_t> &scheduleResult, IdentifyResultInfo &info)
304 {
305 IAM_LOGI("start");
306 if (scheduleResult.size() == 0) {
307 IAM_LOGE("param is invalid");
308 return RESULT_BAD_PARAM;
309 }
310 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
311 if (!IsBufferValid(scheduleResultBuffer)) {
312 IAM_LOGE("scheduleTokenBuffer is invalid");
313 return RESULT_NO_MEMORY;
314 }
315 std::lock_guard<std::mutex> lock(g_mutex);
316 UserAuthTokenHal token = {};
317 int32_t ret = DoUpdateIdentify(contextId, scheduleResultBuffer, &info.userId, &token, &info.result);
318 DestoryBuffer(scheduleResultBuffer);
319 if (ret != RESULT_SUCCESS) {
320 IAM_LOGE("DoUpdateIdentify failed");
321 return ret;
322 }
323 if (info.result == RESULT_SUCCESS) {
324 info.token.resize(sizeof(UserAuthTokenHal));
325 if (memcpy_s(info.token.data(), info.token.size(), &token, sizeof(token)) != EOK) {
326 IAM_LOGE("copy authToken failed");
327 info.token.clear();
328 return RESULT_BAD_COPY;
329 }
330 }
331 return RESULT_SUCCESS;
332 }
333
CancelIdentification(uint64_t contextId)334 int32_t UserAuthInterfaceService::CancelIdentification(uint64_t contextId)
335 {
336 IAM_LOGI("start");
337 std::lock_guard<std::mutex> lock(g_mutex);
338 return DestoryContextbyId(contextId);
339 }
340
GetAuthTrustLevel(int32_t userId,AuthType authType,uint32_t & authTrustLevel)341 int32_t UserAuthInterfaceService::GetAuthTrustLevel(int32_t userId, AuthType authType, uint32_t &authTrustLevel)
342 {
343 IAM_LOGI("start");
344 std::lock_guard<std::mutex> lock(g_mutex);
345 int32_t ret = SingleAuthTrustLevel(userId, authType, &authTrustLevel);
346 return ret;
347 }
348
GetValidSolution(int32_t userId,const std::vector<AuthType> & authTypes,uint32_t authTrustLevel,std::vector<AuthType> & validTypes)349 int32_t UserAuthInterfaceService::GetValidSolution(int32_t userId, const std::vector<AuthType> &authTypes,
350 uint32_t authTrustLevel, std::vector<AuthType> &validTypes)
351 {
352 IAM_LOGI("start");
353 return RESULT_SUCCESS;
354 }
355
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)356 int32_t UserAuthInterfaceService::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
357 {
358 IAM_LOGI("start");
359 std::lock_guard<std::mutex> lock(g_mutex);
360 challenge.resize(CHALLENGE_LEN);
361 int32_t ret = OpenEditSession(userId, challenge.data(), challenge.size());
362 if (ret != RESULT_SUCCESS) {
363 IAM_LOGE("failed to open session");
364 challenge.clear();
365 }
366 return ret;
367 }
368
CloseSession(int32_t userId)369 int32_t UserAuthInterfaceService::CloseSession(int32_t userId)
370 {
371 IAM_LOGI("start");
372 std::lock_guard<std::mutex> lock(g_mutex);
373 return CloseEditSession();
374 }
375
BeginEnrollment(int32_t userId,const std::vector<uint8_t> & authToken,const EnrollParam & param,ScheduleInfo & info)376 int32_t UserAuthInterfaceService::BeginEnrollment(int32_t userId, const std::vector<uint8_t> &authToken,
377 const EnrollParam ¶m, ScheduleInfo &info)
378 {
379 IAM_LOGI("start");
380 if (authToken.size() != sizeof(UserAuthTokenHal) && authToken.size() != 0) {
381 IAM_LOGE("authToken len is invalid");
382 return RESULT_BAD_PARAM;
383 }
384 PermissionCheckParam checkParam = {};
385 if (authToken.size() == sizeof(UserAuthTokenHal) &&
386 memcpy_s(checkParam.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
387 return RESULT_BAD_COPY;
388 }
389 checkParam.authType = param.authType;
390 checkParam.userId = userId;
391 checkParam.executorSensorHint = param.executorSensorHint;
392 std::lock_guard<std::mutex> lock(g_mutex);
393 uint64_t scheduleId;
394 int32_t ret;
395 if (authToken.size() == sizeof(UserAuthTokenHal) && param.authType == PIN) {
396 ret = CheckUpdatePermission(checkParam, &scheduleId);
397 if (ret != RESULT_SUCCESS) {
398 IAM_LOGE("check update permission failed");
399 return ret;
400 }
401 } else {
402 ret = CheckEnrollPermission(checkParam, &scheduleId);
403 if (ret != RESULT_SUCCESS) {
404 IAM_LOGE("check enroll permission failed");
405 return ret;
406 }
407 }
408 const CoAuthSchedule *scheduleInfo = GetCoAuthSchedule(scheduleId);
409 if (scheduleInfo == NULL) {
410 IAM_LOGE("get schedule info failed");
411 return RESULT_UNKNOWN;
412 }
413 if (!CopyScheduleInfo(scheduleInfo, &info)) {
414 IAM_LOGE("copy schedule info failed");
415 return RESULT_BAD_COPY;
416 }
417 return ret;
418 }
419
CancelEnrollment(int32_t userId)420 int32_t UserAuthInterfaceService::CancelEnrollment(int32_t userId)
421 {
422 IAM_LOGI("start");
423 std::lock_guard<std::mutex> lock(g_mutex);
424 BreakOffCoauthSchedule();
425 return RESULT_SUCCESS;
426 }
427
CopyCredentialInfo(const CredentialInfoHal & in,CredentialInfo & out)428 static void CopyCredentialInfo(const CredentialInfoHal &in, CredentialInfo &out)
429 {
430 out.authType = static_cast<AuthType>(in.authType);
431 out.credentialId = in.credentialId;
432 out.templateId = in.templateId;
433 out.executorMatcher = in.executorMatcher;
434 out.executorSensorHint = in.executorSensorHint;
435 out.executorIndex = QueryCredentialExecutorIndex(in.authType, in.executorSensorHint);
436 }
437
UpdateEnrollmentResult(int32_t userId,const std::vector<uint8_t> & scheduleResult,EnrollResultInfo & info)438 int32_t UserAuthInterfaceService::UpdateEnrollmentResult(int32_t userId, const std::vector<uint8_t> &scheduleResult,
439 EnrollResultInfo &info)
440 {
441 IAM_LOGI("start");
442 if (scheduleResult.size() == 0) {
443 IAM_LOGE("enrollToken is invalid");
444 return RESULT_BAD_PARAM;
445 }
446 Buffer *scheduleResultBuffer = CreateBufferByData(&scheduleResult[0], scheduleResult.size());
447 if (scheduleResultBuffer == nullptr) {
448 IAM_LOGE("scheduleTokenBuffer is null");
449 return RESULT_NO_MEMORY;
450 }
451 std::lock_guard<std::mutex> lock(g_mutex);
452 bool isUpdate;
453 int32_t ret = GetIsUpdate(&isUpdate);
454 if (ret != RESULT_SUCCESS) {
455 IAM_LOGE("get isUpdate failed");
456 DestoryBuffer(scheduleResultBuffer);
457 return ret;
458 }
459 Buffer *rootSecret = NULL;
460 if (isUpdate) {
461 CredentialInfoHal oldCredentialHal = {};
462 ret = UpdateCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &oldCredentialHal, &rootSecret);
463 CopyCredentialInfo(oldCredentialHal, info.oldInfo);
464 } else {
465 ret = AddCredentialFunc(userId, scheduleResultBuffer, &info.credentialId, &rootSecret);
466 }
467 if (rootSecret != NULL) {
468 info.rootSecret.resize(rootSecret->contentSize);
469 if (memcpy_s(info.rootSecret.data(), info.rootSecret.size(), rootSecret->buf, rootSecret->contentSize) != EOK) {
470 IAM_LOGE("failed to copy rootSecret");
471 info.rootSecret.clear();
472 ret = RESULT_BAD_COPY;
473 }
474 DestoryBuffer(rootSecret);
475 }
476 DestoryBuffer(scheduleResultBuffer);
477 return ret;
478 }
479
DeleteCredential(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,CredentialInfo & info)480 int32_t UserAuthInterfaceService::DeleteCredential(int32_t userId, uint64_t credentialId,
481 const std::vector<uint8_t> &authToken, CredentialInfo &info)
482 {
483 IAM_LOGI("start");
484 if (authToken.size() != sizeof(UserAuthTokenHal)) {
485 IAM_LOGE("authToken len is invalid");
486 return RESULT_BAD_PARAM;
487 }
488 std::lock_guard<std::mutex> lock(g_mutex);
489 CredentialDeleteParam param = {};
490 if (memcpy_s(param.token, AUTH_TOKEN_LEN, &authToken[0], authToken.size()) != EOK) {
491 IAM_LOGE("param token copy failed");
492 return RESULT_BAD_COPY;
493 }
494 param.userId = userId;
495 param.credentialId = credentialId;
496 CredentialInfoHal credentialInfoHal = {};
497 int32_t ret = DeleteCredentialFunc(param, &credentialInfoHal);
498 if (ret != RESULT_SUCCESS) {
499 IAM_LOGE("delete failed");
500 return ret;
501 }
502 CopyCredentialInfo(credentialInfoHal, info);
503 return RESULT_SUCCESS;
504 }
505
GetCredential(int32_t userId,AuthType authType,std::vector<CredentialInfo> & infos)506 int32_t UserAuthInterfaceService::GetCredential(int32_t userId, AuthType authType, std::vector<CredentialInfo> &infos)
507 {
508 IAM_LOGI("start");
509 std::lock_guard<std::mutex> lock(g_mutex);
510 LinkedList *credList = nullptr;
511 int32_t ret = QueryCredentialFunc(userId, authType, &credList);
512 if (ret != RESULT_SUCCESS) {
513 IAM_LOGE("query credential failed");
514 return ret;
515 }
516 infos.reserve(credList->getSize(credList));
517 LinkedListNode *temp = credList->head;
518 while (temp != nullptr) {
519 if (temp->data == NULL) {
520 IAM_LOGE("list node is invalid");
521 DestroyLinkedList(credList);
522 return RESULT_UNKNOWN;
523 }
524 auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
525 CredentialInfo credentialInfo = {};
526 CopyCredentialInfo(*credentialHal, credentialInfo);
527 infos.push_back(credentialInfo);
528 temp = temp->next;
529 }
530 DestroyLinkedList(credList);
531 return RESULT_SUCCESS;
532 }
533
GetUserInfo(int32_t userId,uint64_t & secureUid,PinSubType & pinSubType,std::vector<EnrolledInfo> & infos)534 int32_t UserAuthInterfaceService::GetUserInfo(int32_t userId, uint64_t &secureUid, PinSubType &pinSubType,
535 std::vector<EnrolledInfo> &infos)
536 {
537 IAM_LOGI("start");
538 std::lock_guard<std::mutex> lock(g_mutex);
539 EnrolledInfoHal *enrolledInfoHals = nullptr;
540 uint32_t num = 0;
541 uint64_t pinSubTypeGet;
542 int32_t ret = GetUserInfoFunc(userId, &secureUid, &pinSubTypeGet, &enrolledInfoHals, &num);
543 if (ret != RESULT_SUCCESS) {
544 IAM_LOGE("get user info failed");
545 return ret;
546 }
547 pinSubType = static_cast<PinSubType>(pinSubTypeGet);
548 for (uint32_t i = 0; i < num; ++i) {
549 EnrolledInfo enrolledInfo = {};
550 enrolledInfo.authType = static_cast<AuthType>(enrolledInfoHals[i].authType);
551 enrolledInfo.enrolledId = enrolledInfoHals[i].enrolledId;
552 infos.push_back(enrolledInfo);
553 }
554 free(enrolledInfoHals);
555 return RESULT_SUCCESS;
556 }
557
DeleteUser(int32_t userId,const std::vector<uint8_t> & authToken,std::vector<CredentialInfo> & deletedInfos)558 int32_t UserAuthInterfaceService::DeleteUser(int32_t userId, const std::vector<uint8_t> &authToken,
559 std::vector<CredentialInfo> &deletedInfos)
560 {
561 IAM_LOGI("start");
562 if (authToken.size() != sizeof(UserAuthTokenHal)) {
563 IAM_LOGE("authToken is invalid");
564 return RESULT_BAD_PARAM;
565 }
566 UserAuthTokenHal authTokenStruct = {};
567 if (memcpy_s(&authTokenStruct, sizeof(UserAuthTokenHal), &authToken[0], authToken.size()) != EOK) {
568 IAM_LOGE("authTokenStruct copy failed");
569 return RESULT_BAD_COPY;
570 }
571 int32_t ret = CheckIdmOperationToken(userId, &authTokenStruct);
572 if (ret != RESULT_SUCCESS) {
573 IAM_LOGE("failed to verify token");
574 return RESULT_BAD_SIGN;
575 }
576 return EnforceDeleteUser(userId, deletedInfos);
577 }
578
EnforceDeleteUser(int32_t userId,std::vector<CredentialInfo> & deletedInfos)579 int32_t UserAuthInterfaceService::EnforceDeleteUser(int32_t userId, std::vector<CredentialInfo> &deletedInfos)
580 {
581 IAM_LOGI("start");
582 std::lock_guard<std::mutex> lock(g_mutex);
583 LinkedList *credList = nullptr;
584 int32_t ret = DeleteUserInfo(userId, &credList);
585 if (ret != RESULT_SUCCESS) {
586 IAM_LOGE("query credential failed");
587 return ret;
588 }
589 RefreshValidTokenTime();
590 LinkedListNode *temp = credList->head;
591 while (temp != NULL) {
592 if (temp->data == NULL) {
593 IAM_LOGE("list node is invalid");
594 DestroyLinkedList(credList);
595 return RESULT_UNKNOWN;
596 }
597 auto credentialHal = static_cast<CredentialInfoHal *>(temp->data);
598 CredentialInfo credentialInfo = {};
599 CopyCredentialInfo(*credentialHal, credentialInfo);
600 deletedInfos.push_back(credentialInfo);
601 temp = temp->next;
602 }
603 DestroyLinkedList(credList);
604 return RESULT_SUCCESS;
605 }
606
CopyExecutorInfo(const ExecutorRegisterInfo & in,ExecutorInfoHal & out)607 static bool CopyExecutorInfo(const ExecutorRegisterInfo &in, ExecutorInfoHal &out)
608 {
609 out.authType = in.authType;
610 out.executorMatcher = in.executorMatcher;
611 out.esl = in.esl;
612 out.executorRole = in.executorRole;
613 out.executorSensorHint = in.executorSensorHint;
614 if (memcpy_s(out.pubKey, PUBLIC_KEY_LEN, &in.publicKey[0], in.publicKey.size()) != EOK) {
615 IAM_LOGE("memcpy failed");
616 return false;
617 }
618 return true;
619 }
620
ObtainReconciliationData(uint32_t authType,uint32_t sensorHint,std::vector<uint64_t> & templateIds)621 static int32_t ObtainReconciliationData(uint32_t authType, uint32_t sensorHint, std::vector<uint64_t> &templateIds)
622 {
623 CredentialCondition condition = {};
624 SetCredentialConditionAuthType(&condition, authType);
625 SetCredentialConditionExecutorSensorHint(&condition, sensorHint);
626 LinkedList *credList = QueryCredentialLimit(&condition);
627 if (credList == NULL) {
628 IAM_LOGE("query credential failed");
629 return RESULT_NOT_FOUND;
630 }
631 LinkedListNode *temp = credList->head;
632 while (temp != NULL) {
633 if (temp->data == NULL) {
634 IAM_LOGE("list node is invalid");
635 DestroyLinkedList(credList);
636 return RESULT_UNKNOWN;
637 }
638 auto credentialInfo = static_cast<CredentialInfoHal *>(temp->data);
639 templateIds.push_back(credentialInfo->templateId);
640 temp = temp->next;
641 }
642 DestroyLinkedList(credList);
643 return RESULT_SUCCESS;
644 }
645
AddExecutor(const ExecutorRegisterInfo & info,uint64_t & index,std::vector<uint8_t> & publicKey,std::vector<uint64_t> & templateIds)646 int32_t UserAuthInterfaceService::AddExecutor(const ExecutorRegisterInfo &info, uint64_t &index,
647 std::vector<uint8_t> &publicKey, std::vector<uint64_t> &templateIds)
648 {
649 IAM_LOGI("start");
650 if (info.publicKey.size() != PUBLIC_KEY_LEN) {
651 IAM_LOGE("invalid info");
652 return RESULT_BAD_PARAM;
653 }
654 templateIds.clear();
655 const Buffer *frameworkPubKey = GetPubKey();
656 if (!IsBufferValid(frameworkPubKey)) {
657 IAM_LOGE("get public key failed");
658 return RESULT_UNKNOWN;
659 }
660 publicKey.resize(PUBLIC_KEY_LEN);
661 if (memcpy_s(&publicKey[0], publicKey.size(), frameworkPubKey->buf, frameworkPubKey->contentSize) != EOK) {
662 IAM_LOGE("copy public key failed");
663 publicKey.clear();
664 return RESULT_UNKNOWN;
665 }
666 std::lock_guard<std::mutex> lock(g_mutex);
667 ExecutorInfoHal executorInfoHal = {};
668 CopyExecutorInfo(info, executorInfoHal);
669 int32_t ret = RegisterExecutor(&executorInfoHal, &index);
670 if (ret != RESULT_SUCCESS) {
671 IAM_LOGE("register executor failed");
672 return ret;
673 }
674 if (info.executorRole == VERIFIER || info.executorRole == ALL_IN_ONE) {
675 return ObtainReconciliationData(executorInfoHal.authType, executorInfoHal.executorSensorHint, templateIds);
676 }
677 return RESULT_SUCCESS;
678 }
679
DeleteExecutor(uint64_t index)680 int32_t UserAuthInterfaceService::DeleteExecutor(uint64_t index)
681 {
682 IAM_LOGI("start");
683 std::lock_guard<std::mutex> lock(g_mutex);
684 return UnRegisterExecutor(index);
685 }
686 } // V1_0
687 } // Userauth
688 } // HDI
689 } // OHOS
690