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