• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     SetCredentialConditionNeedCachePin(&condition);
338     SetCredentialConditionNeedAbandonPin(&condition);
339     LinkedList *credList = QueryCredentialLimit(&condition);
340     if (credList == NULL) {
341         LOG_ERROR("query failed");
342         return true;
343     }
344     if (credList->getSize(credList) != 0) {
345         LOG_ERROR("duplicate credential id");
346         DestroyLinkedList(credList);
347         return true;
348     }
349     DestroyLinkedList(credList);
350     return false;
351 }
352 
IsEnrolledIdDuplicate(LinkedList * enrolledList,uint64_t enrolledId)353 IAM_STATIC bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)
354 {
355     LinkedListNode *temp = enrolledList->head;
356     EnrolledInfoHal *enrolledInfo = NULL;
357     const static uint16_t num = 0xFFFF;
358     while (temp != NULL) {
359         enrolledInfo = (EnrolledInfoHal *)temp->data;
360         if ((enrolledInfo != NULL) && (enrolledInfo->enrolledId & num) == (enrolledId & num)) {
361             return true;
362         }
363         temp = temp->next;
364     }
365 
366     return false;
367 }
368 
GenerateDeduplicateUint64(LinkedList * collection,uint64_t * destValue,DuplicateCheckFunc func)369 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)
370 {
371     if (collection == NULL || destValue == NULL || func == NULL) {
372         LOG_ERROR("param is null");
373         return RESULT_BAD_PARAM;
374     }
375 
376     for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) {
377         uint64_t tempRandom;
378         if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
379             LOG_ERROR("get random failed");
380             return RESULT_GENERAL_ERROR;
381         }
382         if (!func(collection, tempRandom)) {
383             *destValue = tempRandom;
384             return RESULT_SUCCESS;
385         }
386     }
387 
388     LOG_ERROR("generate random failed");
389     return RESULT_GENERAL_ERROR;
390 }
391 
UpdateEnrolledId(LinkedList * enrolledList,uint32_t authType)392 IAM_STATIC ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)
393 {
394     LinkedListNode *temp = enrolledList->head;
395     EnrolledInfoHal *enrolledInfo = NULL;
396     while (temp != NULL) {
397         EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data;
398         if (nodeData != NULL && nodeData->authType == authType) {
399             enrolledInfo = nodeData;
400             break;
401         }
402         temp = temp->next;
403     }
404 
405     if (enrolledInfo != NULL) {
406         return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
407     }
408 
409     enrolledInfo = Malloc(sizeof(EnrolledInfoHal));
410     if (enrolledInfo == NULL) {
411         LOG_ERROR("enrolledInfo malloc failed");
412         return RESULT_NO_MEMORY;
413     }
414     enrolledInfo->authType = authType;
415     ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
416     if (ret != RESULT_SUCCESS) {
417         LOG_ERROR("generate enrolledId failed");
418         Free(enrolledInfo);
419         return ret;
420     }
421     ret = enrolledList->insert(enrolledList, enrolledInfo);
422     if (ret != RESULT_SUCCESS) {
423         LOG_ERROR("enrolledInfo insert failed");
424         Free(enrolledInfo);
425     }
426     return ret;
427 }
428 
429 // add for reliable pin updates
GetRealAuthTypeForEnrolledId(uint32_t authType)430 IAM_STATIC uint32_t GetRealAuthTypeForEnrolledId(uint32_t authType)
431 {
432     if (authType == DEFAULT_AUTH_TYPE) {
433         return PIN_AUTH;
434     }
435     return authType;
436 }
437 
AddCredentialToUser(UserInfo * user,CredentialInfoHal * credentialInfo)438 IAM_STATIC ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)
439 {
440     if (g_userInfoList == NULL) {
441         LOG_ERROR("g_userInfoList is uninitialized");
442         return RESULT_NEED_INIT;
443     }
444     LinkedList *credentialList = user->credentialInfoList;
445     LinkedList *enrolledList = user->enrolledInfoList;
446     if (credentialList->getSize(credentialList) >= MAX_CREDENTIAL) {
447         LOG_ERROR("the number of credentials reaches the maximum");
448         return RESULT_EXCEED_LIMIT;
449     }
450 
451     ResultCode ret = UpdateEnrolledId(enrolledList, GetRealAuthTypeForEnrolledId(credentialInfo->authType));
452     if (ret != RESULT_SUCCESS) {
453         LOG_ERROR("update enrolledId failed");
454         return ret;
455     }
456     ret = GenerateDeduplicateUint64(g_userInfoList, &credentialInfo->credentialId, IsCredentialIdDuplicate);
457     if (ret != RESULT_SUCCESS) {
458         LOG_ERROR("GenerateDeduplicateUint64 failed");
459         return ret;
460     }
461     if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
462         bool isRemoved = false;
463         RemoveCachePin(user, &isRemoved);
464     }
465     CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal));
466     if (credential == NULL) {
467         LOG_ERROR("credential malloc failed");
468         return RESULT_NO_MEMORY;
469     }
470     if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) {
471         LOG_ERROR("credential copy failed");
472         Free(credential);
473         return RESULT_BAD_COPY;
474     }
475     credential->enrolledSysTime = GetReeTime();
476     ret = credentialList->insert(credentialList, credential);
477     if (ret != RESULT_SUCCESS) {
478         LOG_ERROR("insert credential failed");
479         Free(credential);
480     }
481     return ret;
482 }
483 
AddUser(int32_t userId,CredentialInfoHal * credentialInfo,int32_t userType)484 IAM_STATIC ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
485 {
486     if (g_userInfoList == NULL) {
487         LOG_ERROR("please init");
488         return RESULT_NEED_INIT;
489     }
490     if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) {
491         LOG_ERROR("the number of users reaches the maximum");
492         return RESULT_EXCEED_LIMIT;
493     }
494 
495     UserInfo *user = QueryUserInfo(userId);
496     if (user != NULL) {
497         LOG_ERROR("Please check pin");
498         return RESULT_BAD_PARAM;
499     }
500 
501     user = CreateUser(userId, userType);
502     if (user == NULL) {
503         LOG_ERROR("create user failed");
504         return RESULT_UNKNOWN;
505     }
506     LOG_INFO("user userType %{public}d", user->userType);
507     ResultCode ret = AddCredentialToUser(user, credentialInfo);
508     if (ret != RESULT_SUCCESS) {
509         LOG_ERROR("add credential to user failed");
510         goto FAIL;
511     }
512 
513     ret = g_userInfoList->insert(g_userInfoList, user);
514     if (ret != RESULT_SUCCESS) {
515         LOG_ERROR("insert failed");
516         goto FAIL;
517     }
518     return ret;
519 
520 FAIL:
521     DestroyUserInfoNode(user);
522     return ret;
523 }
524 
AddCredentialInfo(int32_t userId,CredentialInfoHal * credentialInfo,int32_t userType)525 ResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
526 {
527     if ((credentialInfo == NULL) || (credentialInfo->authType == DEFAULT_AUTH_TYPE)) {
528         LOG_ERROR("credentialInfo is invalid");
529         return RESULT_BAD_PARAM;
530     }
531     UserInfo *user = QueryUserInfo(userId);
532     if (user == NULL && credentialInfo->authType == PIN_AUTH) {
533         ResultCode ret = AddUser(userId, credentialInfo, userType);
534         if (ret != RESULT_SUCCESS) {
535             LOG_ERROR("add user failed");
536             return ret;
537         }
538         ret = UpdateFileInfo(g_userInfoList);
539         if (ret != RESULT_SUCCESS) {
540             LOG_ERROR("updateFileInfo failed");
541         }
542         return ret;
543     }
544     if (user == NULL) {
545         LOG_ERROR("user is null");
546         return RESULT_BAD_PARAM;
547     }
548     if (credentialInfo->authType == PIN_AUTH) {
549         CredentialCondition condition = {};
550         SetCredentialConditionAuthType(&condition, PIN_AUTH);
551         SetCredentialConditionUserId(&condition, userId);
552         LinkedList *credList = QueryCredentialLimit(&condition);
553         if (credList == NULL) {
554             LOG_ERROR("query credential failed");
555             return RESULT_UNKNOWN;
556         }
557         if (credList->getSize(credList) != 0) {
558             LOG_INFO("cache pin");
559             // add for reliable pin updates
560             credentialInfo->authType = DEFAULT_AUTH_TYPE;
561         }
562         DestroyLinkedList(credList);
563     }
564     ResultCode ret = AddCredentialToUser(user, credentialInfo);
565     if (ret != RESULT_SUCCESS) {
566         LOG_ERROR("add credential to user failed");
567         return ret;
568     }
569     ret = UpdateFileInfo(g_userInfoList);
570     if (ret != RESULT_SUCCESS) {
571         LOG_ERROR("updateFileInfo failed");
572     }
573     return ret;
574 }
575 
MatchCredentialById(const void * data,const void * condition)576 IAM_STATIC bool MatchCredentialById(const void *data, const void *condition)
577 {
578     if (data == NULL || condition == NULL) {
579         return false;
580     }
581     const CredentialInfoHal *credentialInfo = (const CredentialInfoHal *)data;
582     uint64_t credentialId = *(const uint64_t *)condition;
583     if (credentialInfo->credentialId == credentialId) {
584         return true;
585     }
586     return false;
587 }
588 
MatchEnrolledInfoByType(const void * data,const void * condition)589 IAM_STATIC bool MatchEnrolledInfoByType(const void *data, const void *condition)
590 {
591     if (data == NULL || condition == NULL) {
592         return false;
593     }
594     const EnrolledInfoHal *enrolledInfo = (const EnrolledInfoHal *)data;
595     uint32_t authType = *(const uint32_t *)condition;
596     if (enrolledInfo->authType == authType) {
597         return true;
598     }
599     return false;
600 }
601 
RemoveCachePin(UserInfo * user,bool * isRemoved)602 IAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved)
603 {
604     LOG_INFO("RemoveCachePin start");
605     LinkedListNode *temp = user->credentialInfoList->head;
606     CredentialInfoHal *credentialInfoCache = NULL;
607     while (temp != NULL) {
608         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
609         if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
610             credentialInfoCache = nodeData;
611             break;
612         }
613         temp = temp->next;
614     }
615     if (credentialInfoCache == NULL) {
616         LOG_INFO("RemoveCachePin no cache pin");
617         *isRemoved = false;
618         return;
619     }
620     uint64_t credentialId = credentialInfoCache->credentialId;
621     ResultCode ret = (user->credentialInfoList)->remove(
622         user->credentialInfoList, &credentialId, MatchCredentialById, true);
623     if (ret != RESULT_SUCCESS) {
624         LOG_ERROR("remove credential failed");
625         *isRemoved = false;
626         return;
627     }
628     LOG_ERROR("remove credential success");
629     *isRemoved = true;
630 }
631 
ClearCachePin(int32_t userId)632 void ClearCachePin(int32_t userId)
633 {
634     LOG_INFO("ClearCachePin start");
635     UserInfo *user = QueryUserInfo(userId);
636     if (user == NULL) {
637         LOG_ERROR("can't find this user");
638         return;
639     }
640 
641     bool isRemoved = false;
642     RemoveCachePin(user, &isRemoved);
643     if (isRemoved && UpdateFileInfo(g_userInfoList) != RESULT_SUCCESS) {
644         LOG_ERROR("ClearCachePin save fail");
645         return;
646     }
647 }
648 
SwitchSubType(UserInfo * user)649 IAM_STATIC void SwitchSubType(UserInfo *user)
650 {
651     uint64_t tmpSubType = user->pinSubType;
652     user->pinSubType = user->cachePinSubType;
653     user->cachePinSubType = tmpSubType;
654 }
655 
656 // add for reliable pin updates
DeletePinCredentialInfo(UserInfo * user)657 IAM_STATIC ResultCode DeletePinCredentialInfo(UserInfo *user)
658 {
659     LOG_INFO("DeletePinCredentialInfo start");
660     LinkedListNode *temp = user->credentialInfoList->head;
661     CredentialInfoHal *credentialInfoOld = NULL;
662     CredentialInfoHal *credentialInfoCache = NULL;
663     while (temp != NULL) {
664         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
665         if (nodeData != NULL && nodeData->authType == PIN_AUTH) {
666             credentialInfoOld = nodeData;
667         }
668         if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
669             credentialInfoCache = nodeData;
670         }
671         temp = temp->next;
672     }
673     if (credentialInfoOld == NULL || credentialInfoCache == NULL) {
674         LOG_ERROR("no cache pin exist");
675         return RESULT_GENERAL_ERROR;
676     }
677     credentialInfoOld->authType = DEFAULT_AUTH_TYPE;
678     credentialInfoCache->authType = PIN_AUTH;
679     SwitchSubType(user);
680     ResultCode result = UpdateFileInfo(g_userInfoList);
681     if (result == RESULT_SUCCESS) {
682         LOG_INFO("switch cache pin success");
683         ClearCachePin(user->userId);
684         return result;
685     }
686     LOG_ERROR("switch cache pin fail");
687     credentialInfoOld->authType = PIN_AUTH;
688     credentialInfoCache->authType = DEFAULT_AUTH_TYPE;
689     SwitchSubType(user);
690     return RESULT_GENERAL_ERROR;
691 }
692 
DeleteCredentialInfo(int32_t userId,uint64_t credentialId,CredentialInfoHal * credentialInfo)693 ResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
694 {
695     if (credentialInfo == NULL) {
696         LOG_ERROR("param is invalid");
697         return RESULT_BAD_PARAM;
698     }
699 
700     UserInfo *user = QueryUserInfo(userId);
701     if (user == NULL) {
702         LOG_ERROR("can't find this user");
703         return RESULT_BAD_PARAM;
704     }
705 
706     LinkedList *credentialList = user->credentialInfoList;
707     CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList);
708     if (credentialQuery == NULL) {
709         LOG_ERROR("credentialQuery is null");
710         return RESULT_UNKNOWN;
711     }
712     if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
713         LOG_ERROR("copy failed");
714         return RESULT_BAD_COPY;
715     }
716     if (credentialInfo->authType == PIN_AUTH && !credentialInfo->isAbandoned) {
717         return DeletePinCredentialInfo(user);
718     }
719     ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true);
720     if (ret != RESULT_SUCCESS) {
721         LOG_ERROR("remove credential failed");
722         return ret;
723     }
724     if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
725         return UpdateFileInfo(g_userInfoList);
726     }
727     credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList);
728     if (credentialQuery != NULL) {
729         return UpdateFileInfo(g_userInfoList);
730     }
731 
732     LinkedList *enrolledInfoList = user->enrolledInfoList;
733     if (enrolledInfoList == NULL) {
734         LOG_ERROR("enrolledInfoList is null");
735         return RESULT_UNKNOWN;
736     }
737     ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true);
738     if (ret != RESULT_SUCCESS) {
739         LOG_ERROR("remove enrolledInfo failed");
740         return ret;
741     }
742 
743     return UpdateFileInfo(g_userInfoList);
744 }
745 
QueryCredentialById(uint64_t credentialId,LinkedList * credentialList)746 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)
747 {
748     if (credentialList == NULL) {
749         return NULL;
750     }
751     LinkedListNode *temp = credentialList->head;
752     CredentialInfoHal *credentialInfo = NULL;
753     while (temp != NULL) {
754         CredentialInfoHal *nodeData = (CredentialInfoHal *)temp->data;
755         if (nodeData != NULL && nodeData->credentialId == credentialId) {
756             credentialInfo = nodeData;
757             break;
758         }
759         temp = temp->next;
760     }
761     return credentialInfo;
762 }
763 
QueryCredentialByAuthType(uint32_t authType,LinkedList * credentialList)764 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)
765 {
766     if (credentialList == NULL) {
767         return NULL;
768     }
769     LinkedListNode *temp = credentialList->head;
770     CredentialInfoHal *credentialInfo = NULL;
771     while (temp != NULL) {
772         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
773         if (nodeData != NULL && nodeData->authType == authType) {
774             credentialInfo = nodeData;
775             break;
776         }
777         temp = temp->next;
778     }
779     return credentialInfo;
780 }
781 
IsCredentialIdMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)782 IAM_STATIC bool IsCredentialIdMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
783 {
784     if ((limit->conditionFactor & CREDENTIAL_CONDITION_CREDENTIAL_ID) != 0 &&
785         limit->credentialId != credentialInfo->credentialId) {
786         return false;
787     }
788     return true;
789 }
790 
IsAuthTypeMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)791 IAM_STATIC bool IsAuthTypeMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
792 {
793     if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
794         if ((limit->conditionFactor & CREDENTIAL_CONDITION_CACHE_PIN) != 0) {
795             return true;
796         }
797         if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_CACHE_PIN) == 0) {
798             return false;
799         }
800     } else {
801         if ((limit->conditionFactor & CREDENTIAL_CONDITION_AUTH_TYPE) != 0 &&
802             limit->authType != credentialInfo->authType) {
803             return false;
804         }
805         if ((limit->conditionFactor & CREDENTIAL_CONDITION_CACHE_PIN) != 0) {
806             return false;
807         }
808     }
809     return true;
810 }
811 
IsTemplateIdMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)812 IAM_STATIC bool IsTemplateIdMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
813 {
814     if ((limit->conditionFactor & CREDENTIAL_CONDITION_TEMPLATE_ID) != 0 &&
815         limit->templateId != credentialInfo->templateId) {
816         return false;
817     }
818     return true;
819 }
820 
IsExecutorSensorHintMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)821 IAM_STATIC bool IsExecutorSensorHintMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
822 {
823     if ((limit->conditionFactor & CREDENTIAL_CONDITION_SENSOR_HINT) != 0 &&
824         limit->executorSensorHint != INVALID_SENSOR_HINT &&
825         limit->executorSensorHint != credentialInfo->executorSensorHint) {
826         return false;
827     }
828     return true;
829 }
830 
IsExecutorMatcherMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)831 IAM_STATIC bool IsExecutorMatcherMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
832 {
833     if ((limit->conditionFactor & CREDENTIAL_CONDITION_EXECUTOR_MATCHER) != 0 &&
834         limit->executorMatcher != credentialInfo->executorMatcher) {
835         return false;
836     }
837     return true;
838 }
839 
IsAbandonedMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)840 IAM_STATIC bool IsAbandonedMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
841 {
842     if ((limit->conditionFactor & CREDENTIAL_CONDITION_ABANDON) != 0) {
843         if (credentialInfo->isAbandoned) {
844             return true;
845         }
846         return false;
847     }
848     if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_ABANDON) != 0) {
849         return true;
850     }
851     if (!credentialInfo->isAbandoned) {
852         return true;
853     }
854 
855     return false;
856 }
857 
858 // do not cotain cache pin credential
IsCredMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)859 IAM_STATIC bool IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
860 {
861     if (!IsCredentialIdMatch(limit, credentialInfo)) {
862         return false;
863     }
864     if (!IsAuthTypeMatch(limit, credentialInfo)) {
865         return false;
866     }
867     if (!IsTemplateIdMatch(limit, credentialInfo)) {
868         return false;
869     }
870     if (!IsExecutorSensorHintMatch(limit, credentialInfo)) {
871         return false;
872     }
873     if (!IsExecutorMatcherMatch(limit, credentialInfo)) {
874         return false;
875     }
876     if (!IsAbandonedMatch(limit, credentialInfo)) {
877         return false;
878     }
879     return true;
880 }
881 
IsUserMatch(const CredentialCondition * limit,const UserInfo * user)882 IAM_STATIC bool IsUserMatch(const CredentialCondition *limit, const UserInfo *user)
883 {
884     if ((limit->conditionFactor & CREDENTIAL_CONDITION_USER_ID) != 0 && limit->userId != user->userId) {
885         return false;
886     }
887     return true;
888 }
889 
890 // do not cotain cache pin credential
TraverseCredentialList(const CredentialCondition * limit,const LinkedList * credentialList,LinkedList * credListGet)891 IAM_STATIC ResultCode TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList,
892     LinkedList *credListGet)
893 {
894     if (credentialList == NULL) {
895         LOG_ERROR("credentialList is null");
896         return RESULT_GENERAL_ERROR;
897     }
898     LinkedListNode *temp = credentialList->head;
899     while (temp != NULL) {
900         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
901         if (nodeData == NULL) {
902             LOG_ERROR("nodeData is null");
903             return RESULT_UNKNOWN;
904         }
905         if (!IsCredMatch(limit, nodeData)) {
906             temp = temp->next;
907             continue;
908         }
909         CredentialInfoHal *copy = (CredentialInfoHal *)Malloc(sizeof(CredentialInfoHal));
910         if (copy == NULL) {
911             LOG_ERROR("copy malloc failed");
912             return RESULT_NO_MEMORY;
913         }
914         *copy = *nodeData;
915         ResultCode ret = credListGet->insert(credListGet, copy);
916         if (ret != RESULT_SUCCESS) {
917             LOG_ERROR("insert failed");
918             Free(copy);
919             return ret;
920         }
921         temp = temp->next;
922     }
923     return RESULT_SUCCESS;
924 }
925 
926 // do not cotain cache pin credential
QueryCredentialLimit(const CredentialCondition * limit)927 LinkedList *QueryCredentialLimit(const CredentialCondition *limit)
928 {
929     if (limit == NULL) {
930         LOG_ERROR("limit is null");
931         return NULL;
932     }
933     if (g_userInfoList == NULL) {
934         LOG_ERROR("g_userInfoList is null");
935         return NULL;
936     }
937     LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
938     if (credList == NULL) {
939         LOG_ERROR("credList is null");
940         return NULL;
941     }
942     LinkedListNode *temp = g_userInfoList->head;
943     while (temp != NULL) {
944         UserInfo *user = (UserInfo *)temp->data;
945         if (user == NULL) {
946             LOG_ERROR("node data is null");
947             DestroyLinkedList(credList);
948             return NULL;
949         }
950         if (IsUserMatch(limit, user)) {
951             ResultCode ret = TraverseCredentialList(limit, user->credentialInfoList, credList);
952             if (ret != RESULT_SUCCESS) {
953                 LOG_ERROR("TraverseCredentialList failed");
954                 DestroyLinkedList(credList);
955                 return NULL;
956             }
957         }
958         temp = temp->next;
959     }
960     return credList;
961 }
962 
QueryCredentialUserId(uint64_t credentialId,int32_t * userId)963 ResultCode QueryCredentialUserId(uint64_t credentialId, int32_t *userId)
964 {
965     if (userId == NULL) {
966         LOG_ERROR("userId is null");
967         return RESULT_BAD_PARAM;
968     }
969     if (g_userInfoList == NULL) {
970         LOG_ERROR("g_userInfoList is null");
971         return RESULT_NEED_INIT;
972     }
973     LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
974     if (credList == NULL) {
975         LOG_ERROR("credList is null");
976         return RESULT_NO_MEMORY;
977     }
978     LinkedListNode *temp = g_userInfoList->head;
979     CredentialCondition condition = {};
980     SetCredentialConditionCredentialId(&condition, credentialId);
981     SetCredentialConditionNeedAbandonPin(&condition);
982     while (temp != NULL) {
983         UserInfo *user = (UserInfo *)temp->data;
984         if (user == NULL) {
985             LOG_ERROR("user is null");
986             DestroyLinkedList(credList);
987             return RESULT_UNKNOWN;
988         }
989         ResultCode ret = TraverseCredentialList(&condition, user->credentialInfoList, credList);
990         if (ret != RESULT_SUCCESS) {
991             LOG_ERROR("TraverseCredentialList failed");
992             DestroyLinkedList(credList);
993             return RESULT_UNKNOWN;
994         }
995         if (credList->getSize(credList) != 0) {
996             DestroyLinkedList(credList);
997             *userId = user->userId;
998             return RESULT_SUCCESS;
999         }
1000         temp = temp->next;
1001     }
1002     DestroyLinkedList(credList);
1003     LOG_ERROR("can't find this credential");
1004     return RESULT_NOT_FOUND;
1005 }
1006 
SetPinSubType(int32_t userId,uint64_t pinSubType)1007 ResultCode SetPinSubType(int32_t userId, uint64_t pinSubType)
1008 {
1009     UserInfo *user = QueryUserInfo(userId);
1010     if (user == NULL) {
1011         LOG_ERROR("can't find this user");
1012         return RESULT_NOT_FOUND;
1013     }
1014     user->pinSubType = pinSubType;
1015     return RESULT_SUCCESS;
1016 }
1017 
GetPinSubType(int32_t userId,uint64_t * pinSubType)1018 ResultCode GetPinSubType(int32_t userId, uint64_t *pinSubType)
1019 {
1020     if (pinSubType == NULL) {
1021         LOG_ERROR("pinSubType is null");
1022         return RESULT_BAD_PARAM;
1023     }
1024     UserInfo *user = QueryUserInfo(userId);
1025     if (user == NULL) {
1026         LOG_ERROR("can't find this user");
1027         return RESULT_NOT_FOUND;
1028     }
1029     *pinSubType = user->pinSubType;
1030     return RESULT_SUCCESS;
1031 }
1032 
SetCredentialConditionCredentialId(CredentialCondition * condition,uint64_t credentialId)1033 void SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId)
1034 {
1035     if (condition == NULL) {
1036         LOG_ERROR("condition is null");
1037         return;
1038     }
1039     condition->credentialId = credentialId;
1040     condition->conditionFactor |= CREDENTIAL_CONDITION_CREDENTIAL_ID;
1041 }
1042 
SetCredentialConditionTemplateId(CredentialCondition * condition,uint64_t templateId)1043 void SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId)
1044 {
1045     if (condition == NULL) {
1046         LOG_ERROR("condition is null");
1047         return;
1048     }
1049     condition->templateId = templateId;
1050     condition->conditionFactor |= CREDENTIAL_CONDITION_TEMPLATE_ID;
1051 }
1052 
SetCredentialConditionAuthType(CredentialCondition * condition,uint32_t authType)1053 void SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType)
1054 {
1055     if (condition == NULL) {
1056         LOG_ERROR("condition is null");
1057         return;
1058     }
1059     condition->authType = authType;
1060     condition->conditionFactor |= CREDENTIAL_CONDITION_AUTH_TYPE;
1061 }
1062 
SetCredentialConditionExecutorSensorHint(CredentialCondition * condition,uint32_t executorSensorHint)1063 void SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint)
1064 {
1065     if (condition == NULL) {
1066         LOG_ERROR("condition is null");
1067         return;
1068     }
1069     condition->executorSensorHint = executorSensorHint;
1070     condition->conditionFactor |= CREDENTIAL_CONDITION_SENSOR_HINT;
1071 }
1072 
SetCredentialConditionExecutorMatcher(CredentialCondition * condition,uint32_t executorMatcher)1073 void SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher)
1074 {
1075     if (condition == NULL) {
1076         LOG_ERROR("condition is null");
1077         return;
1078     }
1079     condition->executorMatcher = executorMatcher;
1080     condition->conditionFactor |= CREDENTIAL_CONDITION_EXECUTOR_MATCHER;
1081 }
1082 
SetCredentialConditionUserId(CredentialCondition * condition,int32_t userId)1083 void SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId)
1084 {
1085     if (condition == NULL) {
1086         LOG_ERROR("condition is null");
1087         return;
1088     }
1089     condition->userId = userId;
1090     condition->conditionFactor |= CREDENTIAL_CONDITION_USER_ID;
1091 }
1092 
SetCredentialConditionNeedCachePin(CredentialCondition * condition)1093 void SetCredentialConditionNeedCachePin(CredentialCondition *condition)
1094 {
1095     if (condition == NULL) {
1096         LOG_ERROR("condition is null");
1097         return;
1098     }
1099     condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_CACHE_PIN;
1100 }
1101 
SetCredentialConditionNeedAbandonPin(CredentialCondition * condition)1102 void SetCredentialConditionNeedAbandonPin(CredentialCondition *condition)
1103 {
1104     if (condition == NULL) {
1105         LOG_ERROR("condition is null");
1106         return;
1107     }
1108     condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_ABANDON;
1109 }
1110 
SetCredentialConditionAbandonPin(CredentialCondition * condition)1111 void SetCredentialConditionAbandonPin(CredentialCondition *condition)
1112 {
1113     if (condition == NULL) {
1114         LOG_ERROR("condition is null");
1115         return;
1116     }
1117     condition->conditionFactor |= CREDENTIAL_CONDITION_ABANDON;
1118 }
1119 
SetCredentialConditionCachePin(CredentialCondition * condition)1120 void SetCredentialConditionCachePin(CredentialCondition *condition)
1121 {
1122     if (condition == NULL) {
1123         LOG_ERROR("condition is null");
1124         return;
1125     }
1126     condition->conditionFactor |= CREDENTIAL_CONDITION_CACHE_PIN;
1127 }
1128 
IsUserValid(UserInfo * user)1129 IAM_STATIC bool IsUserValid(UserInfo *user)
1130 {
1131     LinkedList *credentialInfoList = user->credentialInfoList;
1132     CredentialInfoHal *pinCredential = QueryCredentialByAuthType(PIN_AUTH, credentialInfoList);
1133     if (pinCredential == NULL) {
1134         LOG_INFO("user is invalid, userId: %{public}d", user->userId);
1135         return false;
1136     }
1137     return true;
1138 }
1139 
GetInvalidUser(int32_t * invalidUserId,uint32_t maxUserCount,uint32_t * userCount,bool * cachePinRemoved)1140 IAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
1141     bool *cachePinRemoved)
1142 {
1143     LOG_INFO("get invalid user start");
1144     if (g_userInfoList == NULL) {
1145         LOG_ERROR("g_userInfoList is null");
1146         return RESULT_GENERAL_ERROR;
1147     }
1148 
1149     LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1150     if (iterator == NULL) {
1151         LOG_ERROR("create iterator failed");
1152         return RESULT_NO_MEMORY;
1153     }
1154 
1155     UserInfo *user = NULL;
1156     *userCount = 0;
1157     while (iterator->hasNext(iterator)) {
1158         user = (UserInfo *)iterator->next(iterator);
1159         if (user == NULL) {
1160             LOG_ERROR("userinfo list node is null, please check");
1161             continue;
1162         }
1163 
1164         if (*userCount >= maxUserCount) {
1165             LOG_ERROR("too many users");
1166             break;
1167         }
1168 
1169         if (!IsUserValid(user)) {
1170             invalidUserId[*userCount] = user->userId;
1171             (*userCount)++;
1172             continue;
1173         }
1174 
1175         bool isRemoved = false;
1176         RemoveCachePin(user, &isRemoved);
1177         if (isRemoved) {
1178             *cachePinRemoved = true;
1179         }
1180         CredentialInfoHal credentialInfo = {};
1181         (void)ClearAbandonExpiredCredential(user->userId, &credentialInfo);
1182     }
1183 
1184     g_userInfoList->destroyIterator(iterator);
1185     return RESULT_SUCCESS;
1186 }
1187 
ClearInvalidData(void)1188 IAM_STATIC ResultCode ClearInvalidData(void)
1189 {
1190     LOG_INFO("clear invalid user start");
1191     int32_t invalidUserId[MAX_USER] = {0};
1192     uint32_t userCount = 0;
1193     bool cachePinRemoved = false;
1194     if (GetInvalidUser(invalidUserId, MAX_USER, &userCount, &cachePinRemoved) != RESULT_SUCCESS) {
1195         LOG_ERROR("GetInvalidUser fail");
1196         return RESULT_GENERAL_ERROR;
1197     }
1198     ResultCode ret = RESULT_SUCCESS;
1199     for (uint32_t i = 0; i < userCount; ++i) {
1200         ret = DeleteUser(invalidUserId[i]);
1201         if (ret != RESULT_SUCCESS) {
1202             LOG_ERROR("delete invalid user fail, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1203             return ret;
1204         }
1205         LOG_INFO("delete invalid user success, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1206     }
1207 
1208     if ((userCount != 0) || cachePinRemoved) {
1209         ret = UpdateFileInfo(g_userInfoList);
1210         if (ret != RESULT_SUCCESS) {
1211             LOG_ERROR("UpdateFileInfo fail, ret: %{public}d", ret);
1212             return ret;
1213         }
1214     }
1215     return RESULT_SUCCESS;
1216 }
1217 
GetAllExtUserInfo(UserInfoResult * userInfos,uint32_t userInfoLen,uint32_t * userInfocount)1218 ResultCode GetAllExtUserInfo(UserInfoResult *userInfos, uint32_t userInfoLen, uint32_t *userInfocount)
1219 {
1220     LOG_INFO("get all user info start");
1221     if (userInfos == NULL || userInfocount == NULL || g_userInfoList == NULL) {
1222         LOG_ERROR("param is null");
1223         return RESULT_BAD_PARAM;
1224     }
1225 
1226     LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1227     if (iterator == NULL) {
1228         LOG_ERROR("create iterator failed");
1229         return RESULT_NO_MEMORY;
1230     }
1231 
1232     UserInfo *user = NULL;
1233     EnrolledInfoHal *enrolledInfoHal = NULL;
1234     *userInfocount = 0;
1235     while (iterator->hasNext(iterator)) {
1236         user = (UserInfo *)iterator->next(iterator);
1237         if (user == NULL) {
1238             LOG_ERROR("userinfo list node is null, please check");
1239             continue;
1240         }
1241 
1242         if (*userInfocount >= userInfoLen) {
1243             LOG_ERROR("too many users");
1244             goto ERROR;
1245         }
1246 
1247         userInfos[*userInfocount].userId = user->userId;
1248         userInfos[*userInfocount].secUid = user->secUid;
1249         userInfos[*userInfocount].pinSubType = (uint32_t)user->pinSubType;
1250 
1251         ResultCode ret = GetAllEnrolledInfoFromUser(user, &enrolledInfoHal, &(userInfos[*userInfocount].enrollNum));
1252         if (ret != RESULT_SUCCESS) {
1253             LOG_ERROR("get enrolled info fail");
1254             goto ERROR;
1255         }
1256         if (userInfos[*userInfocount].enrollNum > MAX_ENROLL_OUTPUT) {
1257             LOG_ERROR("too many elements");
1258             free(enrolledInfoHal);
1259             goto ERROR;
1260         }
1261 
1262         for (uint32_t i = 0; i < userInfos[*userInfocount].enrollNum; i++) {
1263             userInfos[*userInfocount].enrolledInfo[i].authType = enrolledInfoHal[i].authType;
1264             userInfos[*userInfocount].enrolledInfo[i].enrolledId = enrolledInfoHal[i].enrolledId;
1265         }
1266 
1267         free(enrolledInfoHal);
1268         (*userInfocount)++;
1269     }
1270 
1271     g_userInfoList->destroyIterator(iterator);
1272     return RESULT_SUCCESS;
1273 
1274 ERROR:
1275     g_userInfoList->destroyIterator(iterator);
1276     return RESULT_GENERAL_ERROR;
1277 }
1278 
GetEnrolledState(int32_t userId,uint32_t authType,EnrolledStateHal * enrolledStateHal)1279 ResultCode GetEnrolledState(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal)
1280 {
1281     LOG_INFO("get enrolled id info start, userId:%{public}d, authType:%{public}d", userId, authType);
1282 
1283     UserInfo *user = QueryUserInfo(userId);
1284     if (user == NULL) {
1285         LOG_ERROR("user is null");
1286         return RESULT_NOT_ENROLLED;
1287     }
1288     if (user->credentialInfoList == NULL) {
1289         LOG_ERROR("credentialInfoList is null");
1290         return RESULT_NOT_ENROLLED;
1291     }
1292 
1293     uint16_t credentialCount = 0;
1294     LinkedListNode *credentialInfoTemp = user->credentialInfoList->head;
1295     while (credentialInfoTemp != NULL) {
1296         CredentialInfoHal *nodeInfo = credentialInfoTemp->data;
1297         if (nodeInfo != NULL && nodeInfo->authType == authType) {
1298             ++credentialCount;
1299         }
1300         credentialInfoTemp = credentialInfoTemp->next;
1301     }
1302     if (credentialCount == 0) {
1303         LOG_ERROR("not enrolled");
1304         return RESULT_NOT_ENROLLED;
1305     }
1306     enrolledStateHal->credentialCount = credentialCount;
1307     if (user->enrolledInfoList == NULL) {
1308         LOG_ERROR("enrolledInfoList is null");
1309         return RESULT_NOT_ENROLLED;
1310     }
1311     LinkedListNode *enrolledInfoTemp = user->enrolledInfoList->head;
1312     while (enrolledInfoTemp != NULL) {
1313         EnrolledInfoHal *nodeInfo = enrolledInfoTemp->data;
1314         if (nodeInfo != NULL && nodeInfo->authType == authType) {
1315             enrolledStateHal->credentialDigest = nodeInfo->enrolledId;
1316             break;
1317         }
1318         enrolledInfoTemp = enrolledInfoTemp->next;
1319     }
1320     return RESULT_SUCCESS;
1321 }
1322 
UpdateGlobalConfigArray(GlobalConfigParamHal * param,uint32_t authType)1323 IAM_STATIC ResultCode UpdateGlobalConfigArray(GlobalConfigParamHal *param, uint32_t authType)
1324 {
1325     uint32_t infoIndex = 0;
1326     for (infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1327         if (g_globalConfigArray[infoIndex].type == param->type &&
1328             g_globalConfigArray[infoIndex].authType == authType) {
1329             LOG_INFO("globalConfig is already exist, type:%{public}d, authType:%{public}u", param->type, authType);
1330             break;
1331         }
1332     }
1333     if (infoIndex >= MAX_GLOBAL_CONFIG_NUM) {
1334         LOG_ERROR("globalConfigArray is exceed limit");
1335         return RESULT_EXCEED_LIMIT;
1336     }
1337     memset_s(&g_globalConfigArray[infoIndex], sizeof(GlobalConfigInfo), 0, sizeof(GlobalConfigInfo));
1338 
1339     switch (param->type) {
1340         case PIN_EXPIRED_PERIOD:
1341             if (authType != PIN_AUTH) {
1342                 LOG_ERROR("bad authType:%{public}u for PIN_EXPIRED_PERIOD", authType);
1343                 return RESULT_BAD_PARAM;
1344             }
1345             g_globalConfigArray[infoIndex].value.pinExpiredPeriod = param->value.pinExpiredPeriod;
1346             break;
1347         case ENABLE_STATUS:
1348             g_globalConfigArray[infoIndex].value.enableStatus = param->value.enableStatus;
1349             break;
1350         default:
1351             LOG_ERROR("globalConfigType not support, type:%{public}d.", param->type);
1352             return RESULT_BAD_PARAM;
1353     }
1354     g_globalConfigArray[infoIndex].type = param->type;
1355     g_globalConfigArray[infoIndex].authType = authType;
1356     g_globalConfigArray[infoIndex].userIdNum = param->userIdNum;
1357     for (uint32_t i = 0; i < param->userIdNum; i++) {
1358         g_globalConfigArray[infoIndex].userIds[i] = param->userIds[i];
1359     }
1360     if (infoIndex == g_globalConfigInfoNum) {
1361         g_globalConfigInfoNum++;
1362     }
1363     return RESULT_SUCCESS;
1364 }
1365 
CheckAuthType(uint32_t authType)1366 IAM_STATIC bool CheckAuthType(uint32_t authType)
1367 {
1368     if (authType != PIN_AUTH && authType != FACE_AUTH && authType != FINGER_AUTH && authType != RECOVERY_KEY) {
1369         LOG_ERROR("bad authType %{public}u", authType);
1370         return false;
1371     }
1372     return true;
1373 }
1374 
SaveGlobalConfigParam(GlobalConfigParamHal * param)1375 ResultCode SaveGlobalConfigParam(GlobalConfigParamHal *param)
1376 {
1377     if (param == NULL || param->userIdNum > MAX_USER || param->authTypeNum > MAX_AUTH_TYPE_LEN ||
1378         param->authTypeNum == 0) {
1379         LOG_ERROR("bad param");
1380         return RESULT_BAD_PARAM;
1381     }
1382     for (uint32_t i = 0; i < param->authTypeNum; i++) {
1383         if (!CheckAuthType(param->authTypes[i])) {
1384             LOG_ERROR("bad authType %{public}u", param->authTypes[i]);
1385             return RESULT_BAD_PARAM;
1386         }
1387         ResultCode ret = UpdateGlobalConfigArray(param, param->authTypes[i]);
1388         if (ret != RESULT_SUCCESS) {
1389             return ret;
1390         }
1391     }
1392 
1393     return UpdateGlobalConfigFile(g_globalConfigArray, g_globalConfigInfoNum);
1394 }
1395 
QueryPinCredential(int32_t userId,CredentialInfoHal * pinCredential)1396 IAM_STATIC ResultCode QueryPinCredential(int32_t userId, CredentialInfoHal *pinCredential)
1397 {
1398     if (pinCredential == NULL) {
1399         LOG_ERROR("no need to get pin credential");
1400         return RESULT_BAD_PARAM;
1401     }
1402     CredentialCondition condition = {};
1403     SetCredentialConditionUserId(&condition, userId);
1404     SetCredentialConditionAuthType(&condition, PIN_AUTH);
1405     LinkedList *credList = QueryCredentialLimit(&condition);
1406     if (credList == NULL || credList->getSize(credList) == 0) {
1407         LOG_ERROR("pin credential is null");
1408         DestroyLinkedList(credList);
1409         return RESULT_NOT_ENROLLED;
1410     }
1411     if (credList->head == NULL || credList->head->data == NULL) {
1412         LOG_ERROR("pin credList node is invalid");
1413         DestroyLinkedList(credList);
1414         return RESULT_GENERAL_ERROR;
1415     }
1416     if (memcpy_s(pinCredential, sizeof(CredentialInfoHal), credList->head->data, sizeof(CredentialInfoHal)) != EOK) {
1417         LOG_ERROR("credential copy fail");
1418         DestroyLinkedList(credList);
1419         return RESULT_GENERAL_ERROR;
1420     }
1421     DestroyLinkedList(credList);
1422     return RESULT_SUCCESS;
1423 }
1424 
QueryPinExpiredInfo(int64_t * pinExpiredPeriod)1425 ResultCode QueryPinExpiredInfo(int64_t *pinExpiredPeriod)
1426 {
1427     if (pinExpiredPeriod == NULL) {
1428         LOG_ERROR("bad param");
1429         return RESULT_BAD_PARAM;
1430     }
1431     for (uint32_t i = 0; i < g_globalConfigInfoNum; i++) {
1432         if (g_globalConfigArray[i].type == PIN_EXPIRED_PERIOD) {
1433             *pinExpiredPeriod = g_globalConfigArray[i].value.pinExpiredPeriod;
1434             break;
1435         }
1436     }
1437     if (*pinExpiredPeriod <= 0) {
1438         *pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1439         LOG_INFO("no need check pinExpiredPeriod");
1440         return RESULT_SUCCESS;
1441     }
1442     return RESULT_SUCCESS;
1443 }
1444 
GetPinExpiredInfo(int32_t userId,PinExpiredInfo * expiredInfo)1445 ResultCode GetPinExpiredInfo(int32_t userId, PinExpiredInfo *expiredInfo)
1446 {
1447     LOG_INFO("start");
1448     if (expiredInfo == NULL) {
1449         LOG_ERROR("bad param");
1450         return RESULT_BAD_PARAM;
1451     }
1452     (void)memset_s(expiredInfo, sizeof(PinExpiredInfo), 0, sizeof(PinExpiredInfo));
1453     ResultCode ret = QueryPinExpiredInfo(&(expiredInfo->pinExpiredPeriod));
1454     if (ret != RESULT_SUCCESS) {
1455         LOG_ERROR("QueryPinExpiredInfo fail");
1456         return ret;
1457     }
1458     if (expiredInfo->pinExpiredPeriod == NO_CHECK_PIN_EXPIRED_PERIOD) {
1459         LOG_INFO("no need check pinExpiredPeriod");
1460         return RESULT_SUCCESS;
1461     }
1462     CredentialInfoHal pinCredential = {};
1463     if (QueryPinCredential(userId, &pinCredential) != RESULT_SUCCESS) {
1464         LOG_INFO("not enrolled pin");
1465         return RESULT_NOT_ENROLLED;
1466     }
1467     expiredInfo->pinEnrolledSysTime = pinCredential.enrolledSysTime;
1468     return RESULT_SUCCESS;
1469 }
1470 
GetEnableStatus(int32_t userId,uint32_t authType)1471 bool GetEnableStatus(int32_t userId, uint32_t authType)
1472 {
1473     for (uint32_t infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1474         if (g_globalConfigArray[infoIndex].type != ENABLE_STATUS ||
1475             g_globalConfigArray[infoIndex].authType != authType) {
1476             continue;
1477         }
1478         LOG_INFO("enableStatus:%{public}d authType:%{public}u", g_globalConfigArray[infoIndex].value.enableStatus,
1479             authType);
1480         if (userId == INVALID_USER_ID || g_globalConfigArray[infoIndex].userIdNum == 0) {
1481             return g_globalConfigArray[infoIndex].value.enableStatus;
1482         }
1483         for (uint32_t i = 0; i < g_globalConfigArray[infoIndex].userIdNum; i++) {
1484             if (userId == g_globalConfigArray[infoIndex].userIds[i]) {
1485                 return g_globalConfigArray[infoIndex].value.enableStatus;
1486             }
1487         }
1488         LOG_INFO("enableStatus is not set for userId:%{public}d", userId);
1489         return (!g_globalConfigArray[infoIndex].value.enableStatus);
1490     }
1491     return true;
1492 }
1493 
QueryAbandonCredential(int32_t userId,LinkedList ** creds)1494 ResultCode QueryAbandonCredential(int32_t userId, LinkedList **creds)
1495 {
1496     if (creds == NULL) {
1497         LOG_ERROR("creds is null");
1498         return RESULT_BAD_PARAM;
1499     }
1500     CredentialCondition condition = {};
1501     SetCredentialConditionUserId(&condition, userId);
1502     SetCredentialConditionAbandonPin(&condition);
1503     *creds = QueryCredentialLimit(&condition);
1504     if (*creds == NULL) {
1505         LOG_ERROR("query credential failed");
1506         return RESULT_UNKNOWN;
1507     }
1508     LOG_INFO("query abandon credential success");
1509     return RESULT_SUCCESS;
1510 }
1511 
GetCredentialListByAuthType(int32_t userId,uint32_t authType,LinkedList ** creds)1512 ResultCode GetCredentialListByAuthType(int32_t userId, uint32_t authType, LinkedList **creds)
1513 {
1514     if (creds == NULL) {
1515         LOG_ERROR("creds is null");
1516         return RESULT_BAD_PARAM;
1517     }
1518     CredentialCondition condition = {};
1519     SetCredentialConditionUserId(&condition, userId);
1520     SetCredentialConditionAuthType(&condition, authType);
1521 
1522     *creds = QueryCredentialLimit(&condition);
1523     if (*creds == NULL) {
1524         LOG_ERROR("query credential failed");
1525         return RESULT_UNKNOWN;
1526     }
1527     LOG_INFO("query credential success");
1528     return RESULT_SUCCESS;
1529 }
1530 
GetCredentialListByCachePin(int32_t userId,LinkedList ** creds)1531 ResultCode GetCredentialListByCachePin(int32_t userId, LinkedList **creds)
1532 {
1533     if (creds == NULL) {
1534         LOG_ERROR("creds is null");
1535         return RESULT_BAD_PARAM;
1536     }
1537     CredentialCondition condition = {};
1538     SetCredentialConditionCachePin(&condition);
1539 
1540     *creds = QueryCredentialLimit(&condition);
1541     if (*creds == NULL) {
1542         LOG_ERROR("query credential failed");
1543         return RESULT_UNKNOWN;
1544     }
1545     LOG_INFO("query cache credential success");
1546     return RESULT_SUCCESS;
1547 }
1548 
GetCredentialListByAbandonFlag(int32_t userId,uint32_t authType,LinkedList ** creds)1549 ResultCode GetCredentialListByAbandonFlag(int32_t userId, uint32_t authType, LinkedList **creds)
1550 {
1551     if (creds == NULL) {
1552         LOG_ERROR("creds is null");
1553         return RESULT_BAD_PARAM;
1554     }
1555     CredentialCondition condition = {};
1556     SetCredentialConditionUserId(&condition, userId);
1557     if (authType != DEFAULT_AUTH_TYPE) {
1558         SetCredentialConditionAuthType(&condition, authType);
1559         SetCredentialConditionAbandonPin(&condition);
1560     }
1561 
1562     *creds = QueryCredentialLimit(&condition);
1563     if (*creds == NULL) {
1564         LOG_ERROR("query credential failed");
1565         return RESULT_UNKNOWN;
1566     }
1567     LOG_INFO("query abandon credential success");
1568     return RESULT_SUCCESS;
1569 }
1570 
GetCredentialByUserIdAndCredId(int32_t userId,uint64_t credentialId,CredentialInfoHal * credentialInfo)1571 ResultCode GetCredentialByUserIdAndCredId(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
1572 {
1573     UserInfo *user = QueryUserInfo(userId);
1574     if (user == NULL) {
1575         LOG_ERROR("user is null, usrId:%{public}d", userId);
1576         return RESULT_NOT_ENROLLED;
1577     }
1578 
1579     if (user->credentialInfoList == NULL) {
1580         LOG_ERROR("credentialInfoList is null, usrId:%{public}d", userId);
1581         return RESULT_NOT_ENROLLED;
1582     }
1583 
1584     CredentialInfoHal *temp = QueryCredentialById(credentialId, user->credentialInfoList);
1585     if (temp == NULL) {
1586         LOG_ERROR("QueryCredentialById failed, usrId:%{public}d", userId);
1587         return RESULT_NOT_ENROLLED;
1588     }
1589 
1590     if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), temp, sizeof(CredentialInfoHal)) != EOK) {
1591         LOG_ERROR("bad copy");
1592         return RESULT_BAD_COPY;
1593     }
1594 
1595     return RESULT_SUCCESS;
1596 }
1597 
FindCredential(UserInfo * user,CredentialInfoHal ** oldCredential,CredentialInfoHal ** curCredential,CredentialInfoHal ** newCredential)1598 IAM_STATIC void FindCredential(UserInfo *user, CredentialInfoHal **oldCredential,
1599     CredentialInfoHal **curCredential, CredentialInfoHal **newCredential)
1600 {
1601     LinkedListNode *temp = user->credentialInfoList->head;
1602     while (temp != NULL) {
1603         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
1604         if (nodeData == NULL) {
1605             temp = temp->next;
1606             continue;
1607         }
1608         if (nodeData->authType == PIN_AUTH && nodeData->isAbandoned) {
1609             *oldCredential = nodeData;
1610         }
1611         if (nodeData->authType == PIN_AUTH && !nodeData->isAbandoned) {
1612             *curCredential = nodeData;
1613         }
1614         if (nodeData->authType == DEFAULT_AUTH_TYPE) {
1615             *newCredential = nodeData;
1616         }
1617         temp = temp->next;
1618     }
1619     return;
1620 }
1621 
UpdateAbandonResultForReset(int32_t userId,bool * isDelete,CredentialInfoHal * credentialInfo)1622 ResultCode UpdateAbandonResultForReset(int32_t userId, bool *isDelete, CredentialInfoHal *credentialInfo)
1623 {
1624     UserInfo *user = QueryUserInfo(userId);
1625     if (user == NULL) {
1626         LOG_ERROR("user is null, usrId:%{public}d", userId);
1627         return RESULT_BAD_PARAM;
1628     }
1629 
1630     CredentialInfoHal *oldCredential = NULL;
1631     CredentialInfoHal *curCredential = NULL;
1632     CredentialInfoHal *newCredential = NULL;
1633     FindCredential(user, &oldCredential, &curCredential, &newCredential);
1634     if (oldCredential == NULL || curCredential == NULL || newCredential == NULL) {
1635         LOG_ERROR("oldCredential, curCredential or newCredential is not exist");
1636         return RESULT_GENERAL_ERROR;
1637     }
1638 
1639     *isDelete = true;
1640     *credentialInfo = *curCredential;
1641     uint64_t abandonTime = oldCredential->abandonedSysTime;
1642     oldCredential->abandonedSysTime = GetReeTime();
1643     curCredential->authType = DEFAULT_AUTH_TYPE;
1644     newCredential->authType = PIN_AUTH;
1645     SwitchSubType(user);
1646     ResultCode result = UpdateFileInfo(g_userInfoList);
1647     if (result == RESULT_SUCCESS) {
1648         LOG_INFO("switch cache pin success");
1649         ClearCachePin(user->userId);
1650         return result;
1651     }
1652     LOG_ERROR("switch cache pin fail");
1653     curCredential->authType = PIN_AUTH;
1654     newCredential->authType = DEFAULT_AUTH_TYPE;
1655     oldCredential->abandonedSysTime = abandonTime;
1656     SwitchSubType(user);
1657     *isDelete = false;
1658     return RESULT_GENERAL_ERROR;
1659 }
1660 
UpdateAbandonResultForUpdate(int32_t userId,bool * isDelete,CredentialInfoHal * credentialInfo)1661 ResultCode UpdateAbandonResultForUpdate(int32_t userId, bool *isDelete, CredentialInfoHal *credentialInfo)
1662 {
1663     UserInfo *user = QueryUserInfo(userId);
1664     if (user == NULL) {
1665         LOG_ERROR("user is null, usrId:%{public}d", userId);
1666         return RESULT_BAD_PARAM;
1667     }
1668 
1669     CredentialInfoHal *oldCredential = NULL;
1670     CredentialInfoHal *curCredential = NULL;
1671     CredentialInfoHal *newCredential = NULL;
1672     FindCredential(user, &oldCredential, &curCredential, &newCredential);
1673     if (curCredential == NULL || newCredential == NULL) {
1674         LOG_ERROR("curCredential or newCredential is not exist");
1675         return RESULT_GENERAL_ERROR;
1676     }
1677     newCredential->authType = PIN_AUTH;
1678     curCredential->isAbandoned = true;
1679     curCredential->abandonedSysTime = GetReeTime();
1680     if (oldCredential != NULL) {
1681         *isDelete = true;
1682         *credentialInfo = *oldCredential;
1683         oldCredential->authType = DEFAULT_AUTH_TYPE;
1684     }
1685 
1686     SwitchSubType(user);
1687     ResultCode result = UpdateFileInfo(g_userInfoList);
1688     if (result == RESULT_SUCCESS) {
1689         LOG_INFO("switch cache pin success");
1690         ClearCachePin(user->userId);
1691         return result;
1692     }
1693     LOG_ERROR("switch cache pin fail");
1694     curCredential->isAbandoned = false;
1695     curCredential->abandonedSysTime = 0;
1696     newCredential->authType = DEFAULT_AUTH_TYPE;
1697     if (oldCredential != NULL) {
1698         oldCredential->authType = PIN_AUTH;
1699     }
1700     SwitchSubType(user);
1701     *isDelete = false;
1702     return RESULT_GENERAL_ERROR;
1703 }
1704 
IsAbandonCredentialExpired(const CredentialInfoHal * credentialInfo)1705 bool IsAbandonCredentialExpired(const CredentialInfoHal *credentialInfo)
1706 {
1707     if (!credentialInfo->isAbandoned) {
1708         LOG_INFO("isAbandoned is false");
1709         return false;
1710     }
1711 
1712     uint64_t currentTime = GetReeTime();
1713     if (currentTime < credentialInfo->abandonedSysTime) {
1714         LOG_INFO("crdential abandoned time is error");
1715         return true;
1716     }
1717 
1718     if (currentTime > credentialInfo->abandonedSysTime &&
1719         currentTime - credentialInfo->abandonedSysTime > ABANDON_PIN_VALID_PERIOD) {
1720         LOG_INFO("crdential is abandoned");
1721         return true;
1722     }
1723 
1724     return false;
1725 }
1726 
CalcAbandonCredentialValidPeriod(const CredentialInfoHal * credentialInfo)1727 int64_t CalcAbandonCredentialValidPeriod(const CredentialInfoHal *credentialInfo)
1728 {
1729     LOG_INFO("start");
1730     if (IsAbandonCredentialExpired(credentialInfo)) {
1731         LOG_INFO("crdential is Expired");
1732         return 0;
1733     }
1734 
1735     if (credentialInfo->abandonedSysTime + ABANDON_PIN_VALID_PERIOD <= UINT64_MAX) {
1736         return credentialInfo->abandonedSysTime + ABANDON_PIN_VALID_PERIOD - GetReeTime();
1737     }
1738 
1739     return ABANDON_PIN_VALID_PERIOD;
1740 }
1741 
CalcCredentialValidPeriod(const CredentialInfoHal * credentialInfo)1742 int64_t CalcCredentialValidPeriod(const CredentialInfoHal *credentialInfo)
1743 {
1744     LOG_INFO("start");
1745     if (credentialInfo->isAbandoned) {
1746         return CalcAbandonCredentialValidPeriod(credentialInfo);
1747     }
1748 
1749     int64_t pinExpiredPeriod = 0;
1750     ResultCode ret = QueryPinExpiredInfo(&pinExpiredPeriod);
1751     if (ret != RESULT_SUCCESS) {
1752         LOG_INFO("QueryPinExpiredInfo fail, ret:%{public}u", ret);
1753         return 0;
1754     }
1755 
1756     if (pinExpiredPeriod == NO_CHECK_PIN_EXPIRED_PERIOD) {
1757         return NO_SET_PIN_EXPIRED_PERIOD;
1758     }
1759 
1760     uint64_t currentTime = GetReeTime();
1761     if (currentTime < credentialInfo->enrolledSysTime) {
1762         return 0;
1763     }
1764 
1765     if (currentTime > credentialInfo->enrolledSysTime &&
1766         currentTime - credentialInfo->enrolledSysTime >= (uint64_t)pinExpiredPeriod) {
1767         return 0;
1768     }
1769 
1770     if (UINT64_MAX - credentialInfo->enrolledSysTime >= (uint64_t)pinExpiredPeriod) {
1771         return (int64_t)(credentialInfo->enrolledSysTime + (uint64_t)pinExpiredPeriod - currentTime);
1772     }
1773 
1774     return pinExpiredPeriod;
1775 }
1776 
GetCredentialValidPeriod(int32_t userId,uint64_t credentialId)1777 int64_t GetCredentialValidPeriod(int32_t userId, uint64_t credentialId)
1778 {
1779     LOG_INFO("start");
1780     CredentialInfoHal credentialInfo = {};
1781     ResultCode ret = GetCredentialByUserIdAndCredId(userId, credentialId, &credentialInfo);
1782     if (ret != RESULT_SUCCESS) {
1783         LOG_INFO("GetCredentialByUserIdAndCredId fail, ret:%{public}u", ret);
1784         return 0;
1785     }
1786 
1787     return CalcCredentialValidPeriod(&credentialInfo);
1788 }
1789 
ClearAbandonExpiredCredential(int32_t userId,CredentialInfoHal * credentialInfo)1790 ResultCode ClearAbandonExpiredCredential(int32_t userId, CredentialInfoHal *credentialInfo)
1791 {
1792     LinkedList *credList = NULL;
1793     ResultCode ret = QueryAbandonCredential(userId, &credList);
1794     if (ret != RESULT_SUCCESS || credList == NULL) {
1795         LOG_ERROR("query credential failed");
1796         return RESULT_GENERAL_ERROR;
1797     }
1798     if (credList->head == NULL || credList->head->data == NULL) {
1799         LOG_ERROR("credential is null");
1800         DestroyLinkedList(credList);
1801         return RESULT_NOT_ENROLLED;
1802     }
1803     CredentialInfoHal *credentialHal = (CredentialInfoHal *)(credList->head->data);
1804     if (IsAbandonCredentialExpired(credentialHal)) {
1805         ret = DeleteCredentialInfo(userId, credentialHal->credentialId, credentialInfo);
1806         if (ret != RESULT_SUCCESS) {
1807             LOG_ERROR("delete database info failed");
1808             return RESULT_BAD_SIGN;
1809         }
1810     }
1811     return RESULT_SUCCESS;
1812 }