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 }