• 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 #ifdef IAM_TEST_ENABLE
30 #define IAM_STATIC
31 #else
32 #define IAM_STATIC static
33 #endif
34 
35 // Caches IDM user information.
36 IAM_STATIC LinkedList *g_userInfoList = NULL;
37 
38 // Caches the current user to reduce the number of user list traversal times.
39 IAM_STATIC UserInfo *g_currentUser = NULL;
40 
41 typedef bool (*DuplicateCheckFunc)(LinkedList *collection, uint64_t value);
42 
43 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId);
44 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num);
45 IAM_STATIC ResultCode DeleteUser(int32_t userId);
46 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList);
47 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList);
48 IAM_STATIC bool MatchCredentialById(void *data, void *condition);
49 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func);
50 
InitUserInfoList(void)51 ResultCode InitUserInfoList(void)
52 {
53     LOG_INFO("InitUserInfoList start");
54     if (g_userInfoList != NULL) {
55         DestroyUserInfoList();
56         g_userInfoList = NULL;
57     }
58     g_userInfoList = LoadFileInfo();
59     if (g_userInfoList == NULL) {
60         LOG_ERROR("load file info failed");
61         return RESULT_NEED_INIT;
62     }
63     LOG_INFO("InitUserInfoList end");
64     return RESULT_SUCCESS;
65 }
66 
DestroyUserInfoList(void)67 void DestroyUserInfoList(void)
68 {
69     DestroyLinkedList(g_userInfoList);
70     g_userInfoList = NULL;
71 }
72 
MatchUserInfo(void * data,void * condition)73 IAM_STATIC bool MatchUserInfo(void *data, void *condition)
74 {
75     if (data == NULL || condition == NULL) {
76         LOG_ERROR("please check invalid node");
77         return false;
78     }
79     UserInfo *userInfo = (UserInfo *)data;
80     int32_t userId = *(int32_t *)condition;
81     if (userInfo->userId == userId) {
82         return true;
83     }
84     return false;
85 }
86 
IsUserInfoValid(UserInfo * userInfo)87 IAM_STATIC bool IsUserInfoValid(UserInfo *userInfo)
88 {
89     if (userInfo == NULL) {
90         LOG_ERROR("userInfo is null");
91         return false;
92     }
93     if (userInfo->credentialInfoList == NULL) {
94         LOG_ERROR("credentialInfoList is null");
95         return false;
96     }
97     if (userInfo->enrolledInfoList == NULL) {
98         LOG_ERROR("enrolledInfoList is null");
99         return false;
100     }
101     return true;
102 }
103 
GetSecureUid(int32_t userId,uint64_t * secUid)104 ResultCode GetSecureUid(int32_t userId, uint64_t *secUid)
105 {
106     if (secUid == NULL) {
107         LOG_ERROR("secUid is null");
108         return RESULT_BAD_PARAM;
109     }
110     UserInfo *user = QueryUserInfo(userId);
111     if (user == NULL) {
112         LOG_ERROR("can't find this user");
113         return RESULT_NOT_FOUND;
114     }
115     *secUid = user->secUid;
116     return RESULT_SUCCESS;
117 }
118 
GetEnrolledInfoAuthType(int32_t userId,uint32_t authType,EnrolledInfoHal * enrolledInfo)119 ResultCode GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo)
120 {
121     if (enrolledInfo == NULL) {
122         LOG_ERROR("enrolledInfo is null");
123         return RESULT_BAD_PARAM;
124     }
125     UserInfo *user = QueryUserInfo(userId);
126     if (user == NULL) {
127         LOG_ERROR("can't find this user");
128         return RESULT_NOT_FOUND;
129     }
130     if (user->enrolledInfoList == NULL) {
131         LOG_ERROR("enrolledInfoList is null");
132         return RESULT_UNKNOWN;
133     }
134 
135     LinkedListNode *temp = user->enrolledInfoList->head;
136     while (temp != NULL) {
137         EnrolledInfoHal *nodeInfo = temp->data;
138         if (nodeInfo != NULL && nodeInfo->authType == authType) {
139             *enrolledInfo = *nodeInfo;
140             return RESULT_SUCCESS;
141         }
142         temp = temp->next;
143     }
144 
145     return RESULT_NOT_FOUND;
146 }
147 
GetEnrolledInfo(int32_t userId,EnrolledInfoHal ** enrolledInfos,uint32_t * num)148 ResultCode GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num)
149 {
150     if (enrolledInfos == NULL || num == NULL) {
151         LOG_ERROR("param is invalid");
152         return RESULT_BAD_PARAM;
153     }
154     UserInfo *user = QueryUserInfo(userId);
155     if (!IsUserInfoValid(user)) {
156         LOG_ERROR("can't find this user");
157         return RESULT_NOT_FOUND;
158     }
159     return GetAllEnrolledInfoFromUser(user, enrolledInfos, num);
160 }
161 
DeleteUserInfo(int32_t userId,LinkedList ** creds)162 ResultCode DeleteUserInfo(int32_t userId, LinkedList **creds)
163 {
164     if (creds == NULL) {
165         LOG_ERROR("param is invalid");
166         return RESULT_BAD_PARAM;
167     }
168     UserInfo *user = QueryUserInfo(userId);
169     if (!IsUserInfoValid(user)) {
170         LOG_ERROR("can't find this user");
171         return RESULT_NOT_FOUND;
172     }
173     CredentialCondition condition = {};
174     SetCredentialConditionUserId(&condition, userId);
175     *creds = QueryCredentialLimit(&condition);
176     if (*creds == NULL) {
177         LOG_ERROR("query credential failed");
178         return RESULT_UNKNOWN;
179     }
180     g_currentUser = NULL;
181 
182     ResultCode ret = DeleteUser(userId);
183     if (ret != RESULT_SUCCESS) {
184         LOG_ERROR("deleteUser failed");
185         DestroyLinkedList(*creds);
186         *creds = NULL;
187         return ret;
188     }
189     ret = UpdateFileInfo(g_userInfoList);
190     if (ret != RESULT_SUCCESS) {
191         LOG_ERROR("update file info failed");
192         DestroyLinkedList(*creds);
193         *creds = NULL;
194         return ret;
195     }
196     return ret;
197 }
198 
QueryUserInfo(int32_t userId)199 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId)
200 {
201     UserInfo *user = g_currentUser;
202     if (user != NULL && user->userId == userId) {
203         return user;
204     }
205     if (g_userInfoList == NULL) {
206         return NULL;
207     }
208     LinkedListNode *temp = g_userInfoList->head;
209     while (temp != NULL) {
210         user = (UserInfo *)temp->data;
211         if (user != NULL && user->userId == userId) {
212             break;
213         }
214         temp = temp->next;
215     }
216     if (temp == NULL) {
217         return NULL;
218     }
219     if (IsUserInfoValid(user)) {
220         g_currentUser = user;
221         return user;
222     }
223     return NULL;
224 }
225 
GetAllEnrolledInfoFromUser(UserInfo * userInfo,EnrolledInfoHal ** enrolledInfos,uint32_t * num)226 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num)
227 {
228     LinkedList *enrolledInfoList = userInfo->enrolledInfoList;
229     uint32_t size = enrolledInfoList->getSize(enrolledInfoList);
230     *enrolledInfos = Malloc(sizeof(EnrolledInfoHal) * size);
231     if (*enrolledInfos == NULL) {
232         LOG_ERROR("enrolledInfos malloc failed");
233         return RESULT_NO_MEMORY;
234     }
235     (void)memset_s(*enrolledInfos, sizeof(EnrolledInfoHal) * size, 0, sizeof(EnrolledInfoHal) * size);
236     LinkedListNode *temp = enrolledInfoList->head;
237     ResultCode result = RESULT_SUCCESS;
238     for (*num = 0; *num < size; (*num)++) {
239         if (temp == NULL) {
240             LOG_ERROR("temp node is null, something wrong");
241             result = RESULT_BAD_PARAM;
242             goto EXIT;
243         }
244         EnrolledInfoHal *tempInfo = (EnrolledInfoHal *)temp->data;
245         if (memcpy_s(*enrolledInfos + *num, sizeof(EnrolledInfoHal) * (size - *num),
246             tempInfo, sizeof(EnrolledInfoHal)) != EOK) {
247             LOG_ERROR("copy the %u information failed", *num);
248             result = RESULT_NO_MEMORY;
249             goto EXIT;
250         }
251         temp = temp->next;
252     }
253 
254 EXIT:
255     if (result != RESULT_SUCCESS) {
256         Free(*enrolledInfos);
257         *enrolledInfos = NULL;
258         *num = 0;
259     }
260     return result;
261 }
262 
IsSecureUidDuplicate(LinkedList * userInfoList,uint64_t secureUid)263 IAM_STATIC bool IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid)
264 {
265     if (userInfoList == NULL) {
266         LOG_ERROR("the user list is empty, and the branch is abnormal");
267         return false;
268     }
269 
270     LinkedListNode *temp = userInfoList->head;
271     UserInfo *userInfo = NULL;
272     while (temp != NULL) {
273         userInfo = (UserInfo *)temp->data;
274         if (userInfo != NULL && userInfo->secUid == secureUid) {
275             return true;
276         }
277         temp = temp->next;
278     }
279 
280     return false;
281 }
282 
CreateUser(int32_t userId)283 IAM_STATIC UserInfo *CreateUser(int32_t userId)
284 {
285     UserInfo *user = InitUserInfoNode();
286     if (!IsUserInfoValid(user)) {
287         LOG_ERROR("user is invalid");
288         DestroyUserInfoNode(user);
289         return NULL;
290     }
291     user->userId = userId;
292     ResultCode ret = GenerateDeduplicateUint64(g_userInfoList, &user->secUid, IsSecureUidDuplicate);
293     if (ret != RESULT_SUCCESS) {
294         LOG_ERROR("generate secureUid failed");
295         DestroyUserInfoNode(user);
296         return NULL;
297     }
298     return user;
299 }
300 
DeleteUser(int32_t userId)301 IAM_STATIC ResultCode DeleteUser(int32_t userId)
302 {
303     if (g_userInfoList == NULL) {
304         return RESULT_BAD_PARAM;
305     }
306     return g_userInfoList->remove(g_userInfoList, &userId, MatchUserInfo, true);
307 }
308 
IsCredentialIdDuplicate(LinkedList * userInfoList,uint64_t credentialId)309 IAM_STATIC bool IsCredentialIdDuplicate(LinkedList *userInfoList, uint64_t credentialId)
310 {
311     (void)userInfoList;
312     CredentialCondition condition = {};
313     SetCredentialConditionCredentialId(&condition, credentialId);
314     LinkedList *credList = QueryCredentialLimit(&condition);
315     if (credList == NULL) {
316         LOG_ERROR("query failed");
317         return true;
318     }
319     if (credList->getSize(credList) != 0) {
320         LOG_ERROR("duplicate credential id");
321         DestroyLinkedList(credList);
322         return true;
323     }
324     DestroyLinkedList(credList);
325     return false;
326 }
327 
IsEnrolledIdDuplicate(LinkedList * enrolledList,uint64_t enrolledId)328 IAM_STATIC bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)
329 {
330     LinkedListNode *temp = enrolledList->head;
331     EnrolledInfoHal *enrolledInfo = NULL;
332     while (temp != NULL) {
333         enrolledInfo = (EnrolledInfoHal *)temp->data;
334         if (enrolledInfo != NULL && enrolledInfo->enrolledId == enrolledId) {
335             return true;
336         }
337         temp = temp->next;
338     }
339 
340     return false;
341 }
342 
GenerateDeduplicateUint64(LinkedList * collection,uint64_t * destValue,DuplicateCheckFunc func)343 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)
344 {
345     if (collection == NULL || destValue == NULL || func == NULL) {
346         LOG_ERROR("param is null");
347         return RESULT_BAD_PARAM;
348     }
349 
350     for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) {
351         uint64_t tempRandom;
352         if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
353             LOG_ERROR("get random failed");
354             return RESULT_GENERAL_ERROR;
355         }
356         if (!func(collection, tempRandom)) {
357             *destValue = tempRandom;
358             return RESULT_SUCCESS;
359         }
360     }
361 
362     LOG_ERROR("generate random failed");
363     return RESULT_GENERAL_ERROR;
364 }
365 
UpdateEnrolledId(LinkedList * enrolledList,uint32_t authType)366 IAM_STATIC ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)
367 {
368     LinkedListNode *temp = enrolledList->head;
369     EnrolledInfoHal *enrolledInfo = NULL;
370     while (temp != NULL) {
371         EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data;
372         if (nodeData != NULL && nodeData->authType == authType) {
373             enrolledInfo = nodeData;
374             break;
375         }
376         temp = temp->next;
377     }
378 
379     if (enrolledInfo != NULL) {
380         return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
381     }
382 
383     enrolledInfo = Malloc(sizeof(EnrolledInfoHal));
384     if (enrolledInfo == NULL) {
385         LOG_ERROR("enrolledInfo malloc failed");
386         return RESULT_NO_MEMORY;
387     }
388     enrolledInfo->authType = authType;
389     ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
390     if (ret != RESULT_SUCCESS) {
391         LOG_ERROR("generate enrolledId failed");
392         Free(enrolledInfo);
393         return ret;
394     }
395     ret = enrolledList->insert(enrolledList, enrolledInfo);
396     if (ret != RESULT_SUCCESS) {
397         LOG_ERROR("enrolledInfo insert failed");
398         Free(enrolledInfo);
399     }
400     return ret;
401 }
402 
AddCredentialToUser(UserInfo * user,CredentialInfoHal * credentialInfo)403 IAM_STATIC ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)
404 {
405     if (g_userInfoList == NULL) {
406         LOG_ERROR("g_userInfoList is uninitialized");
407         return RESULT_NEED_INIT;
408     }
409     LinkedList *credentialList = user->credentialInfoList;
410     LinkedList *enrolledList = user->enrolledInfoList;
411     if (credentialList->getSize(credentialList) >= MAX_CREDENTIAL) {
412         LOG_ERROR("the number of credentials reaches the maximum");
413         return RESULT_EXCEED_LIMIT;
414     }
415 
416     ResultCode ret = UpdateEnrolledId(enrolledList, credentialInfo->authType);
417     if (ret != RESULT_SUCCESS) {
418         LOG_ERROR("update enrolledId failed");
419         return ret;
420     }
421     ret = GenerateDeduplicateUint64(g_userInfoList, &credentialInfo->credentialId, IsCredentialIdDuplicate);
422     if (ret != RESULT_SUCCESS) {
423         LOG_ERROR("GenerateDeduplicateUint64 failed");
424         return ret;
425     }
426     CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal));
427     if (credential == NULL) {
428         LOG_ERROR("credential malloc failed");
429         return RESULT_NO_MEMORY;
430     }
431     if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) {
432         LOG_ERROR("credential copy failed");
433         Free(credential);
434         return RESULT_BAD_COPY;
435     }
436     ret = credentialList->insert(credentialList, credential);
437     if (ret != RESULT_SUCCESS) {
438         LOG_ERROR("insert credential failed");
439         Free(credential);
440     }
441     return ret;
442 }
443 
AddUser(int32_t userId,CredentialInfoHal * credentialInfo)444 IAM_STATIC ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo)
445 {
446     if (g_userInfoList == NULL) {
447         LOG_ERROR("please init");
448         return RESULT_NEED_INIT;
449     }
450     if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) {
451         LOG_ERROR("the number of users reaches the maximum");
452         return RESULT_EXCEED_LIMIT;
453     }
454 
455     UserInfo *user = QueryUserInfo(userId);
456     if (user != NULL) {
457         LOG_ERROR("Please check pin");
458         return RESULT_BAD_PARAM;
459     }
460 
461     user = CreateUser(userId);
462     if (user == NULL) {
463         LOG_ERROR("create user failed");
464         return RESULT_UNKNOWN;
465     }
466 
467     ResultCode ret = AddCredentialToUser(user, credentialInfo);
468     if (ret != RESULT_SUCCESS) {
469         LOG_ERROR("add credential to user failed");
470         goto FAIL;
471     }
472 
473     ret = g_userInfoList->insert(g_userInfoList, user);
474     if (ret != RESULT_SUCCESS) {
475         LOG_ERROR("insert failed");
476         goto FAIL;
477     }
478     return ret;
479 
480 FAIL:
481     DestroyUserInfoNode(user);
482     return ret;
483 }
484 
AddCredentialInfo(int32_t userId,CredentialInfoHal * credentialInfo)485 ResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo)
486 {
487     if (credentialInfo == NULL) {
488         LOG_ERROR("credentialInfo is null");
489         return RESULT_BAD_PARAM;
490     }
491     UserInfo *user = QueryUserInfo(userId);
492     if (user == NULL && credentialInfo->authType == PIN_AUTH) {
493         ResultCode ret = AddUser(userId, credentialInfo);
494         if (ret != RESULT_SUCCESS) {
495             LOG_ERROR("add user failed");
496             return ret;
497         }
498         ret = UpdateFileInfo(g_userInfoList);
499         if (ret != RESULT_SUCCESS) {
500             LOG_ERROR("updateFileInfo failed");
501         }
502         return ret;
503     }
504     if (user == NULL) {
505         LOG_ERROR("user is null");
506         return RESULT_BAD_PARAM;
507     }
508     if (credentialInfo->authType == PIN_AUTH) {
509         CredentialCondition condition = {};
510         SetCredentialConditionAuthType(&condition, PIN_AUTH);
511         SetCredentialConditionUserId(&condition, userId);
512         LinkedList *credList = QueryCredentialLimit(&condition);
513         if (credList == NULL) {
514             LOG_ERROR("query credential failed");
515             return RESULT_UNKNOWN;
516         }
517         if (credList->getSize(credList) != 0) {
518             LOG_ERROR("double pin");
519             DestroyLinkedList(credList);
520             return RESULT_BAD_PARAM;
521         }
522         DestroyLinkedList(credList);
523     }
524     ResultCode ret = AddCredentialToUser(user, credentialInfo);
525     if (ret != RESULT_SUCCESS) {
526         LOG_ERROR("add credential to user failed");
527         return ret;
528     }
529     ret = UpdateFileInfo(g_userInfoList);
530     if (ret != RESULT_SUCCESS) {
531         LOG_ERROR("updateFileInfo failed");
532     }
533     return ret;
534 }
535 
MatchCredentialById(void * data,void * condition)536 IAM_STATIC bool MatchCredentialById(void *data, void *condition)
537 {
538     if (data == NULL || condition == NULL) {
539         return false;
540     }
541     CredentialInfoHal *credentialInfo = (CredentialInfoHal*)data;
542     uint64_t credentialId = *(uint64_t *)condition;
543     if (credentialInfo->credentialId == credentialId) {
544         return true;
545     }
546     return false;
547 }
548 
MatchEnrolledInfoByType(void * data,void * condition)549 IAM_STATIC bool MatchEnrolledInfoByType(void *data, void *condition)
550 {
551     if (data == NULL || condition == NULL) {
552         return false;
553     }
554     EnrolledInfoHal *enrolledInfo = (EnrolledInfoHal *)data;
555     uint32_t authType = *(uint32_t *)condition;
556     if (enrolledInfo->authType == authType) {
557         return true;
558     }
559     return false;
560 }
561 
DeleteCredentialInfo(int32_t userId,uint64_t credentialId,CredentialInfoHal * credentialInfo)562 ResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
563 {
564     if (credentialInfo == NULL) {
565         LOG_ERROR("param is invalid");
566         return RESULT_BAD_PARAM;
567     }
568 
569     UserInfo *user = QueryUserInfo(userId);
570     if (user == NULL) {
571         LOG_ERROR("can't find this user");
572         return RESULT_BAD_PARAM;
573     }
574 
575     LinkedList *credentialList = user->credentialInfoList;
576     CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList);
577     if (credentialQuery == NULL) {
578         LOG_ERROR("credentialQuery is null");
579         return RESULT_UNKNOWN;
580     }
581     if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
582         LOG_ERROR("copy failed");
583         return RESULT_BAD_COPY;
584     }
585     ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true);
586     if (ret != RESULT_SUCCESS) {
587         LOG_ERROR("remove credential failed");
588         return ret;
589     }
590     credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList);
591     if (credentialQuery != NULL) {
592         return UpdateFileInfo(g_userInfoList);
593     }
594 
595     LinkedList *enrolledInfoList = user->enrolledInfoList;
596     if (enrolledInfoList == NULL) {
597         LOG_ERROR("enrolledInfoList is null");
598         return RESULT_UNKNOWN;
599     }
600     ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true);
601     if (ret != RESULT_SUCCESS) {
602         LOG_ERROR("remove enrolledInfo failed");
603         return ret;
604     }
605 
606     return UpdateFileInfo(g_userInfoList);
607 }
608 
QueryCredentialById(uint64_t credentialId,LinkedList * credentialList)609 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)
610 {
611     if (credentialList == NULL) {
612         return NULL;
613     }
614     LinkedListNode *temp = credentialList->head;
615     CredentialInfoHal *credentialInfo = NULL;
616     while (temp != NULL) {
617         CredentialInfoHal *nodeData = (CredentialInfoHal *)temp->data;
618         if (nodeData != NULL && nodeData->credentialId == credentialId) {
619             credentialInfo = nodeData;
620             break;
621         }
622         temp = temp->next;
623     }
624     return credentialInfo;
625 }
626 
QueryCredentialByAuthType(uint32_t authType,LinkedList * credentialList)627 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)
628 {
629     if (credentialList == NULL) {
630         return NULL;
631     }
632     LinkedListNode *temp = credentialList->head;
633     CredentialInfoHal *credentialInfo = NULL;
634     while (temp != NULL) {
635         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
636         if (nodeData != NULL && nodeData->authType == authType) {
637             credentialInfo = nodeData;
638             break;
639         }
640         temp = temp->next;
641     }
642     return credentialInfo;
643 }
644 
IsCredMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)645 IAM_STATIC bool IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
646 {
647     if ((limit->conditionFactor & CREDENTIAL_CONDITION_CREDENTIAL_ID) != 0 &&
648         limit->credentialId != credentialInfo->credentialId) {
649         return false;
650     }
651     if ((limit->conditionFactor & CREDENTIAL_CONDITION_AUTH_TYPE) != 0 && limit->authType != credentialInfo->authType) {
652         return false;
653     }
654     if ((limit->conditionFactor & CREDENTIAL_CONDITION_TEMPLATE_ID) != 0 &&
655         limit->templateId != credentialInfo->templateId) {
656         return false;
657     }
658     if ((limit->conditionFactor & CREDENTIAL_CONDITION_SENSOR_HINT) != 0 &&
659         limit->executorSensorHint != INVALID_SENSOR_HINT &&
660         limit->executorSensorHint != credentialInfo->executorSensorHint) {
661         return false;
662     }
663     if ((limit->conditionFactor & CREDENTIAL_CONDITION_EXECUTOR_MATCHER) != 0 &&
664         limit->executorMatcher != credentialInfo->executorMatcher) {
665         return false;
666     }
667     return true;
668 }
669 
IsUserMatch(const CredentialCondition * limit,const UserInfo * user)670 IAM_STATIC bool IsUserMatch(const CredentialCondition *limit, const UserInfo *user)
671 {
672     if ((limit->conditionFactor & CREDENTIAL_CONDITION_USER_ID) != 0 && limit->userId != user->userId) {
673         return false;
674     }
675     return true;
676 }
677 
TraverseCredentialList(const CredentialCondition * limit,const LinkedList * credentialList,LinkedList * credListGet)678 IAM_STATIC ResultCode TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList,
679     LinkedList *credListGet)
680 {
681     if (credentialList == NULL) {
682         LOG_ERROR("credentialList is null");
683         return RESULT_GENERAL_ERROR;
684     }
685     LinkedListNode *temp = credentialList->head;
686     while (temp != NULL) {
687         CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
688         if (nodeData == NULL) {
689             LOG_ERROR("nodeData is null");
690             return RESULT_UNKNOWN;
691         }
692         if (!IsCredMatch(limit, nodeData)) {
693             temp = temp->next;
694             continue;
695         }
696         CredentialInfoHal *copy = (CredentialInfoHal *)Malloc(sizeof(CredentialInfoHal));
697         if (copy == NULL) {
698             LOG_ERROR("copy malloc failed");
699             return RESULT_NO_MEMORY;
700         }
701         *copy = *nodeData;
702         ResultCode ret = credListGet->insert(credListGet, copy);
703         if (ret != RESULT_SUCCESS) {
704             LOG_ERROR("insert failed");
705             Free(copy);
706             return ret;
707         }
708         temp = temp->next;
709     }
710     return RESULT_SUCCESS;
711 }
712 
QueryCredentialLimit(const CredentialCondition * limit)713 LinkedList *QueryCredentialLimit(const CredentialCondition *limit)
714 {
715     if (limit == NULL) {
716         LOG_ERROR("limit is null");
717         return NULL;
718     }
719     if (g_userInfoList == NULL) {
720         LOG_ERROR("g_userInfoList is null");
721         return NULL;
722     }
723     LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
724     if (credList == NULL) {
725         LOG_ERROR("credList is null");
726         return NULL;
727     }
728     LinkedListNode *temp = g_userInfoList->head;
729     while (temp != NULL) {
730         UserInfo *user = (UserInfo *)temp->data;
731         if (user == NULL) {
732             LOG_ERROR("node data is null");
733             DestroyLinkedList(credList);
734             return NULL;
735         }
736         if (IsUserMatch(limit, user)) {
737             ResultCode ret = TraverseCredentialList(limit, user->credentialInfoList, credList);
738             if (ret != RESULT_SUCCESS) {
739                 LOG_ERROR("TraverseCredentialList failed");
740                 DestroyLinkedList(credList);
741                 return NULL;
742             }
743         }
744         temp = temp->next;
745     }
746     return credList;
747 }
748 
QueryCredentialUserId(uint64_t credentialId,int32_t * userId)749 ResultCode QueryCredentialUserId(uint64_t credentialId, int32_t *userId)
750 {
751     if (userId == NULL) {
752         LOG_ERROR("userId is null");
753         return RESULT_BAD_PARAM;
754     }
755     if (g_userInfoList == NULL) {
756         LOG_ERROR("g_userInfoList is null");
757         return RESULT_NEED_INIT;
758     }
759     LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
760     if (credList == NULL) {
761         LOG_ERROR("credList is null");
762         return RESULT_NO_MEMORY;
763     }
764     LinkedListNode *temp = g_userInfoList->head;
765     CredentialCondition condition = {};
766     SetCredentialConditionCredentialId(&condition, credentialId);
767     while (temp != NULL) {
768         UserInfo *user = (UserInfo *)temp->data;
769         if (user == NULL) {
770             LOG_ERROR("user is null");
771             DestroyLinkedList(credList);
772             return RESULT_UNKNOWN;
773         }
774         ResultCode ret = TraverseCredentialList(&condition, user->credentialInfoList, credList);
775         if (ret != RESULT_SUCCESS) {
776             LOG_ERROR("TraverseCredentialList failed");
777             DestroyLinkedList(credList);
778             return RESULT_UNKNOWN;
779         }
780         if (credList->getSize(credList) != 0) {
781             DestroyLinkedList(credList);
782             *userId = user->userId;
783             return RESULT_SUCCESS;
784         }
785         temp = temp->next;
786     }
787     DestroyLinkedList(credList);
788     LOG_ERROR("can't find this credential");
789     return RESULT_NOT_FOUND;
790 }
791 
SetPinSubType(int32_t userId,uint64_t pinSubType)792 ResultCode SetPinSubType(int32_t userId, uint64_t pinSubType)
793 {
794     UserInfo *user = QueryUserInfo(userId);
795     if (user == NULL) {
796         LOG_ERROR("can't find this user");
797         return RESULT_NOT_FOUND;
798     }
799     user->pinSubType = pinSubType;
800     return RESULT_SUCCESS;
801 }
802 
GetPinSubType(int32_t userId,uint64_t * pinSubType)803 ResultCode GetPinSubType(int32_t userId, uint64_t *pinSubType)
804 {
805     if (pinSubType == NULL) {
806         LOG_ERROR("pinSubType is null");
807         return RESULT_BAD_PARAM;
808     }
809     UserInfo *user = QueryUserInfo(userId);
810     if (user == NULL) {
811         LOG_ERROR("can't find this user");
812         return RESULT_NOT_FOUND;
813     }
814     *pinSubType = user->pinSubType;
815     return RESULT_SUCCESS;
816 }
817 
SetCredentialConditionCredentialId(CredentialCondition * condition,uint64_t credentialId)818 void SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId)
819 {
820     if (condition == NULL) {
821         LOG_ERROR("condition is null");
822         return;
823     }
824     condition->credentialId = credentialId;
825     condition->conditionFactor |= CREDENTIAL_CONDITION_CREDENTIAL_ID;
826 }
827 
SetCredentialConditionTemplateId(CredentialCondition * condition,uint64_t templateId)828 void SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId)
829 {
830     if (condition == NULL) {
831         LOG_ERROR("condition is null");
832         return;
833     }
834     condition->templateId = templateId;
835     condition->conditionFactor |= CREDENTIAL_CONDITION_TEMPLATE_ID;
836 }
837 
SetCredentialConditionAuthType(CredentialCondition * condition,uint32_t authType)838 void SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType)
839 {
840     if (condition == NULL) {
841         LOG_ERROR("condition is null");
842         return;
843     }
844     condition->authType = authType;
845     condition->conditionFactor |= CREDENTIAL_CONDITION_AUTH_TYPE;
846 }
847 
SetCredentialConditionExecutorSensorHint(CredentialCondition * condition,uint32_t executorSensorHint)848 void SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint)
849 {
850     if (condition == NULL) {
851         LOG_ERROR("condition is null");
852         return;
853     }
854     condition->executorSensorHint = executorSensorHint;
855     condition->conditionFactor |= CREDENTIAL_CONDITION_SENSOR_HINT;
856 }
857 
SetCredentialConditionExecutorMatcher(CredentialCondition * condition,uint32_t executorMatcher)858 void SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher)
859 {
860     if (condition == NULL) {
861         LOG_ERROR("condition is null");
862         return;
863     }
864     condition->executorMatcher = executorMatcher;
865     condition->conditionFactor |= CREDENTIAL_CONDITION_EXECUTOR_MATCHER;
866 }
867 
SetCredentialConditionUserId(CredentialCondition * condition,int32_t userId)868 void SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId)
869 {
870     if (condition == NULL) {
871         LOG_ERROR("condition is null");
872         return;
873     }
874     condition->userId = userId;
875     condition->conditionFactor |= CREDENTIAL_CONDITION_USER_ID;
876 }
877