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