1 /*
2 * Copyright (C) 2022-2024 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 "inttypes.h"
19 #include "securec.h"
20
21 #include "adaptor_algorithm.h"
22 #include "adaptor_log.h"
23 #include "adaptor_time.h"
24 #include "idm_file_manager.h"
25
26 #define MAX_DUPLICATE_CHECK 100
27 #define PRE_APPLY_NUM 5
28 #define MEM_GROWTH_FACTOR 2
29 #define MAX_CREDENTIAL_RETURN 5000
30
31 #ifdef IAM_TEST_ENABLE
32 #define IAM_STATIC
33 #else
34 #define IAM_STATIC static
35 #endif
36
37 // Caches IDM user information.
38 IAM_STATIC LinkedList *g_userInfoList = NULL;
39
40 // Caches the current user to reduce the number of user list traversal times.
41 IAM_STATIC UserInfo *g_currentUser = NULL;
42
43 // Caches global config info.
44 IAM_STATIC GlobalConfigParamHal g_globalConfigArray[MAX_GLOBAL_CONFIG_NUM];
45 IAM_STATIC uint32_t g_globalConfigInfoNum = 0;
46
47 typedef bool (*DuplicateCheckFunc)(LinkedList *collection, uint64_t value);
48
49 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId);
50 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num);
51 IAM_STATIC ResultCode DeleteUser(int32_t userId);
52 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList);
53 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList);
54 IAM_STATIC bool MatchCredentialById(const void *data, const void *condition);
55 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func);
56 IAM_STATIC bool IsUserValid(UserInfo *user);
57 IAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
58 bool *cachePinRemoved);
59 IAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved);
60 IAM_STATIC ResultCode ClearInvalidData(void);
61
InitUserInfoList(void)62 ResultCode InitUserInfoList(void)
63 {
64 LOG_INFO("InitUserInfoList start");
65 if (g_userInfoList != NULL) {
66 DestroyUserInfoList();
67 g_userInfoList = NULL;
68 }
69 g_userInfoList = LoadFileInfo();
70 if (g_userInfoList == NULL) {
71 LOG_ERROR("load file info failed");
72 return RESULT_NEED_INIT;
73 }
74 ResultCode ret = ClearInvalidData();
75 if (ret != RESULT_SUCCESS) {
76 LOG_ERROR("clear invalid user failed");
77 DestroyUserInfoList();
78 return ret;
79 }
80 ret = LoadGlobalConfigInfo(g_globalConfigArray, MAX_GLOBAL_CONFIG_NUM, &g_globalConfigInfoNum);
81 if (ret != RESULT_SUCCESS) {
82 LOG_ERROR("load global config info failed");
83 }
84 LOG_INFO("InitUserInfoList end");
85 return RESULT_SUCCESS;
86 }
87
DestroyUserInfoList(void)88 void DestroyUserInfoList(void)
89 {
90 DestroyLinkedList(g_userInfoList);
91 g_userInfoList = NULL;
92 }
93
MatchUserInfo(const void * data,const void * condition)94 IAM_STATIC bool MatchUserInfo(const void *data, const void *condition)
95 {
96 if (data == NULL || condition == NULL) {
97 LOG_ERROR("please check invalid node");
98 return false;
99 }
100 const UserInfo *userInfo = (const UserInfo *)data;
101 int32_t userId = *(const int32_t *)condition;
102 if (userInfo->userId == userId) {
103 return true;
104 }
105 return false;
106 }
107
IsUserInfoValid(UserInfo * userInfo)108 IAM_STATIC bool IsUserInfoValid(UserInfo *userInfo)
109 {
110 if (userInfo == NULL) {
111 LOG_ERROR("userInfo is null");
112 return false;
113 }
114 if (userInfo->credentialInfoList == NULL) {
115 LOG_ERROR("credentialInfoList is null");
116 return false;
117 }
118 if (userInfo->enrolledInfoList == NULL) {
119 LOG_ERROR("enrolledInfoList is null");
120 return false;
121 }
122 return true;
123 }
124
GetSecureUid(int32_t userId,uint64_t * secUid)125 ResultCode GetSecureUid(int32_t userId, uint64_t *secUid)
126 {
127 if (secUid == NULL) {
128 LOG_ERROR("secUid is null");
129 return RESULT_BAD_PARAM;
130 }
131 UserInfo *user = QueryUserInfo(userId);
132 if (user == NULL) {
133 LOG_ERROR("can't find this user");
134 return RESULT_NOT_FOUND;
135 }
136 *secUid = user->secUid;
137 return RESULT_SUCCESS;
138 }
139
GetEnrolledInfoAuthType(int32_t userId,uint32_t authType,EnrolledInfoHal * enrolledInfo)140 ResultCode GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo)
141 {
142 if (enrolledInfo == NULL) {
143 LOG_ERROR("enrolledInfo is null");
144 return RESULT_BAD_PARAM;
145 }
146 UserInfo *user = QueryUserInfo(userId);
147 if (user == NULL) {
148 LOG_ERROR("can't find this user");
149 return RESULT_NOT_FOUND;
150 }
151 if (user->enrolledInfoList == NULL) {
152 LOG_ERROR("enrolledInfoList is null");
153 return RESULT_UNKNOWN;
154 }
155
156 LinkedListNode *temp = user->enrolledInfoList->head;
157 while (temp != NULL) {
158 EnrolledInfoHal *nodeInfo = temp->data;
159 if (nodeInfo != NULL && nodeInfo->authType == authType) {
160 *enrolledInfo = *nodeInfo;
161 return RESULT_SUCCESS;
162 }
163 temp = temp->next;
164 }
165
166 return RESULT_NOT_FOUND;
167 }
168
GetEnrolledInfo(int32_t userId,EnrolledInfoHal ** enrolledInfos,uint32_t * num)169 ResultCode GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num)
170 {
171 if (enrolledInfos == NULL || num == NULL) {
172 LOG_ERROR("param is invalid");
173 return RESULT_BAD_PARAM;
174 }
175 UserInfo *user = QueryUserInfo(userId);
176 if (!IsUserInfoValid(user)) {
177 LOG_ERROR("can't find this user");
178 return RESULT_NOT_FOUND;
179 }
180 return GetAllEnrolledInfoFromUser(user, enrolledInfos, num);
181 }
182
DeleteUserInfo(int32_t userId,LinkedList ** creds)183 ResultCode DeleteUserInfo(int32_t userId, LinkedList **creds)
184 {
185 if (creds == 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 CredentialCondition condition = {};
195 SetCredentialConditionUserId(&condition, userId);
196 *creds = QueryCredentialLimit(&condition);
197 if (*creds == NULL) {
198 LOG_ERROR("query credential failed");
199 return RESULT_UNKNOWN;
200 }
201 g_currentUser = NULL;
202
203 ResultCode ret = DeleteUser(userId);
204 if (ret != RESULT_SUCCESS) {
205 LOG_ERROR("deleteUser failed");
206 DestroyLinkedList(*creds);
207 *creds = NULL;
208 return ret;
209 }
210 ret = UpdateFileInfo(g_userInfoList);
211 if (ret != RESULT_SUCCESS) {
212 LOG_ERROR("update file info failed");
213 DestroyLinkedList(*creds);
214 *creds = NULL;
215 return ret;
216 }
217 return ret;
218 }
219
QueryUserInfo(int32_t userId)220 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId)
221 {
222 UserInfo *user = g_currentUser;
223 if (user != NULL && user->userId == userId) {
224 return user;
225 }
226 if (g_userInfoList == NULL) {
227 return NULL;
228 }
229 LinkedListNode *temp = g_userInfoList->head;
230 while (temp != NULL) {
231 user = (UserInfo *)temp->data;
232 if (user != NULL && user->userId == userId) {
233 break;
234 }
235 temp = temp->next;
236 }
237 if (temp == NULL) {
238 return NULL;
239 }
240 if (IsUserInfoValid(user)) {
241 g_currentUser = user;
242 return user;
243 }
244 return NULL;
245 }
246
GetAllEnrolledInfoFromUser(UserInfo * userInfo,EnrolledInfoHal ** enrolledInfos,uint32_t * num)247 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num)
248 {
249 LinkedList *enrolledInfoList = userInfo->enrolledInfoList;
250 uint32_t size = enrolledInfoList->getSize(enrolledInfoList);
251 *enrolledInfos = Malloc(sizeof(EnrolledInfoHal) * size);
252 if (*enrolledInfos == NULL) {
253 LOG_ERROR("enrolledInfos malloc failed");
254 return RESULT_NO_MEMORY;
255 }
256 (void)memset_s(*enrolledInfos, sizeof(EnrolledInfoHal) * size, 0, sizeof(EnrolledInfoHal) * size);
257 LinkedListNode *temp = enrolledInfoList->head;
258 ResultCode result = RESULT_SUCCESS;
259 for (*num = 0; *num < size; (*num)++) {
260 if (temp == NULL) {
261 LOG_ERROR("temp node is null, something wrong");
262 result = RESULT_BAD_PARAM;
263 goto EXIT;
264 }
265 EnrolledInfoHal *tempInfo = (EnrolledInfoHal *)temp->data;
266 if (memcpy_s(*enrolledInfos + *num, sizeof(EnrolledInfoHal) * (size - *num),
267 tempInfo, sizeof(EnrolledInfoHal)) != EOK) {
268 LOG_ERROR("copy the %u information failed", *num);
269 result = RESULT_NO_MEMORY;
270 goto EXIT;
271 }
272 temp = temp->next;
273 }
274
275 EXIT:
276 if (result != RESULT_SUCCESS) {
277 Free(*enrolledInfos);
278 *enrolledInfos = NULL;
279 *num = 0;
280 }
281 return result;
282 }
283
IsSecureUidDuplicate(LinkedList * userInfoList,uint64_t secureUid)284 IAM_STATIC bool IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid)
285 {
286 if (userInfoList == NULL) {
287 LOG_ERROR("the user list is empty, and the branch is abnormal");
288 return false;
289 }
290
291 LinkedListNode *temp = userInfoList->head;
292 UserInfo *userInfo = NULL;
293 while (temp != NULL) {
294 userInfo = (UserInfo *)temp->data;
295 if (userInfo != NULL && userInfo->secUid == secureUid) {
296 return true;
297 }
298 temp = temp->next;
299 }
300
301 return false;
302 }
303
CreateUser(int32_t userId,int32_t userType)304 IAM_STATIC UserInfo *CreateUser(int32_t userId, int32_t userType)
305 {
306 UserInfo *user = InitUserInfoNode();
307 if (!IsUserInfoValid(user)) {
308 LOG_ERROR("user is invalid");
309 DestroyUserInfoNode(user);
310 return NULL;
311 }
312 user->userId = userId;
313 user->userType = userType;
314 ResultCode ret = GenerateDeduplicateUint64(g_userInfoList, &user->secUid, IsSecureUidDuplicate);
315 if (ret != RESULT_SUCCESS) {
316 LOG_ERROR("generate secureUid failed");
317 DestroyUserInfoNode(user);
318 return NULL;
319 }
320 return user;
321 }
322
DeleteUser(int32_t userId)323 IAM_STATIC ResultCode DeleteUser(int32_t userId)
324 {
325 if (g_userInfoList == NULL) {
326 return RESULT_BAD_PARAM;
327 }
328 return g_userInfoList->remove(g_userInfoList, &userId, MatchUserInfo, true);
329 }
330
IsCredentialIdDuplicate(LinkedList * userInfoList,uint64_t credentialId)331 IAM_STATIC bool IsCredentialIdDuplicate(LinkedList *userInfoList, uint64_t credentialId)
332 {
333 (void)userInfoList;
334 CredentialCondition condition = {};
335 SetCredentialConditionCredentialId(&condition, credentialId);
336 LinkedList *credList = QueryCredentialLimit(&condition);
337 if (credList == NULL) {
338 LOG_ERROR("query failed");
339 return true;
340 }
341 if (credList->getSize(credList) != 0) {
342 LOG_ERROR("duplicate credential id");
343 DestroyLinkedList(credList);
344 return true;
345 }
346 DestroyLinkedList(credList);
347 return false;
348 }
349
IsEnrolledIdDuplicate(LinkedList * enrolledList,uint64_t enrolledId)350 IAM_STATIC bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)
351 {
352 LinkedListNode *temp = enrolledList->head;
353 EnrolledInfoHal *enrolledInfo = NULL;
354 const static uint16_t num = 0xFFFF;
355 while (temp != NULL) {
356 enrolledInfo = (EnrolledInfoHal *)temp->data;
357 if ((enrolledInfo != NULL) && (enrolledInfo->enrolledId & num) == (enrolledId & num)) {
358 return true;
359 }
360 temp = temp->next;
361 }
362
363 return false;
364 }
365
GenerateDeduplicateUint64(LinkedList * collection,uint64_t * destValue,DuplicateCheckFunc func)366 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)
367 {
368 if (collection == NULL || destValue == NULL || func == NULL) {
369 LOG_ERROR("param is null");
370 return RESULT_BAD_PARAM;
371 }
372
373 for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) {
374 uint64_t tempRandom;
375 if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
376 LOG_ERROR("get random failed");
377 return RESULT_GENERAL_ERROR;
378 }
379 if (!func(collection, tempRandom)) {
380 *destValue = tempRandom;
381 return RESULT_SUCCESS;
382 }
383 }
384
385 LOG_ERROR("generate random failed");
386 return RESULT_GENERAL_ERROR;
387 }
388
UpdateEnrolledId(LinkedList * enrolledList,uint32_t authType)389 IAM_STATIC ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)
390 {
391 LinkedListNode *temp = enrolledList->head;
392 EnrolledInfoHal *enrolledInfo = NULL;
393 while (temp != NULL) {
394 EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data;
395 if (nodeData != NULL && nodeData->authType == authType) {
396 enrolledInfo = nodeData;
397 break;
398 }
399 temp = temp->next;
400 }
401
402 if (enrolledInfo != NULL) {
403 return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
404 }
405
406 enrolledInfo = Malloc(sizeof(EnrolledInfoHal));
407 if (enrolledInfo == NULL) {
408 LOG_ERROR("enrolledInfo malloc failed");
409 return RESULT_NO_MEMORY;
410 }
411 enrolledInfo->authType = authType;
412 ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
413 if (ret != RESULT_SUCCESS) {
414 LOG_ERROR("generate enrolledId failed");
415 Free(enrolledInfo);
416 return ret;
417 }
418 ret = enrolledList->insert(enrolledList, enrolledInfo);
419 if (ret != RESULT_SUCCESS) {
420 LOG_ERROR("enrolledInfo insert failed");
421 Free(enrolledInfo);
422 }
423 return ret;
424 }
425
426 // add for reliable pin updates
GetRealAuthTypeForEnrolledId(uint32_t authType)427 IAM_STATIC uint32_t GetRealAuthTypeForEnrolledId(uint32_t authType)
428 {
429 if (authType == DEFAULT_AUTH_TYPE) {
430 return PIN_AUTH;
431 }
432 return authType;
433 }
434
AddCredentialToUser(UserInfo * user,CredentialInfoHal * credentialInfo)435 IAM_STATIC ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)
436 {
437 if (g_userInfoList == NULL) {
438 LOG_ERROR("g_userInfoList is uninitialized");
439 return RESULT_NEED_INIT;
440 }
441 LinkedList *credentialList = user->credentialInfoList;
442 LinkedList *enrolledList = user->enrolledInfoList;
443 if (credentialList->getSize(credentialList) >= MAX_CREDENTIAL) {
444 LOG_ERROR("the number of credentials reaches the maximum");
445 return RESULT_EXCEED_LIMIT;
446 }
447
448 ResultCode ret = UpdateEnrolledId(enrolledList, GetRealAuthTypeForEnrolledId(credentialInfo->authType));
449 if (ret != RESULT_SUCCESS) {
450 LOG_ERROR("update enrolledId failed");
451 return ret;
452 }
453 ret = GenerateDeduplicateUint64(g_userInfoList, &credentialInfo->credentialId, IsCredentialIdDuplicate);
454 if (ret != RESULT_SUCCESS) {
455 LOG_ERROR("GenerateDeduplicateUint64 failed");
456 return ret;
457 }
458 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
459 bool isRemoved = false;
460 RemoveCachePin(user, &isRemoved);
461 }
462 CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal));
463 if (credential == NULL) {
464 LOG_ERROR("credential malloc failed");
465 return RESULT_NO_MEMORY;
466 }
467 if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) {
468 LOG_ERROR("credential copy failed");
469 Free(credential);
470 return RESULT_BAD_COPY;
471 }
472 credential->enrolledSysTime = GetReeTime();
473 ret = credentialList->insert(credentialList, credential);
474 if (ret != RESULT_SUCCESS) {
475 LOG_ERROR("insert credential failed");
476 Free(credential);
477 }
478 return ret;
479 }
480
AddUser(int32_t userId,CredentialInfoHal * credentialInfo,int32_t userType)481 IAM_STATIC ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
482 {
483 if (g_userInfoList == NULL) {
484 LOG_ERROR("please init");
485 return RESULT_NEED_INIT;
486 }
487 if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) {
488 LOG_ERROR("the number of users reaches the maximum");
489 return RESULT_EXCEED_LIMIT;
490 }
491
492 UserInfo *user = QueryUserInfo(userId);
493 if (user != NULL) {
494 LOG_ERROR("Please check pin");
495 return RESULT_BAD_PARAM;
496 }
497
498 user = CreateUser(userId, userType);
499 if (user == NULL) {
500 LOG_ERROR("create user failed");
501 return RESULT_UNKNOWN;
502 }
503 LOG_INFO("user userType %{public}d", user->userType);
504 ResultCode ret = AddCredentialToUser(user, credentialInfo);
505 if (ret != RESULT_SUCCESS) {
506 LOG_ERROR("add credential to user failed");
507 goto FAIL;
508 }
509
510 ret = g_userInfoList->insert(g_userInfoList, user);
511 if (ret != RESULT_SUCCESS) {
512 LOG_ERROR("insert failed");
513 goto FAIL;
514 }
515 return ret;
516
517 FAIL:
518 DestroyUserInfoNode(user);
519 return ret;
520 }
521
AddCredentialInfo(int32_t userId,CredentialInfoHal * credentialInfo,int32_t userType)522 ResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
523 {
524 if ((credentialInfo == NULL) || (credentialInfo->authType == DEFAULT_AUTH_TYPE)) {
525 LOG_ERROR("credentialInfo is invalid");
526 return RESULT_BAD_PARAM;
527 }
528 UserInfo *user = QueryUserInfo(userId);
529 if (user == NULL && credentialInfo->authType == PIN_AUTH) {
530 ResultCode ret = AddUser(userId, credentialInfo, userType);
531 if (ret != RESULT_SUCCESS) {
532 LOG_ERROR("add user failed");
533 return ret;
534 }
535 ret = UpdateFileInfo(g_userInfoList);
536 if (ret != RESULT_SUCCESS) {
537 LOG_ERROR("updateFileInfo failed");
538 }
539 return ret;
540 }
541 if (user == NULL) {
542 LOG_ERROR("user is null");
543 return RESULT_BAD_PARAM;
544 }
545 if (credentialInfo->authType == PIN_AUTH) {
546 CredentialCondition condition = {};
547 SetCredentialConditionAuthType(&condition, PIN_AUTH);
548 SetCredentialConditionUserId(&condition, userId);
549 LinkedList *credList = QueryCredentialLimit(&condition);
550 if (credList == NULL) {
551 LOG_ERROR("query credential failed");
552 return RESULT_UNKNOWN;
553 }
554 if (credList->getSize(credList) != 0) {
555 LOG_INFO("cache pin");
556 // add for reliable pin updates
557 credentialInfo->authType = DEFAULT_AUTH_TYPE;
558 }
559 DestroyLinkedList(credList);
560 }
561 ResultCode ret = AddCredentialToUser(user, credentialInfo);
562 if (ret != RESULT_SUCCESS) {
563 LOG_ERROR("add credential to user failed");
564 return ret;
565 }
566 ret = UpdateFileInfo(g_userInfoList);
567 if (ret != RESULT_SUCCESS) {
568 LOG_ERROR("updateFileInfo failed");
569 }
570 return ret;
571 }
572
MatchCredentialById(const void * data,const void * condition)573 IAM_STATIC bool MatchCredentialById(const void *data, const void *condition)
574 {
575 if (data == NULL || condition == NULL) {
576 return false;
577 }
578 const CredentialInfoHal *credentialInfo = (const CredentialInfoHal *)data;
579 uint64_t credentialId = *(const uint64_t *)condition;
580 if (credentialInfo->credentialId == credentialId) {
581 return true;
582 }
583 return false;
584 }
585
MatchEnrolledInfoByType(const void * data,const void * condition)586 IAM_STATIC bool MatchEnrolledInfoByType(const void *data, const void *condition)
587 {
588 if (data == NULL || condition == NULL) {
589 return false;
590 }
591 const EnrolledInfoHal *enrolledInfo = (const EnrolledInfoHal *)data;
592 uint32_t authType = *(const uint32_t *)condition;
593 if (enrolledInfo->authType == authType) {
594 return true;
595 }
596 return false;
597 }
598
RemoveCachePin(UserInfo * user,bool * isRemoved)599 IAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved)
600 {
601 LOG_INFO("RemoveCachePin start");
602 LinkedListNode *temp = user->credentialInfoList->head;
603 CredentialInfoHal *credentialInfoCache = NULL;
604 while (temp != NULL) {
605 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
606 if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
607 credentialInfoCache = nodeData;
608 break;
609 }
610 temp = temp->next;
611 }
612 if (credentialInfoCache == NULL) {
613 LOG_INFO("RemoveCachePin no cache pin");
614 *isRemoved = false;
615 return;
616 }
617 uint64_t credentialId = credentialInfoCache->credentialId;
618 ResultCode ret = (user->credentialInfoList)->remove(
619 user->credentialInfoList, &credentialId, MatchCredentialById, true);
620 if (ret != RESULT_SUCCESS) {
621 LOG_ERROR("remove credential failed");
622 *isRemoved = false;
623 return;
624 }
625 LOG_ERROR("remove credential success");
626 *isRemoved = true;
627 }
628
ClearCachePin(int32_t userId)629 void ClearCachePin(int32_t userId)
630 {
631 LOG_INFO("ClearCachePin start");
632 UserInfo *user = QueryUserInfo(userId);
633 if (user == NULL) {
634 LOG_ERROR("can't find this user");
635 return;
636 }
637
638 bool isRemoved = false;
639 RemoveCachePin(user, &isRemoved);
640 if (isRemoved && UpdateFileInfo(g_userInfoList) != RESULT_SUCCESS) {
641 LOG_ERROR("ClearCachePin save fail");
642 return;
643 }
644 }
645
SwitchSubType(UserInfo * user)646 IAM_STATIC void SwitchSubType(UserInfo *user)
647 {
648 uint64_t tmpSubType = user->pinSubType;
649 user->pinSubType = user->cachePinSubType;
650 user->cachePinSubType = tmpSubType;
651 }
652
653 // add for reliable pin updates
DeletePinCredentialInfo(UserInfo * user)654 IAM_STATIC ResultCode DeletePinCredentialInfo(UserInfo *user)
655 {
656 LOG_INFO("DeletePinCredentialInfo start");
657 LinkedListNode *temp = user->credentialInfoList->head;
658 CredentialInfoHal *credentialInfoOld = NULL;
659 CredentialInfoHal *credentialInfoCache = NULL;
660 while (temp != NULL) {
661 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
662 if (nodeData != NULL && nodeData->authType == PIN_AUTH) {
663 credentialInfoOld = nodeData;
664 }
665 if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
666 credentialInfoCache = nodeData;
667 }
668 temp = temp->next;
669 }
670 if (credentialInfoOld == NULL || credentialInfoCache == NULL) {
671 LOG_ERROR("no cache pin exist");
672 return RESULT_GENERAL_ERROR;
673 }
674 credentialInfoOld->authType = DEFAULT_AUTH_TYPE;
675 credentialInfoCache->authType = PIN_AUTH;
676 SwitchSubType(user);
677 ResultCode result = UpdateFileInfo(g_userInfoList);
678 if (result == RESULT_SUCCESS) {
679 LOG_INFO("switch cache pin success");
680 ClearCachePin(user->userId);
681 return result;
682 }
683 LOG_ERROR("switch cache pin fail");
684 credentialInfoOld->authType = PIN_AUTH;
685 credentialInfoCache->authType = DEFAULT_AUTH_TYPE;
686 SwitchSubType(user);
687 return RESULT_GENERAL_ERROR;
688 }
689
DeleteCredentialInfo(int32_t userId,uint64_t credentialId,CredentialInfoHal * credentialInfo)690 ResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
691 {
692 if (credentialInfo == NULL) {
693 LOG_ERROR("param is invalid");
694 return RESULT_BAD_PARAM;
695 }
696
697 UserInfo *user = QueryUserInfo(userId);
698 if (user == NULL) {
699 LOG_ERROR("can't find this user");
700 return RESULT_BAD_PARAM;
701 }
702
703 LinkedList *credentialList = user->credentialInfoList;
704 CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList);
705 if (credentialQuery == NULL) {
706 LOG_ERROR("credentialQuery is null");
707 return RESULT_UNKNOWN;
708 }
709 if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
710 LOG_ERROR("copy failed");
711 return RESULT_BAD_COPY;
712 }
713 if (credentialInfo->authType == PIN_AUTH) {
714 return DeletePinCredentialInfo(user);
715 }
716 ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true);
717 if (ret != RESULT_SUCCESS) {
718 LOG_ERROR("remove credential failed");
719 return ret;
720 }
721 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
722 return UpdateFileInfo(g_userInfoList);
723 }
724 credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList);
725 if (credentialQuery != NULL) {
726 return UpdateFileInfo(g_userInfoList);
727 }
728
729 LinkedList *enrolledInfoList = user->enrolledInfoList;
730 if (enrolledInfoList == NULL) {
731 LOG_ERROR("enrolledInfoList is null");
732 return RESULT_UNKNOWN;
733 }
734 ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true);
735 if (ret != RESULT_SUCCESS) {
736 LOG_ERROR("remove enrolledInfo failed");
737 return ret;
738 }
739
740 return UpdateFileInfo(g_userInfoList);
741 }
742
QueryCredentialById(uint64_t credentialId,LinkedList * credentialList)743 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)
744 {
745 if (credentialList == NULL) {
746 return NULL;
747 }
748 LinkedListNode *temp = credentialList->head;
749 CredentialInfoHal *credentialInfo = NULL;
750 while (temp != NULL) {
751 CredentialInfoHal *nodeData = (CredentialInfoHal *)temp->data;
752 if (nodeData != NULL && nodeData->credentialId == credentialId) {
753 credentialInfo = nodeData;
754 break;
755 }
756 temp = temp->next;
757 }
758 return credentialInfo;
759 }
760
QueryCredentialByAuthType(uint32_t authType,LinkedList * credentialList)761 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)
762 {
763 if (credentialList == NULL) {
764 return NULL;
765 }
766 LinkedListNode *temp = credentialList->head;
767 CredentialInfoHal *credentialInfo = NULL;
768 while (temp != NULL) {
769 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
770 if (nodeData != NULL && nodeData->authType == authType) {
771 credentialInfo = nodeData;
772 break;
773 }
774 temp = temp->next;
775 }
776 return credentialInfo;
777 }
778
779 // do not cotain cache pin credential
IsCredMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)780 IAM_STATIC bool IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
781 {
782 if ((limit->conditionFactor & CREDENTIAL_CONDITION_CREDENTIAL_ID) != 0 &&
783 limit->credentialId != credentialInfo->credentialId) {
784 return false;
785 }
786 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
787 if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_CACHE_PIN) == 0) {
788 return false;
789 }
790 } else {
791 if ((limit->conditionFactor & CREDENTIAL_CONDITION_AUTH_TYPE) != 0 &&
792 limit->authType != credentialInfo->authType) {
793 return false;
794 }
795 }
796 if ((limit->conditionFactor & CREDENTIAL_CONDITION_TEMPLATE_ID) != 0 &&
797 limit->templateId != credentialInfo->templateId) {
798 return false;
799 }
800 if ((limit->conditionFactor & CREDENTIAL_CONDITION_SENSOR_HINT) != 0 &&
801 limit->executorSensorHint != INVALID_SENSOR_HINT &&
802 limit->executorSensorHint != credentialInfo->executorSensorHint) {
803 return false;
804 }
805 if ((limit->conditionFactor & CREDENTIAL_CONDITION_EXECUTOR_MATCHER) != 0 &&
806 limit->executorMatcher != credentialInfo->executorMatcher) {
807 return false;
808 }
809 return true;
810 }
811
IsUserMatch(const CredentialCondition * limit,const UserInfo * user)812 IAM_STATIC bool IsUserMatch(const CredentialCondition *limit, const UserInfo *user)
813 {
814 if ((limit->conditionFactor & CREDENTIAL_CONDITION_USER_ID) != 0 && limit->userId != user->userId) {
815 return false;
816 }
817 return true;
818 }
819
820 // do not cotain cache pin credential
TraverseCredentialList(const CredentialCondition * limit,const LinkedList * credentialList,LinkedList * credListGet)821 IAM_STATIC ResultCode TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList,
822 LinkedList *credListGet)
823 {
824 if (credentialList == NULL) {
825 LOG_ERROR("credentialList is null");
826 return RESULT_GENERAL_ERROR;
827 }
828 LinkedListNode *temp = credentialList->head;
829 while (temp != NULL) {
830 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
831 if (nodeData == NULL) {
832 LOG_ERROR("nodeData is null");
833 return RESULT_UNKNOWN;
834 }
835 if (!IsCredMatch(limit, nodeData)) {
836 temp = temp->next;
837 continue;
838 }
839 CredentialInfoHal *copy = (CredentialInfoHal *)Malloc(sizeof(CredentialInfoHal));
840 if (copy == NULL) {
841 LOG_ERROR("copy malloc failed");
842 return RESULT_NO_MEMORY;
843 }
844 *copy = *nodeData;
845 ResultCode ret = credListGet->insert(credListGet, copy);
846 if (ret != RESULT_SUCCESS) {
847 LOG_ERROR("insert failed");
848 Free(copy);
849 return ret;
850 }
851 temp = temp->next;
852 }
853 return RESULT_SUCCESS;
854 }
855
856 // do not cotain cache pin credential
QueryCredentialLimit(const CredentialCondition * limit)857 LinkedList *QueryCredentialLimit(const CredentialCondition *limit)
858 {
859 if (limit == NULL) {
860 LOG_ERROR("limit is null");
861 return NULL;
862 }
863 if (g_userInfoList == NULL) {
864 LOG_ERROR("g_userInfoList is null");
865 return NULL;
866 }
867 LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
868 if (credList == NULL) {
869 LOG_ERROR("credList is null");
870 return NULL;
871 }
872 LinkedListNode *temp = g_userInfoList->head;
873 while (temp != NULL) {
874 UserInfo *user = (UserInfo *)temp->data;
875 if (user == NULL) {
876 LOG_ERROR("node data is null");
877 DestroyLinkedList(credList);
878 return NULL;
879 }
880 if (IsUserMatch(limit, user)) {
881 ResultCode ret = TraverseCredentialList(limit, user->credentialInfoList, credList);
882 if (ret != RESULT_SUCCESS) {
883 LOG_ERROR("TraverseCredentialList failed");
884 DestroyLinkedList(credList);
885 return NULL;
886 }
887 }
888 temp = temp->next;
889 }
890 return credList;
891 }
892
QueryCredentialUserId(uint64_t credentialId,int32_t * userId)893 ResultCode QueryCredentialUserId(uint64_t credentialId, int32_t *userId)
894 {
895 if (userId == NULL) {
896 LOG_ERROR("userId is null");
897 return RESULT_BAD_PARAM;
898 }
899 if (g_userInfoList == NULL) {
900 LOG_ERROR("g_userInfoList is null");
901 return RESULT_NEED_INIT;
902 }
903 LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
904 if (credList == NULL) {
905 LOG_ERROR("credList is null");
906 return RESULT_NO_MEMORY;
907 }
908 LinkedListNode *temp = g_userInfoList->head;
909 CredentialCondition condition = {};
910 SetCredentialConditionCredentialId(&condition, credentialId);
911 while (temp != NULL) {
912 UserInfo *user = (UserInfo *)temp->data;
913 if (user == NULL) {
914 LOG_ERROR("user is null");
915 DestroyLinkedList(credList);
916 return RESULT_UNKNOWN;
917 }
918 ResultCode ret = TraverseCredentialList(&condition, user->credentialInfoList, credList);
919 if (ret != RESULT_SUCCESS) {
920 LOG_ERROR("TraverseCredentialList failed");
921 DestroyLinkedList(credList);
922 return RESULT_UNKNOWN;
923 }
924 if (credList->getSize(credList) != 0) {
925 DestroyLinkedList(credList);
926 *userId = user->userId;
927 return RESULT_SUCCESS;
928 }
929 temp = temp->next;
930 }
931 DestroyLinkedList(credList);
932 LOG_ERROR("can't find this credential");
933 return RESULT_NOT_FOUND;
934 }
935
SetPinSubType(int32_t userId,uint64_t pinSubType)936 ResultCode SetPinSubType(int32_t userId, uint64_t pinSubType)
937 {
938 UserInfo *user = QueryUserInfo(userId);
939 if (user == NULL) {
940 LOG_ERROR("can't find this user");
941 return RESULT_NOT_FOUND;
942 }
943 user->pinSubType = pinSubType;
944 return RESULT_SUCCESS;
945 }
946
GetPinSubType(int32_t userId,uint64_t * pinSubType)947 ResultCode GetPinSubType(int32_t userId, uint64_t *pinSubType)
948 {
949 if (pinSubType == NULL) {
950 LOG_ERROR("pinSubType is null");
951 return RESULT_BAD_PARAM;
952 }
953 UserInfo *user = QueryUserInfo(userId);
954 if (user == NULL) {
955 LOG_ERROR("can't find this user");
956 return RESULT_NOT_FOUND;
957 }
958 *pinSubType = user->pinSubType;
959 return RESULT_SUCCESS;
960 }
961
SetCredentialConditionCredentialId(CredentialCondition * condition,uint64_t credentialId)962 void SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId)
963 {
964 if (condition == NULL) {
965 LOG_ERROR("condition is null");
966 return;
967 }
968 condition->credentialId = credentialId;
969 condition->conditionFactor |= CREDENTIAL_CONDITION_CREDENTIAL_ID;
970 }
971
SetCredentialConditionTemplateId(CredentialCondition * condition,uint64_t templateId)972 void SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId)
973 {
974 if (condition == NULL) {
975 LOG_ERROR("condition is null");
976 return;
977 }
978 condition->templateId = templateId;
979 condition->conditionFactor |= CREDENTIAL_CONDITION_TEMPLATE_ID;
980 }
981
SetCredentialConditionAuthType(CredentialCondition * condition,uint32_t authType)982 void SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType)
983 {
984 if (condition == NULL) {
985 LOG_ERROR("condition is null");
986 return;
987 }
988 condition->authType = authType;
989 condition->conditionFactor |= CREDENTIAL_CONDITION_AUTH_TYPE;
990 }
991
SetCredentialConditionExecutorSensorHint(CredentialCondition * condition,uint32_t executorSensorHint)992 void SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint)
993 {
994 if (condition == NULL) {
995 LOG_ERROR("condition is null");
996 return;
997 }
998 condition->executorSensorHint = executorSensorHint;
999 condition->conditionFactor |= CREDENTIAL_CONDITION_SENSOR_HINT;
1000 }
1001
SetCredentialConditionExecutorMatcher(CredentialCondition * condition,uint32_t executorMatcher)1002 void SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher)
1003 {
1004 if (condition == NULL) {
1005 LOG_ERROR("condition is null");
1006 return;
1007 }
1008 condition->executorMatcher = executorMatcher;
1009 condition->conditionFactor |= CREDENTIAL_CONDITION_EXECUTOR_MATCHER;
1010 }
1011
SetCredentialConditionUserId(CredentialCondition * condition,int32_t userId)1012 void SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId)
1013 {
1014 if (condition == NULL) {
1015 LOG_ERROR("condition is null");
1016 return;
1017 }
1018 condition->userId = userId;
1019 condition->conditionFactor |= CREDENTIAL_CONDITION_USER_ID;
1020 }
1021
SetCredentiaConditionNeedCachePin(CredentialCondition * condition)1022 void SetCredentiaConditionNeedCachePin(CredentialCondition *condition)
1023 {
1024 if (condition == NULL) {
1025 LOG_ERROR("condition is null");
1026 return;
1027 }
1028 condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_CACHE_PIN;
1029 }
1030
IsUserValid(UserInfo * user)1031 IAM_STATIC bool IsUserValid(UserInfo *user)
1032 {
1033 LinkedList *credentialInfoList = user->credentialInfoList;
1034 CredentialInfoHal *pinCredential = QueryCredentialByAuthType(PIN_AUTH, credentialInfoList);
1035 if (pinCredential == NULL) {
1036 LOG_INFO("user is invalid, userId: %{public}d", user->userId);
1037 return false;
1038 }
1039 return true;
1040 }
1041
GetInvalidUser(int32_t * invalidUserId,uint32_t maxUserCount,uint32_t * userCount,bool * cachePinRemoved)1042 IAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
1043 bool *cachePinRemoved)
1044 {
1045 LOG_INFO("get invalid user start");
1046 if (g_userInfoList == NULL) {
1047 LOG_ERROR("g_userInfoList is null");
1048 return RESULT_GENERAL_ERROR;
1049 }
1050
1051 LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1052 if (iterator == NULL) {
1053 LOG_ERROR("create iterator failed");
1054 return RESULT_NO_MEMORY;
1055 }
1056
1057 UserInfo *user = NULL;
1058 *userCount = 0;
1059 while (iterator->hasNext(iterator)) {
1060 user = (UserInfo *)iterator->next(iterator);
1061 if (user == NULL) {
1062 LOG_ERROR("userinfo list node is null, please check");
1063 continue;
1064 }
1065
1066 if (*userCount >= maxUserCount) {
1067 LOG_ERROR("too many users");
1068 break;
1069 }
1070
1071 if (!IsUserValid(user)) {
1072 invalidUserId[*userCount] = user->userId;
1073 (*userCount)++;
1074 continue;
1075 }
1076
1077 bool isRemoved = false;
1078 RemoveCachePin(user, &isRemoved);
1079 if (isRemoved) {
1080 *cachePinRemoved = true;
1081 }
1082 }
1083
1084 g_userInfoList->destroyIterator(iterator);
1085 return RESULT_SUCCESS;
1086 }
1087
ClearInvalidData(void)1088 IAM_STATIC ResultCode ClearInvalidData(void)
1089 {
1090 LOG_INFO("clear invalid user start");
1091 int32_t invalidUserId[MAX_USER] = {0};
1092 uint32_t userCount = 0;
1093 bool cachePinRemoved = false;
1094 if (GetInvalidUser(invalidUserId, MAX_USER, &userCount, &cachePinRemoved) != RESULT_SUCCESS) {
1095 LOG_ERROR("GetInvalidUser fail");
1096 return RESULT_GENERAL_ERROR;
1097 }
1098 ResultCode ret = RESULT_SUCCESS;
1099 for (uint32_t i = 0; i < userCount; ++i) {
1100 ret = DeleteUser(invalidUserId[i]);
1101 if (ret != RESULT_SUCCESS) {
1102 LOG_ERROR("delete invalid user fail, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1103 return ret;
1104 }
1105 LOG_INFO("delete invalid user success, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1106 }
1107
1108 if ((userCount != 0) || cachePinRemoved) {
1109 ret = UpdateFileInfo(g_userInfoList);
1110 if (ret != RESULT_SUCCESS) {
1111 LOG_ERROR("UpdateFileInfo fail, ret: %{public}d", ret);
1112 return ret;
1113 }
1114 }
1115 return RESULT_SUCCESS;
1116 }
1117
GetAllExtUserInfo(UserInfoResult * userInfos,uint32_t userInfoLen,uint32_t * userInfocount)1118 ResultCode GetAllExtUserInfo(UserInfoResult *userInfos, uint32_t userInfoLen, uint32_t *userInfocount)
1119 {
1120 LOG_INFO("get all user info start");
1121 if (userInfos == NULL || userInfocount == NULL || g_userInfoList == NULL) {
1122 LOG_ERROR("param is null");
1123 return RESULT_BAD_PARAM;
1124 }
1125
1126 LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1127 if (iterator == NULL) {
1128 LOG_ERROR("create iterator failed");
1129 return RESULT_NO_MEMORY;
1130 }
1131
1132 UserInfo *user = NULL;
1133 EnrolledInfoHal *enrolledInfoHal = NULL;
1134 *userInfocount = 0;
1135 while (iterator->hasNext(iterator)) {
1136 user = (UserInfo *)iterator->next(iterator);
1137 if (user == NULL) {
1138 LOG_ERROR("userinfo list node is null, please check");
1139 continue;
1140 }
1141
1142 if (*userInfocount >= userInfoLen) {
1143 LOG_ERROR("too many users");
1144 goto ERROR;
1145 }
1146
1147 userInfos[*userInfocount].userId = user->userId;
1148 userInfos[*userInfocount].secUid = user->secUid;
1149 userInfos[*userInfocount].pinSubType = (uint32_t)user->pinSubType;
1150
1151 ResultCode ret = GetAllEnrolledInfoFromUser(user, &enrolledInfoHal, &(userInfos[*userInfocount].enrollNum));
1152 if (ret != RESULT_SUCCESS) {
1153 LOG_ERROR("get enrolled info fail");
1154 goto ERROR;
1155 }
1156 if (userInfos[*userInfocount].enrollNum > MAX_ENROLL_OUTPUT) {
1157 LOG_ERROR("too many elements");
1158 free(enrolledInfoHal);
1159 goto ERROR;
1160 }
1161
1162 for (uint32_t i = 0; i < userInfos[*userInfocount].enrollNum; i++) {
1163 userInfos[*userInfocount].enrolledInfo[i].authType = enrolledInfoHal[i].authType;
1164 userInfos[*userInfocount].enrolledInfo[i].enrolledId = enrolledInfoHal[i].enrolledId;
1165 }
1166
1167 free(enrolledInfoHal);
1168 (*userInfocount)++;
1169 }
1170
1171 g_userInfoList->destroyIterator(iterator);
1172 return RESULT_SUCCESS;
1173
1174 ERROR:
1175 g_userInfoList->destroyIterator(iterator);
1176 return RESULT_GENERAL_ERROR;
1177 }
1178
GetEnrolledState(int32_t userId,uint32_t authType,EnrolledStateHal * enrolledStateHal)1179 ResultCode GetEnrolledState(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal)
1180 {
1181 LOG_INFO("get enrolled id info start, userId:%{public}d, authType:%{public}d", userId, authType);
1182
1183 UserInfo *user = QueryUserInfo(userId);
1184 if (user == NULL) {
1185 LOG_ERROR("user is null");
1186 return RESULT_NOT_ENROLLED;
1187 }
1188 if (user->credentialInfoList == NULL) {
1189 LOG_ERROR("credentialInfoList is null");
1190 return RESULT_NOT_ENROLLED;
1191 }
1192
1193 uint16_t credentialCount = 0;
1194 LinkedListNode *credentialInfoTemp = user->credentialInfoList->head;
1195 while (credentialInfoTemp != NULL) {
1196 CredentialInfoHal *nodeInfo = credentialInfoTemp->data;
1197 if (nodeInfo != NULL && nodeInfo->authType == authType) {
1198 ++credentialCount;
1199 }
1200 credentialInfoTemp = credentialInfoTemp->next;
1201 }
1202 if (credentialCount == 0) {
1203 LOG_ERROR("not enrolled");
1204 return RESULT_NOT_ENROLLED;
1205 }
1206 enrolledStateHal->credentialCount = credentialCount;
1207 if (user->enrolledInfoList == NULL) {
1208 LOG_ERROR("enrolledInfoList is null");
1209 return RESULT_NOT_ENROLLED;
1210 }
1211 LinkedListNode *enrolledInfoTemp = user->enrolledInfoList->head;
1212 while (enrolledInfoTemp != NULL) {
1213 EnrolledInfoHal *nodeInfo = enrolledInfoTemp->data;
1214 if (nodeInfo != NULL && nodeInfo->authType == authType) {
1215 enrolledStateHal->credentialDigest = nodeInfo->enrolledId;
1216 break;
1217 }
1218 enrolledInfoTemp = enrolledInfoTemp->next;
1219 }
1220 return RESULT_SUCCESS;
1221 }
1222
SavePinExpiredPeriod(int64_t pinExpiredPeriod)1223 IAM_STATIC ResultCode SavePinExpiredPeriod(int64_t pinExpiredPeriod)
1224 {
1225 if (pinExpiredPeriod < 0) {
1226 pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1227 }
1228 for (uint32_t i = 0; i < g_globalConfigInfoNum; i++) {
1229 if (g_globalConfigArray[i].type == PIN_EXPIRED_PERIOD) {
1230 g_globalConfigArray[i].value.pinExpiredPeriod = pinExpiredPeriod;
1231 return UpdateGlobalConfigFile(g_globalConfigArray, g_globalConfigInfoNum);
1232 }
1233 }
1234 if (g_globalConfigInfoNum < MAX_GLOBAL_CONFIG_NUM) {
1235 g_globalConfigInfoNum++;
1236 g_globalConfigArray[g_globalConfigInfoNum - 1].type = PIN_EXPIRED_PERIOD;
1237 g_globalConfigArray[g_globalConfigInfoNum - 1].value.pinExpiredPeriod = pinExpiredPeriod;
1238 return UpdateGlobalConfigFile(g_globalConfigArray, g_globalConfigInfoNum);
1239 }
1240 LOG_ERROR("SavePinExpiredPeriod failed");
1241 return RESULT_GENERAL_ERROR;
1242 }
1243
1244
SaveGlobalConfigParam(GlobalConfigParamHal * param)1245 ResultCode SaveGlobalConfigParam(GlobalConfigParamHal *param)
1246 {
1247 if (param == NULL) {
1248 LOG_ERROR("bad param");
1249 return RESULT_BAD_PARAM;
1250 }
1251 if (param->type == PIN_EXPIRED_PERIOD) {
1252 return SavePinExpiredPeriod(param->value.pinExpiredPeriod);
1253 }
1254 LOG_ERROR("SaveGlobalConfigParam type %{public}d failed", param->type);
1255 return RESULT_GENERAL_ERROR;
1256 }
1257
QueryPinCredential(int32_t userId,CredentialInfoHal * pinCredential)1258 IAM_STATIC ResultCode QueryPinCredential(int32_t userId, CredentialInfoHal *pinCredential)
1259 {
1260 if (pinCredential == NULL) {
1261 LOG_ERROR("no need to get pin credential");
1262 return RESULT_BAD_PARAM;
1263 }
1264 CredentialCondition condition = {};
1265 SetCredentialConditionUserId(&condition, userId);
1266 SetCredentialConditionAuthType(&condition, PIN_AUTH);
1267 LinkedList *credList = QueryCredentialLimit(&condition);
1268 if (credList == NULL || credList->getSize(credList) == 0) {
1269 LOG_ERROR("pin credential is null");
1270 DestroyLinkedList(credList);
1271 return RESULT_NOT_ENROLLED;
1272 }
1273 if (credList->head == NULL || credList->head->data == NULL) {
1274 LOG_ERROR("pin credList node is invalid");
1275 DestroyLinkedList(credList);
1276 return RESULT_GENERAL_ERROR;
1277 }
1278 if (memcpy_s(pinCredential, sizeof(CredentialInfoHal), credList->head->data, sizeof(CredentialInfoHal)) != EOK) {
1279 LOG_ERROR("credential copy fail");
1280 DestroyLinkedList(credList);
1281 return RESULT_GENERAL_ERROR;
1282 }
1283 DestroyLinkedList(credList);
1284 return RESULT_SUCCESS;
1285 }
1286
GetPinExpiredInfo(int32_t userId,PinExpiredInfo * expiredInfo)1287 ResultCode GetPinExpiredInfo(int32_t userId, PinExpiredInfo *expiredInfo)
1288 {
1289 if (expiredInfo == NULL) {
1290 LOG_ERROR("bad param");
1291 return RESULT_BAD_PARAM;
1292 }
1293 (void)memset_s(expiredInfo, sizeof(PinExpiredInfo), 0, sizeof(PinExpiredInfo));
1294 for (uint32_t i = 0; i < g_globalConfigInfoNum; i++) {
1295 if (g_globalConfigArray[i].type == PIN_EXPIRED_PERIOD) {
1296 expiredInfo->pinExpiredPeriod = g_globalConfigArray[i].value.pinExpiredPeriod;
1297 break;
1298 }
1299 }
1300 if (expiredInfo->pinExpiredPeriod <= 0) {
1301 expiredInfo->pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1302 LOG_INFO("no need check pinExpiredPeriod");
1303 return RESULT_SUCCESS;
1304 }
1305 CredentialInfoHal pinCredential = {};
1306 if (QueryPinCredential(userId, &pinCredential) != RESULT_SUCCESS) {
1307 LOG_INFO("not enrolled pin");
1308 return RESULT_NOT_ENROLLED;
1309 }
1310 expiredInfo->pinEnrolledSysTime = pinCredential.enrolledSysTime;
1311 return RESULT_SUCCESS;
1312 }
1313