1 /*
2 * Copyright (C) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "context_manager.h"
17
18 #include "securec.h"
19
20 #include "adaptor_log.h"
21 #include "auth_level.h"
22 #include "coauth.h"
23 #include "idm_database.h"
24 #include "udid_manager.h"
25
26 #ifdef IAM_TEST_ENABLE
27 #define IAM_STATIC
28 #else
29 #define IAM_STATIC static
30 #endif
31
32 IAM_STATIC bool IsContextDuplicate(uint64_t contextId);
33 IAM_STATIC ResultCode CreateAndInsertSchedules(UserAuthContext *context, uint32_t authMode);
34 IAM_STATIC ResultCode CreateAuthSchedule(UserAuthContext *context, CoAuthSchedule **schedule);
35 IAM_STATIC ResultCode CreateIdentifySchedule(const UserAuthContext *context, CoAuthSchedule **schedule);
36 IAM_STATIC void DestroyContextNode(void *data);
37 IAM_STATIC ResultCode InsertScheduleToContext(CoAuthSchedule *schedule, UserAuthContext *context);
38
39 // Stores information about the current user authentication schedule.
40 IAM_STATIC LinkedList *g_contextList = NULL;
41
InitUserAuthContextList(void)42 ResultCode InitUserAuthContextList(void)
43 {
44 if (g_contextList != NULL) {
45 return RESULT_SUCCESS;
46 }
47 g_contextList = CreateLinkedList(DestroyContextNode);
48 if (g_contextList == NULL) {
49 return RESULT_GENERAL_ERROR;
50 }
51 return RESULT_SUCCESS;
52 }
53
DestoryUserAuthContextList(void)54 void DestoryUserAuthContextList(void)
55 {
56 DestroyLinkedList(g_contextList);
57 g_contextList = NULL;
58 }
59
InitAuthContext(AuthParamHal params)60 IAM_STATIC UserAuthContext *InitAuthContext(AuthParamHal params)
61 {
62 UserAuthContext *context = (UserAuthContext *)Malloc(sizeof(UserAuthContext));
63 if (context == NULL) {
64 LOG_ERROR("context malloc failed");
65 return NULL;
66 }
67 (void)memset_s(context, sizeof(UserAuthContext), 0, sizeof(UserAuthContext));
68 if (memcpy_s(context->challenge, CHALLENGE_LEN, params.challenge, CHALLENGE_LEN) != EOK) {
69 LOG_ERROR("failed to copy challenge");
70 Free(context);
71 return NULL;
72 }
73 context->contextId = params.contextId;
74 context->userId = params.userId;
75 context->authType = params.authType;
76 context->authTrustLevel = params.authTrustLevel;
77 context->collectorSensorHint = params.executorSensorHint;
78 context->scheduleList = CreateLinkedList(DestroyScheduleNode);
79 context->authIntent = params.authIntent;
80 context->isExpiredReturnSuccess = params.isExpiredReturnSuccess;
81
82 if (memcpy_s(context->localUdid, sizeof(context->localUdid), params.localUdid,
83 sizeof(params.localUdid)) != EOK) {
84 LOG_ERROR("localUdid copy failed");
85 Free(context);
86 return NULL;
87 }
88
89 if (memcpy_s(context->collectorUdid, sizeof(context->collectorUdid), params.collectorUdid,
90 sizeof(params.collectorUdid)) != EOK) {
91 LOG_ERROR("collectorUdid copy failed");
92 Free(context);
93 return NULL;
94 }
95
96 if (context->scheduleList == NULL) {
97 LOG_ERROR("schedule list create failed");
98 Free(context);
99 return NULL;
100 }
101
102 return context;
103 }
104
SetContextExpiredTime(UserAuthContext * authContext)105 IAM_STATIC ResultCode SetContextExpiredTime(UserAuthContext *authContext)
106 {
107 if (authContext == NULL) {
108 LOG_ERROR("bad param");
109 return RESULT_BAD_PARAM;
110 }
111 PinExpiredInfo expiredInfo = {};
112 ResultCode result = GetPinExpiredInfo(authContext->userId, &expiredInfo);
113 if (result != RESULT_SUCCESS) {
114 LOG_ERROR("GetPinExpiredInfo failed");
115 return result;
116 }
117 if (expiredInfo.pinExpiredPeriod == NO_CHECK_PIN_EXPIRED_PERIOD) {
118 LOG_ERROR("pinExpiredPeriod is not set");
119 authContext->authExpiredSysTime = NO_CHECK_PIN_EXPIRED_PERIOD;
120 return RESULT_SUCCESS;
121 }
122 authContext->authExpiredSysTime = UINT64_MAX;
123 if (expiredInfo.pinEnrolledSysTime + expiredInfo.pinExpiredPeriod < UINT64_MAX) {
124 authContext->authExpiredSysTime = expiredInfo.pinEnrolledSysTime + expiredInfo.pinExpiredPeriod;
125 }
126 return RESULT_SUCCESS;
127 }
128
GenerateAuthContext(AuthParamHal params,UserAuthContext ** context)129 ResultCode GenerateAuthContext(AuthParamHal params, UserAuthContext **context)
130 {
131 LOG_INFO("start");
132 if (context == NULL) {
133 LOG_ERROR("context is null");
134 return RESULT_BAD_PARAM;
135 }
136 if (g_contextList == NULL) {
137 LOG_ERROR("need init");
138 return RESULT_NEED_INIT;
139 }
140 if (IsContextDuplicate(params.contextId)) {
141 LOG_ERROR("contextId is duplicate");
142 return RESULT_DUPLICATE_CHECK_FAILED;
143 }
144 *context = InitAuthContext(params);
145 if (*context == NULL) {
146 LOG_ERROR("init context failed");
147 return RESULT_GENERAL_ERROR;
148 }
149 ResultCode ret = CreateAndInsertSchedules(*context, SCHEDULE_MODE_AUTH);
150 if (ret != RESULT_SUCCESS) {
151 LOG_ERROR("create schedule failed %{public}d", ret);
152 DestroyContextNode(*context);
153 *context = NULL;
154 return ret;
155 }
156 ret = SetContextExpiredTime(*context);
157 if (ret != RESULT_SUCCESS) {
158 LOG_ERROR("GetAuthExpiredSysTime failed");
159 DestroyContextNode(*context);
160 *context = NULL;
161 return ret;
162 }
163 ret = g_contextList->insert(g_contextList, *context);
164 if (ret != RESULT_SUCCESS) {
165 LOG_ERROR("create schedule failed");
166 DestroyContextNode(*context);
167 *context = NULL;
168 return RESULT_GENERAL_ERROR;
169 }
170 return RESULT_SUCCESS;
171 }
172
CreateIdentifySchedule(const UserAuthContext * context,CoAuthSchedule ** schedule)173 IAM_STATIC ResultCode CreateIdentifySchedule(const UserAuthContext *context, CoAuthSchedule **schedule)
174 {
175 ScheduleParam scheduleParam = {};
176 scheduleParam.associateId.contextId = context->contextId;
177 scheduleParam.authType = context->authType;
178 scheduleParam.collectorSensorHint = context->collectorSensorHint;
179 scheduleParam.verifierSensorHint = context->collectorSensorHint;
180 scheduleParam.scheduleMode = SCHEDULE_MODE_IDENTIFY;
181 Uint8Array localUdid = { scheduleParam.localUdid, UDID_LEN };
182 bool getLocalUdidRet = GetLocalUdid(&localUdid);
183 Uint8Array collectorUdid = { scheduleParam.collectorUdid, UDID_LEN };
184 bool getCollectorUdidRet = GetLocalUdid(&collectorUdid);
185 if (!getLocalUdidRet || !getCollectorUdidRet) {
186 LOG_ERROR("get udid failed");
187 return RESULT_GENERAL_ERROR;
188 }
189 *schedule = GenerateSchedule(&scheduleParam);
190 if (*schedule == NULL) {
191 LOG_ERROR("GenerateSchedule failed");
192 return RESULT_GENERAL_ERROR;
193 }
194 return RESULT_SUCCESS;
195 }
196
InitIdentifyContext(const IdentifyParam * params)197 IAM_STATIC UserAuthContext *InitIdentifyContext(const IdentifyParam *params)
198 {
199 UserAuthContext *context = (UserAuthContext *)Malloc(sizeof(UserAuthContext));
200 if (context == NULL) {
201 LOG_ERROR("context malloc failed");
202 return NULL;
203 }
204 (void)memset_s(context, sizeof(UserAuthContext), 0, sizeof(UserAuthContext));
205 if (memcpy_s(context->challenge, CHALLENGE_LEN, params->challenge, CHALLENGE_LEN) != EOK) {
206 LOG_ERROR("failed to copy challenge");
207 Free(context);
208 return NULL;
209 }
210 context->contextId = params->contextId;
211 context->authType = params->authType;
212 context->collectorSensorHint = params->executorSensorHint;
213 context->scheduleList = CreateLinkedList(DestroyScheduleNode);
214 if (context->scheduleList == NULL) {
215 LOG_ERROR("schedule list create failed");
216 Free(context);
217 return NULL;
218 }
219 return context;
220 }
221
GenerateIdentifyContext(IdentifyParam params)222 UserAuthContext *GenerateIdentifyContext(IdentifyParam params)
223 {
224 LOG_INFO("start");
225 if (g_contextList == NULL) {
226 LOG_ERROR("need init");
227 return NULL;
228 }
229 if (IsContextDuplicate(params.contextId)) {
230 LOG_ERROR("contextId is duplicate");
231 return NULL;
232 }
233
234 UserAuthContext *context = InitIdentifyContext(¶ms);
235 if (context == NULL) {
236 LOG_ERROR("init context failed");
237 return NULL;
238 }
239 ResultCode ret = CreateAndInsertSchedules(context, SCHEDULE_MODE_IDENTIFY);
240 if (ret != RESULT_SUCCESS) {
241 LOG_ERROR("create schedule failed");
242 DestroyContextNode(context);
243 return NULL;
244 }
245 ret = g_contextList->insert(g_contextList, context);
246 if (ret != RESULT_SUCCESS) {
247 LOG_ERROR("create schedule failed");
248 DestroyContextNode(context);
249 return NULL;
250 }
251 return context;
252 }
253
GetContext(uint64_t contextId)254 UserAuthContext *GetContext(uint64_t contextId)
255 {
256 if (g_contextList == NULL) {
257 LOG_ERROR("context list is null");
258 return NULL;
259 }
260 uint32_t num = g_contextList->getSize(g_contextList);
261 LinkedListNode *tempNode = g_contextList->head;
262 UserAuthContext *contextRet = NULL;
263 for (uint32_t index = 0; index < num; index++) {
264 if (tempNode == NULL) {
265 LOG_ERROR("node is null");
266 return NULL;
267 }
268 contextRet = (UserAuthContext *)tempNode->data;
269 if (contextRet != NULL && contextRet->contextId == contextId) {
270 return contextRet;
271 }
272 tempNode = tempNode->next;
273 }
274 return NULL;
275 }
276
InsertScheduleToContext(CoAuthSchedule * schedule,UserAuthContext * context)277 IAM_STATIC ResultCode InsertScheduleToContext(CoAuthSchedule *schedule, UserAuthContext *context)
278 {
279 LinkedList *scheduleList = context->scheduleList;
280 return scheduleList->insert(scheduleList, schedule);
281 }
282
CreateAndInsertSchedules(UserAuthContext * context,uint32_t authMode)283 IAM_STATIC ResultCode CreateAndInsertSchedules(UserAuthContext *context, uint32_t authMode)
284 {
285 LOG_INFO("start");
286 CoAuthSchedule *schedule = NULL;
287 ResultCode result = RESULT_BAD_PARAM;
288 if (authMode == SCHEDULE_MODE_AUTH) {
289 result = CreateAuthSchedule(context, &schedule);
290 } else if (authMode == SCHEDULE_MODE_IDENTIFY) {
291 result = CreateIdentifySchedule(context, &schedule);
292 } else {
293 LOG_ERROR("authMode is invalid");
294 return result;
295 }
296
297 if (result != RESULT_SUCCESS) {
298 LOG_INFO("create schedule fail %{public}d", result);
299 return result;
300 }
301
302 if (AddCoAuthSchedule(schedule) != RESULT_SUCCESS) {
303 LOG_ERROR("AddCoAuthSchedule failed");
304 DestroyCoAuthSchedule(schedule);
305 return RESULT_UNKNOWN;
306 }
307
308 if (InsertScheduleToContext(schedule, context) != RESULT_SUCCESS) {
309 RemoveCoAuthSchedule(schedule->scheduleId);
310 DestroyCoAuthSchedule(schedule);
311 LOG_ERROR("insert failed");
312 return RESULT_UNKNOWN;
313 }
314 return RESULT_SUCCESS;
315 }
316
GetAuthCredentialList(const UserAuthContext * context)317 IAM_STATIC LinkedList *GetAuthCredentialList(const UserAuthContext *context)
318 {
319 CredentialCondition condition = {};
320 SetCredentialConditionAuthType(&condition, context->authType);
321 SetCredentialConditionUserId(&condition, context->userId);
322 if (context->collectorSensorHint != INVALID_SENSOR_HINT) {
323 uint32_t executorMatcher;
324 ResultCode ret = QueryCollecterMatcher(context->authType, context->collectorSensorHint, &executorMatcher);
325 if (ret != RESULT_SUCCESS) {
326 LOG_ERROR("query collect matcher failed");
327 return NULL;
328 }
329 SetCredentialConditionExecutorMatcher(&condition, executorMatcher);
330 }
331 return QueryCredentialLimit(&condition);
332 }
333
CheckCredentialSize(LinkedList * credList)334 IAM_STATIC ResultCode CheckCredentialSize(LinkedList *credList)
335 {
336 uint32_t credNum = credList->getSize(credList);
337 if (credNum == 0) {
338 LOG_ERROR("credNum is 0");
339 return RESULT_NOT_ENROLLED;
340 }
341 if (credNum > MAX_CREDENTIAL) {
342 LOG_ERROR("credNum exceed limit");
343 return RESULT_EXCEED_LIMIT;
344 }
345 return RESULT_SUCCESS;
346 }
347
QueryAuthTempletaInfo(UserAuthContext * context,Uint64Array * templateIds,uint32_t * sensorHint,uint32_t * matcher,uint32_t * acl)348 IAM_STATIC ResultCode QueryAuthTempletaInfo(UserAuthContext *context, Uint64Array *templateIds,
349 uint32_t *sensorHint, uint32_t *matcher, uint32_t *acl)
350 {
351 LinkedList *credList = GetAuthCredentialList(context);
352 if (credList == NULL) {
353 LOG_ERROR("query credential failed");
354 return RESULT_UNKNOWN;
355 }
356 ResultCode checkResult = CheckCredentialSize(credList);
357 if (checkResult != RESULT_SUCCESS) {
358 LOG_ERROR("CheckCredentialSize failed %{public}d", checkResult);
359 DestroyLinkedList(credList);
360 return checkResult;
361 }
362 templateIds->data = (uint64_t *)Malloc(sizeof(uint64_t) * credList->getSize(credList));
363 if (templateIds->data == NULL) {
364 LOG_ERROR("value malloc failed");
365 DestroyLinkedList(credList);
366 return RESULT_NO_MEMORY;
367 }
368 templateIds->len = 0;
369 LinkedListNode *temp = credList->head;
370 if (temp == NULL || temp->data == NULL) {
371 LOG_ERROR("link node is invalid");
372 goto FAIL;
373 }
374 CredentialInfoHal *credentialHal = (CredentialInfoHal *)temp->data;
375 *sensorHint = credentialHal->executorSensorHint;
376 *matcher = credentialHal->executorMatcher;
377 *acl = credentialHal->capabilityLevel;
378 while (temp != NULL) {
379 if (temp->data == NULL) {
380 LOG_ERROR("link node is invalid");
381 goto FAIL;
382 }
383 credentialHal = (CredentialInfoHal *)temp->data;
384 if (credentialHal->executorSensorHint == *sensorHint) {
385 templateIds->data[templateIds->len] = credentialHal->templateId;
386 ++(templateIds->len);
387 }
388 temp = temp->next;
389 }
390 DestroyLinkedList(credList);
391 return RESULT_SUCCESS;
392
393 FAIL:
394 Free(templateIds->data);
395 templateIds->data = NULL;
396 DestroyLinkedList(credList);
397 return RESULT_UNKNOWN;
398 }
399
CreateAuthSchedule(UserAuthContext * context,CoAuthSchedule ** schedule)400 IAM_STATIC ResultCode CreateAuthSchedule(UserAuthContext *context, CoAuthSchedule **schedule)
401 {
402 Uint64Array templateIds = {};
403 uint32_t verifierSensorHint;
404 uint32_t executorMatcher;
405 uint32_t acl;
406 ResultCode ret = QueryAuthTempletaInfo(context, &templateIds, &verifierSensorHint, &executorMatcher, &acl);
407 if (ret != RESULT_SUCCESS) {
408 LOG_ERROR("QueryAuthTempletaInfo failed %{public}d", ret);
409 return ret;
410 }
411 ScheduleParam scheduleParam = {};
412 scheduleParam.associateId.contextId = context->contextId;
413 scheduleParam.authType = context->authType;
414 scheduleParam.collectorSensorHint = context->collectorSensorHint;
415 scheduleParam.verifierSensorHint = verifierSensorHint;
416 scheduleParam.templateIds = &templateIds;
417 scheduleParam.executorMatcher = executorMatcher;
418 scheduleParam.scheduleMode = SCHEDULE_MODE_AUTH;
419 if (memcpy_s(scheduleParam.localUdid, sizeof(scheduleParam.localUdid), context->localUdid,
420 sizeof(context->localUdid)) != EOK) {
421 LOG_ERROR("localUdid copy failed");
422 return RESULT_GENERAL_ERROR;
423 }
424
425 if (memcpy_s(scheduleParam.collectorUdid, sizeof(scheduleParam.collectorUdid), context->collectorUdid,
426 sizeof(context->collectorUdid)) != EOK) {
427 LOG_ERROR("collectorUdid copy failed");
428 return RESULT_GENERAL_ERROR;
429 }
430 *schedule = GenerateSchedule(&scheduleParam);
431 if (*schedule == NULL) {
432 LOG_ERROR("schedule is null");
433 Free(templateIds.data);
434 return RESULT_GENERAL_ERROR;
435 }
436 uint32_t scheduleAtl;
437 ret = QueryScheduleAtl(*schedule, acl, &scheduleAtl);
438 if (ret != RESULT_SUCCESS || context->authTrustLevel > scheduleAtl) {
439 Free(templateIds.data);
440 DestroyCoAuthSchedule(*schedule);
441 *schedule = NULL;
442 return ret;
443 }
444 Free(templateIds.data);
445 return RESULT_SUCCESS;
446 }
447
IsContextDuplicate(uint64_t contextId)448 IAM_STATIC bool IsContextDuplicate(uint64_t contextId)
449 {
450 if (g_contextList == NULL) {
451 LOG_ERROR("context list is null");
452 return false;
453 }
454 LinkedListNode *tempNode = g_contextList->head;
455 while (tempNode != NULL) {
456 UserAuthContext *context = (UserAuthContext *)tempNode->data;
457 if (context == NULL) {
458 LOG_ERROR("context is null, please check");
459 tempNode = tempNode->next;
460 continue;
461 }
462 if (context->contextId == contextId) {
463 return true;
464 }
465 tempNode = tempNode->next;
466 }
467 return false;
468 }
469
CopySchedules(UserAuthContext * context,LinkedList ** schedules)470 ResultCode CopySchedules(UserAuthContext *context, LinkedList **schedules)
471 {
472 if (context == NULL || context->scheduleList == NULL || schedules == NULL) {
473 LOG_ERROR("param is null");
474 return RESULT_BAD_PARAM;
475 }
476 LinkedList *scheduleList = context->scheduleList;
477 uint32_t scheduleNum = scheduleList->getSize(scheduleList);
478 if (scheduleNum > AUTH_MAX_SCHEDULING_NUM) {
479 LOG_ERROR("scheduleNum is invalid, scheduleNum is %{public}u", scheduleNum);
480 return RESULT_UNKNOWN;
481 }
482 *schedules = CreateLinkedList(DestroyScheduleNode);
483 if (*schedules == NULL) {
484 LOG_ERROR("schedules malloc failed");
485 return RESULT_NO_MEMORY;
486 }
487 if (scheduleNum == 0) {
488 LOG_INFO("scheduleNum is zero");
489 return RESULT_SUCCESS;
490 }
491
492 LinkedListNode *temp = scheduleList->head;
493 while (temp != NULL) {
494 if (temp->data == NULL) {
495 LOG_ERROR("node data is wrong, please check");
496 goto ERROR;
497 }
498 CoAuthSchedule *schedule = CopyCoAuthSchedule((CoAuthSchedule *)temp->data);
499 if (schedule == NULL) {
500 LOG_ERROR("data is null");
501 goto ERROR;
502 }
503 if ((*schedules)->insert(*schedules, schedule) != RESULT_SUCCESS) {
504 LOG_ERROR("insert schedule failed");
505 DestroyCoAuthSchedule(schedule);
506 goto ERROR;
507 }
508 temp = temp->next;
509 }
510 return RESULT_SUCCESS;
511
512 ERROR:
513 DestroyLinkedList(*schedules);
514 *schedules = NULL;
515 return RESULT_GENERAL_ERROR;
516 }
517
MatchSchedule(const void * data,const void * condition)518 IAM_STATIC bool MatchSchedule(const void *data, const void *condition)
519 {
520 if (data == NULL || condition == NULL) {
521 LOG_ERROR("param is null");
522 return false;
523 }
524 const CoAuthSchedule *schedule = (const CoAuthSchedule *)data;
525 if (schedule->scheduleId == *(const uint64_t *)condition) {
526 return true;
527 }
528 return false;
529 }
530
ScheduleOnceFinish(UserAuthContext * context,uint64_t scheduleId)531 ResultCode ScheduleOnceFinish(UserAuthContext *context, uint64_t scheduleId)
532 {
533 if (context == NULL || context->scheduleList == NULL) {
534 LOG_ERROR("param is null");
535 return RESULT_BAD_PARAM;
536 }
537 RemoveCoAuthSchedule(scheduleId);
538 return context->scheduleList->remove(context->scheduleList, &scheduleId, MatchSchedule, true);
539 }
540
MatchContextSelf(const void * data,const void * condition)541 IAM_STATIC bool MatchContextSelf(const void *data, const void *condition)
542 {
543 return data == condition;
544 }
545
DestroyContext(UserAuthContext * context)546 void DestroyContext(UserAuthContext *context)
547 {
548 if (context == NULL) {
549 LOG_ERROR("context is null");
550 return;
551 }
552 if (g_contextList == NULL) {
553 LOG_ERROR("context list is null");
554 return;
555 }
556 g_contextList->remove(g_contextList, context, MatchContextSelf, true);
557 }
558
DestroyContextNode(void * data)559 IAM_STATIC void DestroyContextNode(void *data)
560 {
561 if (data == NULL) {
562 return;
563 }
564 LinkedList *schedules = ((UserAuthContext *)data)->scheduleList;
565 if (schedules == NULL) {
566 LOG_ERROR("schedules is null");
567 return;
568 }
569 LinkedListNode *tempNode = schedules->head;
570 while (tempNode != NULL) {
571 CoAuthSchedule *schedule = tempNode->data;
572 if (schedule == NULL) {
573 LOG_ERROR("schedule is null, please check");
574 tempNode = tempNode->next;
575 continue;
576 }
577 RemoveCoAuthSchedule(schedule->scheduleId);
578 tempNode = tempNode->next;
579 }
580 DestroyLinkedList(schedules);
581 Free(data);
582 }
583
DestroyContextbyId(uint64_t contextId)584 ResultCode DestroyContextbyId(uint64_t contextId)
585 {
586 UserAuthContext *authContext = GetContext(contextId);
587 if (authContext == NULL) {
588 LOG_ERROR("get context failed");
589 return RESULT_NOT_FOUND;
590 }
591 DestroyContext(authContext);
592 return RESULT_SUCCESS;
593 }
594
GetCoAuthScheduleFromContext(const UserAuthContext * context,uint64_t scheduleId)595 IAM_STATIC const CoAuthSchedule *GetCoAuthScheduleFromContext(const UserAuthContext *context, uint64_t scheduleId)
596 {
597 if (context->scheduleList == NULL) {
598 LOG_ERROR("get null scheduleList");
599 return NULL;
600 }
601
602 LinkedListNode *tempNode = context->scheduleList->head;
603 while (tempNode != NULL) {
604 const CoAuthSchedule *schedule = tempNode->data;
605 if (schedule == NULL) {
606 LOG_ERROR("schedule is null, please check");
607 tempNode = tempNode->next;
608 continue;
609 }
610 if (schedule->scheduleId == scheduleId) {
611 return schedule;
612 }
613 tempNode = tempNode->next;
614 }
615
616 LOG_ERROR("no schedule exist");
617 return NULL;
618 }
619
CheckAndSetContextAtl(UserAuthContext * context,const CoAuthSchedule * schedule,ExecutorResultInfo * info)620 IAM_STATIC ResultCode CheckAndSetContextAtl(
621 UserAuthContext *context, const CoAuthSchedule *schedule, ExecutorResultInfo *info)
622 {
623 uint32_t atl = ATL0;
624 ResultCode ret = QueryScheduleAtl(schedule, info->capabilityLevel, &atl);
625 if (ret != RESULT_SUCCESS) {
626 LOG_ERROR("QueryScheduleAtl fail");
627 return ret;
628 }
629 if (atl < context->authTrustLevel) {
630 LOG_ERROR("atl %u not satisfied, context atl:%u", atl, context->authTrustLevel);
631 return RESULT_TRUST_LEVEL_NOT_SUPPORT;
632 }
633 LOG_INFO("context atl %{public}u:%{public}u", context->authTrustLevel, atl);
634 context->authTrustLevel = atl;
635 return RESULT_SUCCESS;
636 }
637
CheckAndSetContextUserId(UserAuthContext * context,uint64_t credentialId,uint32_t authMode)638 IAM_STATIC ResultCode CheckAndSetContextUserId(UserAuthContext *context, uint64_t credentialId, uint32_t authMode)
639 {
640 int32_t userId = 0;
641 ResultCode ret = QueryCredentialUserId(credentialId, &userId);
642 if (ret != RESULT_SUCCESS) {
643 LOG_ERROR("query userId failed");
644 return ret;
645 }
646 if (authMode == SCHEDULE_MODE_IDENTIFY) {
647 context->userId = userId;
648 }
649 if (userId != context->userId) {
650 LOG_ERROR("userId is not matched");
651 return RESULT_GENERAL_ERROR;
652 }
653 return RESULT_SUCCESS;
654 }
655
FillInContext(UserAuthContext * context,uint64_t * credentialId,ExecutorResultInfo * info,uint32_t authMode)656 ResultCode FillInContext(UserAuthContext *context, uint64_t *credentialId, ExecutorResultInfo *info,
657 uint32_t authMode)
658 {
659 if (context == NULL || credentialId == NULL || info == NULL) {
660 LOG_ERROR("param is null");
661 return RESULT_BAD_PARAM;
662 }
663 const CoAuthSchedule *schedule = GetCoAuthScheduleFromContext(context, info->scheduleId);
664 if (schedule == NULL) {
665 LOG_ERROR("GetCoAuthScheduleFromContext failed");
666 return RESULT_GENERAL_ERROR;
667 }
668 ResultCode ret = CheckAndSetContextAtl(context, schedule, info);
669 if (ret != RESULT_SUCCESS) {
670 LOG_ERROR("CheckAndSetContextAtl failed");
671 return ret;
672 }
673 ret = RESULT_UNKNOWN;
674 uint32_t verifierSensorHint = GetScheduleVerifierSensorHint(schedule);
675 CredentialCondition condition = {};
676 SetCredentialConditionAuthType(&condition, context->authType);
677 SetCredentialConditionTemplateId(&condition, info->templateId);
678 SetCredentialConditionExecutorSensorHint(&condition, verifierSensorHint);
679 LinkedList *credList = QueryCredentialLimit(&condition);
680 if (credList == NULL || credList->getSize(credList) != 1) {
681 LOG_ERROR("query credential failed");
682 goto EXIT;
683 }
684 if (credList->head == NULL || credList->head->data == NULL) {
685 LOG_ERROR("list node is invalid");
686 goto EXIT;
687 }
688 CredentialInfoHal *credentialNode = (CredentialInfoHal *)credList->head->data;
689 ret = CheckAndSetContextUserId(context, credentialNode->credentialId, authMode);
690 if (ret != RESULT_SUCCESS) {
691 LOG_ERROR("CheckAndSetContextUserId failed");
692 goto EXIT;
693 }
694 *credentialId = credentialNode->credentialId;
695 EXIT:
696 DestroyLinkedList(credList);
697 return ret;
698 }
699