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
GetAsl(uint32_t authType,uint32_t * asl)83 IAM_STATIC ResultCode GetAsl(uint32_t authType, uint32_t *asl)
84 {
85 uint32_t allInOneMaxEsl = 0;
86 ExecutorCondition condition = {};
87 SetExecutorConditionAuthType(&condition, authType);
88 LinkedList *executorList = QueryExecutor(&condition);
89 if (executorList == NULL) {
90 LOG_ERROR("query executor failed");
91 return RESULT_UNKNOWN;
92 }
93 if (executorList->getSize(executorList) == 0) {
94 LOG_ERROR("executor is unregistered");
95 DestroyLinkedList(executorList);
96 return RESULT_TYPE_NOT_SUPPORT;
97 }
98 LinkedListNode *temp = executorList->head;
99 while (temp != NULL) {
100 ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)temp->data;
101
102 // currently only all in one is supported
103 if (executorInfo == NULL || executorInfo->executorRole != ALL_IN_ONE) {
104 *asl = 0;
105 LOG_ERROR("executorInfo is invalid");
106 DestroyLinkedList(executorList);
107 return RESULT_GENERAL_ERROR;
108 }
109 if (executorInfo->executorRole == ALL_IN_ONE && allInOneMaxEsl < executorInfo->esl) {
110 allInOneMaxEsl = executorInfo->esl;
111 }
112 temp = temp->next;
113 }
114 *asl = allInOneMaxEsl;
115 DestroyLinkedList(executorList);
116 return RESULT_SUCCESS;
117 }
118
GetAcl(int32_t userId,uint32_t authType,uint32_t * acl)119 IAM_STATIC ResultCode GetAcl(int32_t userId, uint32_t authType, uint32_t *acl)
120 {
121 CredentialCondition condition = {};
122 SetCredentialConditionAuthType(&condition, authType);
123 SetCredentialConditionUserId(&condition, userId);
124 LinkedList *credList = QueryCredentialLimit(&condition);
125 if (credList == NULL || credList->getSize(credList) == 0) {
126 LOG_ERROR("query credential failed");
127 DestroyLinkedList(credList);
128 return RESULT_NOT_ENROLLED;
129 }
130 *acl = 0;
131 LinkedListNode *temp = credList->head;
132 while (temp != NULL) {
133 if (temp->data == NULL) {
134 LOG_ERROR("link node is invalid");
135 DestroyLinkedList(credList);
136 return RESULT_UNKNOWN;
137 }
138 CredentialInfoHal *credInfo = (CredentialInfoHal *)temp->data;
139 *acl = *acl < credInfo->capabilityLevel ? credInfo->capabilityLevel : *acl;
140 temp = temp->next;
141 }
142 DestroyLinkedList(credList);
143 return RESULT_SUCCESS;
144 }
145
SingleAuthTrustLevel(int32_t userId,uint32_t authType,uint32_t * atl)146 ResultCode SingleAuthTrustLevel(int32_t userId, uint32_t authType, uint32_t *atl)
147 {
148 if (atl == NULL) {
149 LOG_ERROR("atl is null");
150 return RESULT_BAD_PARAM;
151 }
152 uint32_t authSecureLevel;
153 ResultCode ret = GetAsl(authType, &authSecureLevel);
154 if (ret != RESULT_SUCCESS) {
155 LOG_ERROR("get asl failed");
156 return ret;
157 }
158
159 uint32_t authCapabilityLevel;
160 ret = GetAcl(userId, authType, &authCapabilityLevel);
161 if (ret != RESULT_SUCCESS) {
162 LOG_ERROR("get acl failed");
163 return ret;
164 }
165
166 for (uint32_t i = 0; i < sizeof(g_generationAtl) / sizeof(AtlGeneration); ++i) {
167 if (authSecureLevel >= g_generationAtl[i].asl && authCapabilityLevel >= g_generationAtl[i].acl) {
168 *atl = g_generationAtl[i].atl;
169 return RESULT_SUCCESS;
170 }
171 }
172
173 return RESULT_NOT_FOUND;
174 }