• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "idm_database.h"
17 
18 #include "securec.h"
19 
20 #include "adaptor_algorithm.h"
21 #include "adaptor_log.h"
22 #include "idm_file_manager.h"
23 
24 #define MAX_DUPLICATE_CHECK 100
25 #define PRE_APPLY_NUM 5
26 #define MEM_GROWTH_FACTOR 2
27 #define MAX_CREDENTIAL_RETURN 5000
28 
29 // Caches IDM user information.
30 static LinkedList *g_userInfoList = NULL;
31 
32 // Caches the current user to reduce the number of user list traversal times.
33 static UserInfo *g_currentUser = NULL;
34 
35 typedef bool (*DuplicateCheckFunc)(LinkedList *collection, uint64_t value);
36 
37 static UserInfo *QueryUserInfo(int32_t userId);
38 static ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num);
39 static ResultCode GetAllCredentialInfoFromUser(UserInfo *userInfo, CredentialInfoHal **credentialInfos, uint32_t *num);
40 static ResultCode DeleteUser(int32_t userId);
41 static CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList);
42 static CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList);
43 static bool MatchCredentialById(void *data, void *condition);
44 static ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func);
45 
InitUserInfoList(void)46 ResultCode InitUserInfoList(void)
47 {
48     if (g_userInfoList != NULL) {
49         DestroyUserInfoList();
50         g_userInfoList = NULL;
51     }
52     g_userInfoList = LoadFileInfo();
53     if (g_userInfoList == NULL) {
54         LOG_ERROR("load file info failed");
55         return RESULT_NEED_INIT;
56     }
57     LOG_INFO("InitUserInfoList done");
58     return RESULT_SUCCESS;
59 }
60 
DestroyUserInfoList(void)61 void DestroyUserInfoList(void)
62 {
63     DestroyLinkedList(g_userInfoList);
64     g_userInfoList = NULL;
65 }
66 
MatchUserInfo(void * data,void * condition)67 static bool MatchUserInfo(void *data, void *condition)
68 {
69     if (data == NULL || condition == NULL) {
70         LOG_ERROR("please check invalid node");
71         return false;
72     }
73     UserInfo *userInfo = (UserInfo *)data;
74     int32_t userId = *(int32_t *)condition;
75     if (userInfo->userId == userId) {
76         return true;
77     }
78     return false;
79 }
80 
IsUserInfoValid(UserInfo * userInfo)81 static bool IsUserInfoValid(UserInfo *userInfo)
82 {
83     if (userInfo == NULL) {
84         LOG_ERROR("userInfo is null");
85         return false;
86     }
87     if (userInfo->credentialInfoList == NULL) {
88         LOG_ERROR("credentialInfoList is null");
89         return false;
90     }
91     if (userInfo->enrolledInfoList == NULL) {
92         LOG_ERROR("enrolledInfoList is null");
93         return false;
94     }
95     return true;
96 }
97 
GetSecureUid(int32_t userId,uint64_t * secUid)98 ResultCode GetSecureUid(int32_t userId, uint64_t *secUid)
99 {
100     if (secUid == NULL) {
101         LOG_ERROR("secUid is null");
102         return RESULT_BAD_PARAM;
103     }
104     UserInfo *user = QueryUserInfo(userId);
105     if (user == NULL) {
106         LOG_ERROR("can't find this user");
107         return RESULT_NOT_FOUND;
108     }
109     *secUid = user->secUid;
110     return RESULT_SUCCESS;
111 }
112 
GetEnrolledInfoAuthType(int32_t userId,uint32_t authType,EnrolledInfoHal * enrolledInfo)113 ResultCode GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo)
114 {
115     if (enrolledInfo == NULL) {
116         LOG_ERROR("enrolledInfo is null");
117         return RESULT_BAD_PARAM;
118     }
119     UserInfo *user = QueryUserInfo(userId);
120     if (user == NULL) {
121         LOG_ERROR("can't find this user");
122         return RESULT_NOT_FOUND;
123     }
124     if (user->enrolledInfoList == NULL) {
125         LOG_ERROR("enrolledInfoList is null");
126         return RESULT_UNKNOWN;
127     }
128 
129     LinkedListNode *temp = user->enrolledInfoList->head;
130     while (temp != NULL) {
131         EnrolledInfoHal *nodeInfo = temp->data;
132         if (nodeInfo != NULL && nodeInfo->authType == authType) {
133             *enrolledInfo = *nodeInfo;
134             return RESULT_SUCCESS;
135         }
136         temp = temp->next;
137     }
138 
139     return RESULT_NOT_FOUND;
140 }
141 
GetEnrolledInfo(int32_t userId,EnrolledInfoHal ** enrolledInfos,uint32_t * num)142 ResultCode GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num)
143 {
144     if (enrolledInfos == NULL || num == NULL) {
145         LOG_ERROR("param is invalid");
146         return RESULT_BAD_PARAM;
147     }
148     UserInfo *user = QueryUserInfo(userId);
149     if (!IsUserInfoValid(user)) {
150         LOG_ERROR("can't find this user");
151         return RESULT_NOT_FOUND;
152     }
153     return GetAllEnrolledInfoFromUser(user, enrolledInfos, num);
154 }
155 
DeleteUserInfo(int32_t userId,CredentialInfoHal ** credentialInfos,uint32_t * num)156 ResultCode DeleteUserInfo(int32_t userId, CredentialInfoHal **credentialInfos, uint32_t *num)
157 {
158     if (credentialInfos == NULL || num == NULL) {
159         LOG_ERROR("param is invalid");
160         return RESULT_BAD_PARAM;
161     }
162     UserInfo *user = QueryUserInfo(userId);
163     if (!IsUserInfoValid(user)) {
164         LOG_ERROR("can't find this user1");
165         return RESULT_NOT_FOUND;
166     }
167     ResultCode ret = GetAllCredentialInfoFromUser(user, credentialInfos, num);
168     if (ret != RESULT_SUCCESS) {
169         LOG_ERROR("GetAllCredentialInfoFromUser failed");
170         return ret;
171     }
172     g_currentUser = NULL;
173 
174     ret = DeleteUser(userId);
175     if (ret != RESULT_SUCCESS) {
176         LOG_ERROR("deleteUser failed");
177         return ret;
178     }
179 
180     return UpdateFileInfo(g_userInfoList);
181 }
182 
QueryCredentialInfoAll(int32_t userId,CredentialInfoHal ** credentialInfos,uint32_t * num)183 ResultCode QueryCredentialInfoAll(int32_t userId, CredentialInfoHal **credentialInfos, uint32_t *num)
184 {
185     if (credentialInfos == NULL || num == NULL) {
186         LOG_ERROR("param is invalid");
187         return RESULT_BAD_PARAM;
188     }
189     UserInfo *user = QueryUserInfo(userId);
190     if (!IsUserInfoValid(user)) {
191         LOG_ERROR("can't find this user");
192         return RESULT_NOT_FOUND;
193     }
194     return GetAllCredentialInfoFromUser(user, credentialInfos, num);
195 }
196 
QueryUserInfo(int32_t userId)197 static UserInfo *QueryUserInfo(int32_t userId)
198 {
199     UserInfo *user = g_currentUser;
200     if (user != NULL && user->userId == userId) {
201         return user;
202     }
203     if (g_userInfoList == NULL) {
204         return NULL;
205     }
206     LinkedListNode *temp = g_userInfoList->head;
207     while (temp != NULL) {
208         user = (UserInfo *)temp->data;
209         if (user != NULL && user->userId == userId) {
210             break;
211         }
212         temp = temp->next;
213     }
214     if (temp == NULL) {
215         return NULL;
216     }
217     if (IsUserInfoValid(user)) {
218         g_currentUser = user;
219         return user;
220     }
221     return NULL;
222 }
223 
GetAllEnrolledInfoFromUser(UserInfo * userInfo,EnrolledInfoHal ** enrolledInfos,uint32_t * num)224 static ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num)
225 {
226     LinkedList *enrolledInfoList = userInfo->enrolledInfoList;
227     uint32_t size = enrolledInfoList->getSize(enrolledInfoList);
228     *enrolledInfos = Malloc(sizeof(EnrolledInfoHal) * size);
229     if (*enrolledInfos == NULL) {
230         LOG_ERROR("enrolledInfos malloc failed");
231         return RESULT_NO_MEMORY;
232     }
233     (void)memset_s(*enrolledInfos, sizeof(EnrolledInfoHal) * size, 0, sizeof(EnrolledInfoHal) * size);
234     LinkedListNode *temp = enrolledInfoList->head;
235     ResultCode result = RESULT_SUCCESS;
236     for (*num = 0; *num < size; (*num)++) {
237         if (temp == NULL) {
238             LOG_ERROR("temp node is null, something wrong");
239             result = RESULT_BAD_PARAM;
240             goto EXIT;
241         }
242         EnrolledInfoHal *tempInfo = (EnrolledInfoHal *)temp->data;
243         if (memcpy_s(*enrolledInfos + *num, sizeof(EnrolledInfoHal) * (size - *num),
244             tempInfo, sizeof(EnrolledInfoHal)) != EOK) {
245             LOG_ERROR("copy the %u information failed", *num);
246             result = RESULT_NO_MEMORY;
247             goto EXIT;
248         }
249         temp = temp->next;
250     }
251 
252 EXIT:
253     if (result != RESULT_SUCCESS) {
254         Free(*enrolledInfos);
255         *enrolledInfos = NULL;
256         *num = 0;
257     }
258     return result;
259 }
260 
GetAllCredentialInfoFromUser(UserInfo * userInfo,CredentialInfoHal ** credentialInfos,uint32_t * num)261 static ResultCode GetAllCredentialInfoFromUser(UserInfo *userInfo, CredentialInfoHal **credentialInfos, uint32_t *num)
262 {
263     LinkedList *credentialInfoList = userInfo->credentialInfoList;
264     uint32_t size = credentialInfoList->getSize(credentialInfoList);
265     *credentialInfos = Malloc(sizeof(CredentialInfoHal) * size);
266     if (*credentialInfos == NULL) {
267         LOG_ERROR("credentialInfos malloc failed");
268         return RESULT_NO_MEMORY;
269     }
270     (void)memset_s(*credentialInfos, sizeof(CredentialInfoHal) * size, 0, sizeof(CredentialInfoHal) * size);
271     LinkedListNode *temp = credentialInfoList->head;
272     ResultCode result = RESULT_SUCCESS;
273     for (*num = 0; *num < size; (*num)++) {
274         if (temp == NULL) {
275             LOG_ERROR("temp node is NULL, something wrong");
276             result = RESULT_BAD_PARAM;
277             goto EXIT;
278         }
279         CredentialInfoHal *tempInfo = (CredentialInfoHal *)temp->data;
280         if (memcpy_s((*credentialInfos) + *num, sizeof(CredentialInfoHal) * (size - *num),
281             tempInfo, sizeof(CredentialInfoHal)) != EOK) {
282             LOG_ERROR("copy the %u information failed", *num);
283             result = RESULT_NO_MEMORY;
284             goto EXIT;
285         }
286         temp = temp->next;
287     }
288 
289 EXIT:
290     if (result != RESULT_SUCCESS) {
291         (void)memset_s(*credentialInfos, sizeof(CredentialInfoHal) * size, 0, sizeof(CredentialInfoHal) * size);
292         Free(*credentialInfos);
293         *credentialInfos = NULL;
294         *num = 0;
295     }
296     return result;
297 }
298 
IsSecureUidDuplicate(LinkedList * userInfoList,uint64_t secureUid)299 static bool IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid)
300 {
301     if (userInfoList == NULL) {
302         LOG_ERROR("the user list is empty, and the branch is abnormal");
303         return false;
304     }
305 
306     LinkedListNode *temp = userInfoList->head;
307     UserInfo *userInfo = NULL;
308     while (temp != NULL) {
309         userInfo = (UserInfo *)temp->data;
310         if (userInfo != NULL && userInfo->secUid == secureUid) {
311             return true;
312         }
313         temp = temp->next;
314     }
315 
316     return false;
317 }
318 
CreateUser(int32_t userId)319 static UserInfo *CreateUser(int32_t userId)
320 {
321     UserInfo *user = InitUserInfoNode();
322     if (!IsUserInfoValid(user)) {
323         LOG_ERROR("user is invalid");
324         DestroyUserInfoNode(user);
325         return NULL;
326     }
327     user->userId = userId;
328     ResultCode ret = GenerateDeduplicateUint64(g_userInfoList, &user->secUid, IsSecureUidDuplicate);
329     if (ret != RESULT_SUCCESS) {
330         LOG_ERROR("generate secureUid failed");
331         DestroyUserInfoNode(user);
332         return NULL;
333     }
334     return user;
335 }
336 
DeleteUser(int32_t userId)337 static ResultCode DeleteUser(int32_t userId)
338 {
339     if (g_userInfoList == NULL) {
340         return RESULT_BAD_PARAM;
341     }
342     return g_userInfoList->remove(g_userInfoList, &userId, MatchUserInfo, true);
343 }
344 
IsCredentialIdDuplicate(LinkedList * credentialList,uint64_t credentialId)345 static bool IsCredentialIdDuplicate(LinkedList *credentialList, uint64_t credentialId)
346 {
347     LinkedListNode *temp = credentialList->head;
348     CredentialInfoHal *credentialInfo = NULL;
349     while (temp != NULL) {
350         credentialInfo = (CredentialInfoHal *)temp->data;
351         if (credentialInfo != NULL && credentialInfo->credentialId == credentialId) {
352             return true;
353         }
354         temp = temp->next;
355     }
356 
357     return false;
358 }
359 
IsEnrolledIdDuplicate(LinkedList * enrolledList,uint64_t enrolledId)360 static bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)
361 {
362     LinkedListNode *temp = enrolledList->head;
363     EnrolledInfoHal *enrolledInfo = NULL;
364     while (temp != NULL) {
365         enrolledInfo = (EnrolledInfoHal *)temp->data;
366         if (enrolledInfo != NULL && enrolledInfo->enrolledId == enrolledId) {
367             return true;
368         }
369         temp = temp->next;
370     }
371 
372     return false;
373 }
374 
GenerateDeduplicateUint64(LinkedList * collection,uint64_t * destValue,DuplicateCheckFunc func)375 static ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)
376 {
377     if (collection == NULL || destValue == NULL || func == NULL) {
378         LOG_ERROR("param is null");
379         return RESULT_BAD_PARAM;
380     }
381 
382     for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; i++) {
383         uint64_t tempRandom;
384         if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
385             LOG_ERROR("get random failed");
386             return RESULT_GENERAL_ERROR;
387         }
388         if (!func(collection, tempRandom)) {
389             *destValue = tempRandom;
390             return RESULT_SUCCESS;
391         }
392     }
393 
394     LOG_ERROR("generate random failed");
395     return RESULT_GENERAL_ERROR;
396 }
397 
UpdateEnrolledId(LinkedList * enrolledList,uint32_t authType)398 static ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)
399 {
400     LinkedListNode *temp = enrolledList->head;
401     EnrolledInfoHal *enrolledInfo = NULL;
402     while (temp != NULL) {
403         EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data;
404         if (nodeData != NULL && nodeData->authType == authType) {
405             enrolledInfo = nodeData;
406             break;
407         }
408         temp = temp->next;
409     }
410 
411     if (enrolledInfo != NULL) {
412         return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
413     }
414 
415     enrolledInfo = Malloc(sizeof(EnrolledInfoHal));
416     if (enrolledInfo == NULL) {
417         LOG_ERROR("enrolledInfo malloc failed");
418         return RESULT_NO_MEMORY;
419     }
420     enrolledInfo->authType = authType;
421     ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
422     if (ret != RESULT_SUCCESS) {
423         LOG_ERROR("generate enrolledId failed");
424         Free(enrolledInfo);
425         return ret;
426     }
427     ret = enrolledList->insert(enrolledList, enrolledInfo);
428     if (ret != RESULT_SUCCESS) {
429         LOG_ERROR("enrolledInfo insert failed");
430         Free(enrolledInfo);
431     }
432     return ret;
433 }
434 
AddCredentialToUser(UserInfo * user,CredentialInfoHal * credentialInfo)435 static ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)
436 {
437     LinkedList *credentialList = user->credentialInfoList;
438     LinkedList *enrolledList = user->enrolledInfoList;
439     if (enrolledList->getSize(enrolledList) > MAX_AUTH_TYPE
440         || credentialList->getSize(credentialList) >= MAX_CREDENTIAL) {
441         LOG_ERROR("the number of credentials reaches the maximum");
442         return RESULT_EXCEED_LIMIT;
443     }
444 
445     ResultCode ret = UpdateEnrolledId(enrolledList, credentialInfo->authType);
446     if (ret != RESULT_SUCCESS) {
447         LOG_ERROR("update enrolledId failed");
448         return ret;
449     }
450 
451     ret = GenerateDeduplicateUint64(credentialList, &credentialInfo->credentialId, IsCredentialIdDuplicate);
452     if (ret != RESULT_SUCCESS) {
453         LOG_ERROR("GenerateValidCredentialId failed");
454         return ret;
455     }
456     CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal));
457     if (credential == NULL) {
458         LOG_ERROR("credential malloc failed");
459         return RESULT_NO_MEMORY;
460     }
461     if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) {
462         LOG_ERROR("credential copy failed");
463         Free(credential);
464         return RESULT_BAD_COPY;
465     }
466     ret = credentialList->insert(credentialList, credential);
467     if (ret != RESULT_SUCCESS) {
468         LOG_ERROR("insert credential failed");
469         Free(credential);
470     }
471     return ret;
472 }
473 
AddUser(int32_t userId,CredentialInfoHal * credentialInfo)474 static ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo)
475 {
476     if (g_userInfoList == NULL) {
477         LOG_ERROR("please init");
478         return RESULT_NEED_INIT;
479     }
480     if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) {
481         LOG_ERROR("the number of users reaches the maximum");
482         return RESULT_EXCEED_LIMIT;
483     }
484 
485     UserInfo *user = QueryUserInfo(userId);
486     if (user != NULL) {
487         LOG_ERROR("Please check pin");
488         return RESULT_BAD_PARAM;
489     }
490 
491     user = CreateUser(userId);
492     if (user == NULL) {
493         LOG_ERROR("create user failed");
494         return RESULT_UNKNOWN;
495     }
496 
497     ResultCode ret = AddCredentialToUser(user, credentialInfo);
498     if (ret != RESULT_SUCCESS) {
499         LOG_ERROR("add credential to user failed");
500         goto FAIL;
501     }
502 
503     ret = g_userInfoList->insert(g_userInfoList, user);
504     if (ret != RESULT_SUCCESS) {
505         LOG_ERROR("insert failed");
506         goto FAIL;
507     }
508     return ret;
509 
510 FAIL:
511     DestroyUserInfoNode(user);
512     return ret;
513 }
514 
AddCredentialInfo(int32_t userId,CredentialInfoHal * credentialInfo)515 ResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo)
516 {
517     if (credentialInfo == NULL) {
518         LOG_ERROR("credentialInfo is null");
519         return RESULT_BAD_PARAM;
520     }
521     UserInfo *user = QueryUserInfo(userId);
522     if (user == NULL && credentialInfo->authType == PIN_AUTH) {
523         ResultCode ret =  AddUser(userId, credentialInfo);
524         if (ret != RESULT_SUCCESS) {
525             LOG_ERROR("add user failed");
526         }
527         ret = UpdateFileInfo(g_userInfoList);
528         if (ret != RESULT_SUCCESS) {
529             LOG_ERROR("updateFileInfo failed");
530         }
531         return ret;
532     }
533     if (user == NULL) {
534         LOG_ERROR("user is null");
535         return RESULT_BAD_PARAM;
536     }
537     if (credentialInfo->authType == PIN_AUTH) {
538         ResultCode ret = QueryCredentialInfo(userId, PIN_AUTH, credentialInfo);
539         if (ret != RESULT_NOT_FOUND) {
540             LOG_ERROR("double pin");
541             return RESULT_BAD_PARAM;
542         }
543     }
544     ResultCode ret = AddCredentialToUser(user, credentialInfo);
545     if (ret != RESULT_SUCCESS) {
546         LOG_ERROR("add credential to user failed");
547         return ret;
548     }
549     ret = UpdateFileInfo(g_userInfoList);
550     if (ret != RESULT_SUCCESS) {
551         LOG_ERROR("updateFileInfo failed");
552         return ret;
553     }
554     return ret;
555 }
556 
MatchCredentialById(void * data,void * condition)557 static bool MatchCredentialById(void *data, void *condition)
558 {
559     if (data == NULL || condition == NULL) {
560         return false;
561     }
562     CredentialInfoHal *credentialInfo = (CredentialInfoHal*)data;
563     uint64_t credentialId = *(uint64_t *)condition;
564     if (credentialInfo->credentialId == credentialId) {
565         return true;
566     }
567     return false;
568 }
569 
MatchEnrolledInfoByType(void * data,void * condition)570 static bool MatchEnrolledInfoByType(void *data, void *condition)
571 {
572     if (data == NULL || condition == NULL) {
573         return false;
574     }
575     EnrolledInfoHal *enrolledInfo = (EnrolledInfoHal *)data;
576     uint32_t authType = *(uint32_t *)condition;
577     if (enrolledInfo->authType == authType) {
578         return true;
579     }
580     return false;
581 }
582 
DeleteCredentialInfo(int32_t userId,uint64_t credentialId,CredentialInfoHal * credentialInfo)583 ResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
584 {
585     if (credentialInfo == NULL) {
586         LOG_ERROR("param is invalid");
587         return RESULT_BAD_PARAM;
588     }
589 
590     UserInfo *user = QueryUserInfo(userId);
591     if (user == NULL) {
592         LOG_ERROR("can't find this user");
593         return RESULT_BAD_PARAM;
594     }
595 
596     LinkedList *credentialList = user->credentialInfoList;
597     CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList);
598     if (credentialQuery == NULL) {
599         LOG_ERROR("credentialQuery is null");
600         return RESULT_UNKNOWN;
601     }
602     if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
603         LOG_ERROR("copy failed");
604         return RESULT_BAD_COPY;
605     }
606     ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true);
607     if (ret != RESULT_SUCCESS) {
608         LOG_ERROR("remove credential failed");
609         return ret;
610     }
611     credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList);
612     if (credentialQuery != NULL) {
613         return RESULT_SUCCESS;
614     }
615 
616     LinkedList *enrolledInfoList = user->enrolledInfoList;
617     if (enrolledInfoList == NULL) {
618         LOG_ERROR("enrolledInfoList is null");
619         return RESULT_UNKNOWN;
620     }
621     ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true);
622     if (ret != RESULT_SUCCESS) {
623         LOG_ERROR("remove enrolledInfo failed");
624         return ret;
625     }
626 
627     return UpdateFileInfo(g_userInfoList);
628 }
629 
QueryCredentialById(uint64_t credentialId,LinkedList * credentialList)630 static CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)
631 {
632     if (credentialList == NULL) {
633         return NULL;
634     }
635     LinkedListNode *temp = credentialList->head;
636     CredentialInfoHal *credentialInfo = NULL;
637     while (temp != NULL) {
638         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
639         if (nodeData != NULL && nodeData->credentialId == credentialId) {
640             credentialInfo = nodeData;
641             break;
642         }
643         temp = temp->next;
644     }
645     return credentialInfo;
646 }
647 
QueryCredentialByAuthType(uint32_t authType,LinkedList * credentialList)648 static CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)
649 {
650     if (credentialList == NULL) {
651         return NULL;
652     }
653     LinkedListNode *temp = credentialList->head;
654     CredentialInfoHal *credentialInfo = NULL;
655     while (temp != NULL) {
656         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
657         if (nodeData != NULL && nodeData->authType == authType) {
658             credentialInfo = nodeData;
659             break;
660         }
661         temp = temp->next;
662     }
663     return credentialInfo;
664 }
665 
QueryCredentialInfo(int32_t userId,uint32_t authType,CredentialInfoHal * credentialInfo)666 ResultCode QueryCredentialInfo(int32_t userId, uint32_t authType, CredentialInfoHal *credentialInfo)
667 {
668     UserInfo *user = QueryUserInfo(userId);
669     if (user == NULL) {
670         LOG_ERROR("can't find this user, userId is %{public}d", userId);
671         return RESULT_NOT_FOUND;
672     }
673     LinkedList *credentialList = user->credentialInfoList;
674     if (credentialList == NULL) {
675         LOG_ERROR("credentialList is null");
676         return RESULT_NOT_FOUND;
677     }
678     CredentialInfoHal *credentialQuery = QueryCredentialByAuthType(authType, credentialList);
679     if (credentialQuery == NULL) {
680         LOG_ERROR("credentialQuery is null");
681         return RESULT_NOT_FOUND;
682     }
683     if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
684         LOG_ERROR("copy credentialInfo failed");
685         return RESULT_BAD_COPY;
686     }
687     return RESULT_SUCCESS;
688 }
689 
QueryCredentialFromExecutor(uint32_t authType,CredentialInfoHal ** credentialInfos,uint32_t * num)690 ResultCode QueryCredentialFromExecutor(uint32_t authType, CredentialInfoHal **credentialInfos, uint32_t *num)
691 {
692     if (credentialInfos == NULL || num == NULL) {
693         LOG_ERROR("param is invalid");
694         return RESULT_BAD_PARAM;
695     }
696     if (g_userInfoList == NULL) {
697         return RESULT_NEED_INIT;
698     }
699     uint32_t preApplyNum = PRE_APPLY_NUM;
700     *credentialInfos = Malloc(preApplyNum * sizeof(CredentialInfoHal));
701     if (*credentialInfos == NULL) {
702         LOG_ERROR("no memory");
703         return RESULT_NO_MEMORY;
704     }
705     *num = 0;
706     LinkedListNode *temp = g_userInfoList->head;
707     while (temp != NULL) {
708         UserInfo *user = (UserInfo *)temp->data;
709         CredentialInfoHal *credentialQuery = QueryCredentialByAuthType(authType, user->credentialInfoList);
710         if (credentialQuery != NULL) {
711             (*num)++;
712             if (*num <= preApplyNum) {
713                 (*credentialInfos)[*num - 1] = *credentialQuery;
714                 temp = temp->next;
715                 continue;
716             }
717             if (preApplyNum * MEM_GROWTH_FACTOR > MAX_CREDENTIAL_RETURN) {
718                 LOG_ERROR("too large");
719                 Free(*credentialInfos);
720                 *credentialInfos = NULL;
721                 return RESULT_NO_MEMORY;
722             }
723             preApplyNum *= MEM_GROWTH_FACTOR;
724             CredentialInfoHal *credentialsTemp = Malloc(sizeof(CredentialInfoHal) * preApplyNum);
725             if (memcpy_s(credentialsTemp, sizeof(CredentialInfoHal) * preApplyNum,
726                 *credentialInfos, sizeof(CredentialInfoHal) * (*num - 1)) != EOK) {
727                 LOG_ERROR("copy failed");
728                 Free(credentialsTemp);
729                 Free(*credentialInfos);
730                 *credentialInfos = NULL;
731                 return RESULT_BAD_COPY;
732             }
733             Free(*credentialInfos);
734             *credentialInfos = credentialsTemp;
735             (*credentialInfos)[*num - 1] = *credentialQuery;
736         }
737         temp = temp->next;
738     }
739     return RESULT_SUCCESS;
740 }
741