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