1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (C) 2022-2024 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "idm_database.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include "inttypes.h" 19094332d3Sopenharmony_ci#include "securec.h" 20094332d3Sopenharmony_ci 21094332d3Sopenharmony_ci#include "adaptor_algorithm.h" 22094332d3Sopenharmony_ci#include "adaptor_log.h" 23094332d3Sopenharmony_ci#include "adaptor_time.h" 24094332d3Sopenharmony_ci#include "idm_file_manager.h" 25094332d3Sopenharmony_ci#include "global_config_file_manager.h" 26094332d3Sopenharmony_ci 27094332d3Sopenharmony_ci#define MAX_DUPLICATE_CHECK 100 28094332d3Sopenharmony_ci#define PRE_APPLY_NUM 5 29094332d3Sopenharmony_ci#define MEM_GROWTH_FACTOR 2 30094332d3Sopenharmony_ci#define MAX_CREDENTIAL_RETURN 5000 31094332d3Sopenharmony_ci 32094332d3Sopenharmony_ci#ifdef IAM_TEST_ENABLE 33094332d3Sopenharmony_ci#define IAM_STATIC 34094332d3Sopenharmony_ci#else 35094332d3Sopenharmony_ci#define IAM_STATIC static 36094332d3Sopenharmony_ci#endif 37094332d3Sopenharmony_ci 38094332d3Sopenharmony_ci// Caches IDM user information. 39094332d3Sopenharmony_ciIAM_STATIC LinkedList *g_userInfoList = NULL; 40094332d3Sopenharmony_ci 41094332d3Sopenharmony_ci// Caches the current user to reduce the number of user list traversal times. 42094332d3Sopenharmony_ciIAM_STATIC UserInfo *g_currentUser = NULL; 43094332d3Sopenharmony_ci 44094332d3Sopenharmony_ci// Caches global config info. 45094332d3Sopenharmony_ciIAM_STATIC GlobalConfigInfo g_globalConfigArray[MAX_GLOBAL_CONFIG_NUM]; 46094332d3Sopenharmony_ciIAM_STATIC uint32_t g_globalConfigInfoNum = 0; 47094332d3Sopenharmony_ci 48094332d3Sopenharmony_citypedef bool (*DuplicateCheckFunc)(LinkedList *collection, uint64_t value); 49094332d3Sopenharmony_ci 50094332d3Sopenharmony_ciIAM_STATIC UserInfo *QueryUserInfo(int32_t userId); 51094332d3Sopenharmony_ciIAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num); 52094332d3Sopenharmony_ciIAM_STATIC ResultCode DeleteUser(int32_t userId); 53094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList); 54094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList); 55094332d3Sopenharmony_ciIAM_STATIC bool MatchCredentialById(const void *data, const void *condition); 56094332d3Sopenharmony_ciIAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func); 57094332d3Sopenharmony_ciIAM_STATIC bool IsUserValid(UserInfo *user); 58094332d3Sopenharmony_ciIAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount, 59094332d3Sopenharmony_ci bool *cachePinRemoved); 60094332d3Sopenharmony_ciIAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved); 61094332d3Sopenharmony_ciIAM_STATIC ResultCode ClearInvalidData(void); 62094332d3Sopenharmony_ci 63094332d3Sopenharmony_ciResultCode InitUserInfoList(void) 64094332d3Sopenharmony_ci{ 65094332d3Sopenharmony_ci LOG_INFO("InitUserInfoList start"); 66094332d3Sopenharmony_ci if (g_userInfoList != NULL) { 67094332d3Sopenharmony_ci DestroyUserInfoList(); 68094332d3Sopenharmony_ci g_userInfoList = NULL; 69094332d3Sopenharmony_ci } 70094332d3Sopenharmony_ci g_userInfoList = LoadFileInfo(); 71094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 72094332d3Sopenharmony_ci LOG_ERROR("load file info failed"); 73094332d3Sopenharmony_ci return RESULT_NEED_INIT; 74094332d3Sopenharmony_ci } 75094332d3Sopenharmony_ci ResultCode ret = ClearInvalidData(); 76094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 77094332d3Sopenharmony_ci LOG_ERROR("clear invalid user failed"); 78094332d3Sopenharmony_ci DestroyUserInfoList(); 79094332d3Sopenharmony_ci return ret; 80094332d3Sopenharmony_ci } 81094332d3Sopenharmony_ci ret = LoadGlobalConfigInfo(g_globalConfigArray, MAX_GLOBAL_CONFIG_NUM, &g_globalConfigInfoNum); 82094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 83094332d3Sopenharmony_ci LOG_ERROR("load global config info failed"); 84094332d3Sopenharmony_ci } 85094332d3Sopenharmony_ci LOG_INFO("InitUserInfoList end"); 86094332d3Sopenharmony_ci return RESULT_SUCCESS; 87094332d3Sopenharmony_ci} 88094332d3Sopenharmony_ci 89094332d3Sopenharmony_civoid DestroyUserInfoList(void) 90094332d3Sopenharmony_ci{ 91094332d3Sopenharmony_ci DestroyLinkedList(g_userInfoList); 92094332d3Sopenharmony_ci g_userInfoList = NULL; 93094332d3Sopenharmony_ci} 94094332d3Sopenharmony_ci 95094332d3Sopenharmony_ciIAM_STATIC bool MatchUserInfo(const void *data, const void *condition) 96094332d3Sopenharmony_ci{ 97094332d3Sopenharmony_ci if (data == NULL || condition == NULL) { 98094332d3Sopenharmony_ci LOG_ERROR("please check invalid node"); 99094332d3Sopenharmony_ci return false; 100094332d3Sopenharmony_ci } 101094332d3Sopenharmony_ci const UserInfo *userInfo = (const UserInfo *)data; 102094332d3Sopenharmony_ci int32_t userId = *(const int32_t *)condition; 103094332d3Sopenharmony_ci if (userInfo->userId == userId) { 104094332d3Sopenharmony_ci return true; 105094332d3Sopenharmony_ci } 106094332d3Sopenharmony_ci return false; 107094332d3Sopenharmony_ci} 108094332d3Sopenharmony_ci 109094332d3Sopenharmony_ciIAM_STATIC bool IsUserInfoValid(UserInfo *userInfo) 110094332d3Sopenharmony_ci{ 111094332d3Sopenharmony_ci if (userInfo == NULL) { 112094332d3Sopenharmony_ci LOG_ERROR("userInfo is null"); 113094332d3Sopenharmony_ci return false; 114094332d3Sopenharmony_ci } 115094332d3Sopenharmony_ci if (userInfo->credentialInfoList == NULL) { 116094332d3Sopenharmony_ci LOG_ERROR("credentialInfoList is null"); 117094332d3Sopenharmony_ci return false; 118094332d3Sopenharmony_ci } 119094332d3Sopenharmony_ci if (userInfo->enrolledInfoList == NULL) { 120094332d3Sopenharmony_ci LOG_ERROR("enrolledInfoList is null"); 121094332d3Sopenharmony_ci return false; 122094332d3Sopenharmony_ci } 123094332d3Sopenharmony_ci return true; 124094332d3Sopenharmony_ci} 125094332d3Sopenharmony_ci 126094332d3Sopenharmony_ciResultCode GetSecureUid(int32_t userId, uint64_t *secUid) 127094332d3Sopenharmony_ci{ 128094332d3Sopenharmony_ci if (secUid == NULL) { 129094332d3Sopenharmony_ci LOG_ERROR("secUid is null"); 130094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 131094332d3Sopenharmony_ci } 132094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 133094332d3Sopenharmony_ci if (user == NULL) { 134094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 135094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 136094332d3Sopenharmony_ci } 137094332d3Sopenharmony_ci *secUid = user->secUid; 138094332d3Sopenharmony_ci return RESULT_SUCCESS; 139094332d3Sopenharmony_ci} 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_ciResultCode GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo) 142094332d3Sopenharmony_ci{ 143094332d3Sopenharmony_ci if (enrolledInfo == NULL) { 144094332d3Sopenharmony_ci LOG_ERROR("enrolledInfo is null"); 145094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 146094332d3Sopenharmony_ci } 147094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 148094332d3Sopenharmony_ci if (user == NULL) { 149094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 150094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 151094332d3Sopenharmony_ci } 152094332d3Sopenharmony_ci if (user->enrolledInfoList == NULL) { 153094332d3Sopenharmony_ci LOG_ERROR("enrolledInfoList is null"); 154094332d3Sopenharmony_ci return RESULT_UNKNOWN; 155094332d3Sopenharmony_ci } 156094332d3Sopenharmony_ci 157094332d3Sopenharmony_ci LinkedListNode *temp = user->enrolledInfoList->head; 158094332d3Sopenharmony_ci while (temp != NULL) { 159094332d3Sopenharmony_ci EnrolledInfoHal *nodeInfo = temp->data; 160094332d3Sopenharmony_ci if (nodeInfo != NULL && nodeInfo->authType == authType) { 161094332d3Sopenharmony_ci *enrolledInfo = *nodeInfo; 162094332d3Sopenharmony_ci return RESULT_SUCCESS; 163094332d3Sopenharmony_ci } 164094332d3Sopenharmony_ci temp = temp->next; 165094332d3Sopenharmony_ci } 166094332d3Sopenharmony_ci 167094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 168094332d3Sopenharmony_ci} 169094332d3Sopenharmony_ci 170094332d3Sopenharmony_ciResultCode GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num) 171094332d3Sopenharmony_ci{ 172094332d3Sopenharmony_ci if (enrolledInfos == NULL || num == NULL) { 173094332d3Sopenharmony_ci LOG_ERROR("param is invalid"); 174094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 175094332d3Sopenharmony_ci } 176094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 177094332d3Sopenharmony_ci if (!IsUserInfoValid(user)) { 178094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 179094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 180094332d3Sopenharmony_ci } 181094332d3Sopenharmony_ci return GetAllEnrolledInfoFromUser(user, enrolledInfos, num); 182094332d3Sopenharmony_ci} 183094332d3Sopenharmony_ci 184094332d3Sopenharmony_ciResultCode DeleteUserInfo(int32_t userId, LinkedList **creds) 185094332d3Sopenharmony_ci{ 186094332d3Sopenharmony_ci if (creds == NULL) { 187094332d3Sopenharmony_ci LOG_ERROR("param is invalid"); 188094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 189094332d3Sopenharmony_ci } 190094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 191094332d3Sopenharmony_ci if (!IsUserInfoValid(user)) { 192094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 193094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 194094332d3Sopenharmony_ci } 195094332d3Sopenharmony_ci CredentialCondition condition = {}; 196094332d3Sopenharmony_ci SetCredentialConditionUserId(&condition, userId); 197094332d3Sopenharmony_ci *creds = QueryCredentialLimit(&condition); 198094332d3Sopenharmony_ci if (*creds == NULL) { 199094332d3Sopenharmony_ci LOG_ERROR("query credential failed"); 200094332d3Sopenharmony_ci return RESULT_UNKNOWN; 201094332d3Sopenharmony_ci } 202094332d3Sopenharmony_ci g_currentUser = NULL; 203094332d3Sopenharmony_ci 204094332d3Sopenharmony_ci ResultCode ret = DeleteUser(userId); 205094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 206094332d3Sopenharmony_ci LOG_ERROR("deleteUser failed"); 207094332d3Sopenharmony_ci DestroyLinkedList(*creds); 208094332d3Sopenharmony_ci *creds = NULL; 209094332d3Sopenharmony_ci return ret; 210094332d3Sopenharmony_ci } 211094332d3Sopenharmony_ci ret = UpdateFileInfo(g_userInfoList); 212094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 213094332d3Sopenharmony_ci LOG_ERROR("update file info failed"); 214094332d3Sopenharmony_ci DestroyLinkedList(*creds); 215094332d3Sopenharmony_ci *creds = NULL; 216094332d3Sopenharmony_ci return ret; 217094332d3Sopenharmony_ci } 218094332d3Sopenharmony_ci return ret; 219094332d3Sopenharmony_ci} 220094332d3Sopenharmony_ci 221094332d3Sopenharmony_ciIAM_STATIC UserInfo *QueryUserInfo(int32_t userId) 222094332d3Sopenharmony_ci{ 223094332d3Sopenharmony_ci UserInfo *user = g_currentUser; 224094332d3Sopenharmony_ci if (user != NULL && user->userId == userId) { 225094332d3Sopenharmony_ci return user; 226094332d3Sopenharmony_ci } 227094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 228094332d3Sopenharmony_ci return NULL; 229094332d3Sopenharmony_ci } 230094332d3Sopenharmony_ci LinkedListNode *temp = g_userInfoList->head; 231094332d3Sopenharmony_ci while (temp != NULL) { 232094332d3Sopenharmony_ci user = (UserInfo *)temp->data; 233094332d3Sopenharmony_ci if (user != NULL && user->userId == userId) { 234094332d3Sopenharmony_ci break; 235094332d3Sopenharmony_ci } 236094332d3Sopenharmony_ci temp = temp->next; 237094332d3Sopenharmony_ci } 238094332d3Sopenharmony_ci if (temp == NULL) { 239094332d3Sopenharmony_ci return NULL; 240094332d3Sopenharmony_ci } 241094332d3Sopenharmony_ci if (IsUserInfoValid(user)) { 242094332d3Sopenharmony_ci g_currentUser = user; 243094332d3Sopenharmony_ci return user; 244094332d3Sopenharmony_ci } 245094332d3Sopenharmony_ci return NULL; 246094332d3Sopenharmony_ci} 247094332d3Sopenharmony_ci 248094332d3Sopenharmony_ciIAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num) 249094332d3Sopenharmony_ci{ 250094332d3Sopenharmony_ci LinkedList *enrolledInfoList = userInfo->enrolledInfoList; 251094332d3Sopenharmony_ci uint32_t size = enrolledInfoList->getSize(enrolledInfoList); 252094332d3Sopenharmony_ci *enrolledInfos = Malloc(sizeof(EnrolledInfoHal) * size); 253094332d3Sopenharmony_ci if (*enrolledInfos == NULL) { 254094332d3Sopenharmony_ci LOG_ERROR("enrolledInfos malloc failed"); 255094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 256094332d3Sopenharmony_ci } 257094332d3Sopenharmony_ci (void)memset_s(*enrolledInfos, sizeof(EnrolledInfoHal) * size, 0, sizeof(EnrolledInfoHal) * size); 258094332d3Sopenharmony_ci LinkedListNode *temp = enrolledInfoList->head; 259094332d3Sopenharmony_ci ResultCode result = RESULT_SUCCESS; 260094332d3Sopenharmony_ci for (*num = 0; *num < size; (*num)++) { 261094332d3Sopenharmony_ci if (temp == NULL) { 262094332d3Sopenharmony_ci LOG_ERROR("temp node is null, something wrong"); 263094332d3Sopenharmony_ci result = RESULT_BAD_PARAM; 264094332d3Sopenharmony_ci goto EXIT; 265094332d3Sopenharmony_ci } 266094332d3Sopenharmony_ci EnrolledInfoHal *tempInfo = (EnrolledInfoHal *)temp->data; 267094332d3Sopenharmony_ci if (memcpy_s(*enrolledInfos + *num, sizeof(EnrolledInfoHal) * (size - *num), 268094332d3Sopenharmony_ci tempInfo, sizeof(EnrolledInfoHal)) != EOK) { 269094332d3Sopenharmony_ci LOG_ERROR("copy the %u information failed", *num); 270094332d3Sopenharmony_ci result = RESULT_NO_MEMORY; 271094332d3Sopenharmony_ci goto EXIT; 272094332d3Sopenharmony_ci } 273094332d3Sopenharmony_ci temp = temp->next; 274094332d3Sopenharmony_ci } 275094332d3Sopenharmony_ci 276094332d3Sopenharmony_ciEXIT: 277094332d3Sopenharmony_ci if (result != RESULT_SUCCESS) { 278094332d3Sopenharmony_ci Free(*enrolledInfos); 279094332d3Sopenharmony_ci *enrolledInfos = NULL; 280094332d3Sopenharmony_ci *num = 0; 281094332d3Sopenharmony_ci } 282094332d3Sopenharmony_ci return result; 283094332d3Sopenharmony_ci} 284094332d3Sopenharmony_ci 285094332d3Sopenharmony_ciIAM_STATIC bool IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid) 286094332d3Sopenharmony_ci{ 287094332d3Sopenharmony_ci if (userInfoList == NULL) { 288094332d3Sopenharmony_ci LOG_ERROR("the user list is empty, and the branch is abnormal"); 289094332d3Sopenharmony_ci return false; 290094332d3Sopenharmony_ci } 291094332d3Sopenharmony_ci 292094332d3Sopenharmony_ci LinkedListNode *temp = userInfoList->head; 293094332d3Sopenharmony_ci UserInfo *userInfo = NULL; 294094332d3Sopenharmony_ci while (temp != NULL) { 295094332d3Sopenharmony_ci userInfo = (UserInfo *)temp->data; 296094332d3Sopenharmony_ci if (userInfo != NULL && userInfo->secUid == secureUid) { 297094332d3Sopenharmony_ci return true; 298094332d3Sopenharmony_ci } 299094332d3Sopenharmony_ci temp = temp->next; 300094332d3Sopenharmony_ci } 301094332d3Sopenharmony_ci 302094332d3Sopenharmony_ci return false; 303094332d3Sopenharmony_ci} 304094332d3Sopenharmony_ci 305094332d3Sopenharmony_ciIAM_STATIC UserInfo *CreateUser(int32_t userId, int32_t userType) 306094332d3Sopenharmony_ci{ 307094332d3Sopenharmony_ci UserInfo *user = InitUserInfoNode(); 308094332d3Sopenharmony_ci if (!IsUserInfoValid(user)) { 309094332d3Sopenharmony_ci LOG_ERROR("user is invalid"); 310094332d3Sopenharmony_ci DestroyUserInfoNode(user); 311094332d3Sopenharmony_ci return NULL; 312094332d3Sopenharmony_ci } 313094332d3Sopenharmony_ci user->userId = userId; 314094332d3Sopenharmony_ci user->userType = userType; 315094332d3Sopenharmony_ci ResultCode ret = GenerateDeduplicateUint64(g_userInfoList, &user->secUid, IsSecureUidDuplicate); 316094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 317094332d3Sopenharmony_ci LOG_ERROR("generate secureUid failed"); 318094332d3Sopenharmony_ci DestroyUserInfoNode(user); 319094332d3Sopenharmony_ci return NULL; 320094332d3Sopenharmony_ci } 321094332d3Sopenharmony_ci return user; 322094332d3Sopenharmony_ci} 323094332d3Sopenharmony_ci 324094332d3Sopenharmony_ciIAM_STATIC ResultCode DeleteUser(int32_t userId) 325094332d3Sopenharmony_ci{ 326094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 327094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 328094332d3Sopenharmony_ci } 329094332d3Sopenharmony_ci return g_userInfoList->remove(g_userInfoList, &userId, MatchUserInfo, true); 330094332d3Sopenharmony_ci} 331094332d3Sopenharmony_ci 332094332d3Sopenharmony_ciIAM_STATIC bool IsCredentialIdDuplicate(LinkedList *userInfoList, uint64_t credentialId) 333094332d3Sopenharmony_ci{ 334094332d3Sopenharmony_ci (void)userInfoList; 335094332d3Sopenharmony_ci CredentialCondition condition = {}; 336094332d3Sopenharmony_ci SetCredentialConditionCredentialId(&condition, credentialId); 337094332d3Sopenharmony_ci LinkedList *credList = QueryCredentialLimit(&condition); 338094332d3Sopenharmony_ci if (credList == NULL) { 339094332d3Sopenharmony_ci LOG_ERROR("query failed"); 340094332d3Sopenharmony_ci return true; 341094332d3Sopenharmony_ci } 342094332d3Sopenharmony_ci if (credList->getSize(credList) != 0) { 343094332d3Sopenharmony_ci LOG_ERROR("duplicate credential id"); 344094332d3Sopenharmony_ci DestroyLinkedList(credList); 345094332d3Sopenharmony_ci return true; 346094332d3Sopenharmony_ci } 347094332d3Sopenharmony_ci DestroyLinkedList(credList); 348094332d3Sopenharmony_ci return false; 349094332d3Sopenharmony_ci} 350094332d3Sopenharmony_ci 351094332d3Sopenharmony_ciIAM_STATIC bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId) 352094332d3Sopenharmony_ci{ 353094332d3Sopenharmony_ci LinkedListNode *temp = enrolledList->head; 354094332d3Sopenharmony_ci EnrolledInfoHal *enrolledInfo = NULL; 355094332d3Sopenharmony_ci const static uint16_t num = 0xFFFF; 356094332d3Sopenharmony_ci while (temp != NULL) { 357094332d3Sopenharmony_ci enrolledInfo = (EnrolledInfoHal *)temp->data; 358094332d3Sopenharmony_ci if ((enrolledInfo != NULL) && (enrolledInfo->enrolledId & num) == (enrolledId & num)) { 359094332d3Sopenharmony_ci return true; 360094332d3Sopenharmony_ci } 361094332d3Sopenharmony_ci temp = temp->next; 362094332d3Sopenharmony_ci } 363094332d3Sopenharmony_ci 364094332d3Sopenharmony_ci return false; 365094332d3Sopenharmony_ci} 366094332d3Sopenharmony_ci 367094332d3Sopenharmony_ciIAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func) 368094332d3Sopenharmony_ci{ 369094332d3Sopenharmony_ci if (collection == NULL || destValue == NULL || func == NULL) { 370094332d3Sopenharmony_ci LOG_ERROR("param is null"); 371094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 372094332d3Sopenharmony_ci } 373094332d3Sopenharmony_ci 374094332d3Sopenharmony_ci for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) { 375094332d3Sopenharmony_ci uint64_t tempRandom; 376094332d3Sopenharmony_ci if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) { 377094332d3Sopenharmony_ci LOG_ERROR("get random failed"); 378094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 379094332d3Sopenharmony_ci } 380094332d3Sopenharmony_ci if (!func(collection, tempRandom)) { 381094332d3Sopenharmony_ci *destValue = tempRandom; 382094332d3Sopenharmony_ci return RESULT_SUCCESS; 383094332d3Sopenharmony_ci } 384094332d3Sopenharmony_ci } 385094332d3Sopenharmony_ci 386094332d3Sopenharmony_ci LOG_ERROR("generate random failed"); 387094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 388094332d3Sopenharmony_ci} 389094332d3Sopenharmony_ci 390094332d3Sopenharmony_ciIAM_STATIC ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType) 391094332d3Sopenharmony_ci{ 392094332d3Sopenharmony_ci LinkedListNode *temp = enrolledList->head; 393094332d3Sopenharmony_ci EnrolledInfoHal *enrolledInfo = NULL; 394094332d3Sopenharmony_ci while (temp != NULL) { 395094332d3Sopenharmony_ci EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data; 396094332d3Sopenharmony_ci if (nodeData != NULL && nodeData->authType == authType) { 397094332d3Sopenharmony_ci enrolledInfo = nodeData; 398094332d3Sopenharmony_ci break; 399094332d3Sopenharmony_ci } 400094332d3Sopenharmony_ci temp = temp->next; 401094332d3Sopenharmony_ci } 402094332d3Sopenharmony_ci 403094332d3Sopenharmony_ci if (enrolledInfo != NULL) { 404094332d3Sopenharmony_ci return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate); 405094332d3Sopenharmony_ci } 406094332d3Sopenharmony_ci 407094332d3Sopenharmony_ci enrolledInfo = Malloc(sizeof(EnrolledInfoHal)); 408094332d3Sopenharmony_ci if (enrolledInfo == NULL) { 409094332d3Sopenharmony_ci LOG_ERROR("enrolledInfo malloc failed"); 410094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 411094332d3Sopenharmony_ci } 412094332d3Sopenharmony_ci enrolledInfo->authType = authType; 413094332d3Sopenharmony_ci ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate); 414094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 415094332d3Sopenharmony_ci LOG_ERROR("generate enrolledId failed"); 416094332d3Sopenharmony_ci Free(enrolledInfo); 417094332d3Sopenharmony_ci return ret; 418094332d3Sopenharmony_ci } 419094332d3Sopenharmony_ci ret = enrolledList->insert(enrolledList, enrolledInfo); 420094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 421094332d3Sopenharmony_ci LOG_ERROR("enrolledInfo insert failed"); 422094332d3Sopenharmony_ci Free(enrolledInfo); 423094332d3Sopenharmony_ci } 424094332d3Sopenharmony_ci return ret; 425094332d3Sopenharmony_ci} 426094332d3Sopenharmony_ci 427094332d3Sopenharmony_ci// add for reliable pin updates 428094332d3Sopenharmony_ciIAM_STATIC uint32_t GetRealAuthTypeForEnrolledId(uint32_t authType) 429094332d3Sopenharmony_ci{ 430094332d3Sopenharmony_ci if (authType == DEFAULT_AUTH_TYPE) { 431094332d3Sopenharmony_ci return PIN_AUTH; 432094332d3Sopenharmony_ci } 433094332d3Sopenharmony_ci return authType; 434094332d3Sopenharmony_ci} 435094332d3Sopenharmony_ci 436094332d3Sopenharmony_ciIAM_STATIC ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo) 437094332d3Sopenharmony_ci{ 438094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 439094332d3Sopenharmony_ci LOG_ERROR("g_userInfoList is uninitialized"); 440094332d3Sopenharmony_ci return RESULT_NEED_INIT; 441094332d3Sopenharmony_ci } 442094332d3Sopenharmony_ci LinkedList *credentialList = user->credentialInfoList; 443094332d3Sopenharmony_ci LinkedList *enrolledList = user->enrolledInfoList; 444094332d3Sopenharmony_ci if (credentialList->getSize(credentialList) >= MAX_CREDENTIAL) { 445094332d3Sopenharmony_ci LOG_ERROR("the number of credentials reaches the maximum"); 446094332d3Sopenharmony_ci return RESULT_EXCEED_LIMIT; 447094332d3Sopenharmony_ci } 448094332d3Sopenharmony_ci 449094332d3Sopenharmony_ci ResultCode ret = UpdateEnrolledId(enrolledList, GetRealAuthTypeForEnrolledId(credentialInfo->authType)); 450094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 451094332d3Sopenharmony_ci LOG_ERROR("update enrolledId failed"); 452094332d3Sopenharmony_ci return ret; 453094332d3Sopenharmony_ci } 454094332d3Sopenharmony_ci ret = GenerateDeduplicateUint64(g_userInfoList, &credentialInfo->credentialId, IsCredentialIdDuplicate); 455094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 456094332d3Sopenharmony_ci LOG_ERROR("GenerateDeduplicateUint64 failed"); 457094332d3Sopenharmony_ci return ret; 458094332d3Sopenharmony_ci } 459094332d3Sopenharmony_ci if (credentialInfo->authType == DEFAULT_AUTH_TYPE) { 460094332d3Sopenharmony_ci bool isRemoved = false; 461094332d3Sopenharmony_ci RemoveCachePin(user, &isRemoved); 462094332d3Sopenharmony_ci } 463094332d3Sopenharmony_ci CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal)); 464094332d3Sopenharmony_ci if (credential == NULL) { 465094332d3Sopenharmony_ci LOG_ERROR("credential malloc failed"); 466094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 467094332d3Sopenharmony_ci } 468094332d3Sopenharmony_ci if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) { 469094332d3Sopenharmony_ci LOG_ERROR("credential copy failed"); 470094332d3Sopenharmony_ci Free(credential); 471094332d3Sopenharmony_ci return RESULT_BAD_COPY; 472094332d3Sopenharmony_ci } 473094332d3Sopenharmony_ci credential->enrolledSysTime = GetReeTime(); 474094332d3Sopenharmony_ci ret = credentialList->insert(credentialList, credential); 475094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 476094332d3Sopenharmony_ci LOG_ERROR("insert credential failed"); 477094332d3Sopenharmony_ci Free(credential); 478094332d3Sopenharmony_ci } 479094332d3Sopenharmony_ci return ret; 480094332d3Sopenharmony_ci} 481094332d3Sopenharmony_ci 482094332d3Sopenharmony_ciIAM_STATIC ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType) 483094332d3Sopenharmony_ci{ 484094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 485094332d3Sopenharmony_ci LOG_ERROR("please init"); 486094332d3Sopenharmony_ci return RESULT_NEED_INIT; 487094332d3Sopenharmony_ci } 488094332d3Sopenharmony_ci if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) { 489094332d3Sopenharmony_ci LOG_ERROR("the number of users reaches the maximum"); 490094332d3Sopenharmony_ci return RESULT_EXCEED_LIMIT; 491094332d3Sopenharmony_ci } 492094332d3Sopenharmony_ci 493094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 494094332d3Sopenharmony_ci if (user != NULL) { 495094332d3Sopenharmony_ci LOG_ERROR("Please check pin"); 496094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 497094332d3Sopenharmony_ci } 498094332d3Sopenharmony_ci 499094332d3Sopenharmony_ci user = CreateUser(userId, userType); 500094332d3Sopenharmony_ci if (user == NULL) { 501094332d3Sopenharmony_ci LOG_ERROR("create user failed"); 502094332d3Sopenharmony_ci return RESULT_UNKNOWN; 503094332d3Sopenharmony_ci } 504094332d3Sopenharmony_ci LOG_INFO("user userType %{public}d", user->userType); 505094332d3Sopenharmony_ci ResultCode ret = AddCredentialToUser(user, credentialInfo); 506094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 507094332d3Sopenharmony_ci LOG_ERROR("add credential to user failed"); 508094332d3Sopenharmony_ci goto FAIL; 509094332d3Sopenharmony_ci } 510094332d3Sopenharmony_ci 511094332d3Sopenharmony_ci ret = g_userInfoList->insert(g_userInfoList, user); 512094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 513094332d3Sopenharmony_ci LOG_ERROR("insert failed"); 514094332d3Sopenharmony_ci goto FAIL; 515094332d3Sopenharmony_ci } 516094332d3Sopenharmony_ci return ret; 517094332d3Sopenharmony_ci 518094332d3Sopenharmony_ciFAIL: 519094332d3Sopenharmony_ci DestroyUserInfoNode(user); 520094332d3Sopenharmony_ci return ret; 521094332d3Sopenharmony_ci} 522094332d3Sopenharmony_ci 523094332d3Sopenharmony_ciResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType) 524094332d3Sopenharmony_ci{ 525094332d3Sopenharmony_ci if ((credentialInfo == NULL) || (credentialInfo->authType == DEFAULT_AUTH_TYPE)) { 526094332d3Sopenharmony_ci LOG_ERROR("credentialInfo is invalid"); 527094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 528094332d3Sopenharmony_ci } 529094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 530094332d3Sopenharmony_ci if (user == NULL && credentialInfo->authType == PIN_AUTH) { 531094332d3Sopenharmony_ci ResultCode ret = AddUser(userId, credentialInfo, userType); 532094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 533094332d3Sopenharmony_ci LOG_ERROR("add user failed"); 534094332d3Sopenharmony_ci return ret; 535094332d3Sopenharmony_ci } 536094332d3Sopenharmony_ci ret = UpdateFileInfo(g_userInfoList); 537094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 538094332d3Sopenharmony_ci LOG_ERROR("updateFileInfo failed"); 539094332d3Sopenharmony_ci } 540094332d3Sopenharmony_ci return ret; 541094332d3Sopenharmony_ci } 542094332d3Sopenharmony_ci if (user == NULL) { 543094332d3Sopenharmony_ci LOG_ERROR("user is null"); 544094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 545094332d3Sopenharmony_ci } 546094332d3Sopenharmony_ci if (credentialInfo->authType == PIN_AUTH) { 547094332d3Sopenharmony_ci CredentialCondition condition = {}; 548094332d3Sopenharmony_ci SetCredentialConditionAuthType(&condition, PIN_AUTH); 549094332d3Sopenharmony_ci SetCredentialConditionUserId(&condition, userId); 550094332d3Sopenharmony_ci LinkedList *credList = QueryCredentialLimit(&condition); 551094332d3Sopenharmony_ci if (credList == NULL) { 552094332d3Sopenharmony_ci LOG_ERROR("query credential failed"); 553094332d3Sopenharmony_ci return RESULT_UNKNOWN; 554094332d3Sopenharmony_ci } 555094332d3Sopenharmony_ci if (credList->getSize(credList) != 0) { 556094332d3Sopenharmony_ci LOG_INFO("cache pin"); 557094332d3Sopenharmony_ci // add for reliable pin updates 558094332d3Sopenharmony_ci credentialInfo->authType = DEFAULT_AUTH_TYPE; 559094332d3Sopenharmony_ci } 560094332d3Sopenharmony_ci DestroyLinkedList(credList); 561094332d3Sopenharmony_ci } 562094332d3Sopenharmony_ci ResultCode ret = AddCredentialToUser(user, credentialInfo); 563094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 564094332d3Sopenharmony_ci LOG_ERROR("add credential to user failed"); 565094332d3Sopenharmony_ci return ret; 566094332d3Sopenharmony_ci } 567094332d3Sopenharmony_ci ret = UpdateFileInfo(g_userInfoList); 568094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 569094332d3Sopenharmony_ci LOG_ERROR("updateFileInfo failed"); 570094332d3Sopenharmony_ci } 571094332d3Sopenharmony_ci return ret; 572094332d3Sopenharmony_ci} 573094332d3Sopenharmony_ci 574094332d3Sopenharmony_ciIAM_STATIC bool MatchCredentialById(const void *data, const void *condition) 575094332d3Sopenharmony_ci{ 576094332d3Sopenharmony_ci if (data == NULL || condition == NULL) { 577094332d3Sopenharmony_ci return false; 578094332d3Sopenharmony_ci } 579094332d3Sopenharmony_ci const CredentialInfoHal *credentialInfo = (const CredentialInfoHal *)data; 580094332d3Sopenharmony_ci uint64_t credentialId = *(const uint64_t *)condition; 581094332d3Sopenharmony_ci if (credentialInfo->credentialId == credentialId) { 582094332d3Sopenharmony_ci return true; 583094332d3Sopenharmony_ci } 584094332d3Sopenharmony_ci return false; 585094332d3Sopenharmony_ci} 586094332d3Sopenharmony_ci 587094332d3Sopenharmony_ciIAM_STATIC bool MatchEnrolledInfoByType(const void *data, const void *condition) 588094332d3Sopenharmony_ci{ 589094332d3Sopenharmony_ci if (data == NULL || condition == NULL) { 590094332d3Sopenharmony_ci return false; 591094332d3Sopenharmony_ci } 592094332d3Sopenharmony_ci const EnrolledInfoHal *enrolledInfo = (const EnrolledInfoHal *)data; 593094332d3Sopenharmony_ci uint32_t authType = *(const uint32_t *)condition; 594094332d3Sopenharmony_ci if (enrolledInfo->authType == authType) { 595094332d3Sopenharmony_ci return true; 596094332d3Sopenharmony_ci } 597094332d3Sopenharmony_ci return false; 598094332d3Sopenharmony_ci} 599094332d3Sopenharmony_ci 600094332d3Sopenharmony_ciIAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved) 601094332d3Sopenharmony_ci{ 602094332d3Sopenharmony_ci LOG_INFO("RemoveCachePin start"); 603094332d3Sopenharmony_ci LinkedListNode *temp = user->credentialInfoList->head; 604094332d3Sopenharmony_ci CredentialInfoHal *credentialInfoCache = NULL; 605094332d3Sopenharmony_ci while (temp != NULL) { 606094332d3Sopenharmony_ci CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data; 607094332d3Sopenharmony_ci if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) { 608094332d3Sopenharmony_ci credentialInfoCache = nodeData; 609094332d3Sopenharmony_ci break; 610094332d3Sopenharmony_ci } 611094332d3Sopenharmony_ci temp = temp->next; 612094332d3Sopenharmony_ci } 613094332d3Sopenharmony_ci if (credentialInfoCache == NULL) { 614094332d3Sopenharmony_ci LOG_INFO("RemoveCachePin no cache pin"); 615094332d3Sopenharmony_ci *isRemoved = false; 616094332d3Sopenharmony_ci return; 617094332d3Sopenharmony_ci } 618094332d3Sopenharmony_ci uint64_t credentialId = credentialInfoCache->credentialId; 619094332d3Sopenharmony_ci ResultCode ret = (user->credentialInfoList)->remove( 620094332d3Sopenharmony_ci user->credentialInfoList, &credentialId, MatchCredentialById, true); 621094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 622094332d3Sopenharmony_ci LOG_ERROR("remove credential failed"); 623094332d3Sopenharmony_ci *isRemoved = false; 624094332d3Sopenharmony_ci return; 625094332d3Sopenharmony_ci } 626094332d3Sopenharmony_ci LOG_ERROR("remove credential success"); 627094332d3Sopenharmony_ci *isRemoved = true; 628094332d3Sopenharmony_ci} 629094332d3Sopenharmony_ci 630094332d3Sopenharmony_civoid ClearCachePin(int32_t userId) 631094332d3Sopenharmony_ci{ 632094332d3Sopenharmony_ci LOG_INFO("ClearCachePin start"); 633094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 634094332d3Sopenharmony_ci if (user == NULL) { 635094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 636094332d3Sopenharmony_ci return; 637094332d3Sopenharmony_ci } 638094332d3Sopenharmony_ci 639094332d3Sopenharmony_ci bool isRemoved = false; 640094332d3Sopenharmony_ci RemoveCachePin(user, &isRemoved); 641094332d3Sopenharmony_ci if (isRemoved && UpdateFileInfo(g_userInfoList) != RESULT_SUCCESS) { 642094332d3Sopenharmony_ci LOG_ERROR("ClearCachePin save fail"); 643094332d3Sopenharmony_ci return; 644094332d3Sopenharmony_ci } 645094332d3Sopenharmony_ci} 646094332d3Sopenharmony_ci 647094332d3Sopenharmony_ciIAM_STATIC void SwitchSubType(UserInfo *user) 648094332d3Sopenharmony_ci{ 649094332d3Sopenharmony_ci uint64_t tmpSubType = user->pinSubType; 650094332d3Sopenharmony_ci user->pinSubType = user->cachePinSubType; 651094332d3Sopenharmony_ci user->cachePinSubType = tmpSubType; 652094332d3Sopenharmony_ci} 653094332d3Sopenharmony_ci 654094332d3Sopenharmony_ci// add for reliable pin updates 655094332d3Sopenharmony_ciIAM_STATIC ResultCode DeletePinCredentialInfo(UserInfo *user) 656094332d3Sopenharmony_ci{ 657094332d3Sopenharmony_ci LOG_INFO("DeletePinCredentialInfo start"); 658094332d3Sopenharmony_ci LinkedListNode *temp = user->credentialInfoList->head; 659094332d3Sopenharmony_ci CredentialInfoHal *credentialInfoOld = NULL; 660094332d3Sopenharmony_ci CredentialInfoHal *credentialInfoCache = NULL; 661094332d3Sopenharmony_ci while (temp != NULL) { 662094332d3Sopenharmony_ci CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data; 663094332d3Sopenharmony_ci if (nodeData != NULL && nodeData->authType == PIN_AUTH) { 664094332d3Sopenharmony_ci credentialInfoOld = nodeData; 665094332d3Sopenharmony_ci } 666094332d3Sopenharmony_ci if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) { 667094332d3Sopenharmony_ci credentialInfoCache = nodeData; 668094332d3Sopenharmony_ci } 669094332d3Sopenharmony_ci temp = temp->next; 670094332d3Sopenharmony_ci } 671094332d3Sopenharmony_ci if (credentialInfoOld == NULL || credentialInfoCache == NULL) { 672094332d3Sopenharmony_ci LOG_ERROR("no cache pin exist"); 673094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 674094332d3Sopenharmony_ci } 675094332d3Sopenharmony_ci credentialInfoOld->authType = DEFAULT_AUTH_TYPE; 676094332d3Sopenharmony_ci credentialInfoCache->authType = PIN_AUTH; 677094332d3Sopenharmony_ci SwitchSubType(user); 678094332d3Sopenharmony_ci ResultCode result = UpdateFileInfo(g_userInfoList); 679094332d3Sopenharmony_ci if (result == RESULT_SUCCESS) { 680094332d3Sopenharmony_ci LOG_INFO("switch cache pin success"); 681094332d3Sopenharmony_ci ClearCachePin(user->userId); 682094332d3Sopenharmony_ci return result; 683094332d3Sopenharmony_ci } 684094332d3Sopenharmony_ci LOG_ERROR("switch cache pin fail"); 685094332d3Sopenharmony_ci credentialInfoOld->authType = PIN_AUTH; 686094332d3Sopenharmony_ci credentialInfoCache->authType = DEFAULT_AUTH_TYPE; 687094332d3Sopenharmony_ci SwitchSubType(user); 688094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 689094332d3Sopenharmony_ci} 690094332d3Sopenharmony_ci 691094332d3Sopenharmony_ciResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo) 692094332d3Sopenharmony_ci{ 693094332d3Sopenharmony_ci if (credentialInfo == NULL) { 694094332d3Sopenharmony_ci LOG_ERROR("param is invalid"); 695094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 696094332d3Sopenharmony_ci } 697094332d3Sopenharmony_ci 698094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 699094332d3Sopenharmony_ci if (user == NULL) { 700094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 701094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 702094332d3Sopenharmony_ci } 703094332d3Sopenharmony_ci 704094332d3Sopenharmony_ci LinkedList *credentialList = user->credentialInfoList; 705094332d3Sopenharmony_ci CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList); 706094332d3Sopenharmony_ci if (credentialQuery == NULL) { 707094332d3Sopenharmony_ci LOG_ERROR("credentialQuery is null"); 708094332d3Sopenharmony_ci return RESULT_UNKNOWN; 709094332d3Sopenharmony_ci } 710094332d3Sopenharmony_ci if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) { 711094332d3Sopenharmony_ci LOG_ERROR("copy failed"); 712094332d3Sopenharmony_ci return RESULT_BAD_COPY; 713094332d3Sopenharmony_ci } 714094332d3Sopenharmony_ci if (credentialInfo->authType == PIN_AUTH) { 715094332d3Sopenharmony_ci return DeletePinCredentialInfo(user); 716094332d3Sopenharmony_ci } 717094332d3Sopenharmony_ci ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true); 718094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 719094332d3Sopenharmony_ci LOG_ERROR("remove credential failed"); 720094332d3Sopenharmony_ci return ret; 721094332d3Sopenharmony_ci } 722094332d3Sopenharmony_ci if (credentialInfo->authType == DEFAULT_AUTH_TYPE) { 723094332d3Sopenharmony_ci return UpdateFileInfo(g_userInfoList); 724094332d3Sopenharmony_ci } 725094332d3Sopenharmony_ci credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList); 726094332d3Sopenharmony_ci if (credentialQuery != NULL) { 727094332d3Sopenharmony_ci return UpdateFileInfo(g_userInfoList); 728094332d3Sopenharmony_ci } 729094332d3Sopenharmony_ci 730094332d3Sopenharmony_ci LinkedList *enrolledInfoList = user->enrolledInfoList; 731094332d3Sopenharmony_ci if (enrolledInfoList == NULL) { 732094332d3Sopenharmony_ci LOG_ERROR("enrolledInfoList is null"); 733094332d3Sopenharmony_ci return RESULT_UNKNOWN; 734094332d3Sopenharmony_ci } 735094332d3Sopenharmony_ci ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true); 736094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 737094332d3Sopenharmony_ci LOG_ERROR("remove enrolledInfo failed"); 738094332d3Sopenharmony_ci return ret; 739094332d3Sopenharmony_ci } 740094332d3Sopenharmony_ci 741094332d3Sopenharmony_ci return UpdateFileInfo(g_userInfoList); 742094332d3Sopenharmony_ci} 743094332d3Sopenharmony_ci 744094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList) 745094332d3Sopenharmony_ci{ 746094332d3Sopenharmony_ci if (credentialList == NULL) { 747094332d3Sopenharmony_ci return NULL; 748094332d3Sopenharmony_ci } 749094332d3Sopenharmony_ci LinkedListNode *temp = credentialList->head; 750094332d3Sopenharmony_ci CredentialInfoHal *credentialInfo = NULL; 751094332d3Sopenharmony_ci while (temp != NULL) { 752094332d3Sopenharmony_ci CredentialInfoHal *nodeData = (CredentialInfoHal *)temp->data; 753094332d3Sopenharmony_ci if (nodeData != NULL && nodeData->credentialId == credentialId) { 754094332d3Sopenharmony_ci credentialInfo = nodeData; 755094332d3Sopenharmony_ci break; 756094332d3Sopenharmony_ci } 757094332d3Sopenharmony_ci temp = temp->next; 758094332d3Sopenharmony_ci } 759094332d3Sopenharmony_ci return credentialInfo; 760094332d3Sopenharmony_ci} 761094332d3Sopenharmony_ci 762094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList) 763094332d3Sopenharmony_ci{ 764094332d3Sopenharmony_ci if (credentialList == NULL) { 765094332d3Sopenharmony_ci return NULL; 766094332d3Sopenharmony_ci } 767094332d3Sopenharmony_ci LinkedListNode *temp = credentialList->head; 768094332d3Sopenharmony_ci CredentialInfoHal *credentialInfo = NULL; 769094332d3Sopenharmony_ci while (temp != NULL) { 770094332d3Sopenharmony_ci CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data; 771094332d3Sopenharmony_ci if (nodeData != NULL && nodeData->authType == authType) { 772094332d3Sopenharmony_ci credentialInfo = nodeData; 773094332d3Sopenharmony_ci break; 774094332d3Sopenharmony_ci } 775094332d3Sopenharmony_ci temp = temp->next; 776094332d3Sopenharmony_ci } 777094332d3Sopenharmony_ci return credentialInfo; 778094332d3Sopenharmony_ci} 779094332d3Sopenharmony_ci 780094332d3Sopenharmony_ci// do not cotain cache pin credential 781094332d3Sopenharmony_ciIAM_STATIC bool IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo) 782094332d3Sopenharmony_ci{ 783094332d3Sopenharmony_ci if ((limit->conditionFactor & CREDENTIAL_CONDITION_CREDENTIAL_ID) != 0 && 784094332d3Sopenharmony_ci limit->credentialId != credentialInfo->credentialId) { 785094332d3Sopenharmony_ci return false; 786094332d3Sopenharmony_ci } 787094332d3Sopenharmony_ci if (credentialInfo->authType == DEFAULT_AUTH_TYPE) { 788094332d3Sopenharmony_ci if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_CACHE_PIN) == 0) { 789094332d3Sopenharmony_ci return false; 790094332d3Sopenharmony_ci } 791094332d3Sopenharmony_ci } else { 792094332d3Sopenharmony_ci if ((limit->conditionFactor & CREDENTIAL_CONDITION_AUTH_TYPE) != 0 && 793094332d3Sopenharmony_ci limit->authType != credentialInfo->authType) { 794094332d3Sopenharmony_ci return false; 795094332d3Sopenharmony_ci } 796094332d3Sopenharmony_ci } 797094332d3Sopenharmony_ci if ((limit->conditionFactor & CREDENTIAL_CONDITION_TEMPLATE_ID) != 0 && 798094332d3Sopenharmony_ci limit->templateId != credentialInfo->templateId) { 799094332d3Sopenharmony_ci return false; 800094332d3Sopenharmony_ci } 801094332d3Sopenharmony_ci if ((limit->conditionFactor & CREDENTIAL_CONDITION_SENSOR_HINT) != 0 && 802094332d3Sopenharmony_ci limit->executorSensorHint != INVALID_SENSOR_HINT && 803094332d3Sopenharmony_ci limit->executorSensorHint != credentialInfo->executorSensorHint) { 804094332d3Sopenharmony_ci return false; 805094332d3Sopenharmony_ci } 806094332d3Sopenharmony_ci if ((limit->conditionFactor & CREDENTIAL_CONDITION_EXECUTOR_MATCHER) != 0 && 807094332d3Sopenharmony_ci limit->executorMatcher != credentialInfo->executorMatcher) { 808094332d3Sopenharmony_ci return false; 809094332d3Sopenharmony_ci } 810094332d3Sopenharmony_ci return true; 811094332d3Sopenharmony_ci} 812094332d3Sopenharmony_ci 813094332d3Sopenharmony_ciIAM_STATIC bool IsUserMatch(const CredentialCondition *limit, const UserInfo *user) 814094332d3Sopenharmony_ci{ 815094332d3Sopenharmony_ci if ((limit->conditionFactor & CREDENTIAL_CONDITION_USER_ID) != 0 && limit->userId != user->userId) { 816094332d3Sopenharmony_ci return false; 817094332d3Sopenharmony_ci } 818094332d3Sopenharmony_ci return true; 819094332d3Sopenharmony_ci} 820094332d3Sopenharmony_ci 821094332d3Sopenharmony_ci// do not cotain cache pin credential 822094332d3Sopenharmony_ciIAM_STATIC ResultCode TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList, 823094332d3Sopenharmony_ci LinkedList *credListGet) 824094332d3Sopenharmony_ci{ 825094332d3Sopenharmony_ci if (credentialList == NULL) { 826094332d3Sopenharmony_ci LOG_ERROR("credentialList is null"); 827094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 828094332d3Sopenharmony_ci } 829094332d3Sopenharmony_ci LinkedListNode *temp = credentialList->head; 830094332d3Sopenharmony_ci while (temp != NULL) { 831094332d3Sopenharmony_ci CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data; 832094332d3Sopenharmony_ci if (nodeData == NULL) { 833094332d3Sopenharmony_ci LOG_ERROR("nodeData is null"); 834094332d3Sopenharmony_ci return RESULT_UNKNOWN; 835094332d3Sopenharmony_ci } 836094332d3Sopenharmony_ci if (!IsCredMatch(limit, nodeData)) { 837094332d3Sopenharmony_ci temp = temp->next; 838094332d3Sopenharmony_ci continue; 839094332d3Sopenharmony_ci } 840094332d3Sopenharmony_ci CredentialInfoHal *copy = (CredentialInfoHal *)Malloc(sizeof(CredentialInfoHal)); 841094332d3Sopenharmony_ci if (copy == NULL) { 842094332d3Sopenharmony_ci LOG_ERROR("copy malloc failed"); 843094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 844094332d3Sopenharmony_ci } 845094332d3Sopenharmony_ci *copy = *nodeData; 846094332d3Sopenharmony_ci ResultCode ret = credListGet->insert(credListGet, copy); 847094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 848094332d3Sopenharmony_ci LOG_ERROR("insert failed"); 849094332d3Sopenharmony_ci Free(copy); 850094332d3Sopenharmony_ci return ret; 851094332d3Sopenharmony_ci } 852094332d3Sopenharmony_ci temp = temp->next; 853094332d3Sopenharmony_ci } 854094332d3Sopenharmony_ci return RESULT_SUCCESS; 855094332d3Sopenharmony_ci} 856094332d3Sopenharmony_ci 857094332d3Sopenharmony_ci// do not cotain cache pin credential 858094332d3Sopenharmony_ciLinkedList *QueryCredentialLimit(const CredentialCondition *limit) 859094332d3Sopenharmony_ci{ 860094332d3Sopenharmony_ci if (limit == NULL) { 861094332d3Sopenharmony_ci LOG_ERROR("limit is null"); 862094332d3Sopenharmony_ci return NULL; 863094332d3Sopenharmony_ci } 864094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 865094332d3Sopenharmony_ci LOG_ERROR("g_userInfoList is null"); 866094332d3Sopenharmony_ci return NULL; 867094332d3Sopenharmony_ci } 868094332d3Sopenharmony_ci LinkedList *credList = CreateLinkedList(DestroyCredentialNode); 869094332d3Sopenharmony_ci if (credList == NULL) { 870094332d3Sopenharmony_ci LOG_ERROR("credList is null"); 871094332d3Sopenharmony_ci return NULL; 872094332d3Sopenharmony_ci } 873094332d3Sopenharmony_ci LinkedListNode *temp = g_userInfoList->head; 874094332d3Sopenharmony_ci while (temp != NULL) { 875094332d3Sopenharmony_ci UserInfo *user = (UserInfo *)temp->data; 876094332d3Sopenharmony_ci if (user == NULL) { 877094332d3Sopenharmony_ci LOG_ERROR("node data is null"); 878094332d3Sopenharmony_ci DestroyLinkedList(credList); 879094332d3Sopenharmony_ci return NULL; 880094332d3Sopenharmony_ci } 881094332d3Sopenharmony_ci if (IsUserMatch(limit, user)) { 882094332d3Sopenharmony_ci ResultCode ret = TraverseCredentialList(limit, user->credentialInfoList, credList); 883094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 884094332d3Sopenharmony_ci LOG_ERROR("TraverseCredentialList failed"); 885094332d3Sopenharmony_ci DestroyLinkedList(credList); 886094332d3Sopenharmony_ci return NULL; 887094332d3Sopenharmony_ci } 888094332d3Sopenharmony_ci } 889094332d3Sopenharmony_ci temp = temp->next; 890094332d3Sopenharmony_ci } 891094332d3Sopenharmony_ci return credList; 892094332d3Sopenharmony_ci} 893094332d3Sopenharmony_ci 894094332d3Sopenharmony_ciResultCode QueryCredentialUserId(uint64_t credentialId, int32_t *userId) 895094332d3Sopenharmony_ci{ 896094332d3Sopenharmony_ci if (userId == NULL) { 897094332d3Sopenharmony_ci LOG_ERROR("userId is null"); 898094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 899094332d3Sopenharmony_ci } 900094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 901094332d3Sopenharmony_ci LOG_ERROR("g_userInfoList is null"); 902094332d3Sopenharmony_ci return RESULT_NEED_INIT; 903094332d3Sopenharmony_ci } 904094332d3Sopenharmony_ci LinkedList *credList = CreateLinkedList(DestroyCredentialNode); 905094332d3Sopenharmony_ci if (credList == NULL) { 906094332d3Sopenharmony_ci LOG_ERROR("credList is null"); 907094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 908094332d3Sopenharmony_ci } 909094332d3Sopenharmony_ci LinkedListNode *temp = g_userInfoList->head; 910094332d3Sopenharmony_ci CredentialCondition condition = {}; 911094332d3Sopenharmony_ci SetCredentialConditionCredentialId(&condition, credentialId); 912094332d3Sopenharmony_ci while (temp != NULL) { 913094332d3Sopenharmony_ci UserInfo *user = (UserInfo *)temp->data; 914094332d3Sopenharmony_ci if (user == NULL) { 915094332d3Sopenharmony_ci LOG_ERROR("user is null"); 916094332d3Sopenharmony_ci DestroyLinkedList(credList); 917094332d3Sopenharmony_ci return RESULT_UNKNOWN; 918094332d3Sopenharmony_ci } 919094332d3Sopenharmony_ci ResultCode ret = TraverseCredentialList(&condition, user->credentialInfoList, credList); 920094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 921094332d3Sopenharmony_ci LOG_ERROR("TraverseCredentialList failed"); 922094332d3Sopenharmony_ci DestroyLinkedList(credList); 923094332d3Sopenharmony_ci return RESULT_UNKNOWN; 924094332d3Sopenharmony_ci } 925094332d3Sopenharmony_ci if (credList->getSize(credList) != 0) { 926094332d3Sopenharmony_ci DestroyLinkedList(credList); 927094332d3Sopenharmony_ci *userId = user->userId; 928094332d3Sopenharmony_ci return RESULT_SUCCESS; 929094332d3Sopenharmony_ci } 930094332d3Sopenharmony_ci temp = temp->next; 931094332d3Sopenharmony_ci } 932094332d3Sopenharmony_ci DestroyLinkedList(credList); 933094332d3Sopenharmony_ci LOG_ERROR("can't find this credential"); 934094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 935094332d3Sopenharmony_ci} 936094332d3Sopenharmony_ci 937094332d3Sopenharmony_ciResultCode SetPinSubType(int32_t userId, uint64_t pinSubType) 938094332d3Sopenharmony_ci{ 939094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 940094332d3Sopenharmony_ci if (user == NULL) { 941094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 942094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 943094332d3Sopenharmony_ci } 944094332d3Sopenharmony_ci user->pinSubType = pinSubType; 945094332d3Sopenharmony_ci return RESULT_SUCCESS; 946094332d3Sopenharmony_ci} 947094332d3Sopenharmony_ci 948094332d3Sopenharmony_ciResultCode GetPinSubType(int32_t userId, uint64_t *pinSubType) 949094332d3Sopenharmony_ci{ 950094332d3Sopenharmony_ci if (pinSubType == NULL) { 951094332d3Sopenharmony_ci LOG_ERROR("pinSubType is null"); 952094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 953094332d3Sopenharmony_ci } 954094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 955094332d3Sopenharmony_ci if (user == NULL) { 956094332d3Sopenharmony_ci LOG_ERROR("can't find this user"); 957094332d3Sopenharmony_ci return RESULT_NOT_FOUND; 958094332d3Sopenharmony_ci } 959094332d3Sopenharmony_ci *pinSubType = user->pinSubType; 960094332d3Sopenharmony_ci return RESULT_SUCCESS; 961094332d3Sopenharmony_ci} 962094332d3Sopenharmony_ci 963094332d3Sopenharmony_civoid SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId) 964094332d3Sopenharmony_ci{ 965094332d3Sopenharmony_ci if (condition == NULL) { 966094332d3Sopenharmony_ci LOG_ERROR("condition is null"); 967094332d3Sopenharmony_ci return; 968094332d3Sopenharmony_ci } 969094332d3Sopenharmony_ci condition->credentialId = credentialId; 970094332d3Sopenharmony_ci condition->conditionFactor |= CREDENTIAL_CONDITION_CREDENTIAL_ID; 971094332d3Sopenharmony_ci} 972094332d3Sopenharmony_ci 973094332d3Sopenharmony_civoid SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId) 974094332d3Sopenharmony_ci{ 975094332d3Sopenharmony_ci if (condition == NULL) { 976094332d3Sopenharmony_ci LOG_ERROR("condition is null"); 977094332d3Sopenharmony_ci return; 978094332d3Sopenharmony_ci } 979094332d3Sopenharmony_ci condition->templateId = templateId; 980094332d3Sopenharmony_ci condition->conditionFactor |= CREDENTIAL_CONDITION_TEMPLATE_ID; 981094332d3Sopenharmony_ci} 982094332d3Sopenharmony_ci 983094332d3Sopenharmony_civoid SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType) 984094332d3Sopenharmony_ci{ 985094332d3Sopenharmony_ci if (condition == NULL) { 986094332d3Sopenharmony_ci LOG_ERROR("condition is null"); 987094332d3Sopenharmony_ci return; 988094332d3Sopenharmony_ci } 989094332d3Sopenharmony_ci condition->authType = authType; 990094332d3Sopenharmony_ci condition->conditionFactor |= CREDENTIAL_CONDITION_AUTH_TYPE; 991094332d3Sopenharmony_ci} 992094332d3Sopenharmony_ci 993094332d3Sopenharmony_civoid SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint) 994094332d3Sopenharmony_ci{ 995094332d3Sopenharmony_ci if (condition == NULL) { 996094332d3Sopenharmony_ci LOG_ERROR("condition is null"); 997094332d3Sopenharmony_ci return; 998094332d3Sopenharmony_ci } 999094332d3Sopenharmony_ci condition->executorSensorHint = executorSensorHint; 1000094332d3Sopenharmony_ci condition->conditionFactor |= CREDENTIAL_CONDITION_SENSOR_HINT; 1001094332d3Sopenharmony_ci} 1002094332d3Sopenharmony_ci 1003094332d3Sopenharmony_civoid SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher) 1004094332d3Sopenharmony_ci{ 1005094332d3Sopenharmony_ci if (condition == NULL) { 1006094332d3Sopenharmony_ci LOG_ERROR("condition is null"); 1007094332d3Sopenharmony_ci return; 1008094332d3Sopenharmony_ci } 1009094332d3Sopenharmony_ci condition->executorMatcher = executorMatcher; 1010094332d3Sopenharmony_ci condition->conditionFactor |= CREDENTIAL_CONDITION_EXECUTOR_MATCHER; 1011094332d3Sopenharmony_ci} 1012094332d3Sopenharmony_ci 1013094332d3Sopenharmony_civoid SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId) 1014094332d3Sopenharmony_ci{ 1015094332d3Sopenharmony_ci if (condition == NULL) { 1016094332d3Sopenharmony_ci LOG_ERROR("condition is null"); 1017094332d3Sopenharmony_ci return; 1018094332d3Sopenharmony_ci } 1019094332d3Sopenharmony_ci condition->userId = userId; 1020094332d3Sopenharmony_ci condition->conditionFactor |= CREDENTIAL_CONDITION_USER_ID; 1021094332d3Sopenharmony_ci} 1022094332d3Sopenharmony_ci 1023094332d3Sopenharmony_civoid SetCredentiaConditionNeedCachePin(CredentialCondition *condition) 1024094332d3Sopenharmony_ci{ 1025094332d3Sopenharmony_ci if (condition == NULL) { 1026094332d3Sopenharmony_ci LOG_ERROR("condition is null"); 1027094332d3Sopenharmony_ci return; 1028094332d3Sopenharmony_ci } 1029094332d3Sopenharmony_ci condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_CACHE_PIN; 1030094332d3Sopenharmony_ci} 1031094332d3Sopenharmony_ci 1032094332d3Sopenharmony_ciIAM_STATIC bool IsUserValid(UserInfo *user) 1033094332d3Sopenharmony_ci{ 1034094332d3Sopenharmony_ci LinkedList *credentialInfoList = user->credentialInfoList; 1035094332d3Sopenharmony_ci CredentialInfoHal *pinCredential = QueryCredentialByAuthType(PIN_AUTH, credentialInfoList); 1036094332d3Sopenharmony_ci if (pinCredential == NULL) { 1037094332d3Sopenharmony_ci LOG_INFO("user is invalid, userId: %{public}d", user->userId); 1038094332d3Sopenharmony_ci return false; 1039094332d3Sopenharmony_ci } 1040094332d3Sopenharmony_ci return true; 1041094332d3Sopenharmony_ci} 1042094332d3Sopenharmony_ci 1043094332d3Sopenharmony_ciIAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount, 1044094332d3Sopenharmony_ci bool *cachePinRemoved) 1045094332d3Sopenharmony_ci{ 1046094332d3Sopenharmony_ci LOG_INFO("get invalid user start"); 1047094332d3Sopenharmony_ci if (g_userInfoList == NULL) { 1048094332d3Sopenharmony_ci LOG_ERROR("g_userInfoList is null"); 1049094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1050094332d3Sopenharmony_ci } 1051094332d3Sopenharmony_ci 1052094332d3Sopenharmony_ci LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList); 1053094332d3Sopenharmony_ci if (iterator == NULL) { 1054094332d3Sopenharmony_ci LOG_ERROR("create iterator failed"); 1055094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 1056094332d3Sopenharmony_ci } 1057094332d3Sopenharmony_ci 1058094332d3Sopenharmony_ci UserInfo *user = NULL; 1059094332d3Sopenharmony_ci *userCount = 0; 1060094332d3Sopenharmony_ci while (iterator->hasNext(iterator)) { 1061094332d3Sopenharmony_ci user = (UserInfo *)iterator->next(iterator); 1062094332d3Sopenharmony_ci if (user == NULL) { 1063094332d3Sopenharmony_ci LOG_ERROR("userinfo list node is null, please check"); 1064094332d3Sopenharmony_ci continue; 1065094332d3Sopenharmony_ci } 1066094332d3Sopenharmony_ci 1067094332d3Sopenharmony_ci if (*userCount >= maxUserCount) { 1068094332d3Sopenharmony_ci LOG_ERROR("too many users"); 1069094332d3Sopenharmony_ci break; 1070094332d3Sopenharmony_ci } 1071094332d3Sopenharmony_ci 1072094332d3Sopenharmony_ci if (!IsUserValid(user)) { 1073094332d3Sopenharmony_ci invalidUserId[*userCount] = user->userId; 1074094332d3Sopenharmony_ci (*userCount)++; 1075094332d3Sopenharmony_ci continue; 1076094332d3Sopenharmony_ci } 1077094332d3Sopenharmony_ci 1078094332d3Sopenharmony_ci bool isRemoved = false; 1079094332d3Sopenharmony_ci RemoveCachePin(user, &isRemoved); 1080094332d3Sopenharmony_ci if (isRemoved) { 1081094332d3Sopenharmony_ci *cachePinRemoved = true; 1082094332d3Sopenharmony_ci } 1083094332d3Sopenharmony_ci } 1084094332d3Sopenharmony_ci 1085094332d3Sopenharmony_ci g_userInfoList->destroyIterator(iterator); 1086094332d3Sopenharmony_ci return RESULT_SUCCESS; 1087094332d3Sopenharmony_ci} 1088094332d3Sopenharmony_ci 1089094332d3Sopenharmony_ciIAM_STATIC ResultCode ClearInvalidData(void) 1090094332d3Sopenharmony_ci{ 1091094332d3Sopenharmony_ci LOG_INFO("clear invalid user start"); 1092094332d3Sopenharmony_ci int32_t invalidUserId[MAX_USER] = {0}; 1093094332d3Sopenharmony_ci uint32_t userCount = 0; 1094094332d3Sopenharmony_ci bool cachePinRemoved = false; 1095094332d3Sopenharmony_ci if (GetInvalidUser(invalidUserId, MAX_USER, &userCount, &cachePinRemoved) != RESULT_SUCCESS) { 1096094332d3Sopenharmony_ci LOG_ERROR("GetInvalidUser fail"); 1097094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1098094332d3Sopenharmony_ci } 1099094332d3Sopenharmony_ci ResultCode ret = RESULT_SUCCESS; 1100094332d3Sopenharmony_ci for (uint32_t i = 0; i < userCount; ++i) { 1101094332d3Sopenharmony_ci ret = DeleteUser(invalidUserId[i]); 1102094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1103094332d3Sopenharmony_ci LOG_ERROR("delete invalid user fail, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret); 1104094332d3Sopenharmony_ci return ret; 1105094332d3Sopenharmony_ci } 1106094332d3Sopenharmony_ci LOG_INFO("delete invalid user success, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret); 1107094332d3Sopenharmony_ci } 1108094332d3Sopenharmony_ci 1109094332d3Sopenharmony_ci if ((userCount != 0) || cachePinRemoved) { 1110094332d3Sopenharmony_ci ret = UpdateFileInfo(g_userInfoList); 1111094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1112094332d3Sopenharmony_ci LOG_ERROR("UpdateFileInfo fail, ret: %{public}d", ret); 1113094332d3Sopenharmony_ci return ret; 1114094332d3Sopenharmony_ci } 1115094332d3Sopenharmony_ci } 1116094332d3Sopenharmony_ci return RESULT_SUCCESS; 1117094332d3Sopenharmony_ci} 1118094332d3Sopenharmony_ci 1119094332d3Sopenharmony_ciResultCode GetAllExtUserInfo(UserInfoResult *userInfos, uint32_t userInfoLen, uint32_t *userInfocount) 1120094332d3Sopenharmony_ci{ 1121094332d3Sopenharmony_ci LOG_INFO("get all user info start"); 1122094332d3Sopenharmony_ci if (userInfos == NULL || userInfocount == NULL || g_userInfoList == NULL) { 1123094332d3Sopenharmony_ci LOG_ERROR("param is null"); 1124094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1125094332d3Sopenharmony_ci } 1126094332d3Sopenharmony_ci 1127094332d3Sopenharmony_ci LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList); 1128094332d3Sopenharmony_ci if (iterator == NULL) { 1129094332d3Sopenharmony_ci LOG_ERROR("create iterator failed"); 1130094332d3Sopenharmony_ci return RESULT_NO_MEMORY; 1131094332d3Sopenharmony_ci } 1132094332d3Sopenharmony_ci 1133094332d3Sopenharmony_ci UserInfo *user = NULL; 1134094332d3Sopenharmony_ci EnrolledInfoHal *enrolledInfoHal = NULL; 1135094332d3Sopenharmony_ci *userInfocount = 0; 1136094332d3Sopenharmony_ci while (iterator->hasNext(iterator)) { 1137094332d3Sopenharmony_ci user = (UserInfo *)iterator->next(iterator); 1138094332d3Sopenharmony_ci if (user == NULL) { 1139094332d3Sopenharmony_ci LOG_ERROR("userinfo list node is null, please check"); 1140094332d3Sopenharmony_ci continue; 1141094332d3Sopenharmony_ci } 1142094332d3Sopenharmony_ci 1143094332d3Sopenharmony_ci if (*userInfocount >= userInfoLen) { 1144094332d3Sopenharmony_ci LOG_ERROR("too many users"); 1145094332d3Sopenharmony_ci goto ERROR; 1146094332d3Sopenharmony_ci } 1147094332d3Sopenharmony_ci 1148094332d3Sopenharmony_ci userInfos[*userInfocount].userId = user->userId; 1149094332d3Sopenharmony_ci userInfos[*userInfocount].secUid = user->secUid; 1150094332d3Sopenharmony_ci userInfos[*userInfocount].pinSubType = (uint32_t)user->pinSubType; 1151094332d3Sopenharmony_ci 1152094332d3Sopenharmony_ci ResultCode ret = GetAllEnrolledInfoFromUser(user, &enrolledInfoHal, &(userInfos[*userInfocount].enrollNum)); 1153094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1154094332d3Sopenharmony_ci LOG_ERROR("get enrolled info fail"); 1155094332d3Sopenharmony_ci goto ERROR; 1156094332d3Sopenharmony_ci } 1157094332d3Sopenharmony_ci if (userInfos[*userInfocount].enrollNum > MAX_ENROLL_OUTPUT) { 1158094332d3Sopenharmony_ci LOG_ERROR("too many elements"); 1159094332d3Sopenharmony_ci free(enrolledInfoHal); 1160094332d3Sopenharmony_ci goto ERROR; 1161094332d3Sopenharmony_ci } 1162094332d3Sopenharmony_ci 1163094332d3Sopenharmony_ci for (uint32_t i = 0; i < userInfos[*userInfocount].enrollNum; i++) { 1164094332d3Sopenharmony_ci userInfos[*userInfocount].enrolledInfo[i].authType = enrolledInfoHal[i].authType; 1165094332d3Sopenharmony_ci userInfos[*userInfocount].enrolledInfo[i].enrolledId = enrolledInfoHal[i].enrolledId; 1166094332d3Sopenharmony_ci } 1167094332d3Sopenharmony_ci 1168094332d3Sopenharmony_ci free(enrolledInfoHal); 1169094332d3Sopenharmony_ci (*userInfocount)++; 1170094332d3Sopenharmony_ci } 1171094332d3Sopenharmony_ci 1172094332d3Sopenharmony_ci g_userInfoList->destroyIterator(iterator); 1173094332d3Sopenharmony_ci return RESULT_SUCCESS; 1174094332d3Sopenharmony_ci 1175094332d3Sopenharmony_ciERROR: 1176094332d3Sopenharmony_ci g_userInfoList->destroyIterator(iterator); 1177094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1178094332d3Sopenharmony_ci} 1179094332d3Sopenharmony_ci 1180094332d3Sopenharmony_ciResultCode GetEnrolledState(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal) 1181094332d3Sopenharmony_ci{ 1182094332d3Sopenharmony_ci LOG_INFO("get enrolled id info start, userId:%{public}d, authType:%{public}d", userId, authType); 1183094332d3Sopenharmony_ci 1184094332d3Sopenharmony_ci UserInfo *user = QueryUserInfo(userId); 1185094332d3Sopenharmony_ci if (user == NULL) { 1186094332d3Sopenharmony_ci LOG_ERROR("user is null"); 1187094332d3Sopenharmony_ci return RESULT_NOT_ENROLLED; 1188094332d3Sopenharmony_ci } 1189094332d3Sopenharmony_ci if (user->credentialInfoList == NULL) { 1190094332d3Sopenharmony_ci LOG_ERROR("credentialInfoList is null"); 1191094332d3Sopenharmony_ci return RESULT_NOT_ENROLLED; 1192094332d3Sopenharmony_ci } 1193094332d3Sopenharmony_ci 1194094332d3Sopenharmony_ci uint16_t credentialCount = 0; 1195094332d3Sopenharmony_ci LinkedListNode *credentialInfoTemp = user->credentialInfoList->head; 1196094332d3Sopenharmony_ci while (credentialInfoTemp != NULL) { 1197094332d3Sopenharmony_ci CredentialInfoHal *nodeInfo = credentialInfoTemp->data; 1198094332d3Sopenharmony_ci if (nodeInfo != NULL && nodeInfo->authType == authType) { 1199094332d3Sopenharmony_ci ++credentialCount; 1200094332d3Sopenharmony_ci } 1201094332d3Sopenharmony_ci credentialInfoTemp = credentialInfoTemp->next; 1202094332d3Sopenharmony_ci } 1203094332d3Sopenharmony_ci if (credentialCount == 0) { 1204094332d3Sopenharmony_ci LOG_ERROR("not enrolled"); 1205094332d3Sopenharmony_ci return RESULT_NOT_ENROLLED; 1206094332d3Sopenharmony_ci } 1207094332d3Sopenharmony_ci enrolledStateHal->credentialCount = credentialCount; 1208094332d3Sopenharmony_ci if (user->enrolledInfoList == NULL) { 1209094332d3Sopenharmony_ci LOG_ERROR("enrolledInfoList is null"); 1210094332d3Sopenharmony_ci return RESULT_NOT_ENROLLED; 1211094332d3Sopenharmony_ci } 1212094332d3Sopenharmony_ci LinkedListNode *enrolledInfoTemp = user->enrolledInfoList->head; 1213094332d3Sopenharmony_ci while (enrolledInfoTemp != NULL) { 1214094332d3Sopenharmony_ci EnrolledInfoHal *nodeInfo = enrolledInfoTemp->data; 1215094332d3Sopenharmony_ci if (nodeInfo != NULL && nodeInfo->authType == authType) { 1216094332d3Sopenharmony_ci enrolledStateHal->credentialDigest = nodeInfo->enrolledId; 1217094332d3Sopenharmony_ci break; 1218094332d3Sopenharmony_ci } 1219094332d3Sopenharmony_ci enrolledInfoTemp = enrolledInfoTemp->next; 1220094332d3Sopenharmony_ci } 1221094332d3Sopenharmony_ci return RESULT_SUCCESS; 1222094332d3Sopenharmony_ci} 1223094332d3Sopenharmony_ci 1224094332d3Sopenharmony_ciIAM_STATIC ResultCode UpdateGlobalConfigArray(GlobalConfigParamHal *param, uint32_t authType) 1225094332d3Sopenharmony_ci{ 1226094332d3Sopenharmony_ci uint32_t infoIndex = 0; 1227094332d3Sopenharmony_ci for (infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) { 1228094332d3Sopenharmony_ci if (g_globalConfigArray[infoIndex].type == param->type && 1229094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].authType == authType) { 1230094332d3Sopenharmony_ci LOG_INFO("globalConfig is already exist, type:%{public}d, authType:%{public}u", param->type, authType); 1231094332d3Sopenharmony_ci break; 1232094332d3Sopenharmony_ci } 1233094332d3Sopenharmony_ci } 1234094332d3Sopenharmony_ci if (infoIndex >= MAX_GLOBAL_CONFIG_NUM) { 1235094332d3Sopenharmony_ci LOG_ERROR("globalConfigArray is exceed limit"); 1236094332d3Sopenharmony_ci return RESULT_EXCEED_LIMIT; 1237094332d3Sopenharmony_ci } 1238094332d3Sopenharmony_ci memset_s(&g_globalConfigArray[infoIndex], sizeof(GlobalConfigInfo), 0, sizeof(GlobalConfigInfo)); 1239094332d3Sopenharmony_ci 1240094332d3Sopenharmony_ci switch (param->type) { 1241094332d3Sopenharmony_ci case PIN_EXPIRED_PERIOD: 1242094332d3Sopenharmony_ci if (authType != PIN_AUTH) { 1243094332d3Sopenharmony_ci LOG_ERROR("bad authType:%{public}u for PIN_EXPIRED_PERIOD", authType); 1244094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1245094332d3Sopenharmony_ci } 1246094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].value.pinExpiredPeriod = param->value.pinExpiredPeriod; 1247094332d3Sopenharmony_ci break; 1248094332d3Sopenharmony_ci case ENABLE_STATUS: 1249094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].value.enableStatus = param->value.enableStatus; 1250094332d3Sopenharmony_ci break; 1251094332d3Sopenharmony_ci default: 1252094332d3Sopenharmony_ci LOG_ERROR("globalConfigType not support, type:%{public}d.", param->type); 1253094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1254094332d3Sopenharmony_ci } 1255094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].type = param->type; 1256094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].authType = authType; 1257094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].userIdNum = param->userIdNum; 1258094332d3Sopenharmony_ci for (uint32_t i = 0; i < param->userIdNum; i++) { 1259094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].userIds[i] = param->userIds[i]; 1260094332d3Sopenharmony_ci } 1261094332d3Sopenharmony_ci if (infoIndex == g_globalConfigInfoNum) { 1262094332d3Sopenharmony_ci g_globalConfigInfoNum++; 1263094332d3Sopenharmony_ci } 1264094332d3Sopenharmony_ci return RESULT_SUCCESS; 1265094332d3Sopenharmony_ci} 1266094332d3Sopenharmony_ci 1267094332d3Sopenharmony_ciIAM_STATIC bool CheckAuthType(uint32_t authType) 1268094332d3Sopenharmony_ci{ 1269094332d3Sopenharmony_ci if (authType != PIN_AUTH && authType != FACE_AUTH && authType != FINGER_AUTH && authType != RECOVERY_KEY) { 1270094332d3Sopenharmony_ci LOG_ERROR("bad authType %{public}u", authType); 1271094332d3Sopenharmony_ci return false; 1272094332d3Sopenharmony_ci } 1273094332d3Sopenharmony_ci return true; 1274094332d3Sopenharmony_ci} 1275094332d3Sopenharmony_ci 1276094332d3Sopenharmony_ciResultCode SaveGlobalConfigParam(GlobalConfigParamHal *param) 1277094332d3Sopenharmony_ci{ 1278094332d3Sopenharmony_ci if (param == NULL || param->userIdNum > MAX_USER || param->authTypeNum > MAX_AUTH_TYPE_LEN || 1279094332d3Sopenharmony_ci param->authTypeNum == 0) { 1280094332d3Sopenharmony_ci LOG_ERROR("bad param"); 1281094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1282094332d3Sopenharmony_ci } 1283094332d3Sopenharmony_ci for (uint32_t i = 0; i < param->authTypeNum; i++) { 1284094332d3Sopenharmony_ci if (!CheckAuthType(param->authTypes[i])) { 1285094332d3Sopenharmony_ci LOG_ERROR("bad authType %{public}u", param->authTypes[i]); 1286094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1287094332d3Sopenharmony_ci } 1288094332d3Sopenharmony_ci ResultCode ret = UpdateGlobalConfigArray(param, param->authTypes[i]); 1289094332d3Sopenharmony_ci if (ret != RESULT_SUCCESS) { 1290094332d3Sopenharmony_ci return ret; 1291094332d3Sopenharmony_ci } 1292094332d3Sopenharmony_ci } 1293094332d3Sopenharmony_ci 1294094332d3Sopenharmony_ci return UpdateGlobalConfigFile(g_globalConfigArray, g_globalConfigInfoNum); 1295094332d3Sopenharmony_ci} 1296094332d3Sopenharmony_ci 1297094332d3Sopenharmony_ciIAM_STATIC ResultCode QueryPinCredential(int32_t userId, CredentialInfoHal *pinCredential) 1298094332d3Sopenharmony_ci{ 1299094332d3Sopenharmony_ci if (pinCredential == NULL) { 1300094332d3Sopenharmony_ci LOG_ERROR("no need to get pin credential"); 1301094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1302094332d3Sopenharmony_ci } 1303094332d3Sopenharmony_ci CredentialCondition condition = {}; 1304094332d3Sopenharmony_ci SetCredentialConditionUserId(&condition, userId); 1305094332d3Sopenharmony_ci SetCredentialConditionAuthType(&condition, PIN_AUTH); 1306094332d3Sopenharmony_ci LinkedList *credList = QueryCredentialLimit(&condition); 1307094332d3Sopenharmony_ci if (credList == NULL || credList->getSize(credList) == 0) { 1308094332d3Sopenharmony_ci LOG_ERROR("pin credential is null"); 1309094332d3Sopenharmony_ci DestroyLinkedList(credList); 1310094332d3Sopenharmony_ci return RESULT_NOT_ENROLLED; 1311094332d3Sopenharmony_ci } 1312094332d3Sopenharmony_ci if (credList->head == NULL || credList->head->data == NULL) { 1313094332d3Sopenharmony_ci LOG_ERROR("pin credList node is invalid"); 1314094332d3Sopenharmony_ci DestroyLinkedList(credList); 1315094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1316094332d3Sopenharmony_ci } 1317094332d3Sopenharmony_ci if (memcpy_s(pinCredential, sizeof(CredentialInfoHal), credList->head->data, sizeof(CredentialInfoHal)) != EOK) { 1318094332d3Sopenharmony_ci LOG_ERROR("credential copy fail"); 1319094332d3Sopenharmony_ci DestroyLinkedList(credList); 1320094332d3Sopenharmony_ci return RESULT_GENERAL_ERROR; 1321094332d3Sopenharmony_ci } 1322094332d3Sopenharmony_ci DestroyLinkedList(credList); 1323094332d3Sopenharmony_ci return RESULT_SUCCESS; 1324094332d3Sopenharmony_ci} 1325094332d3Sopenharmony_ci 1326094332d3Sopenharmony_ciResultCode GetPinExpiredInfo(int32_t userId, PinExpiredInfo *expiredInfo) 1327094332d3Sopenharmony_ci{ 1328094332d3Sopenharmony_ci if (expiredInfo == NULL) { 1329094332d3Sopenharmony_ci LOG_ERROR("bad param"); 1330094332d3Sopenharmony_ci return RESULT_BAD_PARAM; 1331094332d3Sopenharmony_ci } 1332094332d3Sopenharmony_ci (void)memset_s(expiredInfo, sizeof(PinExpiredInfo), 0, sizeof(PinExpiredInfo)); 1333094332d3Sopenharmony_ci for (uint32_t i = 0; i < g_globalConfigInfoNum; i++) { 1334094332d3Sopenharmony_ci if (g_globalConfigArray[i].type == PIN_EXPIRED_PERIOD) { 1335094332d3Sopenharmony_ci expiredInfo->pinExpiredPeriod = g_globalConfigArray[i].value.pinExpiredPeriod; 1336094332d3Sopenharmony_ci break; 1337094332d3Sopenharmony_ci } 1338094332d3Sopenharmony_ci } 1339094332d3Sopenharmony_ci if (expiredInfo->pinExpiredPeriod <= 0) { 1340094332d3Sopenharmony_ci expiredInfo->pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD; 1341094332d3Sopenharmony_ci LOG_INFO("no need check pinExpiredPeriod"); 1342094332d3Sopenharmony_ci return RESULT_SUCCESS; 1343094332d3Sopenharmony_ci } 1344094332d3Sopenharmony_ci CredentialInfoHal pinCredential = {}; 1345094332d3Sopenharmony_ci if (QueryPinCredential(userId, &pinCredential) != RESULT_SUCCESS) { 1346094332d3Sopenharmony_ci LOG_INFO("not enrolled pin"); 1347094332d3Sopenharmony_ci return RESULT_NOT_ENROLLED; 1348094332d3Sopenharmony_ci } 1349094332d3Sopenharmony_ci expiredInfo->pinEnrolledSysTime = pinCredential.enrolledSysTime; 1350094332d3Sopenharmony_ci return RESULT_SUCCESS; 1351094332d3Sopenharmony_ci} 1352094332d3Sopenharmony_ci 1353094332d3Sopenharmony_cibool GetEnableStatus(int32_t userId, uint32_t authType) 1354094332d3Sopenharmony_ci{ 1355094332d3Sopenharmony_ci for (uint32_t infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) { 1356094332d3Sopenharmony_ci if (g_globalConfigArray[infoIndex].type != ENABLE_STATUS || 1357094332d3Sopenharmony_ci g_globalConfigArray[infoIndex].authType != authType) { 1358094332d3Sopenharmony_ci continue; 1359094332d3Sopenharmony_ci } 1360094332d3Sopenharmony_ci LOG_INFO("enableStatus:%{public}d authType:%{public}u", g_globalConfigArray[infoIndex].value.enableStatus, 1361094332d3Sopenharmony_ci authType); 1362094332d3Sopenharmony_ci if (userId == INVALID_USER_ID || g_globalConfigArray[infoIndex].userIdNum == 0) { 1363094332d3Sopenharmony_ci return g_globalConfigArray[infoIndex].value.enableStatus; 1364094332d3Sopenharmony_ci } 1365094332d3Sopenharmony_ci for (uint32_t i = 0; i < g_globalConfigArray[infoIndex].userIdNum; i++) { 1366094332d3Sopenharmony_ci if (userId == g_globalConfigArray[infoIndex].userIds[i]) { 1367094332d3Sopenharmony_ci return g_globalConfigArray[infoIndex].value.enableStatus; 1368094332d3Sopenharmony_ci } 1369094332d3Sopenharmony_ci } 1370094332d3Sopenharmony_ci LOG_INFO("enableStatus is not set for userId:%{public}d", userId); 1371094332d3Sopenharmony_ci return (!g_globalConfigArray[infoIndex].value.enableStatus); 1372094332d3Sopenharmony_ci } 1373094332d3Sopenharmony_ci return true; 1374094332d3Sopenharmony_ci} 1375