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