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