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 #include "global_config_file_manager.h"
26
27 #define MAX_DUPLICATE_CHECK 100
28 #define PRE_APPLY_NUM 5
29 #define MEM_GROWTH_FACTOR 2
30 #define MAX_CREDENTIAL_RETURN 5000
31
32 #ifdef IAM_TEST_ENABLE
33 #define IAM_STATIC
34 #else
35 #define IAM_STATIC static
36 #endif
37
38 // Caches IDM user information.
39 IAM_STATIC LinkedList *g_userInfoList = NULL;
40
41 // Caches the current user to reduce the number of user list traversal times.
42 IAM_STATIC UserInfo *g_currentUser = NULL;
43
44 // Caches global config info.
45 IAM_STATIC GlobalConfigInfo g_globalConfigArray[MAX_GLOBAL_CONFIG_NUM];
46 IAM_STATIC uint32_t g_globalConfigInfoNum = 0;
47
48 typedef bool (*DuplicateCheckFunc)(LinkedList *collection, uint64_t value);
49
50 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId);
51 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num);
52 IAM_STATIC ResultCode DeleteUser(int32_t userId);
53 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList);
54 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList);
55 IAM_STATIC bool MatchCredentialById(const void *data, const void *condition);
56 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func);
57 IAM_STATIC bool IsUserValid(UserInfo *user);
58 IAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
59 bool *cachePinRemoved);
60 IAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved);
61 IAM_STATIC ResultCode ClearInvalidData(void);
62
InitUserInfoList(void)63 ResultCode InitUserInfoList(void)
64 {
65 LOG_INFO("InitUserInfoList start");
66 if (g_userInfoList != NULL) {
67 DestroyUserInfoList();
68 g_userInfoList = NULL;
69 }
70 g_userInfoList = LoadFileInfo();
71 if (g_userInfoList == NULL) {
72 LOG_ERROR("load file info failed");
73 return RESULT_NEED_INIT;
74 }
75 ResultCode ret = ClearInvalidData();
76 if (ret != RESULT_SUCCESS) {
77 LOG_ERROR("clear invalid user failed");
78 DestroyUserInfoList();
79 return ret;
80 }
81 ret = LoadGlobalConfigInfo(g_globalConfigArray, MAX_GLOBAL_CONFIG_NUM, &g_globalConfigInfoNum);
82 if (ret != RESULT_SUCCESS) {
83 LOG_ERROR("load global config info failed");
84 }
85 LOG_INFO("InitUserInfoList end");
86 return RESULT_SUCCESS;
87 }
88
DestroyUserInfoList(void)89 void DestroyUserInfoList(void)
90 {
91 DestroyLinkedList(g_userInfoList);
92 g_userInfoList = NULL;
93 }
94
MatchUserInfo(const void * data,const void * condition)95 IAM_STATIC bool MatchUserInfo(const void *data, const void *condition)
96 {
97 if (data == NULL || condition == NULL) {
98 LOG_ERROR("please check invalid node");
99 return false;
100 }
101 const UserInfo *userInfo = (const UserInfo *)data;
102 int32_t userId = *(const int32_t *)condition;
103 if (userInfo->userId == userId) {
104 return true;
105 }
106 return false;
107 }
108
IsUserInfoValid(UserInfo * userInfo)109 IAM_STATIC bool IsUserInfoValid(UserInfo *userInfo)
110 {
111 if (userInfo == NULL) {
112 LOG_ERROR("userInfo is null");
113 return false;
114 }
115 if (userInfo->credentialInfoList == NULL) {
116 LOG_ERROR("credentialInfoList is null");
117 return false;
118 }
119 if (userInfo->enrolledInfoList == NULL) {
120 LOG_ERROR("enrolledInfoList is null");
121 return false;
122 }
123 return true;
124 }
125
GetSecureUid(int32_t userId,uint64_t * secUid)126 ResultCode GetSecureUid(int32_t userId, uint64_t *secUid)
127 {
128 if (secUid == NULL) {
129 LOG_ERROR("secUid is null");
130 return RESULT_BAD_PARAM;
131 }
132 UserInfo *user = QueryUserInfo(userId);
133 if (user == NULL) {
134 LOG_ERROR("can't find this user");
135 return RESULT_NOT_FOUND;
136 }
137 *secUid = user->secUid;
138 return RESULT_SUCCESS;
139 }
140
GetEnrolledInfoAuthType(int32_t userId,uint32_t authType,EnrolledInfoHal * enrolledInfo)141 ResultCode GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo)
142 {
143 if (enrolledInfo == NULL) {
144 LOG_ERROR("enrolledInfo is null");
145 return RESULT_BAD_PARAM;
146 }
147 UserInfo *user = QueryUserInfo(userId);
148 if (user == NULL) {
149 LOG_ERROR("can't find this user");
150 return RESULT_NOT_FOUND;
151 }
152 if (user->enrolledInfoList == NULL) {
153 LOG_ERROR("enrolledInfoList is null");
154 return RESULT_UNKNOWN;
155 }
156
157 LinkedListNode *temp = user->enrolledInfoList->head;
158 while (temp != NULL) {
159 EnrolledInfoHal *nodeInfo = temp->data;
160 if (nodeInfo != NULL && nodeInfo->authType == authType) {
161 *enrolledInfo = *nodeInfo;
162 return RESULT_SUCCESS;
163 }
164 temp = temp->next;
165 }
166
167 return RESULT_NOT_FOUND;
168 }
169
GetEnrolledInfo(int32_t userId,EnrolledInfoHal ** enrolledInfos,uint32_t * num)170 ResultCode GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num)
171 {
172 if (enrolledInfos == NULL || num == NULL) {
173 LOG_ERROR("param is invalid");
174 return RESULT_BAD_PARAM;
175 }
176 UserInfo *user = QueryUserInfo(userId);
177 if (!IsUserInfoValid(user)) {
178 LOG_ERROR("can't find this user");
179 return RESULT_NOT_FOUND;
180 }
181 return GetAllEnrolledInfoFromUser(user, enrolledInfos, num);
182 }
183
DeleteUserInfo(int32_t userId,LinkedList ** creds)184 ResultCode DeleteUserInfo(int32_t userId, LinkedList **creds)
185 {
186 if (creds == NULL) {
187 LOG_ERROR("param is invalid");
188 return RESULT_BAD_PARAM;
189 }
190 UserInfo *user = QueryUserInfo(userId);
191 if (!IsUserInfoValid(user)) {
192 LOG_ERROR("can't find this user");
193 return RESULT_NOT_FOUND;
194 }
195 CredentialCondition condition = {};
196 SetCredentialConditionUserId(&condition, userId);
197 *creds = QueryCredentialLimit(&condition);
198 if (*creds == NULL) {
199 LOG_ERROR("query credential failed");
200 return RESULT_UNKNOWN;
201 }
202 g_currentUser = NULL;
203
204 ResultCode ret = DeleteUser(userId);
205 if (ret != RESULT_SUCCESS) {
206 LOG_ERROR("deleteUser failed");
207 DestroyLinkedList(*creds);
208 *creds = NULL;
209 return ret;
210 }
211 ret = UpdateFileInfo(g_userInfoList);
212 if (ret != RESULT_SUCCESS) {
213 LOG_ERROR("update file info failed");
214 DestroyLinkedList(*creds);
215 *creds = NULL;
216 return ret;
217 }
218 return ret;
219 }
220
QueryUserInfo(int32_t userId)221 IAM_STATIC UserInfo *QueryUserInfo(int32_t userId)
222 {
223 UserInfo *user = g_currentUser;
224 if (user != NULL && user->userId == userId) {
225 return user;
226 }
227 if (g_userInfoList == NULL) {
228 return NULL;
229 }
230 LinkedListNode *temp = g_userInfoList->head;
231 while (temp != NULL) {
232 user = (UserInfo *)temp->data;
233 if (user != NULL && user->userId == userId) {
234 break;
235 }
236 temp = temp->next;
237 }
238 if (temp == NULL) {
239 return NULL;
240 }
241 if (IsUserInfoValid(user)) {
242 g_currentUser = user;
243 return user;
244 }
245 return NULL;
246 }
247
GetAllEnrolledInfoFromUser(UserInfo * userInfo,EnrolledInfoHal ** enrolledInfos,uint32_t * num)248 IAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num)
249 {
250 LinkedList *enrolledInfoList = userInfo->enrolledInfoList;
251 uint32_t size = enrolledInfoList->getSize(enrolledInfoList);
252 *enrolledInfos = Malloc(sizeof(EnrolledInfoHal) * size);
253 if (*enrolledInfos == NULL) {
254 LOG_ERROR("enrolledInfos malloc failed");
255 return RESULT_NO_MEMORY;
256 }
257 (void)memset_s(*enrolledInfos, sizeof(EnrolledInfoHal) * size, 0, sizeof(EnrolledInfoHal) * size);
258 LinkedListNode *temp = enrolledInfoList->head;
259 ResultCode result = RESULT_SUCCESS;
260 for (*num = 0; *num < size; (*num)++) {
261 if (temp == NULL) {
262 LOG_ERROR("temp node is null, something wrong");
263 result = RESULT_BAD_PARAM;
264 goto EXIT;
265 }
266 EnrolledInfoHal *tempInfo = (EnrolledInfoHal *)temp->data;
267 if (memcpy_s(*enrolledInfos + *num, sizeof(EnrolledInfoHal) * (size - *num),
268 tempInfo, sizeof(EnrolledInfoHal)) != EOK) {
269 LOG_ERROR("copy the %u information failed", *num);
270 result = RESULT_NO_MEMORY;
271 goto EXIT;
272 }
273 temp = temp->next;
274 }
275
276 EXIT:
277 if (result != RESULT_SUCCESS) {
278 Free(*enrolledInfos);
279 *enrolledInfos = NULL;
280 *num = 0;
281 }
282 return result;
283 }
284
IsSecureUidDuplicate(LinkedList * userInfoList,uint64_t secureUid)285 IAM_STATIC bool IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid)
286 {
287 if (userInfoList == NULL) {
288 LOG_ERROR("the user list is empty, and the branch is abnormal");
289 return false;
290 }
291
292 LinkedListNode *temp = userInfoList->head;
293 UserInfo *userInfo = NULL;
294 while (temp != NULL) {
295 userInfo = (UserInfo *)temp->data;
296 if (userInfo != NULL && userInfo->secUid == secureUid) {
297 return true;
298 }
299 temp = temp->next;
300 }
301
302 return false;
303 }
304
CreateUser(int32_t userId,int32_t userType)305 IAM_STATIC UserInfo *CreateUser(int32_t userId, int32_t userType)
306 {
307 UserInfo *user = InitUserInfoNode();
308 if (!IsUserInfoValid(user)) {
309 LOG_ERROR("user is invalid");
310 DestroyUserInfoNode(user);
311 return NULL;
312 }
313 user->userId = userId;
314 user->userType = userType;
315 ResultCode ret = GenerateDeduplicateUint64(g_userInfoList, &user->secUid, IsSecureUidDuplicate);
316 if (ret != RESULT_SUCCESS) {
317 LOG_ERROR("generate secureUid failed");
318 DestroyUserInfoNode(user);
319 return NULL;
320 }
321 return user;
322 }
323
DeleteUser(int32_t userId)324 IAM_STATIC ResultCode DeleteUser(int32_t userId)
325 {
326 if (g_userInfoList == NULL) {
327 return RESULT_BAD_PARAM;
328 }
329 return g_userInfoList->remove(g_userInfoList, &userId, MatchUserInfo, true);
330 }
331
IsCredentialIdDuplicate(LinkedList * userInfoList,uint64_t credentialId)332 IAM_STATIC bool IsCredentialIdDuplicate(LinkedList *userInfoList, uint64_t credentialId)
333 {
334 (void)userInfoList;
335 CredentialCondition condition = {};
336 SetCredentialConditionCredentialId(&condition, credentialId);
337 SetCredentialConditionNeedCachePin(&condition);
338 SetCredentialConditionNeedAbandonPin(&condition);
339 LinkedList *credList = QueryCredentialLimit(&condition);
340 if (credList == NULL) {
341 LOG_ERROR("query failed");
342 return true;
343 }
344 if (credList->getSize(credList) != 0) {
345 LOG_ERROR("duplicate credential id");
346 DestroyLinkedList(credList);
347 return true;
348 }
349 DestroyLinkedList(credList);
350 return false;
351 }
352
IsEnrolledIdDuplicate(LinkedList * enrolledList,uint64_t enrolledId)353 IAM_STATIC bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)
354 {
355 LinkedListNode *temp = enrolledList->head;
356 EnrolledInfoHal *enrolledInfo = NULL;
357 const static uint16_t num = 0xFFFF;
358 while (temp != NULL) {
359 enrolledInfo = (EnrolledInfoHal *)temp->data;
360 if ((enrolledInfo != NULL) && (enrolledInfo->enrolledId & num) == (enrolledId & num)) {
361 return true;
362 }
363 temp = temp->next;
364 }
365
366 return false;
367 }
368
GenerateDeduplicateUint64(LinkedList * collection,uint64_t * destValue,DuplicateCheckFunc func)369 IAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)
370 {
371 if (collection == NULL || destValue == NULL || func == NULL) {
372 LOG_ERROR("param is null");
373 return RESULT_BAD_PARAM;
374 }
375
376 for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) {
377 uint64_t tempRandom;
378 if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
379 LOG_ERROR("get random failed");
380 return RESULT_GENERAL_ERROR;
381 }
382 if (!func(collection, tempRandom)) {
383 *destValue = tempRandom;
384 return RESULT_SUCCESS;
385 }
386 }
387
388 LOG_ERROR("generate random failed");
389 return RESULT_GENERAL_ERROR;
390 }
391
UpdateEnrolledId(LinkedList * enrolledList,uint32_t authType)392 IAM_STATIC ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)
393 {
394 LinkedListNode *temp = enrolledList->head;
395 EnrolledInfoHal *enrolledInfo = NULL;
396 while (temp != NULL) {
397 EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data;
398 if (nodeData != NULL && nodeData->authType == authType) {
399 enrolledInfo = nodeData;
400 break;
401 }
402 temp = temp->next;
403 }
404
405 if (enrolledInfo != NULL) {
406 return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
407 }
408
409 enrolledInfo = Malloc(sizeof(EnrolledInfoHal));
410 if (enrolledInfo == NULL) {
411 LOG_ERROR("enrolledInfo malloc failed");
412 return RESULT_NO_MEMORY;
413 }
414 enrolledInfo->authType = authType;
415 ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
416 if (ret != RESULT_SUCCESS) {
417 LOG_ERROR("generate enrolledId failed");
418 Free(enrolledInfo);
419 return ret;
420 }
421 ret = enrolledList->insert(enrolledList, enrolledInfo);
422 if (ret != RESULT_SUCCESS) {
423 LOG_ERROR("enrolledInfo insert failed");
424 Free(enrolledInfo);
425 }
426 return ret;
427 }
428
429 // add for reliable pin updates
GetRealAuthTypeForEnrolledId(uint32_t authType)430 IAM_STATIC uint32_t GetRealAuthTypeForEnrolledId(uint32_t authType)
431 {
432 if (authType == DEFAULT_AUTH_TYPE) {
433 return PIN_AUTH;
434 }
435 return authType;
436 }
437
AddCredentialToUser(UserInfo * user,CredentialInfoHal * credentialInfo)438 IAM_STATIC ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)
439 {
440 if (g_userInfoList == NULL) {
441 LOG_ERROR("g_userInfoList is uninitialized");
442 return RESULT_NEED_INIT;
443 }
444 LinkedList *credentialList = user->credentialInfoList;
445 LinkedList *enrolledList = user->enrolledInfoList;
446 if (credentialList->getSize(credentialList) >= MAX_CREDENTIAL) {
447 LOG_ERROR("the number of credentials reaches the maximum");
448 return RESULT_EXCEED_LIMIT;
449 }
450
451 ResultCode ret = UpdateEnrolledId(enrolledList, GetRealAuthTypeForEnrolledId(credentialInfo->authType));
452 if (ret != RESULT_SUCCESS) {
453 LOG_ERROR("update enrolledId failed");
454 return ret;
455 }
456 ret = GenerateDeduplicateUint64(g_userInfoList, &credentialInfo->credentialId, IsCredentialIdDuplicate);
457 if (ret != RESULT_SUCCESS) {
458 LOG_ERROR("GenerateDeduplicateUint64 failed");
459 return ret;
460 }
461 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
462 bool isRemoved = false;
463 RemoveCachePin(user, &isRemoved);
464 }
465 CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal));
466 if (credential == NULL) {
467 LOG_ERROR("credential malloc failed");
468 return RESULT_NO_MEMORY;
469 }
470 if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) {
471 LOG_ERROR("credential copy failed");
472 Free(credential);
473 return RESULT_BAD_COPY;
474 }
475 credential->enrolledSysTime = GetReeTime();
476 ret = credentialList->insert(credentialList, credential);
477 if (ret != RESULT_SUCCESS) {
478 LOG_ERROR("insert credential failed");
479 Free(credential);
480 }
481 return ret;
482 }
483
AddUser(int32_t userId,CredentialInfoHal * credentialInfo,int32_t userType)484 IAM_STATIC ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
485 {
486 if (g_userInfoList == NULL) {
487 LOG_ERROR("please init");
488 return RESULT_NEED_INIT;
489 }
490 if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) {
491 LOG_ERROR("the number of users reaches the maximum");
492 return RESULT_EXCEED_LIMIT;
493 }
494
495 UserInfo *user = QueryUserInfo(userId);
496 if (user != NULL) {
497 LOG_ERROR("Please check pin");
498 return RESULT_BAD_PARAM;
499 }
500
501 user = CreateUser(userId, userType);
502 if (user == NULL) {
503 LOG_ERROR("create user failed");
504 return RESULT_UNKNOWN;
505 }
506 LOG_INFO("user userType %{public}d", user->userType);
507 ResultCode ret = AddCredentialToUser(user, credentialInfo);
508 if (ret != RESULT_SUCCESS) {
509 LOG_ERROR("add credential to user failed");
510 goto FAIL;
511 }
512
513 ret = g_userInfoList->insert(g_userInfoList, user);
514 if (ret != RESULT_SUCCESS) {
515 LOG_ERROR("insert failed");
516 goto FAIL;
517 }
518 return ret;
519
520 FAIL:
521 DestroyUserInfoNode(user);
522 return ret;
523 }
524
AddCredentialInfo(int32_t userId,CredentialInfoHal * credentialInfo,int32_t userType)525 ResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
526 {
527 if ((credentialInfo == NULL) || (credentialInfo->authType == DEFAULT_AUTH_TYPE)) {
528 LOG_ERROR("credentialInfo is invalid");
529 return RESULT_BAD_PARAM;
530 }
531 UserInfo *user = QueryUserInfo(userId);
532 if (user == NULL && credentialInfo->authType == PIN_AUTH) {
533 ResultCode ret = AddUser(userId, credentialInfo, userType);
534 if (ret != RESULT_SUCCESS) {
535 LOG_ERROR("add 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 if (user == NULL) {
545 LOG_ERROR("user is null");
546 return RESULT_BAD_PARAM;
547 }
548 if (credentialInfo->authType == PIN_AUTH) {
549 CredentialCondition condition = {};
550 SetCredentialConditionAuthType(&condition, PIN_AUTH);
551 SetCredentialConditionUserId(&condition, userId);
552 LinkedList *credList = QueryCredentialLimit(&condition);
553 if (credList == NULL) {
554 LOG_ERROR("query credential failed");
555 return RESULT_UNKNOWN;
556 }
557 if (credList->getSize(credList) != 0) {
558 LOG_INFO("cache pin");
559 // add for reliable pin updates
560 credentialInfo->authType = DEFAULT_AUTH_TYPE;
561 }
562 DestroyLinkedList(credList);
563 }
564 ResultCode ret = AddCredentialToUser(user, credentialInfo);
565 if (ret != RESULT_SUCCESS) {
566 LOG_ERROR("add credential to user failed");
567 return ret;
568 }
569 ret = UpdateFileInfo(g_userInfoList);
570 if (ret != RESULT_SUCCESS) {
571 LOG_ERROR("updateFileInfo failed");
572 }
573 return ret;
574 }
575
MatchCredentialById(const void * data,const void * condition)576 IAM_STATIC bool MatchCredentialById(const void *data, const void *condition)
577 {
578 if (data == NULL || condition == NULL) {
579 return false;
580 }
581 const CredentialInfoHal *credentialInfo = (const CredentialInfoHal *)data;
582 uint64_t credentialId = *(const uint64_t *)condition;
583 if (credentialInfo->credentialId == credentialId) {
584 return true;
585 }
586 return false;
587 }
588
MatchEnrolledInfoByType(const void * data,const void * condition)589 IAM_STATIC bool MatchEnrolledInfoByType(const void *data, const void *condition)
590 {
591 if (data == NULL || condition == NULL) {
592 return false;
593 }
594 const EnrolledInfoHal *enrolledInfo = (const EnrolledInfoHal *)data;
595 uint32_t authType = *(const uint32_t *)condition;
596 if (enrolledInfo->authType == authType) {
597 return true;
598 }
599 return false;
600 }
601
RemoveCachePin(UserInfo * user,bool * isRemoved)602 IAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved)
603 {
604 LOG_INFO("RemoveCachePin start");
605 LinkedListNode *temp = user->credentialInfoList->head;
606 CredentialInfoHal *credentialInfoCache = NULL;
607 while (temp != NULL) {
608 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
609 if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
610 credentialInfoCache = nodeData;
611 break;
612 }
613 temp = temp->next;
614 }
615 if (credentialInfoCache == NULL) {
616 LOG_INFO("RemoveCachePin no cache pin");
617 *isRemoved = false;
618 return;
619 }
620 uint64_t credentialId = credentialInfoCache->credentialId;
621 ResultCode ret = (user->credentialInfoList)->remove(
622 user->credentialInfoList, &credentialId, MatchCredentialById, true);
623 if (ret != RESULT_SUCCESS) {
624 LOG_ERROR("remove credential failed");
625 *isRemoved = false;
626 return;
627 }
628 LOG_ERROR("remove credential success");
629 *isRemoved = true;
630 }
631
ClearCachePin(int32_t userId)632 void ClearCachePin(int32_t userId)
633 {
634 LOG_INFO("ClearCachePin start");
635 UserInfo *user = QueryUserInfo(userId);
636 if (user == NULL) {
637 LOG_ERROR("can't find this user");
638 return;
639 }
640
641 bool isRemoved = false;
642 RemoveCachePin(user, &isRemoved);
643 if (isRemoved && UpdateFileInfo(g_userInfoList) != RESULT_SUCCESS) {
644 LOG_ERROR("ClearCachePin save fail");
645 return;
646 }
647 }
648
SwitchSubType(UserInfo * user)649 IAM_STATIC void SwitchSubType(UserInfo *user)
650 {
651 uint64_t tmpSubType = user->pinSubType;
652 user->pinSubType = user->cachePinSubType;
653 user->cachePinSubType = tmpSubType;
654 }
655
656 // add for reliable pin updates
DeletePinCredentialInfo(UserInfo * user)657 IAM_STATIC ResultCode DeletePinCredentialInfo(UserInfo *user)
658 {
659 LOG_INFO("DeletePinCredentialInfo start");
660 LinkedListNode *temp = user->credentialInfoList->head;
661 CredentialInfoHal *credentialInfoOld = NULL;
662 CredentialInfoHal *credentialInfoCache = NULL;
663 while (temp != NULL) {
664 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
665 if (nodeData != NULL && nodeData->authType == PIN_AUTH) {
666 credentialInfoOld = nodeData;
667 }
668 if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
669 credentialInfoCache = nodeData;
670 }
671 temp = temp->next;
672 }
673 if (credentialInfoOld == NULL || credentialInfoCache == NULL) {
674 LOG_ERROR("no cache pin exist");
675 return RESULT_GENERAL_ERROR;
676 }
677 credentialInfoOld->authType = DEFAULT_AUTH_TYPE;
678 credentialInfoCache->authType = PIN_AUTH;
679 SwitchSubType(user);
680 ResultCode result = UpdateFileInfo(g_userInfoList);
681 if (result == RESULT_SUCCESS) {
682 LOG_INFO("switch cache pin success");
683 ClearCachePin(user->userId);
684 return result;
685 }
686 LOG_ERROR("switch cache pin fail");
687 credentialInfoOld->authType = PIN_AUTH;
688 credentialInfoCache->authType = DEFAULT_AUTH_TYPE;
689 SwitchSubType(user);
690 return RESULT_GENERAL_ERROR;
691 }
692
DeleteCredentialInfo(int32_t userId,uint64_t credentialId,CredentialInfoHal * credentialInfo)693 ResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
694 {
695 if (credentialInfo == NULL) {
696 LOG_ERROR("param is invalid");
697 return RESULT_BAD_PARAM;
698 }
699
700 UserInfo *user = QueryUserInfo(userId);
701 if (user == NULL) {
702 LOG_ERROR("can't find this user");
703 return RESULT_BAD_PARAM;
704 }
705
706 LinkedList *credentialList = user->credentialInfoList;
707 CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList);
708 if (credentialQuery == NULL) {
709 LOG_ERROR("credentialQuery is null");
710 return RESULT_UNKNOWN;
711 }
712 if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
713 LOG_ERROR("copy failed");
714 return RESULT_BAD_COPY;
715 }
716 if (credentialInfo->authType == PIN_AUTH && !credentialInfo->isAbandoned) {
717 return DeletePinCredentialInfo(user);
718 }
719 ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true);
720 if (ret != RESULT_SUCCESS) {
721 LOG_ERROR("remove credential failed");
722 return ret;
723 }
724 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
725 return UpdateFileInfo(g_userInfoList);
726 }
727 credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList);
728 if (credentialQuery != NULL) {
729 return UpdateFileInfo(g_userInfoList);
730 }
731
732 LinkedList *enrolledInfoList = user->enrolledInfoList;
733 if (enrolledInfoList == NULL) {
734 LOG_ERROR("enrolledInfoList is null");
735 return RESULT_UNKNOWN;
736 }
737 ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true);
738 if (ret != RESULT_SUCCESS) {
739 LOG_ERROR("remove enrolledInfo failed");
740 return ret;
741 }
742
743 return UpdateFileInfo(g_userInfoList);
744 }
745
QueryCredentialById(uint64_t credentialId,LinkedList * credentialList)746 IAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)
747 {
748 if (credentialList == NULL) {
749 return NULL;
750 }
751 LinkedListNode *temp = credentialList->head;
752 CredentialInfoHal *credentialInfo = NULL;
753 while (temp != NULL) {
754 CredentialInfoHal *nodeData = (CredentialInfoHal *)temp->data;
755 if (nodeData != NULL && nodeData->credentialId == credentialId) {
756 credentialInfo = nodeData;
757 break;
758 }
759 temp = temp->next;
760 }
761 return credentialInfo;
762 }
763
QueryCredentialByAuthType(uint32_t authType,LinkedList * credentialList)764 IAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)
765 {
766 if (credentialList == NULL) {
767 return NULL;
768 }
769 LinkedListNode *temp = credentialList->head;
770 CredentialInfoHal *credentialInfo = NULL;
771 while (temp != NULL) {
772 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
773 if (nodeData != NULL && nodeData->authType == authType) {
774 credentialInfo = nodeData;
775 break;
776 }
777 temp = temp->next;
778 }
779 return credentialInfo;
780 }
781
IsCredentialIdMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)782 IAM_STATIC bool IsCredentialIdMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
783 {
784 if ((limit->conditionFactor & CREDENTIAL_CONDITION_CREDENTIAL_ID) != 0 &&
785 limit->credentialId != credentialInfo->credentialId) {
786 return false;
787 }
788 return true;
789 }
790
IsAuthTypeMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)791 IAM_STATIC bool IsAuthTypeMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
792 {
793 if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
794 if ((limit->conditionFactor & CREDENTIAL_CONDITION_CACHE_PIN) != 0) {
795 return true;
796 }
797 if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_CACHE_PIN) == 0) {
798 return false;
799 }
800 } else {
801 if ((limit->conditionFactor & CREDENTIAL_CONDITION_AUTH_TYPE) != 0 &&
802 limit->authType != credentialInfo->authType) {
803 return false;
804 }
805 if ((limit->conditionFactor & CREDENTIAL_CONDITION_CACHE_PIN) != 0) {
806 return false;
807 }
808 }
809 return true;
810 }
811
IsTemplateIdMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)812 IAM_STATIC bool IsTemplateIdMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
813 {
814 if ((limit->conditionFactor & CREDENTIAL_CONDITION_TEMPLATE_ID) != 0 &&
815 limit->templateId != credentialInfo->templateId) {
816 return false;
817 }
818 return true;
819 }
820
IsExecutorSensorHintMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)821 IAM_STATIC bool IsExecutorSensorHintMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
822 {
823 if ((limit->conditionFactor & CREDENTIAL_CONDITION_SENSOR_HINT) != 0 &&
824 limit->executorSensorHint != INVALID_SENSOR_HINT &&
825 limit->executorSensorHint != credentialInfo->executorSensorHint) {
826 return false;
827 }
828 return true;
829 }
830
IsExecutorMatcherMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)831 IAM_STATIC bool IsExecutorMatcherMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
832 {
833 if ((limit->conditionFactor & CREDENTIAL_CONDITION_EXECUTOR_MATCHER) != 0 &&
834 limit->executorMatcher != credentialInfo->executorMatcher) {
835 return false;
836 }
837 return true;
838 }
839
IsAbandonedMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)840 IAM_STATIC bool IsAbandonedMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
841 {
842 if ((limit->conditionFactor & CREDENTIAL_CONDITION_ABANDON) != 0) {
843 if (credentialInfo->isAbandoned) {
844 return true;
845 }
846 return false;
847 }
848 if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_ABANDON) != 0) {
849 return true;
850 }
851 if (!credentialInfo->isAbandoned) {
852 return true;
853 }
854
855 return false;
856 }
857
858 // do not cotain cache pin credential
IsCredMatch(const CredentialCondition * limit,const CredentialInfoHal * credentialInfo)859 IAM_STATIC bool IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
860 {
861 if (!IsCredentialIdMatch(limit, credentialInfo)) {
862 return false;
863 }
864 if (!IsAuthTypeMatch(limit, credentialInfo)) {
865 return false;
866 }
867 if (!IsTemplateIdMatch(limit, credentialInfo)) {
868 return false;
869 }
870 if (!IsExecutorSensorHintMatch(limit, credentialInfo)) {
871 return false;
872 }
873 if (!IsExecutorMatcherMatch(limit, credentialInfo)) {
874 return false;
875 }
876 if (!IsAbandonedMatch(limit, credentialInfo)) {
877 return false;
878 }
879 return true;
880 }
881
IsUserMatch(const CredentialCondition * limit,const UserInfo * user)882 IAM_STATIC bool IsUserMatch(const CredentialCondition *limit, const UserInfo *user)
883 {
884 if ((limit->conditionFactor & CREDENTIAL_CONDITION_USER_ID) != 0 && limit->userId != user->userId) {
885 return false;
886 }
887 return true;
888 }
889
890 // do not cotain cache pin credential
TraverseCredentialList(const CredentialCondition * limit,const LinkedList * credentialList,LinkedList * credListGet)891 IAM_STATIC ResultCode TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList,
892 LinkedList *credListGet)
893 {
894 if (credentialList == NULL) {
895 LOG_ERROR("credentialList is null");
896 return RESULT_GENERAL_ERROR;
897 }
898 LinkedListNode *temp = credentialList->head;
899 while (temp != NULL) {
900 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
901 if (nodeData == NULL) {
902 LOG_ERROR("nodeData is null");
903 return RESULT_UNKNOWN;
904 }
905 if (!IsCredMatch(limit, nodeData)) {
906 temp = temp->next;
907 continue;
908 }
909 CredentialInfoHal *copy = (CredentialInfoHal *)Malloc(sizeof(CredentialInfoHal));
910 if (copy == NULL) {
911 LOG_ERROR("copy malloc failed");
912 return RESULT_NO_MEMORY;
913 }
914 *copy = *nodeData;
915 ResultCode ret = credListGet->insert(credListGet, copy);
916 if (ret != RESULT_SUCCESS) {
917 LOG_ERROR("insert failed");
918 Free(copy);
919 return ret;
920 }
921 temp = temp->next;
922 }
923 return RESULT_SUCCESS;
924 }
925
926 // do not cotain cache pin credential
QueryCredentialLimit(const CredentialCondition * limit)927 LinkedList *QueryCredentialLimit(const CredentialCondition *limit)
928 {
929 if (limit == NULL) {
930 LOG_ERROR("limit is null");
931 return NULL;
932 }
933 if (g_userInfoList == NULL) {
934 LOG_ERROR("g_userInfoList is null");
935 return NULL;
936 }
937 LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
938 if (credList == NULL) {
939 LOG_ERROR("credList is null");
940 return NULL;
941 }
942 LinkedListNode *temp = g_userInfoList->head;
943 while (temp != NULL) {
944 UserInfo *user = (UserInfo *)temp->data;
945 if (user == NULL) {
946 LOG_ERROR("node data is null");
947 DestroyLinkedList(credList);
948 return NULL;
949 }
950 if (IsUserMatch(limit, user)) {
951 ResultCode ret = TraverseCredentialList(limit, user->credentialInfoList, credList);
952 if (ret != RESULT_SUCCESS) {
953 LOG_ERROR("TraverseCredentialList failed");
954 DestroyLinkedList(credList);
955 return NULL;
956 }
957 }
958 temp = temp->next;
959 }
960 return credList;
961 }
962
QueryCredentialUserId(uint64_t credentialId,int32_t * userId)963 ResultCode QueryCredentialUserId(uint64_t credentialId, int32_t *userId)
964 {
965 if (userId == NULL) {
966 LOG_ERROR("userId is null");
967 return RESULT_BAD_PARAM;
968 }
969 if (g_userInfoList == NULL) {
970 LOG_ERROR("g_userInfoList is null");
971 return RESULT_NEED_INIT;
972 }
973 LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
974 if (credList == NULL) {
975 LOG_ERROR("credList is null");
976 return RESULT_NO_MEMORY;
977 }
978 LinkedListNode *temp = g_userInfoList->head;
979 CredentialCondition condition = {};
980 SetCredentialConditionCredentialId(&condition, credentialId);
981 SetCredentialConditionNeedAbandonPin(&condition);
982 while (temp != NULL) {
983 UserInfo *user = (UserInfo *)temp->data;
984 if (user == NULL) {
985 LOG_ERROR("user is null");
986 DestroyLinkedList(credList);
987 return RESULT_UNKNOWN;
988 }
989 ResultCode ret = TraverseCredentialList(&condition, user->credentialInfoList, credList);
990 if (ret != RESULT_SUCCESS) {
991 LOG_ERROR("TraverseCredentialList failed");
992 DestroyLinkedList(credList);
993 return RESULT_UNKNOWN;
994 }
995 if (credList->getSize(credList) != 0) {
996 DestroyLinkedList(credList);
997 *userId = user->userId;
998 return RESULT_SUCCESS;
999 }
1000 temp = temp->next;
1001 }
1002 DestroyLinkedList(credList);
1003 LOG_ERROR("can't find this credential");
1004 return RESULT_NOT_FOUND;
1005 }
1006
SetPinSubType(int32_t userId,uint64_t pinSubType)1007 ResultCode SetPinSubType(int32_t userId, uint64_t pinSubType)
1008 {
1009 UserInfo *user = QueryUserInfo(userId);
1010 if (user == NULL) {
1011 LOG_ERROR("can't find this user");
1012 return RESULT_NOT_FOUND;
1013 }
1014 user->pinSubType = pinSubType;
1015 return RESULT_SUCCESS;
1016 }
1017
GetPinSubType(int32_t userId,uint64_t * pinSubType)1018 ResultCode GetPinSubType(int32_t userId, uint64_t *pinSubType)
1019 {
1020 if (pinSubType == NULL) {
1021 LOG_ERROR("pinSubType is null");
1022 return RESULT_BAD_PARAM;
1023 }
1024 UserInfo *user = QueryUserInfo(userId);
1025 if (user == NULL) {
1026 LOG_ERROR("can't find this user");
1027 return RESULT_NOT_FOUND;
1028 }
1029 *pinSubType = user->pinSubType;
1030 return RESULT_SUCCESS;
1031 }
1032
SetCredentialConditionCredentialId(CredentialCondition * condition,uint64_t credentialId)1033 void SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId)
1034 {
1035 if (condition == NULL) {
1036 LOG_ERROR("condition is null");
1037 return;
1038 }
1039 condition->credentialId = credentialId;
1040 condition->conditionFactor |= CREDENTIAL_CONDITION_CREDENTIAL_ID;
1041 }
1042
SetCredentialConditionTemplateId(CredentialCondition * condition,uint64_t templateId)1043 void SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId)
1044 {
1045 if (condition == NULL) {
1046 LOG_ERROR("condition is null");
1047 return;
1048 }
1049 condition->templateId = templateId;
1050 condition->conditionFactor |= CREDENTIAL_CONDITION_TEMPLATE_ID;
1051 }
1052
SetCredentialConditionAuthType(CredentialCondition * condition,uint32_t authType)1053 void SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType)
1054 {
1055 if (condition == NULL) {
1056 LOG_ERROR("condition is null");
1057 return;
1058 }
1059 condition->authType = authType;
1060 condition->conditionFactor |= CREDENTIAL_CONDITION_AUTH_TYPE;
1061 }
1062
SetCredentialConditionExecutorSensorHint(CredentialCondition * condition,uint32_t executorSensorHint)1063 void SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint)
1064 {
1065 if (condition == NULL) {
1066 LOG_ERROR("condition is null");
1067 return;
1068 }
1069 condition->executorSensorHint = executorSensorHint;
1070 condition->conditionFactor |= CREDENTIAL_CONDITION_SENSOR_HINT;
1071 }
1072
SetCredentialConditionExecutorMatcher(CredentialCondition * condition,uint32_t executorMatcher)1073 void SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher)
1074 {
1075 if (condition == NULL) {
1076 LOG_ERROR("condition is null");
1077 return;
1078 }
1079 condition->executorMatcher = executorMatcher;
1080 condition->conditionFactor |= CREDENTIAL_CONDITION_EXECUTOR_MATCHER;
1081 }
1082
SetCredentialConditionUserId(CredentialCondition * condition,int32_t userId)1083 void SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId)
1084 {
1085 if (condition == NULL) {
1086 LOG_ERROR("condition is null");
1087 return;
1088 }
1089 condition->userId = userId;
1090 condition->conditionFactor |= CREDENTIAL_CONDITION_USER_ID;
1091 }
1092
SetCredentialConditionNeedCachePin(CredentialCondition * condition)1093 void SetCredentialConditionNeedCachePin(CredentialCondition *condition)
1094 {
1095 if (condition == NULL) {
1096 LOG_ERROR("condition is null");
1097 return;
1098 }
1099 condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_CACHE_PIN;
1100 }
1101
SetCredentialConditionNeedAbandonPin(CredentialCondition * condition)1102 void SetCredentialConditionNeedAbandonPin(CredentialCondition *condition)
1103 {
1104 if (condition == NULL) {
1105 LOG_ERROR("condition is null");
1106 return;
1107 }
1108 condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_ABANDON;
1109 }
1110
SetCredentialConditionAbandonPin(CredentialCondition * condition)1111 void SetCredentialConditionAbandonPin(CredentialCondition *condition)
1112 {
1113 if (condition == NULL) {
1114 LOG_ERROR("condition is null");
1115 return;
1116 }
1117 condition->conditionFactor |= CREDENTIAL_CONDITION_ABANDON;
1118 }
1119
SetCredentialConditionCachePin(CredentialCondition * condition)1120 void SetCredentialConditionCachePin(CredentialCondition *condition)
1121 {
1122 if (condition == NULL) {
1123 LOG_ERROR("condition is null");
1124 return;
1125 }
1126 condition->conditionFactor |= CREDENTIAL_CONDITION_CACHE_PIN;
1127 }
1128
IsUserValid(UserInfo * user)1129 IAM_STATIC bool IsUserValid(UserInfo *user)
1130 {
1131 LinkedList *credentialInfoList = user->credentialInfoList;
1132 CredentialInfoHal *pinCredential = QueryCredentialByAuthType(PIN_AUTH, credentialInfoList);
1133 if (pinCredential == NULL) {
1134 LOG_INFO("user is invalid, userId: %{public}d", user->userId);
1135 return false;
1136 }
1137 return true;
1138 }
1139
GetInvalidUser(int32_t * invalidUserId,uint32_t maxUserCount,uint32_t * userCount,bool * cachePinRemoved)1140 IAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
1141 bool *cachePinRemoved)
1142 {
1143 LOG_INFO("get invalid user start");
1144 if (g_userInfoList == NULL) {
1145 LOG_ERROR("g_userInfoList is null");
1146 return RESULT_GENERAL_ERROR;
1147 }
1148
1149 LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1150 if (iterator == NULL) {
1151 LOG_ERROR("create iterator failed");
1152 return RESULT_NO_MEMORY;
1153 }
1154
1155 UserInfo *user = NULL;
1156 *userCount = 0;
1157 while (iterator->hasNext(iterator)) {
1158 user = (UserInfo *)iterator->next(iterator);
1159 if (user == NULL) {
1160 LOG_ERROR("userinfo list node is null, please check");
1161 continue;
1162 }
1163
1164 if (*userCount >= maxUserCount) {
1165 LOG_ERROR("too many users");
1166 break;
1167 }
1168
1169 if (!IsUserValid(user)) {
1170 invalidUserId[*userCount] = user->userId;
1171 (*userCount)++;
1172 continue;
1173 }
1174
1175 bool isRemoved = false;
1176 RemoveCachePin(user, &isRemoved);
1177 if (isRemoved) {
1178 *cachePinRemoved = true;
1179 }
1180 CredentialInfoHal credentialInfo = {};
1181 (void)ClearAbandonExpiredCredential(user->userId, &credentialInfo);
1182 }
1183
1184 g_userInfoList->destroyIterator(iterator);
1185 return RESULT_SUCCESS;
1186 }
1187
ClearInvalidData(void)1188 IAM_STATIC ResultCode ClearInvalidData(void)
1189 {
1190 LOG_INFO("clear invalid user start");
1191 int32_t invalidUserId[MAX_USER] = {0};
1192 uint32_t userCount = 0;
1193 bool cachePinRemoved = false;
1194 if (GetInvalidUser(invalidUserId, MAX_USER, &userCount, &cachePinRemoved) != RESULT_SUCCESS) {
1195 LOG_ERROR("GetInvalidUser fail");
1196 return RESULT_GENERAL_ERROR;
1197 }
1198 ResultCode ret = RESULT_SUCCESS;
1199 for (uint32_t i = 0; i < userCount; ++i) {
1200 ret = DeleteUser(invalidUserId[i]);
1201 if (ret != RESULT_SUCCESS) {
1202 LOG_ERROR("delete invalid user fail, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1203 return ret;
1204 }
1205 LOG_INFO("delete invalid user success, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1206 }
1207
1208 if ((userCount != 0) || cachePinRemoved) {
1209 ret = UpdateFileInfo(g_userInfoList);
1210 if (ret != RESULT_SUCCESS) {
1211 LOG_ERROR("UpdateFileInfo fail, ret: %{public}d", ret);
1212 return ret;
1213 }
1214 }
1215 return RESULT_SUCCESS;
1216 }
1217
GetAllExtUserInfo(UserInfoResult * userInfos,uint32_t userInfoLen,uint32_t * userInfocount)1218 ResultCode GetAllExtUserInfo(UserInfoResult *userInfos, uint32_t userInfoLen, uint32_t *userInfocount)
1219 {
1220 LOG_INFO("get all user info start");
1221 if (userInfos == NULL || userInfocount == NULL || g_userInfoList == NULL) {
1222 LOG_ERROR("param is null");
1223 return RESULT_BAD_PARAM;
1224 }
1225
1226 LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1227 if (iterator == NULL) {
1228 LOG_ERROR("create iterator failed");
1229 return RESULT_NO_MEMORY;
1230 }
1231
1232 UserInfo *user = NULL;
1233 EnrolledInfoHal *enrolledInfoHal = NULL;
1234 *userInfocount = 0;
1235 while (iterator->hasNext(iterator)) {
1236 user = (UserInfo *)iterator->next(iterator);
1237 if (user == NULL) {
1238 LOG_ERROR("userinfo list node is null, please check");
1239 continue;
1240 }
1241
1242 if (*userInfocount >= userInfoLen) {
1243 LOG_ERROR("too many users");
1244 goto ERROR;
1245 }
1246
1247 userInfos[*userInfocount].userId = user->userId;
1248 userInfos[*userInfocount].secUid = user->secUid;
1249 userInfos[*userInfocount].pinSubType = (uint32_t)user->pinSubType;
1250
1251 ResultCode ret = GetAllEnrolledInfoFromUser(user, &enrolledInfoHal, &(userInfos[*userInfocount].enrollNum));
1252 if (ret != RESULT_SUCCESS) {
1253 LOG_ERROR("get enrolled info fail");
1254 goto ERROR;
1255 }
1256 if (userInfos[*userInfocount].enrollNum > MAX_ENROLL_OUTPUT) {
1257 LOG_ERROR("too many elements");
1258 free(enrolledInfoHal);
1259 goto ERROR;
1260 }
1261
1262 for (uint32_t i = 0; i < userInfos[*userInfocount].enrollNum; i++) {
1263 userInfos[*userInfocount].enrolledInfo[i].authType = enrolledInfoHal[i].authType;
1264 userInfos[*userInfocount].enrolledInfo[i].enrolledId = enrolledInfoHal[i].enrolledId;
1265 }
1266
1267 free(enrolledInfoHal);
1268 (*userInfocount)++;
1269 }
1270
1271 g_userInfoList->destroyIterator(iterator);
1272 return RESULT_SUCCESS;
1273
1274 ERROR:
1275 g_userInfoList->destroyIterator(iterator);
1276 return RESULT_GENERAL_ERROR;
1277 }
1278
GetEnrolledState(int32_t userId,uint32_t authType,EnrolledStateHal * enrolledStateHal)1279 ResultCode GetEnrolledState(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal)
1280 {
1281 LOG_INFO("get enrolled id info start, userId:%{public}d, authType:%{public}d", userId, authType);
1282
1283 UserInfo *user = QueryUserInfo(userId);
1284 if (user == NULL) {
1285 LOG_ERROR("user is null");
1286 return RESULT_NOT_ENROLLED;
1287 }
1288 if (user->credentialInfoList == NULL) {
1289 LOG_ERROR("credentialInfoList is null");
1290 return RESULT_NOT_ENROLLED;
1291 }
1292
1293 uint16_t credentialCount = 0;
1294 LinkedListNode *credentialInfoTemp = user->credentialInfoList->head;
1295 while (credentialInfoTemp != NULL) {
1296 CredentialInfoHal *nodeInfo = credentialInfoTemp->data;
1297 if (nodeInfo != NULL && nodeInfo->authType == authType) {
1298 ++credentialCount;
1299 }
1300 credentialInfoTemp = credentialInfoTemp->next;
1301 }
1302 if (credentialCount == 0) {
1303 LOG_ERROR("not enrolled");
1304 return RESULT_NOT_ENROLLED;
1305 }
1306 enrolledStateHal->credentialCount = credentialCount;
1307 if (user->enrolledInfoList == NULL) {
1308 LOG_ERROR("enrolledInfoList is null");
1309 return RESULT_NOT_ENROLLED;
1310 }
1311 LinkedListNode *enrolledInfoTemp = user->enrolledInfoList->head;
1312 while (enrolledInfoTemp != NULL) {
1313 EnrolledInfoHal *nodeInfo = enrolledInfoTemp->data;
1314 if (nodeInfo != NULL && nodeInfo->authType == authType) {
1315 enrolledStateHal->credentialDigest = nodeInfo->enrolledId;
1316 break;
1317 }
1318 enrolledInfoTemp = enrolledInfoTemp->next;
1319 }
1320 return RESULT_SUCCESS;
1321 }
1322
UpdateGlobalConfigArray(GlobalConfigParamHal * param,uint32_t authType)1323 IAM_STATIC ResultCode UpdateGlobalConfigArray(GlobalConfigParamHal *param, uint32_t authType)
1324 {
1325 uint32_t infoIndex = 0;
1326 for (infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1327 if (g_globalConfigArray[infoIndex].type == param->type &&
1328 g_globalConfigArray[infoIndex].authType == authType) {
1329 LOG_INFO("globalConfig is already exist, type:%{public}d, authType:%{public}u", param->type, authType);
1330 break;
1331 }
1332 }
1333 if (infoIndex >= MAX_GLOBAL_CONFIG_NUM) {
1334 LOG_ERROR("globalConfigArray is exceed limit");
1335 return RESULT_EXCEED_LIMIT;
1336 }
1337 memset_s(&g_globalConfigArray[infoIndex], sizeof(GlobalConfigInfo), 0, sizeof(GlobalConfigInfo));
1338
1339 switch (param->type) {
1340 case PIN_EXPIRED_PERIOD:
1341 if (authType != PIN_AUTH) {
1342 LOG_ERROR("bad authType:%{public}u for PIN_EXPIRED_PERIOD", authType);
1343 return RESULT_BAD_PARAM;
1344 }
1345 g_globalConfigArray[infoIndex].value.pinExpiredPeriod = param->value.pinExpiredPeriod;
1346 break;
1347 case ENABLE_STATUS:
1348 g_globalConfigArray[infoIndex].value.enableStatus = param->value.enableStatus;
1349 break;
1350 default:
1351 LOG_ERROR("globalConfigType not support, type:%{public}d.", param->type);
1352 return RESULT_BAD_PARAM;
1353 }
1354 g_globalConfigArray[infoIndex].type = param->type;
1355 g_globalConfigArray[infoIndex].authType = authType;
1356 g_globalConfigArray[infoIndex].userIdNum = param->userIdNum;
1357 for (uint32_t i = 0; i < param->userIdNum; i++) {
1358 g_globalConfigArray[infoIndex].userIds[i] = param->userIds[i];
1359 }
1360 if (infoIndex == g_globalConfigInfoNum) {
1361 g_globalConfigInfoNum++;
1362 }
1363 return RESULT_SUCCESS;
1364 }
1365
CheckAuthType(uint32_t authType)1366 IAM_STATIC bool CheckAuthType(uint32_t authType)
1367 {
1368 if (authType != PIN_AUTH && authType != FACE_AUTH && authType != FINGER_AUTH && authType != RECOVERY_KEY) {
1369 LOG_ERROR("bad authType %{public}u", authType);
1370 return false;
1371 }
1372 return true;
1373 }
1374
SaveGlobalConfigParam(GlobalConfigParamHal * param)1375 ResultCode SaveGlobalConfigParam(GlobalConfigParamHal *param)
1376 {
1377 if (param == NULL || param->userIdNum > MAX_USER || param->authTypeNum > MAX_AUTH_TYPE_LEN ||
1378 param->authTypeNum == 0) {
1379 LOG_ERROR("bad param");
1380 return RESULT_BAD_PARAM;
1381 }
1382 for (uint32_t i = 0; i < param->authTypeNum; i++) {
1383 if (!CheckAuthType(param->authTypes[i])) {
1384 LOG_ERROR("bad authType %{public}u", param->authTypes[i]);
1385 return RESULT_BAD_PARAM;
1386 }
1387 ResultCode ret = UpdateGlobalConfigArray(param, param->authTypes[i]);
1388 if (ret != RESULT_SUCCESS) {
1389 return ret;
1390 }
1391 }
1392
1393 return UpdateGlobalConfigFile(g_globalConfigArray, g_globalConfigInfoNum);
1394 }
1395
QueryPinCredential(int32_t userId,CredentialInfoHal * pinCredential)1396 IAM_STATIC ResultCode QueryPinCredential(int32_t userId, CredentialInfoHal *pinCredential)
1397 {
1398 if (pinCredential == NULL) {
1399 LOG_ERROR("no need to get pin credential");
1400 return RESULT_BAD_PARAM;
1401 }
1402 CredentialCondition condition = {};
1403 SetCredentialConditionUserId(&condition, userId);
1404 SetCredentialConditionAuthType(&condition, PIN_AUTH);
1405 LinkedList *credList = QueryCredentialLimit(&condition);
1406 if (credList == NULL || credList->getSize(credList) == 0) {
1407 LOG_ERROR("pin credential is null");
1408 DestroyLinkedList(credList);
1409 return RESULT_NOT_ENROLLED;
1410 }
1411 if (credList->head == NULL || credList->head->data == NULL) {
1412 LOG_ERROR("pin credList node is invalid");
1413 DestroyLinkedList(credList);
1414 return RESULT_GENERAL_ERROR;
1415 }
1416 if (memcpy_s(pinCredential, sizeof(CredentialInfoHal), credList->head->data, sizeof(CredentialInfoHal)) != EOK) {
1417 LOG_ERROR("credential copy fail");
1418 DestroyLinkedList(credList);
1419 return RESULT_GENERAL_ERROR;
1420 }
1421 DestroyLinkedList(credList);
1422 return RESULT_SUCCESS;
1423 }
1424
QueryPinExpiredInfo(int64_t * pinExpiredPeriod)1425 ResultCode QueryPinExpiredInfo(int64_t *pinExpiredPeriod)
1426 {
1427 if (pinExpiredPeriod == NULL) {
1428 LOG_ERROR("bad param");
1429 return RESULT_BAD_PARAM;
1430 }
1431 for (uint32_t i = 0; i < g_globalConfigInfoNum; i++) {
1432 if (g_globalConfigArray[i].type == PIN_EXPIRED_PERIOD) {
1433 *pinExpiredPeriod = g_globalConfigArray[i].value.pinExpiredPeriod;
1434 break;
1435 }
1436 }
1437 if (*pinExpiredPeriod <= 0) {
1438 *pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1439 LOG_INFO("no need check pinExpiredPeriod");
1440 return RESULT_SUCCESS;
1441 }
1442 return RESULT_SUCCESS;
1443 }
1444
GetPinExpiredInfo(int32_t userId,PinExpiredInfo * expiredInfo)1445 ResultCode GetPinExpiredInfo(int32_t userId, PinExpiredInfo *expiredInfo)
1446 {
1447 LOG_INFO("start");
1448 if (expiredInfo == NULL) {
1449 LOG_ERROR("bad param");
1450 return RESULT_BAD_PARAM;
1451 }
1452 (void)memset_s(expiredInfo, sizeof(PinExpiredInfo), 0, sizeof(PinExpiredInfo));
1453 ResultCode ret = QueryPinExpiredInfo(&(expiredInfo->pinExpiredPeriod));
1454 if (ret != RESULT_SUCCESS) {
1455 LOG_ERROR("QueryPinExpiredInfo fail");
1456 return ret;
1457 }
1458 if (expiredInfo->pinExpiredPeriod == NO_CHECK_PIN_EXPIRED_PERIOD) {
1459 LOG_INFO("no need check pinExpiredPeriod");
1460 return RESULT_SUCCESS;
1461 }
1462 CredentialInfoHal pinCredential = {};
1463 if (QueryPinCredential(userId, &pinCredential) != RESULT_SUCCESS) {
1464 LOG_INFO("not enrolled pin");
1465 return RESULT_NOT_ENROLLED;
1466 }
1467 expiredInfo->pinEnrolledSysTime = pinCredential.enrolledSysTime;
1468 return RESULT_SUCCESS;
1469 }
1470
GetEnableStatus(int32_t userId,uint32_t authType)1471 bool GetEnableStatus(int32_t userId, uint32_t authType)
1472 {
1473 for (uint32_t infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1474 if (g_globalConfigArray[infoIndex].type != ENABLE_STATUS ||
1475 g_globalConfigArray[infoIndex].authType != authType) {
1476 continue;
1477 }
1478 LOG_INFO("enableStatus:%{public}d authType:%{public}u", g_globalConfigArray[infoIndex].value.enableStatus,
1479 authType);
1480 if (userId == INVALID_USER_ID || g_globalConfigArray[infoIndex].userIdNum == 0) {
1481 return g_globalConfigArray[infoIndex].value.enableStatus;
1482 }
1483 for (uint32_t i = 0; i < g_globalConfigArray[infoIndex].userIdNum; i++) {
1484 if (userId == g_globalConfigArray[infoIndex].userIds[i]) {
1485 return g_globalConfigArray[infoIndex].value.enableStatus;
1486 }
1487 }
1488 LOG_INFO("enableStatus is not set for userId:%{public}d", userId);
1489 return (!g_globalConfigArray[infoIndex].value.enableStatus);
1490 }
1491 return true;
1492 }
1493
QueryAbandonCredential(int32_t userId,LinkedList ** creds)1494 ResultCode QueryAbandonCredential(int32_t userId, LinkedList **creds)
1495 {
1496 if (creds == NULL) {
1497 LOG_ERROR("creds is null");
1498 return RESULT_BAD_PARAM;
1499 }
1500 CredentialCondition condition = {};
1501 SetCredentialConditionUserId(&condition, userId);
1502 SetCredentialConditionAbandonPin(&condition);
1503 *creds = QueryCredentialLimit(&condition);
1504 if (*creds == NULL) {
1505 LOG_ERROR("query credential failed");
1506 return RESULT_UNKNOWN;
1507 }
1508 LOG_INFO("query abandon credential success");
1509 return RESULT_SUCCESS;
1510 }
1511
GetCredentialListByAuthType(int32_t userId,uint32_t authType,LinkedList ** creds)1512 ResultCode GetCredentialListByAuthType(int32_t userId, uint32_t authType, LinkedList **creds)
1513 {
1514 if (creds == NULL) {
1515 LOG_ERROR("creds is null");
1516 return RESULT_BAD_PARAM;
1517 }
1518 CredentialCondition condition = {};
1519 SetCredentialConditionUserId(&condition, userId);
1520 SetCredentialConditionAuthType(&condition, authType);
1521
1522 *creds = QueryCredentialLimit(&condition);
1523 if (*creds == NULL) {
1524 LOG_ERROR("query credential failed");
1525 return RESULT_UNKNOWN;
1526 }
1527 LOG_INFO("query credential success");
1528 return RESULT_SUCCESS;
1529 }
1530
GetCredentialListByCachePin(int32_t userId,LinkedList ** creds)1531 ResultCode GetCredentialListByCachePin(int32_t userId, LinkedList **creds)
1532 {
1533 if (creds == NULL) {
1534 LOG_ERROR("creds is null");
1535 return RESULT_BAD_PARAM;
1536 }
1537 CredentialCondition condition = {};
1538 SetCredentialConditionCachePin(&condition);
1539
1540 *creds = QueryCredentialLimit(&condition);
1541 if (*creds == NULL) {
1542 LOG_ERROR("query credential failed");
1543 return RESULT_UNKNOWN;
1544 }
1545 LOG_INFO("query cache credential success");
1546 return RESULT_SUCCESS;
1547 }
1548
GetCredentialListByAbandonFlag(int32_t userId,uint32_t authType,LinkedList ** creds)1549 ResultCode GetCredentialListByAbandonFlag(int32_t userId, uint32_t authType, LinkedList **creds)
1550 {
1551 if (creds == NULL) {
1552 LOG_ERROR("creds is null");
1553 return RESULT_BAD_PARAM;
1554 }
1555 CredentialCondition condition = {};
1556 SetCredentialConditionUserId(&condition, userId);
1557 if (authType != DEFAULT_AUTH_TYPE) {
1558 SetCredentialConditionAuthType(&condition, authType);
1559 SetCredentialConditionAbandonPin(&condition);
1560 }
1561
1562 *creds = QueryCredentialLimit(&condition);
1563 if (*creds == NULL) {
1564 LOG_ERROR("query credential failed");
1565 return RESULT_UNKNOWN;
1566 }
1567 LOG_INFO("query abandon credential success");
1568 return RESULT_SUCCESS;
1569 }
1570
GetCredentialByUserIdAndCredId(int32_t userId,uint64_t credentialId,CredentialInfoHal * credentialInfo)1571 ResultCode GetCredentialByUserIdAndCredId(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
1572 {
1573 UserInfo *user = QueryUserInfo(userId);
1574 if (user == NULL) {
1575 LOG_ERROR("user is null, usrId:%{public}d", userId);
1576 return RESULT_NOT_ENROLLED;
1577 }
1578
1579 if (user->credentialInfoList == NULL) {
1580 LOG_ERROR("credentialInfoList is null, usrId:%{public}d", userId);
1581 return RESULT_NOT_ENROLLED;
1582 }
1583
1584 CredentialInfoHal *temp = QueryCredentialById(credentialId, user->credentialInfoList);
1585 if (temp == NULL) {
1586 LOG_ERROR("QueryCredentialById failed, usrId:%{public}d", userId);
1587 return RESULT_NOT_ENROLLED;
1588 }
1589
1590 if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), temp, sizeof(CredentialInfoHal)) != EOK) {
1591 LOG_ERROR("bad copy");
1592 return RESULT_BAD_COPY;
1593 }
1594
1595 return RESULT_SUCCESS;
1596 }
1597
FindCredential(UserInfo * user,CredentialInfoHal ** oldCredential,CredentialInfoHal ** curCredential,CredentialInfoHal ** newCredential)1598 IAM_STATIC void FindCredential(UserInfo *user, CredentialInfoHal **oldCredential,
1599 CredentialInfoHal **curCredential, CredentialInfoHal **newCredential)
1600 {
1601 LinkedListNode *temp = user->credentialInfoList->head;
1602 while (temp != NULL) {
1603 CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
1604 if (nodeData == NULL) {
1605 temp = temp->next;
1606 continue;
1607 }
1608 if (nodeData->authType == PIN_AUTH && nodeData->isAbandoned) {
1609 *oldCredential = nodeData;
1610 }
1611 if (nodeData->authType == PIN_AUTH && !nodeData->isAbandoned) {
1612 *curCredential = nodeData;
1613 }
1614 if (nodeData->authType == DEFAULT_AUTH_TYPE) {
1615 *newCredential = nodeData;
1616 }
1617 temp = temp->next;
1618 }
1619 return;
1620 }
1621
UpdateAbandonResultForReset(int32_t userId,bool * isDelete,CredentialInfoHal * credentialInfo)1622 ResultCode UpdateAbandonResultForReset(int32_t userId, bool *isDelete, CredentialInfoHal *credentialInfo)
1623 {
1624 UserInfo *user = QueryUserInfo(userId);
1625 if (user == NULL) {
1626 LOG_ERROR("user is null, usrId:%{public}d", userId);
1627 return RESULT_BAD_PARAM;
1628 }
1629
1630 CredentialInfoHal *oldCredential = NULL;
1631 CredentialInfoHal *curCredential = NULL;
1632 CredentialInfoHal *newCredential = NULL;
1633 FindCredential(user, &oldCredential, &curCredential, &newCredential);
1634 if (oldCredential == NULL || curCredential == NULL || newCredential == NULL) {
1635 LOG_ERROR("oldCredential, curCredential or newCredential is not exist");
1636 return RESULT_GENERAL_ERROR;
1637 }
1638
1639 *isDelete = true;
1640 *credentialInfo = *curCredential;
1641 uint64_t abandonTime = oldCredential->abandonedSysTime;
1642 oldCredential->abandonedSysTime = GetReeTime();
1643 curCredential->authType = DEFAULT_AUTH_TYPE;
1644 newCredential->authType = PIN_AUTH;
1645 SwitchSubType(user);
1646 ResultCode result = UpdateFileInfo(g_userInfoList);
1647 if (result == RESULT_SUCCESS) {
1648 LOG_INFO("switch cache pin success");
1649 ClearCachePin(user->userId);
1650 return result;
1651 }
1652 LOG_ERROR("switch cache pin fail");
1653 curCredential->authType = PIN_AUTH;
1654 newCredential->authType = DEFAULT_AUTH_TYPE;
1655 oldCredential->abandonedSysTime = abandonTime;
1656 SwitchSubType(user);
1657 *isDelete = false;
1658 return RESULT_GENERAL_ERROR;
1659 }
1660
UpdateAbandonResultForUpdate(int32_t userId,bool * isDelete,CredentialInfoHal * credentialInfo)1661 ResultCode UpdateAbandonResultForUpdate(int32_t userId, bool *isDelete, CredentialInfoHal *credentialInfo)
1662 {
1663 UserInfo *user = QueryUserInfo(userId);
1664 if (user == NULL) {
1665 LOG_ERROR("user is null, usrId:%{public}d", userId);
1666 return RESULT_BAD_PARAM;
1667 }
1668
1669 CredentialInfoHal *oldCredential = NULL;
1670 CredentialInfoHal *curCredential = NULL;
1671 CredentialInfoHal *newCredential = NULL;
1672 FindCredential(user, &oldCredential, &curCredential, &newCredential);
1673 if (curCredential == NULL || newCredential == NULL) {
1674 LOG_ERROR("curCredential or newCredential is not exist");
1675 return RESULT_GENERAL_ERROR;
1676 }
1677 newCredential->authType = PIN_AUTH;
1678 curCredential->isAbandoned = true;
1679 curCredential->abandonedSysTime = GetReeTime();
1680 if (oldCredential != NULL) {
1681 *isDelete = true;
1682 *credentialInfo = *oldCredential;
1683 oldCredential->authType = DEFAULT_AUTH_TYPE;
1684 }
1685
1686 SwitchSubType(user);
1687 ResultCode result = UpdateFileInfo(g_userInfoList);
1688 if (result == RESULT_SUCCESS) {
1689 LOG_INFO("switch cache pin success");
1690 ClearCachePin(user->userId);
1691 return result;
1692 }
1693 LOG_ERROR("switch cache pin fail");
1694 curCredential->isAbandoned = false;
1695 curCredential->abandonedSysTime = 0;
1696 newCredential->authType = DEFAULT_AUTH_TYPE;
1697 if (oldCredential != NULL) {
1698 oldCredential->authType = PIN_AUTH;
1699 }
1700 SwitchSubType(user);
1701 *isDelete = false;
1702 return RESULT_GENERAL_ERROR;
1703 }
1704
IsAbandonCredentialExpired(const CredentialInfoHal * credentialInfo)1705 bool IsAbandonCredentialExpired(const CredentialInfoHal *credentialInfo)
1706 {
1707 if (!credentialInfo->isAbandoned) {
1708 LOG_INFO("isAbandoned is false");
1709 return false;
1710 }
1711
1712 uint64_t currentTime = GetReeTime();
1713 if (currentTime < credentialInfo->abandonedSysTime) {
1714 LOG_INFO("crdential abandoned time is error");
1715 return true;
1716 }
1717
1718 if (currentTime > credentialInfo->abandonedSysTime &&
1719 currentTime - credentialInfo->abandonedSysTime > ABANDON_PIN_VALID_PERIOD) {
1720 LOG_INFO("crdential is abandoned");
1721 return true;
1722 }
1723
1724 return false;
1725 }
1726
CalcAbandonCredentialValidPeriod(const CredentialInfoHal * credentialInfo)1727 int64_t CalcAbandonCredentialValidPeriod(const CredentialInfoHal *credentialInfo)
1728 {
1729 LOG_INFO("start");
1730 if (IsAbandonCredentialExpired(credentialInfo)) {
1731 LOG_INFO("crdential is Expired");
1732 return 0;
1733 }
1734
1735 if (credentialInfo->abandonedSysTime + ABANDON_PIN_VALID_PERIOD <= UINT64_MAX) {
1736 return credentialInfo->abandonedSysTime + ABANDON_PIN_VALID_PERIOD - GetReeTime();
1737 }
1738
1739 return ABANDON_PIN_VALID_PERIOD;
1740 }
1741
CalcCredentialValidPeriod(const CredentialInfoHal * credentialInfo)1742 int64_t CalcCredentialValidPeriod(const CredentialInfoHal *credentialInfo)
1743 {
1744 LOG_INFO("start");
1745 if (credentialInfo->isAbandoned) {
1746 return CalcAbandonCredentialValidPeriod(credentialInfo);
1747 }
1748
1749 int64_t pinExpiredPeriod = 0;
1750 ResultCode ret = QueryPinExpiredInfo(&pinExpiredPeriod);
1751 if (ret != RESULT_SUCCESS) {
1752 LOG_INFO("QueryPinExpiredInfo fail, ret:%{public}u", ret);
1753 return 0;
1754 }
1755
1756 if (pinExpiredPeriod == NO_CHECK_PIN_EXPIRED_PERIOD) {
1757 return NO_SET_PIN_EXPIRED_PERIOD;
1758 }
1759
1760 uint64_t currentTime = GetReeTime();
1761 if (currentTime < credentialInfo->enrolledSysTime) {
1762 return 0;
1763 }
1764
1765 if (currentTime > credentialInfo->enrolledSysTime &&
1766 currentTime - credentialInfo->enrolledSysTime >= (uint64_t)pinExpiredPeriod) {
1767 return 0;
1768 }
1769
1770 if (UINT64_MAX - credentialInfo->enrolledSysTime >= (uint64_t)pinExpiredPeriod) {
1771 return (int64_t)(credentialInfo->enrolledSysTime + (uint64_t)pinExpiredPeriod - currentTime);
1772 }
1773
1774 return pinExpiredPeriod;
1775 }
1776
GetCredentialValidPeriod(int32_t userId,uint64_t credentialId)1777 int64_t GetCredentialValidPeriod(int32_t userId, uint64_t credentialId)
1778 {
1779 LOG_INFO("start");
1780 CredentialInfoHal credentialInfo = {};
1781 ResultCode ret = GetCredentialByUserIdAndCredId(userId, credentialId, &credentialInfo);
1782 if (ret != RESULT_SUCCESS) {
1783 LOG_INFO("GetCredentialByUserIdAndCredId fail, ret:%{public}u", ret);
1784 return 0;
1785 }
1786
1787 return CalcCredentialValidPeriod(&credentialInfo);
1788 }
1789
ClearAbandonExpiredCredential(int32_t userId,CredentialInfoHal * credentialInfo)1790 ResultCode ClearAbandonExpiredCredential(int32_t userId, CredentialInfoHal *credentialInfo)
1791 {
1792 LinkedList *credList = NULL;
1793 ResultCode ret = QueryAbandonCredential(userId, &credList);
1794 if (ret != RESULT_SUCCESS || credList == NULL) {
1795 LOG_ERROR("query credential failed");
1796 return RESULT_GENERAL_ERROR;
1797 }
1798 if (credList->head == NULL || credList->head->data == NULL) {
1799 LOG_ERROR("credential is null");
1800 DestroyLinkedList(credList);
1801 return RESULT_NOT_ENROLLED;
1802 }
1803 CredentialInfoHal *credentialHal = (CredentialInfoHal *)(credList->head->data);
1804 if (IsAbandonCredentialExpired(credentialHal)) {
1805 ret = DeleteCredentialInfo(userId, credentialHal->credentialId, credentialInfo);
1806 if (ret != RESULT_SUCCESS) {
1807 LOG_ERROR("delete database info failed");
1808 return RESULT_BAD_SIGN;
1809 }
1810 }
1811 return RESULT_SUCCESS;
1812 }