1 /*
2 * Copyright (C) 2022-2024 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 "idm_database.h"
17
18 #include "inttypes.h"
19 #include "securec.h"
20
21 #include "adaptor_algorithm.h"
22 #include "adaptor_log.h"
23 #include "adaptor_time.h"
24 #include "idm_file_manager.h"
25 #include "global_config_file_manager.h"
26
27 #define MAX_DUPLICATE_CHECK 100
28 #define PRE_APPLY_NUM 5
29 #define MEM_GROWTH_FACTOR 2
30 #define MAX_CREDENTIAL_RETURN 5000
31
32 #ifdef IAM_TEST_ENABLE
33 #define IAM_STATIC
34 #else
35 #define IAM_STATIC static
36 #endif
37
38 // Caches IDM user information.
39 IAM_STATIC LinkedList *g_userInfoList = NULL;
40
41 // Caches the current user to reduce the number of user list traversal times.
42 IAM_STATIC UserInfo *g_currentUser = NULL;
43
44 // Caches global config info.
45 IAM_STATIC GlobalConfigInfo g_globalConfigArray[MAX_GLOBAL_CONFIG_NUM];
46 IAM_STATIC uint32_t g_globalConfigInfoNum = 0;
47
48 typedef bool (*DuplicateCheckFunc)(LinkedList *collection, uint64_t value);
49
50 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId);
51 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num);
52 IAM_STATIC ResultCode DeleteUser(int32_t userId);
53 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList);
54 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList);
55 IAM_STATIC bool MatchCredentialById(const void *data, const void *condition);
56 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func);
57 IAM_STATIC bool IsUserValid(UserInfo *user);
58 IAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
59 bool *cachePinRemoved);
60 IAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved);
61 IAM_STATIC ResultCode ClearInvalidData(void);
62
InitUserInfoList(void)63 ResultCode InitUserInfoList(void)
64 {
65 LOG_INFO("InitUserInfoList start");
66 if (g_userInfoList != NULL) {
67 DestroyUserInfoList();
68 g_userInfoList = NULL;
69 }
70 g_userInfoList = LoadFileInfo();
71 if (g_userInfoList == NULL) {
72 LOG_ERROR("load file info failed");
73 return RESULT_NEED_INIT;
74 }
75 ResultCode ret = ClearInvalidData();
76 if (ret != RESULT_SUCCESS) {
77 LOG_ERROR("clear invalid user failed");
78 DestroyUserInfoList();
79 return ret;
80 }
81 ret = LoadGlobalConfigInfo(g_globalConfigArray, MAX_GLOBAL_CONFIG_NUM, &g_globalConfigInfoNum);
82 if (ret != RESULT_SUCCESS) {
83 LOG_ERROR("load global config info failed");
84 }
85 LOG_INFO("InitUserInfoList end");
86 return RESULT_SUCCESS;
87 }
88
DestroyUserInfoList(void)89 void DestroyUserInfoList(void)
90 {
91 DestroyLinkedList(g_userInfoList);
92 g_userInfoList = NULL;
93 }
94
MatchUserInfo(const void *data, const void *condition)95 IAM_STATIC bool MatchUserInfo(const void *data, const void *condition)
96 {
97 if (data == NULL || condition == NULL) {
98 LOG_ERROR("please check invalid node");
99 return false;
100 }
101 const UserInfo *userInfo = (const UserInfo *)data;
102 int32_t userId = *(const int32_t *)condition;
103 if (userInfo->userId == userId) {
104 return true;
105 }
106 return false;
107 }
108
IsUserInfoValid(UserInfo *userInfo)109 IAM_STATIC bool IsUserInfoValid(UserInfo *userInfo)
110 {
111 if (userInfo == NULL) {
112 LOG_ERROR("userInfo is null");
113 return false;
114 }
115 if (userInfo->credentialInfoList == NULL) {
116 LOG_ERROR("credentialInfoList is null");
117 return false;
118 }
119 if (userInfo->enrolledInfoList == NULL) {
120 LOG_ERROR("enrolledInfoList is null");
121 return false;
122 }
123 return true;
124 }
125
GetSecureUid(int32_t userId, uint64_t *secUid)126 ResultCode GetSecureUid(int32_t userId, uint64_t *secUid)
127 {
128 if (secUid == NULL) {
129 LOG_ERROR("secUid is null");
130 return RESULT_BAD_PARAM;
131 }
132 UserInfo *user = QueryUserInfo(userId);
133 if (user == NULL) {
134 LOG_ERROR("can't find this user");
135 return RESULT_NOT_FOUND;
136 }
137 *secUid = user->secUid;
138 return RESULT_SUCCESS;
139 }
140
GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo)141 ResultCode GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo)
142 {
143 if (enrolledInfo == NULL) {
144 LOG_ERROR("enrolledInfo is null");
145 return RESULT_BAD_PARAM;
146 }
147 UserInfo *user = QueryUserInfo(userId);
148 if (user == NULL) {
149 LOG_ERROR("can't find this user");
150 return RESULT_NOT_FOUND;
151 }
152 if (user->enrolledInfoList == NULL) {
153 LOG_ERROR("enrolledInfoList is null");
154 return RESULT_UNKNOWN;
155 }
156
157 LinkedListNode *temp = user->enrolledInfoList->head;
158 while (temp != NULL) {
159 EnrolledInfoHal *nodeInfo = temp->data;
160 if (nodeInfo != NULL && nodeInfo->authType == authType) {
161 *enrolledInfo = *nodeInfo;
162 return RESULT_SUCCESS;
163 }
164 temp = temp->next;
165 }
166
167 return RESULT_NOT_FOUND;
168 }
169
GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num)170 ResultCode GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num)
171 {
172 if (enrolledInfos == NULL || num == NULL) {
173 LOG_ERROR("param is invalid");
174 return RESULT_BAD_PARAM;
175 }
176 UserInfo *user = QueryUserInfo(userId);
177 if (!IsUserInfoValid(user)) {
178 LOG_ERROR("can't find this user");
179 return RESULT_NOT_FOUND;
180 }
181 return GetAllEnrolledInfoFromUser(user, enrolledInfos, num);
182 }
183
DeleteUserInfo(int32_t userId, LinkedList **creds)184 ResultCode DeleteUserInfo(int32_t userId, LinkedList **creds)
185 {
186 if (creds == NULL) {
187 LOG_ERROR("param is invalid");
188 return RESULT_BAD_PARAM;
189 }
190 UserInfo *user = QueryUserInfo(userId);
191 if (!IsUserInfoValid(user)) {
192 LOG_ERROR("can't find this user");
193 return RESULT_NOT_FOUND;
194 }
195 CredentialCondition condition = {};
196 SetCredentialConditionUserId(&condition, userId);
197 *creds = QueryCredentialLimit(&condition);
198 if (*creds == NULL) {
199 LOG_ERROR("query credential failed");
200 return RESULT_UNKNOWN;
201 }
202 g_currentUser = NULL;
203
204 ResultCode ret = DeleteUser(userId);
205 if (ret != RESULT_SUCCESS) {
206 LOG_ERROR("deleteUser failed");
207 DestroyLinkedList(*creds);
208 *creds = NULL;
209 return ret;
210 }
211 ret = UpdateFileInfo(g_userInfoList);
212 if (ret != RESULT_SUCCESS) {
213 LOG_ERROR("update file info failed");
214 DestroyLinkedList(*creds);
215 *creds = NULL;
216 return ret;
217 }
218 return ret;
219 }
220
QueryUserInfo(int32_t userId)221 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId)
222 {
223 UserInfo *user = g_currentUser;
224 if (user != NULL && user->userId == userId) {
225 return user;
226 }
227 if (g_userInfoList == NULL) {
228 return NULL;
229 }
230 LinkedListNode *temp = g_userInfoList->head;
231 while (temp != NULL) {
232 user = (UserInfo *)temp->data;
233 if (user != NULL && user->userId == userId) {
234 break;
235 }
236 temp = temp->next;
237 }
238 if (temp == NULL) {
239 return NULL;
240 }
241 if (IsUserInfoValid(user)) {
242 g_currentUser = user;
243 return user;
244 }
245 return NULL;
246 }
247
GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num)248 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num)
249 {
250 LinkedList *enrolledInfoList = userInfo->enrolledInfoList;
251 uint32_t size = enrolledInfoList->getSize(enrolledInfoList);
252 *enrolledInfos = Malloc(sizeof(EnrolledInfoHal) * size);
253 if (*enrolledInfos == NULL) {
254 LOG_ERROR("enrolledInfos malloc failed");
255 return RESULT_NO_MEMORY;
256 }
257 (void)memset_s(*enrolledInfos, sizeof(EnrolledInfoHal) * size, 0, sizeof(EnrolledInfoHal) * size);
258 LinkedListNode *temp = enrolledInfoList->head;
259 ResultCode result = RESULT_SUCCESS;
260 for (*num = 0; *num < size; (*num)++) {
261 if (temp == NULL) {
262 LOG_ERROR("temp node is null, something wrong");
263 result = RESULT_BAD_PARAM;
264 goto EXIT;
265 }
266 EnrolledInfoHal *tempInfo = (EnrolledInfoHal *)temp->data;
267 if (memcpy_s(*enrolledInfos + *num, sizeof(EnrolledInfoHal) * (size - *num),
268 tempInfo, sizeof(EnrolledInfoHal)) != EOK) {
269 LOG_ERROR("copy the %u information failed", *num);
270 result = RESULT_NO_MEMORY;
271 goto EXIT;
272 }
273 temp = temp->next;
274 }
275
276 EXIT:
277 if (result != RESULT_SUCCESS) {
278 Free(*enrolledInfos);
279 *enrolledInfos = NULL;
280 *num = 0;
281 }
282 return result;
283 }
284
IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid)285 IAM_STATIC bool IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid)
286 {
287 if (userInfoList == NULL) {
288 LOG_ERROR("the user list is empty, and the branch is abnormal");
289 return false;
290 }
291
292 LinkedListNode *temp = userInfoList->head;
293 UserInfo *userInfo = NULL;
294 while (temp != NULL) {
295 userInfo = (UserInfo *)temp->data;
296 if (userInfo != NULL && userInfo->secUid == secureUid) {
297 return true;
298 }
299 temp = temp->next;
300 }
301
302 return false;
303 }
304
CreateUser(int32_t userId, int32_t userType)305 IAM_STATIC UserInfo *CreateUser(int32_t userId, int32_t userType)
306 {
307 UserInfo *user = InitUserInfoNode();
308 if (!IsUserInfoValid(user)) {
309 LOG_ERROR("user is invalid");
310 DestroyUserInfoNode(user);
311 return NULL;
312 }
313 user->userId = userId;
314 user->userType = userType;
315 ResultCode ret = GenerateDeduplicateUint64(g_userInfoList, &user->secUid, IsSecureUidDuplicate);
316 if (ret != RESULT_SUCCESS) {
317 LOG_ERROR("generate secureUid failed");
318 DestroyUserInfoNode(user);
319 return NULL;
320 }
321 return user;
322 }
323
DeleteUser(int32_t userId)324 IAM_STATIC ResultCode DeleteUser(int32_t userId)
325 {
326 if (g_userInfoList == NULL) {
327 return RESULT_BAD_PARAM;
328 }
329 return g_userInfoList->remove(g_userInfoList, &userId, MatchUserInfo, true);
330 }
331
IsCredentialIdDuplicate(LinkedList *userInfoList, uint64_t credentialId)332 IAM_STATIC bool IsCredentialIdDuplicate(LinkedList *userInfoList, uint64_t credentialId)
333 {
334 (void)userInfoList;
335 CredentialCondition condition = {};
336 SetCredentialConditionCredentialId(&condition, credentialId);
337 LinkedList *credList = QueryCredentialLimit(&condition);
338 if (credList == NULL) {
339 LOG_ERROR("query failed");
340 return true;
341 }
342 if (credList->getSize(credList) != 0) {
343 LOG_ERROR("duplicate credential id");
344 DestroyLinkedList(credList);
345 return true;
346 }
347 DestroyLinkedList(credList);
348 return false;
349 }
350
IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)351 IAM_STATIC bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)
352 {
353 LinkedListNode *temp = enrolledList->head;
354 EnrolledInfoHal *enrolledInfo = NULL;
355 const static uint16_t num = 0xFFFF;
356 while (temp != NULL) {
357 enrolledInfo = (EnrolledInfoHal *)temp->data;
358 if ((enrolledInfo != NULL) && (enrolledInfo->enrolledId & num) == (enrolledId & num)) {
359 return true;
360 }
361 temp = temp->next;
362 }
363
364 return false;
365 }
366
GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)367 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)
368 {
369 if (collection == NULL || destValue == NULL || func == NULL) {
370 LOG_ERROR("param is null");
371 return RESULT_BAD_PARAM;
372 }
373
374 for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) {
375 uint64_t tempRandom;
376 if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
377 LOG_ERROR("get random failed");
378 return RESULT_GENERAL_ERROR;
379 }
380 if (!func(collection, tempRandom)) {
381 *destValue = tempRandom;
382 return RESULT_SUCCESS;
383 }
384 }
385
386 LOG_ERROR("generate random failed");
387 return RESULT_GENERAL_ERROR;
388 }
389
UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)390 IAM_STATIC ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)
391 {
392 LinkedListNode *temp = enrolledList->head;
393 EnrolledInfoHal *enrolledInfo = NULL;
394 while (temp != NULL) {
395 EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data;
396 if (nodeData != NULL && nodeData->authType == authType) {
397 enrolledInfo = nodeData;
398 break;
399 }
400 temp = temp->next;
401 }
402
403 if (enrolledInfo != NULL) {
404 return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
405 }
406
407 enrolledInfo = Malloc(sizeof(EnrolledInfoHal));
408 if (enrolledInfo == NULL) {
409 LOG_ERROR("enrolledInfo malloc failed");
410 return RESULT_NO_MEMORY;
411 }
412 enrolledInfo->authType = authType;
413 ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
414 if (ret != RESULT_SUCCESS) {
415 LOG_ERROR("generate enrolledId failed");
416 Free(enrolledInfo);
417 return ret;
418 }
419 ret = enrolledList->insert(enrolledList, enrolledInfo);
420 if (ret != RESULT_SUCCESS) {
421 LOG_ERROR("enrolledInfo insert failed");
422 Free(enrolledInfo);
423 }
424 return ret;
425 }
426
427 // add for reliable pin updates
GetRealAuthTypeForEnrolledId(uint32_t authType)428 IAM_STATIC uint32_t GetRealAuthTypeForEnrolledId(uint32_t authType)
429 {
430 if (authType == DEFAULT_AUTH_TYPE) {
431 return PIN_AUTH;
432 }
433 return authType;
434 }
435
AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)436 IAM_STATIC ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)
437 {
438 if (g_userInfoList == NULL) {
439 LOG_ERROR("g_userInfoList is uninitialized");
440 return RESULT_NEED_INIT;
441 }
442 LinkedList *credentialList = user->credentialInfoList;
443 LinkedList *enrolledList = user->enrolledInfoList;
444 if (credentialList->getSize(credentialList) >= MAX_CREDENTIAL) {
445 LOG_ERROR("the number of credentials reaches the maximum");
446 return RESULT_EXCEED_LIMIT;
447 }
448
449 ResultCode ret = UpdateEnrolledId(enrolledList, GetRealAuthTypeForEnrolledId(credentialInfo->authType));
450 if (ret != RESULT_SUCCESS) {
451 LOG_ERROR("update enrolledId failed");
452 return ret;
453 }
454 ret = GenerateDeduplicateUint64(g_userInfoList, &credentialInfo->credentialId, IsCredentialIdDuplicate);
455 if (ret != RESULT_SUCCESS) {
456 LOG_ERROR("GenerateDeduplicateUint64 failed");
457 return ret;
458 }
459 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
460 bool isRemoved = false;
461 RemoveCachePin(user, &isRemoved);
462 }
463 CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal));
464 if (credential == NULL) {
465 LOG_ERROR("credential malloc failed");
466 return RESULT_NO_MEMORY;
467 }
468 if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) {
469 LOG_ERROR("credential copy failed");
470 Free(credential);
471 return RESULT_BAD_COPY;
472 }
473 credential->enrolledSysTime = GetReeTime();
474 ret = credentialList->insert(credentialList, credential);
475 if (ret != RESULT_SUCCESS) {
476 LOG_ERROR("insert credential failed");
477 Free(credential);
478 }
479 return ret;
480 }
481
AddUser(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)482 IAM_STATIC ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
483 {
484 if (g_userInfoList == NULL) {
485 LOG_ERROR("please init");
486 return RESULT_NEED_INIT;
487 }
488 if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) {
489 LOG_ERROR("the number of users reaches the maximum");
490 return RESULT_EXCEED_LIMIT;
491 }
492
493 UserInfo *user = QueryUserInfo(userId);
494 if (user != NULL) {
495 LOG_ERROR("Please check pin");
496 return RESULT_BAD_PARAM;
497 }
498
499 user = CreateUser(userId, userType);
500 if (user == NULL) {
501 LOG_ERROR("create user failed");
502 return RESULT_UNKNOWN;
503 }
504 LOG_INFO("user userType %{public}d", user->userType);
505 ResultCode ret = AddCredentialToUser(user, credentialInfo);
506 if (ret != RESULT_SUCCESS) {
507 LOG_ERROR("add credential to user failed");
508 goto FAIL;
509 }
510
511 ret = g_userInfoList->insert(g_userInfoList, user);
512 if (ret != RESULT_SUCCESS) {
513 LOG_ERROR("insert failed");
514 goto FAIL;
515 }
516 return ret;
517
518 FAIL:
519 DestroyUserInfoNode(user);
520 return ret;
521 }
522
AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)523 ResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
524 {
525 if ((credentialInfo == NULL) || (credentialInfo->authType == DEFAULT_AUTH_TYPE)) {
526 LOG_ERROR("credentialInfo is invalid");
527 return RESULT_BAD_PARAM;
528 }
529 UserInfo *user = QueryUserInfo(userId);
530 if (user == NULL && credentialInfo->authType == PIN_AUTH) {
531 ResultCode ret = AddUser(userId, credentialInfo, userType);
532 if (ret != RESULT_SUCCESS) {
533 LOG_ERROR("add user failed");
534 return ret;
535 }
536 ret = UpdateFileInfo(g_userInfoList);
537 if (ret != RESULT_SUCCESS) {
538 LOG_ERROR("updateFileInfo failed");
539 }
540 return ret;
541 }
542 if (user == NULL) {
543 LOG_ERROR("user is null");
544 return RESULT_BAD_PARAM;
545 }
546 if (credentialInfo->authType == PIN_AUTH) {
547 CredentialCondition condition = {};
548 SetCredentialConditionAuthType(&condition, PIN_AUTH);
549 SetCredentialConditionUserId(&condition, userId);
550 LinkedList *credList = QueryCredentialLimit(&condition);
551 if (credList == NULL) {
552 LOG_ERROR("query credential failed");
553 return RESULT_UNKNOWN;
554 }
555 if (credList->getSize(credList) != 0) {
556 LOG_INFO("cache pin");
557 // add for reliable pin updates
558 credentialInfo->authType = DEFAULT_AUTH_TYPE;
559 }
560 DestroyLinkedList(credList);
561 }
562 ResultCode ret = AddCredentialToUser(user, credentialInfo);
563 if (ret != RESULT_SUCCESS) {
564 LOG_ERROR("add credential to user failed");
565 return ret;
566 }
567 ret = UpdateFileInfo(g_userInfoList);
568 if (ret != RESULT_SUCCESS) {
569 LOG_ERROR("updateFileInfo failed");
570 }
571 return ret;
572 }
573
MatchCredentialById(const void *data, const void *condition)574 IAM_STATIC bool MatchCredentialById(const void *data, const void *condition)
575 {
576 if (data == NULL || condition == NULL) {
577 return false;
578 }
579 const CredentialInfoHal *credentialInfo = (const CredentialInfoHal *)data;
580 uint64_t credentialId = *(const uint64_t *)condition;
581 if (credentialInfo->credentialId == credentialId) {
582 return true;
583 }
584 return false;
585 }
586
MatchEnrolledInfoByType(const void *data, const void *condition)587 IAM_STATIC bool MatchEnrolledInfoByType(const void *data, const void *condition)
588 {
589 if (data == NULL || condition == NULL) {
590 return false;
591 }
592 const EnrolledInfoHal *enrolledInfo = (const EnrolledInfoHal *)data;
593 uint32_t authType = *(const uint32_t *)condition;
594 if (enrolledInfo->authType == authType) {
595 return true;
596 }
597 return false;
598 }
599
RemoveCachePin(UserInfo *user, bool *isRemoved)600 IAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved)
601 {
602 LOG_INFO("RemoveCachePin start");
603 LinkedListNode *temp = user->credentialInfoList->head;
604 CredentialInfoHal *credentialInfoCache = NULL;
605 while (temp != NULL) {
606 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
607 if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
608 credentialInfoCache = nodeData;
609 break;
610 }
611 temp = temp->next;
612 }
613 if (credentialInfoCache == NULL) {
614 LOG_INFO("RemoveCachePin no cache pin");
615 *isRemoved = false;
616 return;
617 }
618 uint64_t credentialId = credentialInfoCache->credentialId;
619 ResultCode ret = (user->credentialInfoList)->remove(
620 user->credentialInfoList, &credentialId, MatchCredentialById, true);
621 if (ret != RESULT_SUCCESS) {
622 LOG_ERROR("remove credential failed");
623 *isRemoved = false;
624 return;
625 }
626 LOG_ERROR("remove credential success");
627 *isRemoved = true;
628 }
629
ClearCachePin(int32_t userId)630 void ClearCachePin(int32_t userId)
631 {
632 LOG_INFO("ClearCachePin start");
633 UserInfo *user = QueryUserInfo(userId);
634 if (user == NULL) {
635 LOG_ERROR("can't find this user");
636 return;
637 }
638
639 bool isRemoved = false;
640 RemoveCachePin(user, &isRemoved);
641 if (isRemoved && UpdateFileInfo(g_userInfoList) != RESULT_SUCCESS) {
642 LOG_ERROR("ClearCachePin save fail");
643 return;
644 }
645 }
646
SwitchSubType(UserInfo *user)647 IAM_STATIC void SwitchSubType(UserInfo *user)
648 {
649 uint64_t tmpSubType = user->pinSubType;
650 user->pinSubType = user->cachePinSubType;
651 user->cachePinSubType = tmpSubType;
652 }
653
654 // add for reliable pin updates
DeletePinCredentialInfo(UserInfo *user)655 IAM_STATIC ResultCode DeletePinCredentialInfo(UserInfo *user)
656 {
657 LOG_INFO("DeletePinCredentialInfo start");
658 LinkedListNode *temp = user->credentialInfoList->head;
659 CredentialInfoHal *credentialInfoOld = NULL;
660 CredentialInfoHal *credentialInfoCache = NULL;
661 while (temp != NULL) {
662 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
663 if (nodeData != NULL && nodeData->authType == PIN_AUTH) {
664 credentialInfoOld = nodeData;
665 }
666 if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
667 credentialInfoCache = nodeData;
668 }
669 temp = temp->next;
670 }
671 if (credentialInfoOld == NULL || credentialInfoCache == NULL) {
672 LOG_ERROR("no cache pin exist");
673 return RESULT_GENERAL_ERROR;
674 }
675 credentialInfoOld->authType = DEFAULT_AUTH_TYPE;
676 credentialInfoCache->authType = PIN_AUTH;
677 SwitchSubType(user);
678 ResultCode result = UpdateFileInfo(g_userInfoList);
679 if (result == RESULT_SUCCESS) {
680 LOG_INFO("switch cache pin success");
681 ClearCachePin(user->userId);
682 return result;
683 }
684 LOG_ERROR("switch cache pin fail");
685 credentialInfoOld->authType = PIN_AUTH;
686 credentialInfoCache->authType = DEFAULT_AUTH_TYPE;
687 SwitchSubType(user);
688 return RESULT_GENERAL_ERROR;
689 }
690
DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)691 ResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
692 {
693 if (credentialInfo == NULL) {
694 LOG_ERROR("param is invalid");
695 return RESULT_BAD_PARAM;
696 }
697
698 UserInfo *user = QueryUserInfo(userId);
699 if (user == NULL) {
700 LOG_ERROR("can't find this user");
701 return RESULT_BAD_PARAM;
702 }
703
704 LinkedList *credentialList = user->credentialInfoList;
705 CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList);
706 if (credentialQuery == NULL) {
707 LOG_ERROR("credentialQuery is null");
708 return RESULT_UNKNOWN;
709 }
710 if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
711 LOG_ERROR("copy failed");
712 return RESULT_BAD_COPY;
713 }
714 if (credentialInfo->authType == PIN_AUTH) {
715 return DeletePinCredentialInfo(user);
716 }
717 ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true);
718 if (ret != RESULT_SUCCESS) {
719 LOG_ERROR("remove credential failed");
720 return ret;
721 }
722 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
723 return UpdateFileInfo(g_userInfoList);
724 }
725 credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList);
726 if (credentialQuery != NULL) {
727 return UpdateFileInfo(g_userInfoList);
728 }
729
730 LinkedList *enrolledInfoList = user->enrolledInfoList;
731 if (enrolledInfoList == NULL) {
732 LOG_ERROR("enrolledInfoList is null");
733 return RESULT_UNKNOWN;
734 }
735 ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true);
736 if (ret != RESULT_SUCCESS) {
737 LOG_ERROR("remove enrolledInfo failed");
738 return ret;
739 }
740
741 return UpdateFileInfo(g_userInfoList);
742 }
743
QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)744 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)
745 {
746 if (credentialList == NULL) {
747 return NULL;
748 }
749 LinkedListNode *temp = credentialList->head;
750 CredentialInfoHal *credentialInfo = NULL;
751 while (temp != NULL) {
752 CredentialInfoHal *nodeData = (CredentialInfoHal *)temp->data;
753 if (nodeData != NULL && nodeData->credentialId == credentialId) {
754 credentialInfo = nodeData;
755 break;
756 }
757 temp = temp->next;
758 }
759 return credentialInfo;
760 }
761
QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)762 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)
763 {
764 if (credentialList == NULL) {
765 return NULL;
766 }
767 LinkedListNode *temp = credentialList->head;
768 CredentialInfoHal *credentialInfo = NULL;
769 while (temp != NULL) {
770 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
771 if (nodeData != NULL && nodeData->authType == authType) {
772 credentialInfo = nodeData;
773 break;
774 }
775 temp = temp->next;
776 }
777 return credentialInfo;
778 }
779
780 // do not cotain cache pin credential
IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)781 IAM_STATIC bool IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
782 {
783 if ((limit->conditionFactor & CREDENTIAL_CONDITION_CREDENTIAL_ID) != 0 &&
784 limit->credentialId != credentialInfo->credentialId) {
785 return false;
786 }
787 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
788 if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_CACHE_PIN) == 0) {
789 return false;
790 }
791 } else {
792 if ((limit->conditionFactor & CREDENTIAL_CONDITION_AUTH_TYPE) != 0 &&
793 limit->authType != credentialInfo->authType) {
794 return false;
795 }
796 }
797 if ((limit->conditionFactor & CREDENTIAL_CONDITION_TEMPLATE_ID) != 0 &&
798 limit->templateId != credentialInfo->templateId) {
799 return false;
800 }
801 if ((limit->conditionFactor & CREDENTIAL_CONDITION_SENSOR_HINT) != 0 &&
802 limit->executorSensorHint != INVALID_SENSOR_HINT &&
803 limit->executorSensorHint != credentialInfo->executorSensorHint) {
804 return false;
805 }
806 if ((limit->conditionFactor & CREDENTIAL_CONDITION_EXECUTOR_MATCHER) != 0 &&
807 limit->executorMatcher != credentialInfo->executorMatcher) {
808 return false;
809 }
810 return true;
811 }
812
IsUserMatch(const CredentialCondition *limit, const UserInfo *user)813 IAM_STATIC bool IsUserMatch(const CredentialCondition *limit, const UserInfo *user)
814 {
815 if ((limit->conditionFactor & CREDENTIAL_CONDITION_USER_ID) != 0 && limit->userId != user->userId) {
816 return false;
817 }
818 return true;
819 }
820
821 // do not cotain cache pin credential
TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList, LinkedList *credListGet)822 IAM_STATIC ResultCode TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList,
823 LinkedList *credListGet)
824 {
825 if (credentialList == NULL) {
826 LOG_ERROR("credentialList is null");
827 return RESULT_GENERAL_ERROR;
828 }
829 LinkedListNode *temp = credentialList->head;
830 while (temp != NULL) {
831 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
832 if (nodeData == NULL) {
833 LOG_ERROR("nodeData is null");
834 return RESULT_UNKNOWN;
835 }
836 if (!IsCredMatch(limit, nodeData)) {
837 temp = temp->next;
838 continue;
839 }
840 CredentialInfoHal *copy = (CredentialInfoHal *)Malloc(sizeof(CredentialInfoHal));
841 if (copy == NULL) {
842 LOG_ERROR("copy malloc failed");
843 return RESULT_NO_MEMORY;
844 }
845 *copy = *nodeData;
846 ResultCode ret = credListGet->insert(credListGet, copy);
847 if (ret != RESULT_SUCCESS) {
848 LOG_ERROR("insert failed");
849 Free(copy);
850 return ret;
851 }
852 temp = temp->next;
853 }
854 return RESULT_SUCCESS;
855 }
856
857 // do not cotain cache pin credential
QueryCredentialLimit(const CredentialCondition *limit)858 LinkedList *QueryCredentialLimit(const CredentialCondition *limit)
859 {
860 if (limit == NULL) {
861 LOG_ERROR("limit is null");
862 return NULL;
863 }
864 if (g_userInfoList == NULL) {
865 LOG_ERROR("g_userInfoList is null");
866 return NULL;
867 }
868 LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
869 if (credList == NULL) {
870 LOG_ERROR("credList is null");
871 return NULL;
872 }
873 LinkedListNode *temp = g_userInfoList->head;
874 while (temp != NULL) {
875 UserInfo *user = (UserInfo *)temp->data;
876 if (user == NULL) {
877 LOG_ERROR("node data is null");
878 DestroyLinkedList(credList);
879 return NULL;
880 }
881 if (IsUserMatch(limit, user)) {
882 ResultCode ret = TraverseCredentialList(limit, user->credentialInfoList, credList);
883 if (ret != RESULT_SUCCESS) {
884 LOG_ERROR("TraverseCredentialList failed");
885 DestroyLinkedList(credList);
886 return NULL;
887 }
888 }
889 temp = temp->next;
890 }
891 return credList;
892 }
893
QueryCredentialUserId(uint64_t credentialId, int32_t *userId)894 ResultCode QueryCredentialUserId(uint64_t credentialId, int32_t *userId)
895 {
896 if (userId == NULL) {
897 LOG_ERROR("userId is null");
898 return RESULT_BAD_PARAM;
899 }
900 if (g_userInfoList == NULL) {
901 LOG_ERROR("g_userInfoList is null");
902 return RESULT_NEED_INIT;
903 }
904 LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
905 if (credList == NULL) {
906 LOG_ERROR("credList is null");
907 return RESULT_NO_MEMORY;
908 }
909 LinkedListNode *temp = g_userInfoList->head;
910 CredentialCondition condition = {};
911 SetCredentialConditionCredentialId(&condition, credentialId);
912 while (temp != NULL) {
913 UserInfo *user = (UserInfo *)temp->data;
914 if (user == NULL) {
915 LOG_ERROR("user is null");
916 DestroyLinkedList(credList);
917 return RESULT_UNKNOWN;
918 }
919 ResultCode ret = TraverseCredentialList(&condition, user->credentialInfoList, credList);
920 if (ret != RESULT_SUCCESS) {
921 LOG_ERROR("TraverseCredentialList failed");
922 DestroyLinkedList(credList);
923 return RESULT_UNKNOWN;
924 }
925 if (credList->getSize(credList) != 0) {
926 DestroyLinkedList(credList);
927 *userId = user->userId;
928 return RESULT_SUCCESS;
929 }
930 temp = temp->next;
931 }
932 DestroyLinkedList(credList);
933 LOG_ERROR("can't find this credential");
934 return RESULT_NOT_FOUND;
935 }
936
SetPinSubType(int32_t userId, uint64_t pinSubType)937 ResultCode SetPinSubType(int32_t userId, uint64_t pinSubType)
938 {
939 UserInfo *user = QueryUserInfo(userId);
940 if (user == NULL) {
941 LOG_ERROR("can't find this user");
942 return RESULT_NOT_FOUND;
943 }
944 user->pinSubType = pinSubType;
945 return RESULT_SUCCESS;
946 }
947
GetPinSubType(int32_t userId, uint64_t *pinSubType)948 ResultCode GetPinSubType(int32_t userId, uint64_t *pinSubType)
949 {
950 if (pinSubType == NULL) {
951 LOG_ERROR("pinSubType is null");
952 return RESULT_BAD_PARAM;
953 }
954 UserInfo *user = QueryUserInfo(userId);
955 if (user == NULL) {
956 LOG_ERROR("can't find this user");
957 return RESULT_NOT_FOUND;
958 }
959 *pinSubType = user->pinSubType;
960 return RESULT_SUCCESS;
961 }
962
SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId)963 void SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId)
964 {
965 if (condition == NULL) {
966 LOG_ERROR("condition is null");
967 return;
968 }
969 condition->credentialId = credentialId;
970 condition->conditionFactor |= CREDENTIAL_CONDITION_CREDENTIAL_ID;
971 }
972
SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId)973 void SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId)
974 {
975 if (condition == NULL) {
976 LOG_ERROR("condition is null");
977 return;
978 }
979 condition->templateId = templateId;
980 condition->conditionFactor |= CREDENTIAL_CONDITION_TEMPLATE_ID;
981 }
982
SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType)983 void SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType)
984 {
985 if (condition == NULL) {
986 LOG_ERROR("condition is null");
987 return;
988 }
989 condition->authType = authType;
990 condition->conditionFactor |= CREDENTIAL_CONDITION_AUTH_TYPE;
991 }
992
SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint)993 void SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint)
994 {
995 if (condition == NULL) {
996 LOG_ERROR("condition is null");
997 return;
998 }
999 condition->executorSensorHint = executorSensorHint;
1000 condition->conditionFactor |= CREDENTIAL_CONDITION_SENSOR_HINT;
1001 }
1002
SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher)1003 void SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher)
1004 {
1005 if (condition == NULL) {
1006 LOG_ERROR("condition is null");
1007 return;
1008 }
1009 condition->executorMatcher = executorMatcher;
1010 condition->conditionFactor |= CREDENTIAL_CONDITION_EXECUTOR_MATCHER;
1011 }
1012
SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId)1013 void SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId)
1014 {
1015 if (condition == NULL) {
1016 LOG_ERROR("condition is null");
1017 return;
1018 }
1019 condition->userId = userId;
1020 condition->conditionFactor |= CREDENTIAL_CONDITION_USER_ID;
1021 }
1022
SetCredentiaConditionNeedCachePin(CredentialCondition *condition)1023 void SetCredentiaConditionNeedCachePin(CredentialCondition *condition)
1024 {
1025 if (condition == NULL) {
1026 LOG_ERROR("condition is null");
1027 return;
1028 }
1029 condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_CACHE_PIN;
1030 }
1031
IsUserValid(UserInfo *user)1032 IAM_STATIC bool IsUserValid(UserInfo *user)
1033 {
1034 LinkedList *credentialInfoList = user->credentialInfoList;
1035 CredentialInfoHal *pinCredential = QueryCredentialByAuthType(PIN_AUTH, credentialInfoList);
1036 if (pinCredential == NULL) {
1037 LOG_INFO("user is invalid, userId: %{public}d", user->userId);
1038 return false;
1039 }
1040 return true;
1041 }
1042
GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount, bool *cachePinRemoved)1043 IAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
1044 bool *cachePinRemoved)
1045 {
1046 LOG_INFO("get invalid user start");
1047 if (g_userInfoList == NULL) {
1048 LOG_ERROR("g_userInfoList is null");
1049 return RESULT_GENERAL_ERROR;
1050 }
1051
1052 LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1053 if (iterator == NULL) {
1054 LOG_ERROR("create iterator failed");
1055 return RESULT_NO_MEMORY;
1056 }
1057
1058 UserInfo *user = NULL;
1059 *userCount = 0;
1060 while (iterator->hasNext(iterator)) {
1061 user = (UserInfo *)iterator->next(iterator);
1062 if (user == NULL) {
1063 LOG_ERROR("userinfo list node is null, please check");
1064 continue;
1065 }
1066
1067 if (*userCount >= maxUserCount) {
1068 LOG_ERROR("too many users");
1069 break;
1070 }
1071
1072 if (!IsUserValid(user)) {
1073 invalidUserId[*userCount] = user->userId;
1074 (*userCount)++;
1075 continue;
1076 }
1077
1078 bool isRemoved = false;
1079 RemoveCachePin(user, &isRemoved);
1080 if (isRemoved) {
1081 *cachePinRemoved = true;
1082 }
1083 }
1084
1085 g_userInfoList->destroyIterator(iterator);
1086 return RESULT_SUCCESS;
1087 }
1088
ClearInvalidData(void)1089 IAM_STATIC ResultCode ClearInvalidData(void)
1090 {
1091 LOG_INFO("clear invalid user start");
1092 int32_t invalidUserId[MAX_USER] = {0};
1093 uint32_t userCount = 0;
1094 bool cachePinRemoved = false;
1095 if (GetInvalidUser(invalidUserId, MAX_USER, &userCount, &cachePinRemoved) != RESULT_SUCCESS) {
1096 LOG_ERROR("GetInvalidUser fail");
1097 return RESULT_GENERAL_ERROR;
1098 }
1099 ResultCode ret = RESULT_SUCCESS;
1100 for (uint32_t i = 0; i < userCount; ++i) {
1101 ret = DeleteUser(invalidUserId[i]);
1102 if (ret != RESULT_SUCCESS) {
1103 LOG_ERROR("delete invalid user fail, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1104 return ret;
1105 }
1106 LOG_INFO("delete invalid user success, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1107 }
1108
1109 if ((userCount != 0) || cachePinRemoved) {
1110 ret = UpdateFileInfo(g_userInfoList);
1111 if (ret != RESULT_SUCCESS) {
1112 LOG_ERROR("UpdateFileInfo fail, ret: %{public}d", ret);
1113 return ret;
1114 }
1115 }
1116 return RESULT_SUCCESS;
1117 }
1118
GetAllExtUserInfo(UserInfoResult *userInfos, uint32_t userInfoLen, uint32_t *userInfocount)1119 ResultCode GetAllExtUserInfo(UserInfoResult *userInfos, uint32_t userInfoLen, uint32_t *userInfocount)
1120 {
1121 LOG_INFO("get all user info start");
1122 if (userInfos == NULL || userInfocount == NULL || g_userInfoList == NULL) {
1123 LOG_ERROR("param is null");
1124 return RESULT_BAD_PARAM;
1125 }
1126
1127 LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1128 if (iterator == NULL) {
1129 LOG_ERROR("create iterator failed");
1130 return RESULT_NO_MEMORY;
1131 }
1132
1133 UserInfo *user = NULL;
1134 EnrolledInfoHal *enrolledInfoHal = NULL;
1135 *userInfocount = 0;
1136 while (iterator->hasNext(iterator)) {
1137 user = (UserInfo *)iterator->next(iterator);
1138 if (user == NULL) {
1139 LOG_ERROR("userinfo list node is null, please check");
1140 continue;
1141 }
1142
1143 if (*userInfocount >= userInfoLen) {
1144 LOG_ERROR("too many users");
1145 goto ERROR;
1146 }
1147
1148 userInfos[*userInfocount].userId = user->userId;
1149 userInfos[*userInfocount].secUid = user->secUid;
1150 userInfos[*userInfocount].pinSubType = (uint32_t)user->pinSubType;
1151
1152 ResultCode ret = GetAllEnrolledInfoFromUser(user, &enrolledInfoHal, &(userInfos[*userInfocount].enrollNum));
1153 if (ret != RESULT_SUCCESS) {
1154 LOG_ERROR("get enrolled info fail");
1155 goto ERROR;
1156 }
1157 if (userInfos[*userInfocount].enrollNum > MAX_ENROLL_OUTPUT) {
1158 LOG_ERROR("too many elements");
1159 free(enrolledInfoHal);
1160 goto ERROR;
1161 }
1162
1163 for (uint32_t i = 0; i < userInfos[*userInfocount].enrollNum; i++) {
1164 userInfos[*userInfocount].enrolledInfo[i].authType = enrolledInfoHal[i].authType;
1165 userInfos[*userInfocount].enrolledInfo[i].enrolledId = enrolledInfoHal[i].enrolledId;
1166 }
1167
1168 free(enrolledInfoHal);
1169 (*userInfocount)++;
1170 }
1171
1172 g_userInfoList->destroyIterator(iterator);
1173 return RESULT_SUCCESS;
1174
1175 ERROR:
1176 g_userInfoList->destroyIterator(iterator);
1177 return RESULT_GENERAL_ERROR;
1178 }
1179
GetEnrolledState(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal)1180 ResultCode GetEnrolledState(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal)
1181 {
1182 LOG_INFO("get enrolled id info start, userId:%{public}d, authType:%{public}d", userId, authType);
1183
1184 UserInfo *user = QueryUserInfo(userId);
1185 if (user == NULL) {
1186 LOG_ERROR("user is null");
1187 return RESULT_NOT_ENROLLED;
1188 }
1189 if (user->credentialInfoList == NULL) {
1190 LOG_ERROR("credentialInfoList is null");
1191 return RESULT_NOT_ENROLLED;
1192 }
1193
1194 uint16_t credentialCount = 0;
1195 LinkedListNode *credentialInfoTemp = user->credentialInfoList->head;
1196 while (credentialInfoTemp != NULL) {
1197 CredentialInfoHal *nodeInfo = credentialInfoTemp->data;
1198 if (nodeInfo != NULL && nodeInfo->authType == authType) {
1199 ++credentialCount;
1200 }
1201 credentialInfoTemp = credentialInfoTemp->next;
1202 }
1203 if (credentialCount == 0) {
1204 LOG_ERROR("not enrolled");
1205 return RESULT_NOT_ENROLLED;
1206 }
1207 enrolledStateHal->credentialCount = credentialCount;
1208 if (user->enrolledInfoList == NULL) {
1209 LOG_ERROR("enrolledInfoList is null");
1210 return RESULT_NOT_ENROLLED;
1211 }
1212 LinkedListNode *enrolledInfoTemp = user->enrolledInfoList->head;
1213 while (enrolledInfoTemp != NULL) {
1214 EnrolledInfoHal *nodeInfo = enrolledInfoTemp->data;
1215 if (nodeInfo != NULL && nodeInfo->authType == authType) {
1216 enrolledStateHal->credentialDigest = nodeInfo->enrolledId;
1217 break;
1218 }
1219 enrolledInfoTemp = enrolledInfoTemp->next;
1220 }
1221 return RESULT_SUCCESS;
1222 }
1223
UpdateGlobalConfigArray(GlobalConfigParamHal *param, uint32_t authType)1224 IAM_STATIC ResultCode UpdateGlobalConfigArray(GlobalConfigParamHal *param, uint32_t authType)
1225 {
1226 uint32_t infoIndex = 0;
1227 for (infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1228 if (g_globalConfigArray[infoIndex].type == param->type &&
1229 g_globalConfigArray[infoIndex].authType == authType) {
1230 LOG_INFO("globalConfig is already exist, type:%{public}d, authType:%{public}u", param->type, authType);
1231 break;
1232 }
1233 }
1234 if (infoIndex >= MAX_GLOBAL_CONFIG_NUM) {
1235 LOG_ERROR("globalConfigArray is exceed limit");
1236 return RESULT_EXCEED_LIMIT;
1237 }
1238 memset_s(&g_globalConfigArray[infoIndex], sizeof(GlobalConfigInfo), 0, sizeof(GlobalConfigInfo));
1239
1240 switch (param->type) {
1241 case PIN_EXPIRED_PERIOD:
1242 if (authType != PIN_AUTH) {
1243 LOG_ERROR("bad authType:%{public}u for PIN_EXPIRED_PERIOD", authType);
1244 return RESULT_BAD_PARAM;
1245 }
1246 g_globalConfigArray[infoIndex].value.pinExpiredPeriod = param->value.pinExpiredPeriod;
1247 break;
1248 case ENABLE_STATUS:
1249 g_globalConfigArray[infoIndex].value.enableStatus = param->value.enableStatus;
1250 break;
1251 default:
1252 LOG_ERROR("globalConfigType not support, type:%{public}d.", param->type);
1253 return RESULT_BAD_PARAM;
1254 }
1255 g_globalConfigArray[infoIndex].type = param->type;
1256 g_globalConfigArray[infoIndex].authType = authType;
1257 g_globalConfigArray[infoIndex].userIdNum = param->userIdNum;
1258 for (uint32_t i = 0; i < param->userIdNum; i++) {
1259 g_globalConfigArray[infoIndex].userIds[i] = param->userIds[i];
1260 }
1261 if (infoIndex == g_globalConfigInfoNum) {
1262 g_globalConfigInfoNum++;
1263 }
1264 return RESULT_SUCCESS;
1265 }
1266
CheckAuthType(uint32_t authType)1267 IAM_STATIC bool CheckAuthType(uint32_t authType)
1268 {
1269 if (authType != PIN_AUTH && authType != FACE_AUTH && authType != FINGER_AUTH && authType != RECOVERY_KEY) {
1270 LOG_ERROR("bad authType %{public}u", authType);
1271 return false;
1272 }
1273 return true;
1274 }
1275
SaveGlobalConfigParam(GlobalConfigParamHal *param)1276 ResultCode SaveGlobalConfigParam(GlobalConfigParamHal *param)
1277 {
1278 if (param == NULL || param->userIdNum > MAX_USER || param->authTypeNum > MAX_AUTH_TYPE_LEN ||
1279 param->authTypeNum == 0) {
1280 LOG_ERROR("bad param");
1281 return RESULT_BAD_PARAM;
1282 }
1283 for (uint32_t i = 0; i < param->authTypeNum; i++) {
1284 if (!CheckAuthType(param->authTypes[i])) {
1285 LOG_ERROR("bad authType %{public}u", param->authTypes[i]);
1286 return RESULT_BAD_PARAM;
1287 }
1288 ResultCode ret = UpdateGlobalConfigArray(param, param->authTypes[i]);
1289 if (ret != RESULT_SUCCESS) {
1290 return ret;
1291 }
1292 }
1293
1294 return UpdateGlobalConfigFile(g_globalConfigArray, g_globalConfigInfoNum);
1295 }
1296
QueryPinCredential(int32_t userId, CredentialInfoHal *pinCredential)1297 IAM_STATIC ResultCode QueryPinCredential(int32_t userId, CredentialInfoHal *pinCredential)
1298 {
1299 if (pinCredential == NULL) {
1300 LOG_ERROR("no need to get pin credential");
1301 return RESULT_BAD_PARAM;
1302 }
1303 CredentialCondition condition = {};
1304 SetCredentialConditionUserId(&condition, userId);
1305 SetCredentialConditionAuthType(&condition, PIN_AUTH);
1306 LinkedList *credList = QueryCredentialLimit(&condition);
1307 if (credList == NULL || credList->getSize(credList) == 0) {
1308 LOG_ERROR("pin credential is null");
1309 DestroyLinkedList(credList);
1310 return RESULT_NOT_ENROLLED;
1311 }
1312 if (credList->head == NULL || credList->head->data == NULL) {
1313 LOG_ERROR("pin credList node is invalid");
1314 DestroyLinkedList(credList);
1315 return RESULT_GENERAL_ERROR;
1316 }
1317 if (memcpy_s(pinCredential, sizeof(CredentialInfoHal), credList->head->data, sizeof(CredentialInfoHal)) != EOK) {
1318 LOG_ERROR("credential copy fail");
1319 DestroyLinkedList(credList);
1320 return RESULT_GENERAL_ERROR;
1321 }
1322 DestroyLinkedList(credList);
1323 return RESULT_SUCCESS;
1324 }
1325
GetPinExpiredInfo(int32_t userId, PinExpiredInfo *expiredInfo)1326 ResultCode GetPinExpiredInfo(int32_t userId, PinExpiredInfo *expiredInfo)
1327 {
1328 if (expiredInfo == NULL) {
1329 LOG_ERROR("bad param");
1330 return RESULT_BAD_PARAM;
1331 }
1332 (void)memset_s(expiredInfo, sizeof(PinExpiredInfo), 0, sizeof(PinExpiredInfo));
1333 for (uint32_t i = 0; i < g_globalConfigInfoNum; i++) {
1334 if (g_globalConfigArray[i].type == PIN_EXPIRED_PERIOD) {
1335 expiredInfo->pinExpiredPeriod = g_globalConfigArray[i].value.pinExpiredPeriod;
1336 break;
1337 }
1338 }
1339 if (expiredInfo->pinExpiredPeriod <= 0) {
1340 expiredInfo->pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1341 LOG_INFO("no need check pinExpiredPeriod");
1342 return RESULT_SUCCESS;
1343 }
1344 CredentialInfoHal pinCredential = {};
1345 if (QueryPinCredential(userId, &pinCredential) != RESULT_SUCCESS) {
1346 LOG_INFO("not enrolled pin");
1347 return RESULT_NOT_ENROLLED;
1348 }
1349 expiredInfo->pinEnrolledSysTime = pinCredential.enrolledSysTime;
1350 return RESULT_SUCCESS;
1351 }
1352
GetEnableStatus(int32_t userId, uint32_t authType)1353 bool GetEnableStatus(int32_t userId, uint32_t authType)
1354 {
1355 for (uint32_t infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1356 if (g_globalConfigArray[infoIndex].type != ENABLE_STATUS ||
1357 g_globalConfigArray[infoIndex].authType != authType) {
1358 continue;
1359 }
1360 LOG_INFO("enableStatus:%{public}d authType:%{public}u", g_globalConfigArray[infoIndex].value.enableStatus,
1361 authType);
1362 if (userId == INVALID_USER_ID || g_globalConfigArray[infoIndex].userIdNum == 0) {
1363 return g_globalConfigArray[infoIndex].value.enableStatus;
1364 }
1365 for (uint32_t i = 0; i < g_globalConfigArray[infoIndex].userIdNum; i++) {
1366 if (userId == g_globalConfigArray[infoIndex].userIds[i]) {
1367 return g_globalConfigArray[infoIndex].value.enableStatus;
1368 }
1369 }
1370 LOG_INFO("enableStatus is not set for userId:%{public}d", userId);
1371 return (!g_globalConfigArray[infoIndex].value.enableStatus);
1372 }
1373 return true;
1374 }
1375