• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "user_idm_funcs.h"
17 
18 #include "securec.h"
19 
20 #include "adaptor_log.h"
21 #include "adaptor_memory.h"
22 #include "coauth.h"
23 #include "executor_message.h"
24 #include "idm_database.h"
25 #include "enroll_specification_check.h"
26 
GenerateIdmSchedule(const PermissionCheckParam * param)27 static CoAuthSchedule *GenerateIdmSchedule(const PermissionCheckParam *param)
28 {
29     ScheduleParam scheduleParam = {};
30     scheduleParam.associateId.userId = param->userId;
31     scheduleParam.authType = param->authType;
32     scheduleParam.scheduleMode = SCHEDULE_MODE_ENROLL;
33     scheduleParam.collectorSensorHint = param->executorSensorHint;
34     if (scheduleParam.collectorSensorHint != INVALID_SENSOR_HINT) {
35         int32_t ret = QueryCollecterMatcher(scheduleParam.authType, scheduleParam.collectorSensorHint,
36             &scheduleParam.executorMatcher);
37         if (ret != RESULT_SUCCESS) {
38             LOG_ERROR("QueryCollecterMatcher failed");
39             return NULL;
40         }
41     }
42     return GenerateSchedule(&scheduleParam);
43 }
44 
CheckEnrollPermission(PermissionCheckParam param,uint64_t * scheduleId)45 int32_t CheckEnrollPermission(PermissionCheckParam param, uint64_t *scheduleId)
46 {
47     if (scheduleId == NULL) {
48         LOG_ERROR("scheduleId is null");
49         return RESULT_BAD_PARAM;
50     }
51     if (!IsSessionValid(param.userId)) {
52         LOG_ERROR("session is invalid");
53         return RESULT_BAD_PARAM;
54     }
55     UserAuthTokenHal *authToken = (UserAuthTokenHal *)param.token;
56     int32_t ret = CheckSpecification(param.userId, param.authType);
57     if (ret != RESULT_SUCCESS) {
58         LOG_ERROR("check specification failed, authType is %{public}u, ret is %{public}d", param.authType, ret);
59         return ret;
60     }
61     if (param.authType != PIN_AUTH) {
62         ret = CheckIdmOperationToken(param.userId, authToken);
63         if (ret != RESULT_SUCCESS) {
64             LOG_ERROR("a valid token is required");
65             return ret;
66         }
67     }
68     CoAuthSchedule *enrollSchedule = GenerateIdmSchedule(&param);
69     if (enrollSchedule == NULL) {
70         LOG_ERROR("enrollSchedule malloc failed");
71         return RESULT_NO_MEMORY;
72     }
73     ret = AddCoAuthSchedule(enrollSchedule);
74     if (ret != RESULT_SUCCESS) {
75         LOG_ERROR("add coauth schedule failed");
76         goto EXIT;
77     }
78     ret = AssociateCoauthSchedule(enrollSchedule->scheduleId, param.authType, false);
79     if (ret != RESULT_SUCCESS) {
80         LOG_ERROR("idm associate coauth schedule failed");
81         RemoveCoAuthSchedule(enrollSchedule->scheduleId);
82         goto EXIT;
83     }
84     *scheduleId = enrollSchedule->scheduleId;
85 
86 EXIT:
87     DestroyCoAuthSchedule(enrollSchedule);
88     return ret;
89 }
90 
CheckUpdatePermission(PermissionCheckParam param,uint64_t * scheduleId)91 int32_t CheckUpdatePermission(PermissionCheckParam param, uint64_t *scheduleId)
92 {
93     if (scheduleId == NULL || param.authType != PIN_AUTH) {
94         LOG_ERROR("param is invalid");
95         return RESULT_BAD_PARAM;
96     }
97     if (!IsSessionValid(param.userId)) {
98         LOG_ERROR("session is invalid");
99         return RESULT_BAD_PARAM;
100     }
101     int32_t ret = CheckSpecification(param.userId, param.authType);
102     if (ret != RESULT_EXCEED_LIMIT) {
103         LOG_ERROR("no pin or exception, authType is %{public}u, ret is %{public}d", param.authType, ret);
104         return ret;
105     }
106     CoAuthSchedule *enrollSchedule = GenerateIdmSchedule(&param);
107     if (enrollSchedule == NULL) {
108         LOG_ERROR("enrollSchedule malloc failed");
109         return RESULT_NO_MEMORY;
110     }
111     ret = AddCoAuthSchedule(enrollSchedule);
112     if (ret != RESULT_SUCCESS) {
113         LOG_ERROR("add coauth schedule failed");
114         goto EXIT;
115     }
116     ret = AssociateCoauthSchedule(enrollSchedule->scheduleId, param.authType, true);
117     if (ret != RESULT_SUCCESS) {
118         LOG_ERROR("idm associate coauth schedule failed");
119         RemoveCoAuthSchedule(enrollSchedule->scheduleId);
120         goto EXIT;
121     }
122     *scheduleId = enrollSchedule->scheduleId;
123 
124 EXIT:
125     DestroyCoAuthSchedule(enrollSchedule);
126     return ret;
127 }
128 
GetInfoFromResult(CredentialInfoHal * credentialInfo,const ExecutorResultInfo * result,const CoAuthSchedule * schedule)129 static void GetInfoFromResult(CredentialInfoHal *credentialInfo, const ExecutorResultInfo *result,
130     const CoAuthSchedule *schedule)
131 {
132     credentialInfo->authType = schedule->authType;
133     credentialInfo->templateId = result->templateId;
134     credentialInfo->capabilityLevel = result->capabilityLevel;
135     credentialInfo->executorSensorHint = GetScheduleVeriferSensorHint(schedule);
136     credentialInfo->executorMatcher = schedule->executors[0].executorMatcher;
137 }
138 
GetCredentialInfoFromSchedule(const ExecutorResultInfo * executorInfo,CredentialInfoHal * credentialInfo)139 static int32_t GetCredentialInfoFromSchedule(const ExecutorResultInfo *executorInfo, CredentialInfoHal *credentialInfo)
140 {
141     uint64_t currentScheduleId;
142     uint32_t scheduleAuthType;
143     int32_t ret = GetEnrollScheduleInfo(&currentScheduleId, &scheduleAuthType);
144     if (ret != RESULT_SUCCESS || executorInfo->scheduleId != currentScheduleId || IsSessionTimeout()) {
145         LOG_ERROR("schedule is mismatch");
146         return RESULT_REACH_LIMIT;
147     }
148     const CoAuthSchedule *schedule = GetCoAuthSchedule(executorInfo->scheduleId);
149     if (schedule == NULL) {
150         LOG_ERROR("schedule is null");
151         return RESULT_GENERAL_ERROR;
152     }
153     GetInfoFromResult(credentialInfo, executorInfo, schedule);
154     return RESULT_SUCCESS;
155 }
156 
AddCredentialFunc(int32_t userId,const Buffer * scheduleResult,uint64_t * credentialId,Buffer ** rootSecret)157 int32_t AddCredentialFunc(int32_t userId, const Buffer *scheduleResult, uint64_t *credentialId, Buffer **rootSecret)
158 {
159     if (!IsBufferValid(scheduleResult) || credentialId == NULL || rootSecret == NULL) {
160         LOG_ERROR("param is null");
161         return RESULT_BAD_PARAM;
162     }
163     int32_t sessionUserId;
164     int32_t ret = GetUserId(&sessionUserId);
165     if (ret != RESULT_SUCCESS || sessionUserId != userId) {
166         LOG_ERROR("userId mismatch");
167         return RESULT_UNKNOWN;
168     }
169     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
170     if (executorResultInfo == NULL) {
171         LOG_ERROR("executorResultInfo is null");
172         return RESULT_UNKNOWN;
173     }
174     CredentialInfoHal credentialInfo;
175     ret = GetCredentialInfoFromSchedule(executorResultInfo, &credentialInfo);
176     if (ret != RESULT_SUCCESS) {
177         LOG_ERROR("failed to get credential info result");
178         goto EXIT;
179     }
180     ret = AddCredentialInfo(userId, &credentialInfo);
181     if (ret != RESULT_SUCCESS) {
182         LOG_ERROR("add credential failed");
183         goto EXIT;
184     }
185     *credentialId = credentialInfo.credentialId;
186     if (credentialInfo.authType != PIN_AUTH) {
187         goto EXIT;
188     }
189     ret = SetPinSubType(userId, executorResultInfo->authSubType);
190     if (ret != RESULT_SUCCESS) {
191         LOG_ERROR("set pin sub type failed");
192         goto EXIT;
193     }
194     *rootSecret = CopyBuffer(executorResultInfo->rootSecret);
195     if (!IsBufferValid(*rootSecret)) {
196         LOG_ERROR("rootSecret is invalid");
197         ret = RESULT_NO_MEMORY;
198     }
199 
200 EXIT:
201     DestoryExecutorResultInfo(executorResultInfo);
202     return ret;
203 }
204 
DeleteCredentialFunc(CredentialDeleteParam param,CredentialInfoHal * credentialInfo)205 int32_t DeleteCredentialFunc(CredentialDeleteParam param, CredentialInfoHal *credentialInfo)
206 {
207     if (credentialInfo == NULL) {
208         LOG_ERROR("param is null");
209         return RESULT_BAD_PARAM;
210     }
211     UserAuthTokenHal token;
212     if (memcpy_s(&token, sizeof(UserAuthTokenHal), param.token, AUTH_TOKEN_LEN) != EOK) {
213         LOG_ERROR("token copy failed");
214         return RESULT_BAD_COPY;
215     }
216     int32_t ret = CheckIdmOperationToken(param.userId, &token);
217     if (ret != RESULT_SUCCESS) {
218         LOG_ERROR("token is invalid");
219         return ret;
220     }
221 
222     ret = DeleteCredentialInfo(param.userId, param.credentialId, credentialInfo);
223     if (ret != RESULT_SUCCESS) {
224         LOG_ERROR("delete database info failed");
225         return RESULT_BAD_SIGN;
226     }
227     return ret;
228 }
229 
QueryCredentialFunc(int32_t userId,uint32_t authType,LinkedList ** creds)230 int32_t QueryCredentialFunc(int32_t userId, uint32_t authType, LinkedList **creds)
231 {
232     if (creds == NULL) {
233         LOG_ERROR("creds is null");
234         return RESULT_BAD_PARAM;
235     }
236     CredentialCondition condition = {};
237     SetCredentialConditionUserId(&condition, userId);
238     if (authType != DEFAULT_AUTH_TYPE) {
239         SetCredentialConditionAuthType(&condition, authType);
240     }
241     *creds = QueryCredentialLimit(&condition);
242     if (*creds == NULL) {
243         LOG_ERROR("query credential failed");
244         return RESULT_UNKNOWN;
245     }
246     LOG_INFO("query credential success");
247     return RESULT_SUCCESS;
248 }
249 
GetUserInfoFunc(int32_t userId,uint64_t * secureUid,uint64_t * pinSubType,EnrolledInfoHal ** enrolledInfoArray,uint32_t * enrolledNum)250 int32_t GetUserInfoFunc(int32_t userId, uint64_t *secureUid, uint64_t *pinSubType, EnrolledInfoHal **enrolledInfoArray,
251     uint32_t *enrolledNum)
252 {
253     if (secureUid == NULL || pinSubType == NULL || enrolledInfoArray == NULL || enrolledNum == NULL) {
254         LOG_ERROR("param is null");
255         return RESULT_BAD_PARAM;
256     }
257     int32_t ret = GetSecureUid(userId, secureUid);
258     if (ret != RESULT_SUCCESS) {
259         LOG_ERROR("get secureUid failed");
260         return ret;
261     }
262     ret = GetPinSubType(userId, pinSubType);
263     if (ret != RESULT_SUCCESS) {
264         LOG_ERROR("get pinSubType failed");
265         return ret;
266     }
267     return GetEnrolledInfo(userId, enrolledInfoArray, enrolledNum);
268 }
269 
GetDeletedCredential(int32_t userId,CredentialInfoHal * deletedCredential)270 static int32_t GetDeletedCredential(int32_t userId, CredentialInfoHal *deletedCredential)
271 {
272     CredentialCondition condition = {};
273     SetCredentialConditionAuthType(&condition, PIN_AUTH);
274     SetCredentialConditionUserId(&condition, userId);
275     LinkedList *credList = QueryCredentialLimit(&condition);
276     if (credList == NULL || credList->head == NULL || credList->head->data == NULL) {
277         LOG_ERROR("query credential failed");
278         DestroyLinkedList(credList);
279         return RESULT_UNKNOWN;
280     }
281     if (credList->getSize(credList) != MAX_NUMBER_OF_PIN_PER_USER) {
282         LOG_ERROR("pin num is invalid");
283         DestroyLinkedList(credList);
284         return RESULT_UNKNOWN;
285     }
286     *deletedCredential = *((CredentialInfoHal *)credList->head->data);
287     DestroyLinkedList(credList);
288     return RESULT_SUCCESS;
289 }
290 
CheckResultValid(uint64_t scheduleId,int32_t userId)291 static int32_t CheckResultValid(uint64_t scheduleId, int32_t userId)
292 {
293     uint64_t currentScheduleId;
294     uint32_t scheduleAuthType;
295     int32_t ret = GetEnrollScheduleInfo(&currentScheduleId, &scheduleAuthType);
296     if (ret != RESULT_SUCCESS || scheduleId != currentScheduleId || IsSessionTimeout()) {
297         LOG_ERROR("schedule is mismatch");
298         return RESULT_REACH_LIMIT;
299     }
300     int32_t userIdGet;
301     ret = GetUserId(&userIdGet);
302     if (ret != RESULT_SUCCESS || userId != userIdGet) {
303         LOG_ERROR("check userId failed");
304         return RESULT_REACH_LIMIT;
305     }
306     if (scheduleAuthType != PIN_AUTH) {
307         LOG_ERROR("only pin is allowed to be updated");
308         return RESULT_UNKNOWN;
309     }
310     return RESULT_SUCCESS;
311 }
312 
UpdateCredentialFunc(int32_t userId,const Buffer * scheduleResult,uint64_t * credentialId,CredentialInfoHal * deletedCredential,Buffer ** rootSecret)313 int32_t UpdateCredentialFunc(int32_t userId, const Buffer *scheduleResult, uint64_t *credentialId,
314     CredentialInfoHal *deletedCredential, Buffer **rootSecret)
315 {
316     if (!IsBufferValid(scheduleResult) || credentialId == NULL || deletedCredential == NULL || rootSecret == NULL) {
317         LOG_ERROR("param is invalid");
318         return RESULT_BAD_PARAM;
319     }
320     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
321     if (executorResultInfo == NULL) {
322         LOG_ERROR("executorResultInfo is null");
323         return RESULT_UNKNOWN;
324     }
325     int32_t ret = CheckResultValid(executorResultInfo->scheduleId, userId);
326     if (ret != RESULT_SUCCESS) {
327         LOG_ERROR("check result failed");
328         goto EXIT;
329     }
330     ret = GetDeletedCredential(userId, deletedCredential);
331     if (ret != RESULT_SUCCESS) {
332         LOG_ERROR("get old credential failed");
333         goto EXIT;
334     }
335     ret = DeleteCredentialInfo(userId, deletedCredential->credentialId, deletedCredential);
336     if (ret != RESULT_SUCCESS) {
337         LOG_ERROR("delete failed");
338         goto EXIT;
339     }
340     const CoAuthSchedule *schedule = GetCoAuthSchedule(executorResultInfo->scheduleId);
341     if (schedule == NULL) {
342         LOG_ERROR("schedule is null");
343         ret = RESULT_UNKNOWN;
344         goto EXIT;
345     }
346     CredentialInfoHal credentialInfo;
347     GetInfoFromResult(&credentialInfo, executorResultInfo, schedule);
348     ret = AddCredentialInfo(userId, &credentialInfo);
349     if (ret != RESULT_SUCCESS) {
350         LOG_ERROR("failed to add credential");
351         goto EXIT;
352     }
353     *credentialId = credentialInfo.credentialId;
354     *rootSecret = CopyBuffer(executorResultInfo->rootSecret);
355     if (!IsBufferValid(*rootSecret)) {
356         LOG_ERROR("rootSecret is invalid");
357         ret = RESULT_NO_MEMORY;
358     }
359 
360 EXIT:
361     DestoryExecutorResultInfo(executorResultInfo);
362     return ret;
363 }
364