• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2024 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 "adaptor_time.h"
23 #include "coauth.h"
24 #include "enroll_specification_check.h"
25 #include "executor_message.h"
26 #include "idm_database.h"
27 #include "udid_manager.h"
28 
29 #ifdef IAM_TEST_ENABLE
30 #define IAM_STATIC
31 #else
32 #define IAM_STATIC static
33 #endif
34 
SetScheduleParam(const PermissionCheckParam * param,ScheduleType scheduleType,ScheduleParam * scheduleParam)35 IAM_STATIC ResultCode SetScheduleParam(const PermissionCheckParam *param, ScheduleType scheduleType,
36     ScheduleParam *scheduleParam)
37 {
38     scheduleParam->associateId.userId = param->userId;
39     scheduleParam->authType = param->authType;
40     scheduleParam->userType = param->userType;
41     scheduleParam->scheduleMode = (scheduleType == SCHEDULE_TYPE_ABANDON) ?
42         SCHEDULE_MODE_ABANDON : SCHEDULE_MODE_ENROLL;
43     scheduleParam->collectorSensorHint = param->executorSensorHint;
44 
45     Uint8Array localUdid = { scheduleParam->localUdid, UDID_LEN };
46     bool getLocalUdidRet = GetLocalUdid(&localUdid);
47     if (!getLocalUdidRet) {
48         LOG_ERROR("get udid failed");
49         return RESULT_GENERAL_ERROR;
50     }
51     return RESULT_SUCCESS;
52 }
53 
GetEnrollTemplateIdList(ScheduleParam * scheduleParam,const PermissionCheckParam * param)54 IAM_STATIC ResultCode GetEnrollTemplateIdList(ScheduleParam *scheduleParam, const PermissionCheckParam *param)
55 {
56     LinkedList *credList = NULL;
57     if (GetCredentialListByAuthType(param->userId, param->authType, &credList) != RESULT_SUCCESS) {
58         LOG_ERROR("query credential failed");
59         return RESULT_GENERAL_ERROR;
60     }
61     uint64_t templateIdsBuffer[MAX_CREDENTIAL_OUTPUT];
62     uint32_t len = 0;
63     LinkedListNode *temp = credList->head;
64     while (temp != NULL) {
65         if (temp->data == NULL) {
66             LOG_ERROR("list node is invalid");
67             DestroyLinkedList(credList);
68             return RESULT_GENERAL_ERROR;
69         }
70         CredentialInfoHal *credentialHal = (CredentialInfoHal *)(temp->data);
71         if (len >= MAX_CREDENTIAL_OUTPUT) {
72             LOG_ERROR("len out of bound");
73             DestroyLinkedList(credList);
74             return RESULT_GENERAL_ERROR;
75         }
76         templateIdsBuffer[len] = credentialHal->templateId;
77         ++len;
78         temp = temp->next;
79     }
80 
81     scheduleParam->templateIds = CreateUint64ArrayByData(templateIdsBuffer, len);
82     DestroyLinkedList(credList);
83     return RESULT_SUCCESS;
84 }
85 
CopyTemplateIds(LinkedList * credList,uint64_t * templateIdsBuffer,uint32_t tempalteIdsMaxLen,uint32_t * templateIdsLen)86 IAM_STATIC ResultCode CopyTemplateIds(LinkedList *credList, uint64_t *templateIdsBuffer,
87     uint32_t tempalteIdsMaxLen, uint32_t *templateIdsLen)
88 {
89     uint32_t len = *templateIdsLen;
90     LinkedListNode *temp = credList->head;
91     while (temp != NULL) {
92         if (temp->data == NULL) {
93             LOG_ERROR("list node is invalid");
94             return RESULT_GENERAL_ERROR;
95         }
96         CredentialInfoHal *credentialHal = (CredentialInfoHal *)(temp->data);
97         if (len >= MAX_CREDENTIAL_OUTPUT) {
98             LOG_ERROR("len out of bound");
99             return RESULT_GENERAL_ERROR;
100         }
101         templateIdsBuffer[len] = credentialHal->templateId;
102         ++len;
103         temp = temp->next;
104     }
105     *templateIdsLen = len;
106     return RESULT_SUCCESS;
107 }
108 
GetAbandonTemplateIdList(ScheduleParam * scheduleParam,const PermissionCheckParam * param)109 IAM_STATIC ResultCode GetAbandonTemplateIdList(ScheduleParam *scheduleParam, const PermissionCheckParam *param)
110 {
111     uint64_t templateIdsBuffer[MAX_CREDENTIAL_OUTPUT];
112     uint32_t len = 0;
113     LinkedList *currCredList = NULL;
114     LinkedList *cacheCredList = NULL;
115     PinChangeScence pinChangeScence = GetPinChangeScence(param->userId);
116     if (pinChangeScence == PIN_RESET_SCENCE) {
117         if (GetCredentialListByAbandonFlag(param->userId, param->authType, &currCredList) != RESULT_SUCCESS) {
118             LOG_ERROR("query abandon credential failed");
119             goto FAIL;
120         }
121     } else {
122         if (GetCredentialListByAuthType(param->userId, param->authType, &currCredList) != RESULT_SUCCESS) {
123             LOG_ERROR("query current credential failed");
124             goto FAIL;
125         }
126     }
127 
128     if (GetCredentialListByCachePin(param->userId, &cacheCredList) != RESULT_SUCCESS) {
129         LOG_ERROR("query current credential failed");
130         goto FAIL;
131     }
132 
133     if (currCredList != NULL &&
134         CopyTemplateIds(currCredList, templateIdsBuffer, MAX_CREDENTIAL_OUTPUT, &len) != RESULT_SUCCESS) {
135         LOG_ERROR("copy current credential failed");
136         goto FAIL;
137     }
138 
139     if (cacheCredList != NULL &&
140         CopyTemplateIds(cacheCredList, templateIdsBuffer, MAX_CREDENTIAL_OUTPUT, &len) != RESULT_SUCCESS) {
141         LOG_ERROR("copy cache credential failed");
142         goto FAIL;
143     }
144     scheduleParam->templateIds = CreateUint64ArrayByData(templateIdsBuffer, len);
145 FAIL:
146     DestroyLinkedList(currCredList);
147     DestroyLinkedList(cacheCredList);
148     return RESULT_SUCCESS;
149 }
150 
GetTemplateIdList(ScheduleParam * scheduleParam,const PermissionCheckParam * param,ScheduleType scheduleType)151 IAM_STATIC ResultCode GetTemplateIdList(ScheduleParam *scheduleParam, const PermissionCheckParam *param,
152     ScheduleType scheduleType)
153 {
154     switch (scheduleType) {
155         case SCHEDULE_TYPE_ENROLL:
156         case SCHEDULE_TYPE_UPDATE: {
157             return GetEnrollTemplateIdList(scheduleParam, param);
158         }
159         case SCHEDULE_TYPE_ABANDON: {
160             return GetAbandonTemplateIdList(scheduleParam, param);
161         }
162         default: {
163             LOG_ERROR("scheduleType:%{public}d", scheduleType);
164         }
165     }
166     return RESULT_GENERAL_ERROR;
167 }
168 
GenerateIdmSchedule(const PermissionCheckParam * param,ScheduleType scheduleType)169 IAM_STATIC CoAuthSchedule *GenerateIdmSchedule(const PermissionCheckParam *param, ScheduleType scheduleType)
170 {
171     ResultCode ret = RESULT_SUCCESS;
172     ScheduleParam scheduleParam = {};
173     if (SetScheduleParam(param, scheduleType, &scheduleParam) != RESULT_SUCCESS) {
174         LOG_ERROR("SetScheduleParam failed");
175         return NULL;
176     }
177 
178     if (scheduleParam.collectorSensorHint != INVALID_SENSOR_HINT) {
179         ResultCode ret = QueryCollecterMatcher(scheduleParam.authType, scheduleParam.collectorSensorHint,
180             &scheduleParam.executorMatcher);
181         if (ret != RESULT_SUCCESS) {
182             LOG_ERROR("QueryCollecterMatcher failed");
183             return NULL;
184         }
185     }
186 
187     ret = GetTemplateIdList(&scheduleParam, param, scheduleType);
188     if (ret != RESULT_SUCCESS) {
189         LOG_ERROR("GetTemplateIdList failed");
190         DestroyUint64Array(&(scheduleParam.templateIds));
191         return NULL;
192     }
193     CoAuthSchedule *coAuthSchedule = GenerateSchedule(&scheduleParam);
194     if (coAuthSchedule == NULL) {
195         LOG_ERROR("GenerateSchedule failed");
196         DestroyUint64Array(&(scheduleParam.templateIds));
197         return NULL;
198     }
199     DestroyUint64Array(&(scheduleParam.templateIds));
200     return coAuthSchedule;
201 }
202 
GenerateCoAuthSchedule(PermissionCheckParam * param,ScheduleType scheduleType)203 CoAuthSchedule *GenerateCoAuthSchedule(PermissionCheckParam *param, ScheduleType scheduleType)
204 {
205     CoAuthSchedule *enrollSchedule = GenerateIdmSchedule(param, scheduleType);
206     if (enrollSchedule == NULL) {
207         LOG_ERROR("enrollSchedule malloc failed");
208         return NULL;
209     }
210     ResultCode ret = AddCoAuthSchedule(enrollSchedule);
211     if (ret != RESULT_SUCCESS) {
212         LOG_ERROR("add coauth schedule failed");
213         goto EXIT;
214     }
215     ret = AssociateCoauthSchedule(enrollSchedule->scheduleId, param->authType, scheduleType);
216     if (ret != RESULT_SUCCESS) {
217         LOG_ERROR("idm associate coauth schedule failed");
218         RemoveCoAuthSchedule(enrollSchedule->scheduleId);
219         goto EXIT;
220     }
221     return enrollSchedule;
222 
223 EXIT:
224     DestroyCoAuthSchedule(enrollSchedule);
225     return NULL;
226 }
227 
CheckEnrollPermission(PermissionCheckParam * param)228 ResultCode CheckEnrollPermission(PermissionCheckParam *param)
229 {
230     if (!GetEnableStatus(param->userId, param->authType)) {
231         LOG_ERROR("authType is not support %{public}d", param->authType);
232         return RESULT_TYPE_NOT_SUPPORT;
233     }
234     ResultCode ret = IsValidUserType(param->userType);
235     if (ret != RESULT_SUCCESS) {
236         LOG_ERROR("userType is invalid");
237         return ret;
238     }
239     ret = CheckSessionValid(param->userId);
240     if (ret != RESULT_SUCCESS) {
241         LOG_ERROR("session is invalid");
242         return ret;
243     }
244     UserAuthTokenHal *authToken = (UserAuthTokenHal *)param->token;
245     ret = CheckSpecification(param->userId, param->authType);
246     if (ret != RESULT_SUCCESS) {
247         LOG_ERROR("check specification failed, authType is %{public}u, ret is %{public}d", param->authType, ret);
248         return ret;
249     }
250     if (param->authType != PIN_AUTH) {
251         ret = CheckIdmOperationToken(param->userId, authToken);
252         if (ret != RESULT_SUCCESS) {
253             LOG_ERROR("a valid token is required");
254             return RESULT_VERIFY_TOKEN_FAIL;
255         }
256     }
257     return RESULT_SUCCESS;
258 }
259 
CheckUpdatePermission(PermissionCheckParam * param)260 ResultCode CheckUpdatePermission(PermissionCheckParam *param)
261 {
262     if (param->authType != PIN_AUTH) {
263         LOG_ERROR("param is invalid");
264         return RESULT_BAD_PARAM;
265     }
266     if (!GetEnableStatus(param->userId, param->authType)) {
267         LOG_ERROR("authType is not support %{public}d", param->authType);
268         return RESULT_TYPE_NOT_SUPPORT;
269     }
270     ResultCode ret = CheckSessionValid(param->userId);
271     if (ret != RESULT_SUCCESS) {
272         LOG_ERROR("session is invalid");
273         return ret;
274     }
275     ret = CheckSpecification(param->userId, param->authType);
276     if (ret != RESULT_EXCEED_LIMIT) {
277         LOG_ERROR("no pin or exception, authType is %{public}u, ret is %{public}d", param->authType, ret);
278         return ret;
279     }
280     UserAuthTokenHal *authToken = (UserAuthTokenHal *)param->token;
281     ret = CheckIdmOperationToken(param->userId, authToken);
282     if (ret != RESULT_SUCCESS) {
283         LOG_ERROR("a valid token is required");
284         return RESULT_VERIFY_TOKEN_FAIL;
285     }
286 
287     return RESULT_SUCCESS;
288 }
289 
GetInfoFromResult(CredentialInfoHal * credentialInfo,const ExecutorResultInfo * result,const CoAuthSchedule * schedule)290 IAM_STATIC void GetInfoFromResult(CredentialInfoHal *credentialInfo, const ExecutorResultInfo *result,
291     const CoAuthSchedule *schedule)
292 {
293     credentialInfo->authType = schedule->authType;
294     credentialInfo->templateId = result->templateId;
295     credentialInfo->capabilityLevel = result->capabilityLevel;
296     credentialInfo->executorSensorHint = GetScheduleVerifierSensorHint(schedule);
297     credentialInfo->executorMatcher = schedule->executors[0].executorMatcher;
298     credentialInfo->credentialType = result->authSubType;
299     credentialInfo->isAbandoned = false;
300     credentialInfo->abandonedSysTime = 0;
301 }
302 
GetCredentialInfoFromSchedule(const ExecutorResultInfo * executorInfo,CredentialInfoHal * credentialInfo,const CoAuthSchedule * schedule)303 IAM_STATIC ResultCode GetCredentialInfoFromSchedule(const ExecutorResultInfo *executorInfo,
304     CredentialInfoHal *credentialInfo, const CoAuthSchedule *schedule)
305 {
306     uint64_t currentScheduleId;
307     uint32_t scheduleAuthType;
308     ResultCode ret = GetEnrollScheduleInfo(&currentScheduleId, &scheduleAuthType);
309     if (ret != RESULT_SUCCESS || executorInfo->scheduleId != currentScheduleId) {
310         LOG_ERROR("schedule is mismatch, ret:%{public}d", ret);
311         return RESULT_GENERAL_ERROR;
312     }
313     ret = CheckSessionTimeout();
314     if (ret != RESULT_SUCCESS) {
315         LOG_ERROR("idm session is time out");
316         return ret;
317     }
318     GetInfoFromResult(credentialInfo, executorInfo, schedule);
319     return RESULT_SUCCESS;
320 }
321 
GetEnrollTokenDataPlain(const CredentialInfoHal * credentialInfo,TokenDataPlain * dataPlain)322 IAM_STATIC ResultCode GetEnrollTokenDataPlain(const CredentialInfoHal *credentialInfo, TokenDataPlain *dataPlain)
323 {
324     ResultCode ret = GetChallenge(dataPlain->challenge, CHALLENGE_LEN);
325     if (ret != RESULT_SUCCESS) {
326         LOG_ERROR("get challenge fail");
327         return ret;
328     }
329 
330     dataPlain->time = GetSystemTime();
331     dataPlain->authTrustLevel = ATL3;
332     dataPlain->authType = credentialInfo->authType;
333     dataPlain->authMode = SCHEDULE_MODE_ENROLL;
334     return RESULT_SUCCESS;
335 }
336 
GetEnrollTokenDataToEncrypt(const CredentialInfoHal * credentialInfo,int32_t userId,TokenDataToEncrypt * data)337 IAM_STATIC ResultCode GetEnrollTokenDataToEncrypt(const CredentialInfoHal *credentialInfo, int32_t userId,
338     TokenDataToEncrypt *data)
339 {
340     data->userId = userId;
341     uint64_t secureUid;
342     ResultCode ret = GetSecureUid(userId, &secureUid);
343     if (ret != RESULT_SUCCESS) {
344         LOG_ERROR("get secure uid failed");
345         return ret;
346     }
347     data->secureUid = secureUid;
348     EnrolledInfoHal enrolledInfo = {};
349     ret = GetEnrolledInfoAuthType(userId, credentialInfo->authType, &enrolledInfo);
350     if (ret != RESULT_SUCCESS) {
351         LOG_ERROR("get enrolled info failed");
352         return ret;
353     }
354     data->enrolledId = enrolledInfo.enrolledId;
355     data->credentialId = credentialInfo->credentialId;
356     return RESULT_SUCCESS;
357 }
358 
GetAuthTokenForPinEnroll(const CredentialInfoHal * credentialInfo,int32_t userId)359 IAM_STATIC Buffer *GetAuthTokenForPinEnroll(const CredentialInfoHal *credentialInfo, int32_t userId)
360 {
361     UserAuthTokenPlainHal tokenPlain = {};
362     ResultCode ret = GetEnrollTokenDataPlain(credentialInfo, &(tokenPlain.tokenDataPlain));
363     if (ret != RESULT_SUCCESS) {
364         LOG_ERROR("GetEnrollTokenDataPlain fail");
365         return NULL;
366     }
367     ret = GetEnrollTokenDataToEncrypt(credentialInfo, userId, &(tokenPlain.tokenDataToEncrypt));
368     if (ret != RESULT_SUCCESS) {
369         LOG_ERROR("GetEnrollTokenDataToEncrypt fail");
370         return NULL;
371     }
372 
373     UserAuthTokenHal authTokenHal = {};
374     ret = UserAuthTokenSign(&tokenPlain, &authTokenHal);
375     if (ret != RESULT_SUCCESS) {
376         LOG_ERROR("generate pin enroll authToken fail");
377         return NULL;
378     }
379     Buffer *authToken = CreateBufferByData((uint8_t *)(&authTokenHal), sizeof(UserAuthTokenHal));
380     if (!IsBufferValid(authToken)) {
381         LOG_ERROR("create authToken buffer fail");
382         return NULL;
383     }
384 
385     return authToken;
386 }
387 
ProcessAddPinCredential(int32_t userId,const CredentialInfoHal * credentialInfo,const ExecutorResultInfo * executorResultInfo,Buffer ** rootSecret,Buffer ** authToken)388 IAM_STATIC ResultCode ProcessAddPinCredential(int32_t userId, const CredentialInfoHal *credentialInfo,
389     const ExecutorResultInfo *executorResultInfo, Buffer **rootSecret, Buffer **authToken)
390 {
391     ResultCode ret = SetPinSubType(userId, executorResultInfo->authSubType);
392     if (ret != RESULT_SUCCESS) {
393         LOG_ERROR("set pin sub type failed");
394         return ret;
395     }
396     *rootSecret = CopyBuffer(executorResultInfo->rootSecret);
397     if ((*rootSecret) == NULL) {
398         LOG_ERROR("copy rootSecret fail");
399         return RESULT_NO_MEMORY;
400     }
401     *authToken = GetAuthTokenForPinEnroll(credentialInfo, userId);
402     if (!IsBufferValid(*authToken)) {
403         LOG_ERROR("authToken is invalid");
404         DestoryBuffer(*rootSecret);
405         *rootSecret = NULL;
406         return RESULT_NO_MEMORY;
407     }
408 
409     return RESULT_SUCCESS;
410 }
411 
AddCredentialFunc(int32_t userId,const Buffer * scheduleResult,uint64_t * credentialId,Buffer ** rootSecret,Buffer ** authToken)412 ResultCode AddCredentialFunc(
413     int32_t userId, const Buffer *scheduleResult, uint64_t *credentialId, Buffer **rootSecret, Buffer **authToken)
414 {
415     if (!IsBufferValid(scheduleResult) || credentialId == NULL || rootSecret == NULL || authToken == NULL) {
416         LOG_ERROR("param is null");
417         return RESULT_BAD_PARAM;
418     }
419     int32_t sessionUserId;
420     ResultCode ret = GetUserId(&sessionUserId);
421     if (ret != RESULT_SUCCESS || sessionUserId != userId) {
422         LOG_ERROR("userId mismatch");
423         return RESULT_UNKNOWN;
424     }
425     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
426     if (executorResultInfo == NULL) {
427         LOG_ERROR("executorResultInfo is null");
428         return RESULT_UNKNOWN;
429     }
430     const CoAuthSchedule *schedule = GetCoAuthSchedule(executorResultInfo->scheduleId);
431     if (schedule == NULL) {
432         LOG_ERROR("schedule is null");
433         ret = RESULT_GENERAL_ERROR;
434         goto EXIT;
435     }
436     CredentialInfoHal credentialInfo;
437     ret = GetCredentialInfoFromSchedule(executorResultInfo, &credentialInfo, schedule);
438     if (ret != RESULT_SUCCESS) {
439         LOG_ERROR("failed to get credential info result");
440         goto EXIT;
441     }
442     ret = AddCredentialInfo(userId, &credentialInfo, schedule->userType);
443     if (ret != RESULT_SUCCESS) {
444         LOG_ERROR("add credential failed");
445         goto EXIT;
446     }
447     *credentialId = credentialInfo.credentialId;
448     if (credentialInfo.authType != PIN_AUTH) {
449         goto EXIT;
450     }
451     ret = ProcessAddPinCredential(userId, &credentialInfo, executorResultInfo, rootSecret, authToken);
452     if (ret != RESULT_SUCCESS) {
453         LOG_ERROR("ProcessAddPinCredential fail");
454         goto EXIT;
455     }
456 
457 EXIT:
458     DestroyExecutorResultInfo(executorResultInfo);
459     return ret;
460 }
461 
GenerateAbandonSchedule(CredentialDeleteParam param,CoAuthSchedule * info)462 static ResultCode GenerateAbandonSchedule(CredentialDeleteParam param, CoAuthSchedule *info)
463 {
464     PermissionCheckParam checkParam = {};
465     if (memcpy_s(checkParam.token, AUTH_TOKEN_LEN, param.token, AUTH_TOKEN_LEN) != EOK) {
466         LOG_ERROR("bad copy");
467         return RESULT_BAD_COPY;
468     }
469 
470     checkParam.userId = param.userId;
471     checkParam.authType = PIN_AUTH;
472     CoAuthSchedule *scheduleInfo = GenerateCoAuthSchedule(&checkParam, SCHEDULE_TYPE_ABANDON);
473     if (scheduleInfo == NULL) {
474         LOG_ERROR("get schedule info failed");
475         BreakOffCoauthSchedule();
476         return RESULT_UNKNOWN;
477     }
478 
479     if (memcpy_s(info, sizeof(CoAuthSchedule), scheduleInfo, sizeof(CoAuthSchedule)) != EOK) {
480         LOG_ERROR("bad copy");
481         DestroyCoAuthSchedule(scheduleInfo);
482         BreakOffCoauthSchedule();
483         return RESULT_BAD_COPY;
484     }
485 
486     return RESULT_SUCCESS;
487 }
488 
DeleteCredentialFunc(CredentialDeleteParam param,OperateResult * operateResult)489 ResultCode DeleteCredentialFunc(CredentialDeleteParam param, OperateResult *operateResult)
490 {
491     if (operateResult == NULL) {
492         LOG_ERROR("param is null");
493         return RESULT_BAD_PARAM;
494     }
495     UserAuthTokenHal token;
496     if (memcpy_s(&token, sizeof(UserAuthTokenHal), param.token, AUTH_TOKEN_LEN) != EOK) {
497         LOG_ERROR("token copy failed");
498         return RESULT_BAD_COPY;
499     }
500     ResultCode ret = CheckIdmOperationToken(param.userId, &token);
501     if (ret != RESULT_SUCCESS) {
502         LOG_ERROR("token is invalid");
503         return RESULT_VERIFY_TOKEN_FAIL;
504     }
505 
506     CredentialInfoHal credentialInfo = {};
507     ret = GetCredentialByUserIdAndCredId(param.userId, param.credentialId, &credentialInfo);
508     if (ret != RESULT_SUCCESS) {
509         LOG_ERROR("GetCredentialByUserIdAndCredId failed, ret:%d", ret);
510         return ret;
511     }
512 
513     if (credentialInfo.authType == PIN_AUTH && !credentialInfo.isAbandoned) {
514         operateResult->operateType = ABANDON_CREDENTIAL;
515         return GenerateAbandonSchedule(param, &(operateResult->scheduleInfo));
516     }
517     operateResult->operateType = DELETE_CREDENTIAL;
518     operateResult->credentialCount = 0;
519     ret = DeleteCredentialInfo(param.userId, param.credentialId, &(operateResult->credentialInfos[0]));
520     if (ret != RESULT_SUCCESS) {
521         LOG_ERROR("delete database info failed");
522         return RESULT_BAD_SIGN;
523     }
524     operateResult->credentialCount++;
525 
526     return RESULT_SUCCESS;
527 }
528 
QueryCredentialFunc(int32_t userId,uint32_t authType,LinkedList ** creds)529 ResultCode QueryCredentialFunc(int32_t userId, uint32_t authType, LinkedList **creds)
530 {
531     if (creds == NULL) {
532         LOG_ERROR("creds is null");
533         return RESULT_BAD_PARAM;
534     }
535     CredentialCondition condition = {};
536     SetCredentialConditionUserId(&condition, userId);
537     if (authType != DEFAULT_AUTH_TYPE) {
538         SetCredentialConditionAuthType(&condition, authType);
539     }
540     SetCredentialConditionNeedAbandonPin(&condition);
541     *creds = QueryCredentialLimit(&condition);
542     if (*creds == NULL) {
543         LOG_ERROR("query credential failed");
544         return RESULT_UNKNOWN;
545     }
546     LOG_INFO("query credential success");
547     return RESULT_SUCCESS;
548 }
549 
GetUserInfoFunc(int32_t userId,uint64_t * secureUid,uint64_t * pinSubType,EnrolledInfoHal ** enrolledInfoArray,uint32_t * enrolledNum)550 ResultCode GetUserInfoFunc(int32_t userId, uint64_t *secureUid, uint64_t *pinSubType,
551     EnrolledInfoHal **enrolledInfoArray, uint32_t *enrolledNum)
552 {
553     if (secureUid == NULL || pinSubType == NULL || enrolledInfoArray == NULL || enrolledNum == NULL) {
554         LOG_ERROR("param is null");
555         return RESULT_BAD_PARAM;
556     }
557     ResultCode ret = GetSecureUid(userId, secureUid);
558     if (ret != RESULT_SUCCESS) {
559         LOG_ERROR("get secureUid failed");
560         return ret;
561     }
562     ret = GetPinSubType(userId, pinSubType);
563     if (ret != RESULT_SUCCESS) {
564         LOG_ERROR("get pinSubType failed");
565         return ret;
566     }
567     return GetEnrolledInfo(userId, enrolledInfoArray, enrolledNum);
568 }
569 
GetDeletedCredential(int32_t userId,CredentialInfoHal * deletedCredential)570 IAM_STATIC ResultCode GetDeletedCredential(int32_t userId, CredentialInfoHal *deletedCredential)
571 {
572     CredentialCondition condition = {};
573     SetCredentialConditionAuthType(&condition, PIN_AUTH);
574     SetCredentialConditionUserId(&condition, userId);
575     LinkedList *credList = QueryCredentialLimit(&condition);
576     if (credList == NULL || credList->head == NULL || credList->head->data == NULL) {
577         LOG_ERROR("query credential failed");
578         DestroyLinkedList(credList);
579         return RESULT_UNKNOWN;
580     }
581     if (credList->getSize(credList) != MAX_NUMBER_OF_PIN_PER_USER) {
582         LOG_ERROR("pin num is invalid");
583         DestroyLinkedList(credList);
584         return RESULT_UNKNOWN;
585     }
586     *deletedCredential = *((CredentialInfoHal *)credList->head->data);
587     DestroyLinkedList(credList);
588     return RESULT_SUCCESS;
589 }
590 
CheckResultValid(uint64_t scheduleId,int32_t userId)591 IAM_STATIC ResultCode CheckResultValid(uint64_t scheduleId, int32_t userId)
592 {
593     uint64_t currentScheduleId;
594     uint32_t scheduleAuthType;
595     ResultCode ret = GetEnrollScheduleInfo(&currentScheduleId, &scheduleAuthType);
596     if (ret != RESULT_SUCCESS || scheduleId != currentScheduleId) {
597         LOG_ERROR("schedule is mismatch");
598         return RESULT_GENERAL_ERROR;
599     }
600     ret = CheckSessionTimeout();
601     if (ret != RESULT_SUCCESS) {
602         LOG_ERROR("idm session is time out");
603         return ret;
604     }
605     int32_t userIdGet;
606     ret = GetUserId(&userIdGet);
607     if (ret != RESULT_SUCCESS || userId != userIdGet) {
608         LOG_ERROR("check userId failed");
609         return RESULT_REACH_LIMIT;
610     }
611     if (scheduleAuthType != PIN_AUTH) {
612         LOG_ERROR("only pin is allowed to be updated");
613         return RESULT_UNKNOWN;
614     }
615     return RESULT_SUCCESS;
616 }
617 
GetUpdateCredentialOutput(int32_t userId,const Buffer * rootSecret,const CredentialInfoHal * credentialInfo,UpdateCredentialOutput * output)618 IAM_STATIC ResultCode GetUpdateCredentialOutput(int32_t userId, const Buffer *rootSecret,
619     const CredentialInfoHal *credentialInfo, UpdateCredentialOutput *output)
620 {
621     if (credentialInfo->authType != PIN_AUTH && credentialInfo->authType != DEFAULT_AUTH_TYPE) {
622         LOG_ERROR("bad authType");
623         return RESULT_GENERAL_ERROR;
624     }
625     CredentialInfoHal credInfo = (*credentialInfo);
626     credInfo.authType = PIN_AUTH;
627 
628     output->credentialId = credInfo.credentialId;
629     output->rootSecret = CopyBuffer(rootSecret);
630     if (!IsBufferValid(output->rootSecret)) {
631         LOG_ERROR("copy rootSecret fail");
632         goto ERROR;
633     }
634     output->oldRootSecret = CopyBuffer(GetCurRootSecret(userId));
635     if (!IsBufferValid(output->oldRootSecret)) {
636         LOG_ERROR("GetCurRootSecret fail");
637         goto ERROR;
638     }
639     output->authToken = GetAuthTokenForPinEnroll(&credInfo, userId);
640     if (!IsBufferValid(output->authToken)) {
641         LOG_ERROR("authToken is invalid");
642         goto ERROR;
643     }
644     return RESULT_SUCCESS;
645 
646 ERROR:
647     DestoryBuffer(output->rootSecret);
648     output->rootSecret = NULL;
649     DestoryBuffer(output->oldRootSecret);
650     output->oldRootSecret = NULL;
651     DestoryBuffer(output->authToken);
652     output->authToken = NULL;
653     return RESULT_NO_MEMORY;
654 }
655 
UpdateCredentialFunc(int32_t userId,const Buffer * scheduleResult,UpdateCredentialOutput * output)656 ResultCode UpdateCredentialFunc(int32_t userId, const Buffer *scheduleResult, UpdateCredentialOutput *output)
657 {
658     if (!IsBufferValid(scheduleResult) || output == NULL) {
659         LOG_ERROR("param is invalid");
660         return RESULT_BAD_PARAM;
661     }
662     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
663     if (executorResultInfo == NULL) {
664         LOG_ERROR("executorResultInfo is null");
665         return RESULT_UNKNOWN;
666     }
667     ResultCode ret = CheckResultValid(executorResultInfo->scheduleId, userId);
668     if (ret != RESULT_SUCCESS) {
669         LOG_ERROR("check result failed");
670         goto EXIT;
671     }
672     ret = GetDeletedCredential(userId, &(output->deletedCredential));
673     if (ret != RESULT_SUCCESS) {
674         LOG_ERROR("get old credential failed");
675         goto EXIT;
676     }
677     const CoAuthSchedule *schedule = GetCoAuthSchedule(executorResultInfo->scheduleId);
678     if (schedule == NULL) {
679         LOG_ERROR("schedule is null");
680         ret = RESULT_UNKNOWN;
681         goto EXIT;
682     }
683     CredentialInfoHal credentialInfo;
684     GetInfoFromResult(&credentialInfo, executorResultInfo, schedule);
685     ret = AddCredentialInfo(userId, &credentialInfo, schedule->userType);
686     if (ret != RESULT_SUCCESS) {
687         LOG_ERROR("failed to add credential");
688         goto EXIT;
689     }
690     ret = GetUpdateCredentialOutput(userId, executorResultInfo->rootSecret, &credentialInfo, output);
691     if (ret != RESULT_SUCCESS) {
692         LOG_ERROR("GetUpdateCredentialOutputRootSecret fail");
693         goto EXIT;
694     }
695     ret = SetNewRootSecret(userId, executorResultInfo->rootSecret);
696     if (ret != RESULT_SUCCESS) {
697         LOG_ERROR("SetNewRootSecret fail");
698         goto EXIT;
699     }
700 EXIT:
701     DestroyExecutorResultInfo(executorResultInfo);
702     return ret;
703 }
704 
QueryAllExtUserInfoFunc(UserInfoResult * userInfos,uint32_t userInfolen,uint32_t * userInfoCount)705 ResultCode QueryAllExtUserInfoFunc(UserInfoResult *userInfos, uint32_t userInfolen, uint32_t *userInfoCount)
706 {
707     ResultCode ret = GetAllExtUserInfo(userInfos, userInfolen, userInfoCount);
708     if (ret != RESULT_SUCCESS) {
709         LOG_ERROR("GetAllExtUserInfo failed");
710         return RESULT_BAD_PARAM;
711     }
712 
713     return RESULT_SUCCESS;
714 }
QueryCredentialByIdFunc(uint64_t credentialId,LinkedList ** creds)715 ResultCode QueryCredentialByIdFunc(uint64_t credentialId, LinkedList **creds)
716 {
717     if (creds == NULL) {
718         LOG_ERROR("creds is null");
719         return RESULT_BAD_PARAM;
720     }
721     CredentialCondition condition = {};
722     SetCredentialConditionCredentialId(&condition, credentialId);
723     SetCredentialConditionNeedCachePin(&condition);
724     SetCredentialConditionNeedAbandonPin(&condition);
725     *creds = QueryCredentialLimit(&condition);
726     if (*creds == NULL) {
727         LOG_ERROR("query credential failed");
728         return RESULT_UNKNOWN;
729     }
730     LOG_INFO("query credential success");
731     return RESULT_SUCCESS;
732 }
733 
UpdateAbandonResultInnerFunc(int32_t userId,uint64_t scheduleId,bool * isDelete,CredentialInfoHal * credentialInfo)734 ResultCode UpdateAbandonResultInnerFunc(int32_t userId, uint64_t scheduleId,
735     bool *isDelete, CredentialInfoHal *credentialInfo)
736 {
737     const CoAuthSchedule *schedule = GetCoAuthSchedule(scheduleId);
738     if (schedule == NULL) {
739         LOG_ERROR("schedule is null");
740         return RESULT_GENERAL_ERROR;
741     }
742 
743     PinChangeScence pinChangeScence = GetPinChangeScence(userId);
744     if (pinChangeScence == PIN_RESET_SCENCE) {
745         return UpdateAbandonResultForReset(userId, isDelete, credentialInfo);
746     } else {
747         return UpdateAbandonResultForUpdate(userId, isDelete, credentialInfo);
748     }
749 
750     LOG_ERROR("UpdateAbandonResultInnerFunc fail, pinChangeScence:%d", pinChangeScence);
751     return RESULT_GENERAL_ERROR;
752 }
753 
UpdateAbandonResultFunc(int32_t userId,const Buffer * scheduleResult,bool * isDelete,CredentialInfoHal * credentialInfo)754 ResultCode UpdateAbandonResultFunc(int32_t userId, const Buffer *scheduleResult,
755     bool *isDelete, CredentialInfoHal *credentialInfo)
756 {
757     if (!IsBufferValid(scheduleResult) || isDelete == NULL || credentialInfo == NULL) {
758         LOG_ERROR("query credential failed");
759         return RESULT_BAD_PARAM;
760     }
761 
762     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
763     if (executorResultInfo == NULL) {
764         LOG_ERROR("executorResultInfo is null");
765         return RESULT_UNKNOWN;
766     }
767 
768     ResultCode ret = RESULT_GENERAL_ERROR;
769     if (executorResultInfo->result != RESULT_SUCCESS) {
770         LOG_ERROR("executorResultInfo result is %d", executorResultInfo->result);
771         goto EXIT;
772     }
773 
774     ret = UpdateAbandonResultInnerFunc(userId, executorResultInfo->scheduleId, isDelete, credentialInfo);
775     if (ret != RESULT_SUCCESS) {
776         LOG_ERROR("UpdateAbandonResultInnerFunc fali, ret:%d", ret);
777         goto EXIT;
778     }
779 EXIT:
780     DestroyExecutorResultInfo(executorResultInfo);
781     return ret;
782 }
783 
ClearUnavailableCredentialFunc(int32_t userId,CredentialInfoHal * credentialInfo)784 ResultCode ClearUnavailableCredentialFunc(int32_t userId, CredentialInfoHal *credentialInfo)
785 {
786     if (CheckSessionValid(userId) == RESULT_SUCCESS) {
787         LOG_ERROR("session is vliad, expired pin delay delete");
788         return RESULT_SUCCESS;
789     }
790     return ClearAbandonExpiredCredential(userId, credentialInfo);
791 }