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