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 LOG_INFO("start");
108 if (authContext == NULL) {
109 LOG_ERROR("bad param");
110 return RESULT_BAD_PARAM;
111 }
112 if (authContext->authIntent == ABANDONED_PIN_AUTH) {
113 authContext->authExpiredSysTime = NO_CHECK_PIN_EXPIRED_PERIOD;
114 return RESULT_SUCCESS;
115 }
116 PinExpiredInfo expiredInfo = {};
117 ResultCode result = GetPinExpiredInfo(authContext->userId, &expiredInfo);
118 if (result != RESULT_SUCCESS) {
119 LOG_ERROR("GetPinExpiredInfo failed");
120 return result;
121 }
122 if (expiredInfo.pinExpiredPeriod == NO_CHECK_PIN_EXPIRED_PERIOD) {
123 LOG_ERROR("pinExpiredPeriod is not set");
124 authContext->authExpiredSysTime = NO_CHECK_PIN_EXPIRED_PERIOD;
125 return RESULT_SUCCESS;
126 }
127 authContext->authExpiredSysTime = UINT64_MAX;
128 if (expiredInfo.pinEnrolledSysTime + expiredInfo.pinExpiredPeriod < UINT64_MAX) {
129 authContext->authExpiredSysTime = expiredInfo.pinEnrolledSysTime + expiredInfo.pinExpiredPeriod;
130 }
131 return RESULT_SUCCESS;
132 }
133
GenerateAuthContext(AuthParamHal params,UserAuthContext ** context)134 ResultCode GenerateAuthContext(AuthParamHal params, UserAuthContext **context)
135 {
136 LOG_INFO("start");
137 if (context == NULL) {
138 LOG_ERROR("context is null");
139 return RESULT_BAD_PARAM;
140 }
141 if (g_contextList == NULL) {
142 LOG_ERROR("need init");
143 return RESULT_NEED_INIT;
144 }
145 if (IsContextDuplicate(params.contextId)) {
146 LOG_ERROR("contextId is duplicate");
147 return RESULT_DUPLICATE_CHECK_FAILED;
148 }
149 *context = InitAuthContext(params);
150 if (*context == NULL) {
151 LOG_ERROR("init context failed");
152 return RESULT_GENERAL_ERROR;
153 }
154 ResultCode ret = CreateAndInsertSchedules(*context, SCHEDULE_MODE_AUTH);
155 if (ret != RESULT_SUCCESS) {
156 LOG_ERROR("create schedule failed %{public}d", ret);
157 DestroyContextNode(*context);
158 *context = NULL;
159 return ret;
160 }
161 ret = SetContextExpiredTime(*context);
162 if (ret != RESULT_SUCCESS) {
163 LOG_ERROR("GetAuthExpiredSysTime failed");
164 DestroyContextNode(*context);
165 *context = NULL;
166 return ret;
167 }
168 ret = g_contextList->insert(g_contextList, *context);
169 if (ret != RESULT_SUCCESS) {
170 LOG_ERROR("create schedule failed");
171 DestroyContextNode(*context);
172 *context = NULL;
173 return RESULT_GENERAL_ERROR;
174 }
175 return RESULT_SUCCESS;
176 }
177
CreateIdentifySchedule(const UserAuthContext * context,CoAuthSchedule ** schedule)178 IAM_STATIC ResultCode CreateIdentifySchedule(const UserAuthContext *context, CoAuthSchedule **schedule)
179 {
180 ScheduleParam scheduleParam = {};
181 scheduleParam.associateId.contextId = context->contextId;
182 scheduleParam.authType = context->authType;
183 scheduleParam.collectorSensorHint = context->collectorSensorHint;
184 scheduleParam.verifierSensorHint = context->collectorSensorHint;
185 scheduleParam.scheduleMode = SCHEDULE_MODE_IDENTIFY;
186 Uint8Array localUdid = { scheduleParam.localUdid, UDID_LEN };
187 bool getLocalUdidRet = GetLocalUdid(&localUdid);
188 if (!getLocalUdidRet) {
189 LOG_ERROR("get udid failed");
190 return RESULT_GENERAL_ERROR;
191 }
192 *schedule = GenerateSchedule(&scheduleParam);
193 if (*schedule == NULL) {
194 LOG_ERROR("GenerateSchedule failed");
195 return RESULT_GENERAL_ERROR;
196 }
197 return RESULT_SUCCESS;
198 }
199
InitIdentifyContext(const IdentifyParam * params)200 IAM_STATIC UserAuthContext *InitIdentifyContext(const IdentifyParam *params)
201 {
202 UserAuthContext *context = (UserAuthContext *)Malloc(sizeof(UserAuthContext));
203 if (context == NULL) {
204 LOG_ERROR("context malloc failed");
205 return NULL;
206 }
207 (void)memset_s(context, sizeof(UserAuthContext), 0, sizeof(UserAuthContext));
208 if (memcpy_s(context->challenge, CHALLENGE_LEN, params->challenge, CHALLENGE_LEN) != EOK) {
209 LOG_ERROR("failed to copy challenge");
210 Free(context);
211 return NULL;
212 }
213 context->contextId = params->contextId;
214 context->authType = params->authType;
215 context->collectorSensorHint = params->executorSensorHint;
216 context->scheduleList = CreateLinkedList(DestroyScheduleNode);
217 if (context->scheduleList == NULL) {
218 LOG_ERROR("schedule list create failed");
219 Free(context);
220 return NULL;
221 }
222 return context;
223 }
224
GenerateIdentifyContext(IdentifyParam params)225 UserAuthContext *GenerateIdentifyContext(IdentifyParam params)
226 {
227 LOG_INFO("start");
228 if (g_contextList == NULL) {
229 LOG_ERROR("need init");
230 return NULL;
231 }
232 if (IsContextDuplicate(params.contextId)) {
233 LOG_ERROR("contextId is duplicate");
234 return NULL;
235 }
236
237 UserAuthContext *context = InitIdentifyContext(¶ms);
238 if (context == NULL) {
239 LOG_ERROR("init context failed");
240 return NULL;
241 }
242 ResultCode ret = CreateAndInsertSchedules(context, SCHEDULE_MODE_IDENTIFY);
243 if (ret != RESULT_SUCCESS) {
244 LOG_ERROR("create schedule failed");
245 DestroyContextNode(context);
246 return NULL;
247 }
248 ret = g_contextList->insert(g_contextList, context);
249 if (ret != RESULT_SUCCESS) {
250 LOG_ERROR("create schedule failed");
251 DestroyContextNode(context);
252 return NULL;
253 }
254 return context;
255 }
256
GetContext(uint64_t contextId)257 UserAuthContext *GetContext(uint64_t contextId)
258 {
259 if (g_contextList == NULL) {
260 LOG_ERROR("context list is null");
261 return NULL;
262 }
263 uint32_t num = g_contextList->getSize(g_contextList);
264 LinkedListNode *tempNode = g_contextList->head;
265 UserAuthContext *contextRet = NULL;
266 for (uint32_t index = 0; index < num; index++) {
267 if (tempNode == NULL) {
268 LOG_ERROR("node is null");
269 return NULL;
270 }
271 contextRet = (UserAuthContext *)tempNode->data;
272 if (contextRet != NULL && contextRet->contextId == contextId) {
273 return contextRet;
274 }
275 tempNode = tempNode->next;
276 }
277 return NULL;
278 }
279
InsertScheduleToContext(CoAuthSchedule * schedule,UserAuthContext * context)280 IAM_STATIC ResultCode InsertScheduleToContext(CoAuthSchedule *schedule, UserAuthContext *context)
281 {
282 LinkedList *scheduleList = context->scheduleList;
283 return scheduleList->insert(scheduleList, schedule);
284 }
285
CreateAndInsertSchedules(UserAuthContext * context,uint32_t authMode)286 IAM_STATIC ResultCode CreateAndInsertSchedules(UserAuthContext *context, uint32_t authMode)
287 {
288 LOG_INFO("start");
289 CoAuthSchedule *schedule = NULL;
290 ResultCode result = RESULT_BAD_PARAM;
291 if (authMode == SCHEDULE_MODE_AUTH) {
292 result = CreateAuthSchedule(context, &schedule);
293 } else if (authMode == SCHEDULE_MODE_IDENTIFY) {
294 result = CreateIdentifySchedule(context, &schedule);
295 } else {
296 LOG_ERROR("authMode is invalid");
297 return result;
298 }
299
300 if (result != RESULT_SUCCESS) {
301 LOG_INFO("create schedule fail %{public}d", result);
302 return result;
303 }
304
305 if (AddCoAuthSchedule(schedule) != RESULT_SUCCESS) {
306 LOG_ERROR("AddCoAuthSchedule failed");
307 DestroyCoAuthSchedule(schedule);
308 return RESULT_UNKNOWN;
309 }
310
311 if (InsertScheduleToContext(schedule, context) != RESULT_SUCCESS) {
312 RemoveCoAuthSchedule(schedule->scheduleId);
313 DestroyCoAuthSchedule(schedule);
314 LOG_ERROR("insert failed");
315 return RESULT_UNKNOWN;
316 }
317 return RESULT_SUCCESS;
318 }
319
GetAuthCredentialList(const UserAuthContext * context)320 IAM_STATIC LinkedList *GetAuthCredentialList(const UserAuthContext *context)
321 {
322 CredentialCondition condition = {};
323 SetCredentialConditionAuthType(&condition, context->authType);
324 SetCredentialConditionUserId(&condition, context->userId);
325 if (context->authIntent == ABANDONED_PIN_AUTH) {
326 SetCredentialConditionAbandonPin(&condition);
327 }
328 if (context->collectorSensorHint != INVALID_SENSOR_HINT) {
329 uint32_t executorMatcher;
330 ResultCode ret = QueryCollecterMatcher(context->authType, context->collectorSensorHint, &executorMatcher);
331 if (ret != RESULT_SUCCESS) {
332 LOG_ERROR("query collect matcher failed");
333 return NULL;
334 }
335 SetCredentialConditionExecutorMatcher(&condition, executorMatcher);
336 }
337 return QueryCredentialLimit(&condition);
338 }
339
CheckCredentialSize(LinkedList * credList)340 IAM_STATIC ResultCode CheckCredentialSize(LinkedList *credList)
341 {
342 uint32_t credNum = credList->getSize(credList);
343 if (credNum == 0) {
344 LOG_ERROR("credNum is 0");
345 return RESULT_NOT_ENROLLED;
346 }
347 if (credNum > MAX_CREDENTIAL) {
348 LOG_ERROR("credNum exceed limit");
349 return RESULT_EXCEED_LIMIT;
350 }
351 return RESULT_SUCCESS;
352 }
353
QueryAuthTempletaInfo(UserAuthContext * context,Uint64Array * templateIds,uint32_t * sensorHint,uint32_t * matcher,uint32_t * acl)354 IAM_STATIC ResultCode QueryAuthTempletaInfo(UserAuthContext *context, Uint64Array *templateIds,
355 uint32_t *sensorHint, uint32_t *matcher, uint32_t *acl)
356 {
357 LinkedList *credList = GetAuthCredentialList(context);
358 if (credList == NULL) {
359 LOG_ERROR("query credential failed");
360 return RESULT_UNKNOWN;
361 }
362 ResultCode checkResult = CheckCredentialSize(credList);
363 if (checkResult != RESULT_SUCCESS) {
364 LOG_ERROR("CheckCredentialSize failed %{public}d", checkResult);
365 DestroyLinkedList(credList);
366 return checkResult;
367 }
368 templateIds->data = (uint64_t *)Malloc(sizeof(uint64_t) * credList->getSize(credList));
369 if (templateIds->data == NULL) {
370 LOG_ERROR("value malloc failed");
371 DestroyLinkedList(credList);
372 return RESULT_NO_MEMORY;
373 }
374 templateIds->len = 0;
375 LinkedListNode *temp = credList->head;
376 if (temp == NULL || temp->data == NULL) {
377 LOG_ERROR("link node is invalid");
378 goto FAIL;
379 }
380 CredentialInfoHal *credentialHal = (CredentialInfoHal *)temp->data;
381 *sensorHint = credentialHal->executorSensorHint;
382 *matcher = credentialHal->executorMatcher;
383 *acl = credentialHal->capabilityLevel;
384 while (temp != NULL) {
385 if (temp->data == NULL) {
386 LOG_ERROR("link node is invalid");
387 goto FAIL;
388 }
389 credentialHal = (CredentialInfoHal *)temp->data;
390 if (credentialHal->executorSensorHint == *sensorHint) {
391 templateIds->data[templateIds->len] = credentialHal->templateId;
392 ++(templateIds->len);
393 }
394 temp = temp->next;
395 }
396 DestroyLinkedList(credList);
397 return RESULT_SUCCESS;
398
399 FAIL:
400 Free(templateIds->data);
401 templateIds->data = NULL;
402 DestroyLinkedList(credList);
403 return RESULT_UNKNOWN;
404 }
405
CreateAuthSchedule(UserAuthContext * context,CoAuthSchedule ** schedule)406 IAM_STATIC ResultCode CreateAuthSchedule(UserAuthContext *context, CoAuthSchedule **schedule)
407 {
408 Uint64Array templateIds = {};
409 uint32_t verifierSensorHint;
410 uint32_t executorMatcher;
411 uint32_t acl;
412 ResultCode ret = QueryAuthTempletaInfo(context, &templateIds, &verifierSensorHint, &executorMatcher, &acl);
413 if (ret != RESULT_SUCCESS) {
414 LOG_ERROR("QueryAuthTempletaInfo failed %{public}d", ret);
415 return ret;
416 }
417 ScheduleParam scheduleParam = {};
418 scheduleParam.associateId.contextId = context->contextId;
419 scheduleParam.authType = context->authType;
420 scheduleParam.collectorSensorHint = context->collectorSensorHint;
421 scheduleParam.verifierSensorHint = verifierSensorHint;
422 scheduleParam.templateIds = &templateIds;
423 scheduleParam.executorMatcher = executorMatcher;
424 scheduleParam.scheduleMode = SCHEDULE_MODE_AUTH;
425 if (memcpy_s(scheduleParam.localUdid, sizeof(scheduleParam.localUdid), context->localUdid,
426 sizeof(context->localUdid)) != EOK) {
427 LOG_ERROR("localUdid copy failed");
428 return RESULT_GENERAL_ERROR;
429 }
430
431 if (memcpy_s(scheduleParam.collectorUdid, sizeof(scheduleParam.collectorUdid), context->collectorUdid,
432 sizeof(context->collectorUdid)) != EOK) {
433 LOG_ERROR("collectorUdid copy failed");
434 return RESULT_GENERAL_ERROR;
435 }
436 *schedule = GenerateSchedule(&scheduleParam);
437 if (*schedule == NULL) {
438 LOG_ERROR("schedule is null");
439 Free(templateIds.data);
440 return RESULT_GENERAL_ERROR;
441 }
442 uint32_t scheduleAtl;
443 ret = QueryScheduleAtl(*schedule, acl, &scheduleAtl);
444 if (ret != RESULT_SUCCESS || context->authTrustLevel > scheduleAtl) {
445 Free(templateIds.data);
446 DestroyCoAuthSchedule(*schedule);
447 *schedule = NULL;
448 return ret;
449 }
450 Free(templateIds.data);
451 return RESULT_SUCCESS;
452 }
453
IsContextDuplicate(uint64_t contextId)454 IAM_STATIC bool IsContextDuplicate(uint64_t contextId)
455 {
456 if (g_contextList == NULL) {
457 LOG_ERROR("context list is null");
458 return false;
459 }
460 LinkedListNode *tempNode = g_contextList->head;
461 while (tempNode != NULL) {
462 UserAuthContext *context = (UserAuthContext *)tempNode->data;
463 if (context == NULL) {
464 LOG_ERROR("context is null, please check");
465 tempNode = tempNode->next;
466 continue;
467 }
468 if (context->contextId == contextId) {
469 return true;
470 }
471 tempNode = tempNode->next;
472 }
473 return false;
474 }
475
CopySchedules(UserAuthContext * context,LinkedList ** schedules)476 ResultCode CopySchedules(UserAuthContext *context, LinkedList **schedules)
477 {
478 if (context == NULL || context->scheduleList == NULL || schedules == NULL) {
479 LOG_ERROR("param is null");
480 return RESULT_BAD_PARAM;
481 }
482 LinkedList *scheduleList = context->scheduleList;
483 uint32_t scheduleNum = scheduleList->getSize(scheduleList);
484 if (scheduleNum > AUTH_MAX_SCHEDULING_NUM) {
485 LOG_ERROR("scheduleNum is invalid, scheduleNum is %{public}u", scheduleNum);
486 return RESULT_UNKNOWN;
487 }
488 *schedules = CreateLinkedList(DestroyScheduleNode);
489 if (*schedules == NULL) {
490 LOG_ERROR("schedules malloc failed");
491 return RESULT_NO_MEMORY;
492 }
493 if (scheduleNum == 0) {
494 LOG_INFO("scheduleNum is zero");
495 return RESULT_SUCCESS;
496 }
497
498 LinkedListNode *temp = scheduleList->head;
499 while (temp != NULL) {
500 if (temp->data == NULL) {
501 LOG_ERROR("node data is wrong, please check");
502 goto ERROR;
503 }
504 CoAuthSchedule *schedule = CopyCoAuthSchedule((CoAuthSchedule *)temp->data);
505 if (schedule == NULL) {
506 LOG_ERROR("data is null");
507 goto ERROR;
508 }
509 if ((*schedules)->insert(*schedules, schedule) != RESULT_SUCCESS) {
510 LOG_ERROR("insert schedule failed");
511 DestroyCoAuthSchedule(schedule);
512 goto ERROR;
513 }
514 temp = temp->next;
515 }
516 return RESULT_SUCCESS;
517
518 ERROR:
519 DestroyLinkedList(*schedules);
520 *schedules = NULL;
521 return RESULT_GENERAL_ERROR;
522 }
523
MatchSchedule(const void * data,const void * condition)524 IAM_STATIC bool MatchSchedule(const void *data, const void *condition)
525 {
526 if (data == NULL || condition == NULL) {
527 LOG_ERROR("param is null");
528 return false;
529 }
530 const CoAuthSchedule *schedule = (const CoAuthSchedule *)data;
531 if (schedule->scheduleId == *(const uint64_t *)condition) {
532 return true;
533 }
534 return false;
535 }
536
ScheduleOnceFinish(UserAuthContext * context,uint64_t scheduleId)537 ResultCode ScheduleOnceFinish(UserAuthContext *context, uint64_t scheduleId)
538 {
539 if (context == NULL || context->scheduleList == NULL) {
540 LOG_ERROR("param is null");
541 return RESULT_BAD_PARAM;
542 }
543 RemoveCoAuthSchedule(scheduleId);
544 return context->scheduleList->remove(context->scheduleList, &scheduleId, MatchSchedule, true);
545 }
546
MatchContextSelf(const void * data,const void * condition)547 IAM_STATIC bool MatchContextSelf(const void *data, const void *condition)
548 {
549 return data == condition;
550 }
551
DestroyContext(UserAuthContext * context)552 void DestroyContext(UserAuthContext *context)
553 {
554 if (context == NULL) {
555 LOG_ERROR("context is null");
556 return;
557 }
558 if (g_contextList == NULL) {
559 LOG_ERROR("context list is null");
560 return;
561 }
562 g_contextList->remove(g_contextList, context, MatchContextSelf, true);
563 }
564
DestroyContextNode(void * data)565 IAM_STATIC void DestroyContextNode(void *data)
566 {
567 if (data == NULL) {
568 return;
569 }
570 LinkedList *schedules = ((UserAuthContext *)data)->scheduleList;
571 if (schedules == NULL) {
572 LOG_ERROR("schedules is null");
573 return;
574 }
575 LinkedListNode *tempNode = schedules->head;
576 while (tempNode != NULL) {
577 CoAuthSchedule *schedule = tempNode->data;
578 if (schedule == NULL) {
579 LOG_ERROR("schedule is null, please check");
580 tempNode = tempNode->next;
581 continue;
582 }
583 RemoveCoAuthSchedule(schedule->scheduleId);
584 tempNode = tempNode->next;
585 }
586 DestroyLinkedList(schedules);
587 Free(data);
588 }
589
DestroyContextbyId(uint64_t contextId)590 ResultCode DestroyContextbyId(uint64_t contextId)
591 {
592 UserAuthContext *authContext = GetContext(contextId);
593 if (authContext == NULL) {
594 LOG_ERROR("get context failed");
595 return RESULT_NOT_FOUND;
596 }
597 DestroyContext(authContext);
598 return RESULT_SUCCESS;
599 }
600
GetCredentialInfoByTemplateId(uint32_t authType,uint64_t templateId,uint32_t verifierSensorHint,CredentialInfoHal * credentialInfo)601 IAM_STATIC ResultCode GetCredentialInfoByTemplateId(uint32_t authType, uint64_t templateId,
602 uint32_t verifierSensorHint, CredentialInfoHal *credentialInfo)
603 {
604 CredentialCondition condition = {};
605 SetCredentialConditionAuthType(&condition, authType);
606 SetCredentialConditionTemplateId(&condition, templateId);
607 SetCredentialConditionExecutorSensorHint(&condition, verifierSensorHint);
608 SetCredentialConditionNeedAbandonPin(&condition);
609
610 LinkedList *credList = QueryCredentialLimit(&condition);
611 if (credList == NULL || credList->getSize(credList) != 1) {
612 LOG_ERROR("credList len is not 1");
613 DestroyLinkedList(credList);
614 return RESULT_GENERAL_ERROR;
615 }
616 if (credList->head == NULL || credList->head->data == NULL) {
617 LOG_ERROR("list node is invalid");
618 DestroyLinkedList(credList);
619 return RESULT_GENERAL_ERROR;
620 }
621
622 *credentialInfo = *((CredentialInfoHal *)credList->head->data);
623 DestroyLinkedList(credList);
624 return RESULT_SUCCESS;
625 }
626
GetCoAuthScheduleFromContext(const UserAuthContext * context,uint64_t scheduleId)627 IAM_STATIC const CoAuthSchedule *GetCoAuthScheduleFromContext(const UserAuthContext *context, uint64_t scheduleId)
628 {
629 if (context->scheduleList == NULL) {
630 LOG_ERROR("get null scheduleList");
631 return NULL;
632 }
633
634 LinkedListNode *tempNode = context->scheduleList->head;
635 while (tempNode != NULL) {
636 const CoAuthSchedule *schedule = tempNode->data;
637 if (schedule == NULL) {
638 LOG_ERROR("schedule is null, please check");
639 tempNode = tempNode->next;
640 continue;
641 }
642 if (schedule->scheduleId == scheduleId) {
643 return schedule;
644 }
645 tempNode = tempNode->next;
646 }
647
648 LOG_ERROR("no schedule exist");
649 return NULL;
650 }
651
CheckAndSetContextAtl(UserAuthContext * context,const CoAuthSchedule * schedule,ExecutorResultInfo * info)652 IAM_STATIC ResultCode CheckAndSetContextAtl(
653 UserAuthContext *context, const CoAuthSchedule *schedule, ExecutorResultInfo *info)
654 {
655 uint32_t atl = ATL0;
656 ResultCode ret = QueryScheduleAtl(schedule, info->capabilityLevel, &atl);
657 if (ret != RESULT_SUCCESS) {
658 LOG_ERROR("QueryScheduleAtl fail");
659 return ret;
660 }
661 if (atl < context->authTrustLevel) {
662 LOG_ERROR("atl %u not satisfied, context atl:%u", atl, context->authTrustLevel);
663 return RESULT_TRUST_LEVEL_NOT_SUPPORT;
664 }
665 LOG_INFO("context atl %{public}u:%{public}u", context->authTrustLevel, atl);
666 context->authTrustLevel = atl;
667 return RESULT_SUCCESS;
668 }
669
CheckAndSetContextUserId(UserAuthContext * context,uint64_t credentialId,uint32_t authMode)670 IAM_STATIC ResultCode CheckAndSetContextUserId(UserAuthContext *context, uint64_t credentialId, uint32_t authMode)
671 {
672 int32_t userId = 0;
673 ResultCode ret = QueryCredentialUserId(credentialId, &userId);
674 if (ret != RESULT_SUCCESS) {
675 LOG_ERROR("query userId failed");
676 return ret;
677 }
678 if (authMode == SCHEDULE_MODE_IDENTIFY) {
679 context->userId = userId;
680 }
681 if (userId != context->userId) {
682 LOG_ERROR("userId is not matched");
683 return RESULT_GENERAL_ERROR;
684 }
685 return RESULT_SUCCESS;
686 }
687
CheckAbandonPinAuth(int32_t authIntent,CredentialInfoHal * credentialInfo)688 IAM_STATIC bool CheckAbandonPinAuth(int32_t authIntent, CredentialInfoHal *credentialInfo)
689 {
690 if (authIntent == ABANDONED_PIN_AUTH && !credentialInfo->isAbandoned) {
691 LOG_ERROR("credentialInfo is not abandoned");
692 return false;
693 }
694 if (authIntent != ABANDONED_PIN_AUTH && credentialInfo->isAbandoned) {
695 LOG_ERROR("credentialInfo is abandoned");
696 return false;
697 }
698 return true;
699 }
700
FillInContext(UserAuthContext * context,uint64_t * credentialId,ExecutorResultInfo * info,uint32_t authMode)701 ResultCode FillInContext(UserAuthContext *context, uint64_t *credentialId, ExecutorResultInfo *info,
702 uint32_t authMode)
703 {
704 if (context == NULL || credentialId == NULL || info == NULL) {
705 LOG_ERROR("param is null");
706 return RESULT_BAD_PARAM;
707 }
708 const CoAuthSchedule *schedule = GetCoAuthScheduleFromContext(context, info->scheduleId);
709 if (schedule == NULL) {
710 LOG_ERROR("GetCoAuthScheduleFromContext failed");
711 return RESULT_GENERAL_ERROR;
712 }
713 ResultCode ret = CheckAndSetContextAtl(context, schedule, info);
714 if (ret != RESULT_SUCCESS) {
715 LOG_ERROR("CheckAndSetContextAtl failed");
716 return ret;
717 }
718 CredentialInfoHal credentialInfo = {};
719 uint32_t verifierSensorHint = GetScheduleVerifierSensorHint(schedule);
720 ret = GetCredentialInfoByTemplateId(context->authType, info->templateId, verifierSensorHint, &credentialInfo);
721 if (ret != RESULT_SUCCESS) {
722 LOG_ERROR("get credential info failed");
723 return ret;
724 }
725 if (!CheckAbandonPinAuth(context->authIntent, &credentialInfo)) {
726 LOG_ERROR("check abandon pin auth fail");
727 return RESULT_GENERAL_ERROR;
728 }
729 ret = CheckAndSetContextUserId(context, credentialInfo.credentialId, authMode);
730 if (ret != RESULT_SUCCESS) {
731 LOG_ERROR("CheckAndSetContextUserId failed");
732 return ret;
733 }
734 *credentialId = credentialInfo.credentialId;
735 return RESULT_SUCCESS;
736 }
737