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 "adaptor_log.h"
17 #include "auth_level.h"
18 #include "defines.h"
19 #include "idm_database.h"
20 #include "pool.h"
21 
22 #ifdef IAM_TEST_ENABLE
23 #define IAM_STATIC
24 #else
25 #define IAM_STATIC static
26 #endif
27 
28 typedef struct {
29     Atl atl;
30     Acl acl;
31     Asl asl;
32 } AtlGeneration;
33 
34 // Used to map the authentication capability level and authentication security level to the authentication trust level.
35 IAM_STATIC AtlGeneration g_generationAtl[] = {
36     {ATL4, ACL3, ASL2}, {ATL3, ACL2, ASL2}, {ATL2, ACL2, ASL1},
37     {ATL2, ACL1, ASL2}, {ATL1, ACL1, ASL0}, {ATL0, ACL0, ASL0},
38 };
39 
GetAtl(uint32_t acl,uint32_t asl)40 uint32_t GetAtl(uint32_t acl, uint32_t asl)
41 {
42     for (uint32_t i = 0; i < sizeof(g_generationAtl) / sizeof(AtlGeneration); ++i) {
43         if (asl >= g_generationAtl[i].asl && acl >= g_generationAtl[i].acl) {
44             return g_generationAtl[i].atl;
45         }
46     }
47     return ATL0;
48 }
49 
QueryScheduleAsl(const CoAuthSchedule * coAuthSchedule,uint32_t * asl)50 IAM_STATIC ResultCode QueryScheduleAsl(const CoAuthSchedule *coAuthSchedule, uint32_t *asl)
51 {
52     if (coAuthSchedule == NULL || asl == NULL || coAuthSchedule->executorSize == 0) {
53         LOG_ERROR("param is null");
54         return RESULT_BAD_PARAM;
55     }
56 
57     *asl = MAX_ASL;
58     for (uint32_t i = 0; i < coAuthSchedule->executorSize; ++i) {
59         uint32_t esl = coAuthSchedule->executors[i].esl;
60         if (*asl > esl) {
61             *asl = esl;
62         }
63     }
64     return RESULT_SUCCESS;
65 }
66 
QueryScheduleAtl(const CoAuthSchedule * coAuthSchedule,uint32_t acl,uint32_t * atl)67 ResultCode QueryScheduleAtl(const CoAuthSchedule *coAuthSchedule, uint32_t acl, uint32_t *atl)
68 {
69     if (coAuthSchedule == NULL || atl == NULL) {
70         LOG_ERROR("param is null");
71         return RESULT_BAD_PARAM;
72     }
73     uint32_t asl;
74     ResultCode ret = QueryScheduleAsl(coAuthSchedule, &asl);
75     if (ret != RESULT_SUCCESS) {
76         LOG_ERROR("QueryScheduleAsl failed");
77         return ret;
78     }
79     *atl = GetAtl(acl, asl);
80     return RESULT_SUCCESS;
81 }
82 
GetExecutorAslAndAcl(uint32_t authType,uint32_t * asl,uint32_t * acl)83 IAM_STATIC ResultCode GetExecutorAslAndAcl(uint32_t authType, uint32_t *asl, uint32_t *acl)
84 {
85     uint32_t allInOneMaxEsl = 0;
86     uint32_t allInOneMaxAcl = 0;
87     ExecutorCondition condition = {};
88     SetExecutorConditionAuthType(&condition, authType);
89     LinkedList *executorList = QueryExecutor(&condition);
90     if (executorList == NULL) {
91         LOG_ERROR("query executor failed");
92         return RESULT_UNKNOWN;
93     }
94     if (executorList->getSize(executorList) == 0) {
95         LOG_ERROR("executor is unregistered");
96         DestroyLinkedList(executorList);
97         return RESULT_TYPE_NOT_SUPPORT;
98     }
99     LinkedListNode *temp = executorList->head;
100     while (temp != NULL) {
101         ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)temp->data;
102         if (executorInfo == NULL) {
103             *asl = 0;
104             LOG_ERROR("executorInfo is invalid");
105             DestroyLinkedList(executorList);
106             return RESULT_GENERAL_ERROR;
107         }
108         if (executorInfo->executorRole == ALL_IN_ONE && allInOneMaxEsl < executorInfo->esl) {
109             allInOneMaxEsl = executorInfo->esl;
110         }
111         if (executorInfo->executorRole == ALL_IN_ONE && allInOneMaxAcl < executorInfo->maxTemplateAcl) {
112             allInOneMaxAcl = executorInfo->maxTemplateAcl;
113         }
114         temp = temp->next;
115     }
116     *asl = allInOneMaxEsl;
117     *acl = allInOneMaxAcl;
118     DestroyLinkedList(executorList);
119 
120     LOG_INFO("allInOneMaxEsl:%{public}d, allInOneMaxAcl:%{public}u", allInOneMaxEsl, allInOneMaxAcl);
121     return RESULT_SUCCESS;
122 }
123 
GetCredMaxAcl(int32_t userId,uint32_t authType,uint32_t * maxCredAcl)124 IAM_STATIC ResultCode GetCredMaxAcl(int32_t userId, uint32_t authType, uint32_t *maxCredAcl)
125 {
126     CredentialCondition condition = {};
127     SetCredentialConditionUserId(&condition, userId);
128     SetCredentialConditionAuthType(&condition, authType);
129     LinkedList *creds = QueryCredentialLimit(&condition);
130     if (creds == NULL || creds->getSize(creds) == 0) {
131         LOG_ERROR("query credential failed");
132         DestroyLinkedList(creds);
133         return RESULT_NOT_ENROLLED;
134     }
135     *maxCredAcl = 0;
136     LinkedListNode *temp = creds->head;
137     while (temp != NULL) {
138         if (temp->data == NULL) {
139             LOG_ERROR("link node is invalid");
140             DestroyLinkedList(creds);
141             return RESULT_UNKNOWN;
142         }
143         CredentialInfoHal *credInfo = (CredentialInfoHal *)temp->data;
144         *maxCredAcl = *maxCredAcl < credInfo->capabilityLevel ? credInfo->capabilityLevel : *maxCredAcl;
145         temp = temp->next;
146     }
147     DestroyLinkedList(creds);
148     return RESULT_SUCCESS;
149 }
150 
CheckAtlByExecutorAndCred(int32_t userId,uint32_t authType,uint32_t atl)151 ResultCode CheckAtlByExecutorAndCred(int32_t userId, uint32_t authType, uint32_t atl)
152 {
153     uint32_t maxAsl;
154     uint32_t maxAcl;
155     ResultCode ret = GetExecutorAslAndAcl(authType, &maxAsl, &maxAcl);
156     if (ret != RESULT_SUCCESS) {
157         LOG_ERROR("get asl failed");
158         return ret;
159     }
160     uint32_t supportedAtl = GetAtl(maxAcl, maxAsl);
161     if (atl > supportedAtl) {
162         LOG_ERROR("atl does not support, authType:%{public}d, supportedAtl:%{public}u", authType, supportedAtl);
163         return RESULT_TRUST_LEVEL_NOT_SUPPORT;
164     }
165 
166     uint32_t maxCredAcl = 0;
167     ret = GetCredMaxAcl(userId, authType, &maxCredAcl);
168     if (ret != RESULT_SUCCESS) {
169         LOG_ERROR("get credmaxAcl failed");
170         return ret;
171     }
172     uint32_t credInfoAtl = GetAtl(maxAcl, maxAsl);
173     if (atl > credInfoAtl) {
174         LOG_ERROR("atl does not support, authType:%{public}d, supportedAtl:%{public}u", authType, supportedAtl);
175         return RESULT_NOT_ENROLLED;
176     }
177 
178     return RESULT_SUCCESS;
179 }