• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params);
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