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,ScheduleParam * scheduleParam)35 IAM_STATIC ResultCode SetScheduleParam(const PermissionCheckParam *param, ScheduleParam *scheduleParam)
36 {
37     scheduleParam->associateId.userId = param->userId;
38     scheduleParam->authType = param->authType;
39     scheduleParam->userType = param->userType;
40     scheduleParam->scheduleMode = SCHEDULE_MODE_ENROLL;
41     scheduleParam->collectorSensorHint = param->executorSensorHint;
42 
43     Uint8Array localUdid = { scheduleParam->localUdid, UDID_LEN };
44     bool getLocalUdidRet = GetLocalUdid(&localUdid);
45     Uint8Array collectorUdid = { scheduleParam->collectorUdid, UDID_LEN };
46     bool getCollectorUdidRet = GetLocalUdid(&collectorUdid);
47     if (!getLocalUdidRet || !getCollectorUdidRet) {
48         LOG_ERROR("get udid failed");
49         return RESULT_GENERAL_ERROR;
50     }
51     return RESULT_SUCCESS;
52 }
53 
GenerateIdmSchedule(const PermissionCheckParam * param)54 IAM_STATIC CoAuthSchedule *GenerateIdmSchedule(const PermissionCheckParam *param)
55 {
56     ScheduleParam scheduleParam = {};
57     if (SetScheduleParam(param, &scheduleParam) != RESULT_SUCCESS) {
58         LOG_ERROR("SetScheduleParam failed");
59         return NULL;
60     }
61 
62     if (scheduleParam.collectorSensorHint != INVALID_SENSOR_HINT) {
63         ResultCode ret = QueryCollecterMatcher(scheduleParam.authType, scheduleParam.collectorSensorHint,
64             &scheduleParam.executorMatcher);
65         if (ret != RESULT_SUCCESS) {
66             LOG_ERROR("QueryCollecterMatcher failed");
67             return NULL;
68         }
69     }
70 
71     LinkedList *credList = NULL;
72     if (QueryCredentialFunc(param->userId, param->authType, &credList) != RESULT_SUCCESS) {
73         LOG_ERROR("query credential failed");
74         return NULL;
75     }
76     uint64_t templateIdsBuffer[MAX_CREDENTIAL_OUTPUT];
77     uint32_t len = 0;
78     LinkedListNode *temp = credList->head;
79     while (temp != NULL) {
80         if (temp->data == NULL) {
81             LOG_ERROR("list node is invalid");
82             DestroyLinkedList(credList);
83             return NULL;
84         }
85         CredentialInfoHal *credentialHal = (CredentialInfoHal *)(temp->data);
86         if (len >= MAX_CREDENTIAL_OUTPUT) {
87             LOG_ERROR("len out of bound");
88             DestroyLinkedList(credList);
89             return NULL;
90         }
91         templateIdsBuffer[len] = credentialHal->templateId;
92         ++len;
93         temp = temp->next;
94     }
95 
96     Uint64Array templateIds = { templateIdsBuffer, len };
97     scheduleParam.templateIds = &templateIds;
98 
99     DestroyLinkedList(credList);
100     return GenerateSchedule(&scheduleParam);
101 }
102 
GenerateCoAuthSchedule(PermissionCheckParam * param,bool isUpdate,uint64_t * scheduleId)103 IAM_STATIC ResultCode GenerateCoAuthSchedule(PermissionCheckParam *param, bool isUpdate, uint64_t *scheduleId)
104 {
105     CoAuthSchedule *enrollSchedule = GenerateIdmSchedule(param);
106     if (enrollSchedule == NULL) {
107         LOG_ERROR("enrollSchedule malloc failed");
108         return RESULT_NO_MEMORY;
109     }
110     ResultCode ret = AddCoAuthSchedule(enrollSchedule);
111     if (ret != RESULT_SUCCESS) {
112         LOG_ERROR("add coauth schedule failed");
113         goto EXIT;
114     }
115     ret = AssociateCoauthSchedule(enrollSchedule->scheduleId, param->authType, isUpdate);
116     if (ret != RESULT_SUCCESS) {
117         LOG_ERROR("idm associate coauth schedule failed");
118         RemoveCoAuthSchedule(enrollSchedule->scheduleId);
119         goto EXIT;
120     }
121     *scheduleId = enrollSchedule->scheduleId;
122 
123 EXIT:
124     DestroyCoAuthSchedule(enrollSchedule);
125     return ret;
126 }
127 
CheckEnrollPermission(PermissionCheckParam param,uint64_t * scheduleId)128 ResultCode CheckEnrollPermission(PermissionCheckParam param, uint64_t *scheduleId)
129 {
130     if (scheduleId == NULL) {
131         LOG_ERROR("scheduleId is null");
132         return RESULT_BAD_PARAM;
133     }
134     ResultCode ret = IsValidUserType(param.userType);
135     if (ret != RESULT_SUCCESS) {
136         LOG_ERROR("userType is invalid");
137         return ret;
138     }
139     ret = CheckSessionValid(param.userId);
140     if (ret != RESULT_SUCCESS) {
141         LOG_ERROR("session is invalid");
142         return ret;
143     }
144     UserAuthTokenHal *authToken = (UserAuthTokenHal *)param.token;
145     ret = CheckSpecification(param.userId, param.authType);
146     if (ret != RESULT_SUCCESS) {
147         LOG_ERROR("check specification failed, authType is %{public}u, ret is %{public}d", param.authType, ret);
148         return ret;
149     }
150     if (param.authType != PIN_AUTH) {
151         ret = CheckIdmOperationToken(param.userId, authToken);
152         if (ret != RESULT_SUCCESS) {
153             LOG_ERROR("a valid token is required");
154             return RESULT_VERIFY_TOKEN_FAIL;
155         }
156     }
157 
158     return GenerateCoAuthSchedule(&param, false, scheduleId);
159 }
160 
CheckUpdatePermission(PermissionCheckParam param,uint64_t * scheduleId)161 ResultCode CheckUpdatePermission(PermissionCheckParam param, uint64_t *scheduleId)
162 {
163     if (scheduleId == NULL || param.authType != PIN_AUTH) {
164         LOG_ERROR("param is invalid");
165         return RESULT_BAD_PARAM;
166     }
167     ResultCode ret = CheckSessionValid(param.userId);
168     if (ret != RESULT_SUCCESS) {
169         LOG_ERROR("session is invalid");
170         return ret;
171     }
172     ret = CheckSpecification(param.userId, param.authType);
173     if (ret != RESULT_EXCEED_LIMIT) {
174         LOG_ERROR("no pin or exception, authType is %{public}u, ret is %{public}d", param.authType, ret);
175         return ret;
176     }
177     UserAuthTokenHal *authToken = (UserAuthTokenHal *)param.token;
178     ret = CheckIdmOperationToken(param.userId, authToken);
179     if (ret != RESULT_SUCCESS) {
180         LOG_ERROR("a valid token is required");
181         return RESULT_VERIFY_TOKEN_FAIL;
182     }
183 
184     return GenerateCoAuthSchedule(&param, true, scheduleId);
185 }
186 
GetInfoFromResult(CredentialInfoHal * credentialInfo,const ExecutorResultInfo * result,const CoAuthSchedule * schedule)187 IAM_STATIC void GetInfoFromResult(CredentialInfoHal *credentialInfo, const ExecutorResultInfo *result,
188     const CoAuthSchedule *schedule)
189 {
190     credentialInfo->authType = schedule->authType;
191     credentialInfo->templateId = result->templateId;
192     credentialInfo->capabilityLevel = result->capabilityLevel;
193     credentialInfo->executorSensorHint = GetScheduleVerifierSensorHint(schedule);
194     credentialInfo->executorMatcher = schedule->executors[0].executorMatcher;
195 }
196 
GetCredentialInfoFromSchedule(const ExecutorResultInfo * executorInfo,CredentialInfoHal * credentialInfo,const CoAuthSchedule * schedule)197 IAM_STATIC ResultCode GetCredentialInfoFromSchedule(const ExecutorResultInfo *executorInfo,
198     CredentialInfoHal *credentialInfo, const CoAuthSchedule *schedule)
199 {
200     uint64_t currentScheduleId;
201     uint32_t scheduleAuthType;
202     ResultCode ret = GetEnrollScheduleInfo(&currentScheduleId, &scheduleAuthType);
203     if (ret != RESULT_SUCCESS || executorInfo->scheduleId != currentScheduleId) {
204         LOG_ERROR("schedule is mismatch");
205         return RESULT_GENERAL_ERROR;
206     }
207     ret = CheckSessionTimeout();
208     if (ret != RESULT_SUCCESS) {
209         LOG_ERROR("idm session is time out");
210         return ret;
211     }
212     GetInfoFromResult(credentialInfo, executorInfo, schedule);
213     return RESULT_SUCCESS;
214 }
215 
GetEnrollTokenDataPlain(const CredentialInfoHal * credentialInfo,TokenDataPlain * dataPlain)216 IAM_STATIC ResultCode GetEnrollTokenDataPlain(const CredentialInfoHal *credentialInfo, TokenDataPlain *dataPlain)
217 {
218     ResultCode ret = GetChallenge(dataPlain->challenge, CHALLENGE_LEN);
219     if (ret != RESULT_SUCCESS) {
220         LOG_ERROR("get challenge fail");
221         return ret;
222     }
223 
224     dataPlain->time = GetSystemTime();
225     dataPlain->authTrustLevel = ATL3;
226     dataPlain->authType = credentialInfo->authType;
227     dataPlain->authMode = SCHEDULE_MODE_ENROLL;
228     return RESULT_SUCCESS;
229 }
230 
GetEnrollTokenDataToEncrypt(const CredentialInfoHal * credentialInfo,int32_t userId,TokenDataToEncrypt * data)231 IAM_STATIC ResultCode GetEnrollTokenDataToEncrypt(const CredentialInfoHal *credentialInfo, int32_t userId,
232     TokenDataToEncrypt *data)
233 {
234     data->userId = userId;
235     uint64_t secureUid;
236     ResultCode ret = GetSecureUid(userId, &secureUid);
237     if (ret != RESULT_SUCCESS) {
238         LOG_ERROR("get secure uid failed");
239         return ret;
240     }
241     data->secureUid = secureUid;
242     EnrolledInfoHal enrolledInfo = {};
243     ret = GetEnrolledInfoAuthType(userId, credentialInfo->authType, &enrolledInfo);
244     if (ret != RESULT_SUCCESS) {
245         LOG_ERROR("get enrolled info failed");
246         return ret;
247     }
248     data->enrolledId = enrolledInfo.enrolledId;
249     data->credentialId = credentialInfo->credentialId;
250     return RESULT_SUCCESS;
251 }
252 
GetAuthTokenForPinEnroll(const CredentialInfoHal * credentialInfo,int32_t userId)253 IAM_STATIC Buffer *GetAuthTokenForPinEnroll(const CredentialInfoHal *credentialInfo, int32_t userId)
254 {
255     UserAuthTokenPlain tokenPlain = {};
256     ResultCode ret = GetEnrollTokenDataPlain(credentialInfo, &(tokenPlain.tokenDataPlain));
257     if (ret != RESULT_SUCCESS) {
258         LOG_ERROR("GetEnrollTokenDataPlain fail");
259         return NULL;
260     }
261     ret = GetEnrollTokenDataToEncrypt(credentialInfo, userId, &(tokenPlain.tokenDataToEncrypt));
262     if (ret != RESULT_SUCCESS) {
263         LOG_ERROR("GetEnrollTokenDataToEncrypt fail");
264         return NULL;
265     }
266 
267     UserAuthTokenHal authTokenHal = {};
268     ret = UserAuthTokenSign(&tokenPlain, &authTokenHal);
269     if (ret != RESULT_SUCCESS) {
270         LOG_ERROR("generate pin enroll authToken fail");
271         return NULL;
272     }
273     Buffer *authToken = CreateBufferByData((uint8_t *)(&authTokenHal), sizeof(UserAuthTokenHal));
274     if (!IsBufferValid(authToken)) {
275         LOG_ERROR("create authToken buffer fail");
276         return NULL;
277     }
278 
279     return authToken;
280 }
281 
ProcessAddPinCredential(int32_t userId,const CredentialInfoHal * credentialInfo,const ExecutorResultInfo * executorResultInfo,Buffer ** rootSecret,Buffer ** authToken)282 IAM_STATIC ResultCode ProcessAddPinCredential(int32_t userId, const CredentialInfoHal *credentialInfo,
283     const ExecutorResultInfo *executorResultInfo, Buffer **rootSecret, Buffer **authToken)
284 {
285     ResultCode ret = SetPinSubType(userId, executorResultInfo->authSubType);
286     if (ret != RESULT_SUCCESS) {
287         LOG_ERROR("set pin sub type failed");
288         return ret;
289     }
290     *rootSecret = CopyBuffer(executorResultInfo->rootSecret);
291     if ((*rootSecret) == NULL) {
292         LOG_ERROR("copy rootSecret fail");
293         return RESULT_NO_MEMORY;
294     }
295     *authToken = GetAuthTokenForPinEnroll(credentialInfo, userId);
296     if (!IsBufferValid(*authToken)) {
297         LOG_ERROR("authToken is invalid");
298         DestoryBuffer(*rootSecret);
299         *rootSecret = NULL;
300         return RESULT_NO_MEMORY;
301     }
302 
303     return RESULT_SUCCESS;
304 }
305 
AddCredentialFunc(int32_t userId,const Buffer * scheduleResult,uint64_t * credentialId,Buffer ** rootSecret,Buffer ** authToken)306 ResultCode AddCredentialFunc(
307     int32_t userId, const Buffer *scheduleResult, uint64_t *credentialId, Buffer **rootSecret, Buffer **authToken)
308 {
309     if (!IsBufferValid(scheduleResult) || credentialId == NULL || rootSecret == NULL || authToken == NULL) {
310         LOG_ERROR("param is null");
311         return RESULT_BAD_PARAM;
312     }
313     int32_t sessionUserId;
314     ResultCode ret = GetUserId(&sessionUserId);
315     if (ret != RESULT_SUCCESS || sessionUserId != userId) {
316         LOG_ERROR("userId mismatch");
317         return RESULT_UNKNOWN;
318     }
319     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
320     if (executorResultInfo == NULL) {
321         LOG_ERROR("executorResultInfo is null");
322         return RESULT_UNKNOWN;
323     }
324     const CoAuthSchedule *schedule = GetCoAuthSchedule(executorResultInfo->scheduleId);
325     if (schedule == NULL) {
326         LOG_ERROR("schedule is null");
327         ret = RESULT_GENERAL_ERROR;
328         goto EXIT;
329     }
330     CredentialInfoHal credentialInfo;
331     ret = GetCredentialInfoFromSchedule(executorResultInfo, &credentialInfo, schedule);
332     if (ret != RESULT_SUCCESS) {
333         LOG_ERROR("failed to get credential info result");
334         goto EXIT;
335     }
336     ret = AddCredentialInfo(userId, &credentialInfo, schedule->userType);
337     if (ret != RESULT_SUCCESS) {
338         LOG_ERROR("add credential failed");
339         goto EXIT;
340     }
341     *credentialId = credentialInfo.credentialId;
342     if (credentialInfo.authType != PIN_AUTH) {
343         goto EXIT;
344     }
345     ret = ProcessAddPinCredential(userId, &credentialInfo, executorResultInfo, rootSecret, authToken);
346     if (ret != RESULT_SUCCESS) {
347         LOG_ERROR("ProcessAddPinCredential fail");
348         goto EXIT;
349     }
350 
351 EXIT:
352     DestroyExecutorResultInfo(executorResultInfo);
353     return ret;
354 }
355 
DeleteCredentialFunc(CredentialDeleteParam param,CredentialInfoHal * credentialInfo)356 ResultCode DeleteCredentialFunc(CredentialDeleteParam param, CredentialInfoHal *credentialInfo)
357 {
358     if (credentialInfo == NULL) {
359         LOG_ERROR("param is null");
360         return RESULT_BAD_PARAM;
361     }
362     UserAuthTokenHal token;
363     if (memcpy_s(&token, sizeof(UserAuthTokenHal), param.token, AUTH_TOKEN_LEN) != EOK) {
364         LOG_ERROR("token copy failed");
365         return RESULT_BAD_COPY;
366     }
367     ResultCode ret = CheckIdmOperationToken(param.userId, &token);
368     if (ret != RESULT_SUCCESS) {
369         LOG_ERROR("token is invalid");
370         return RESULT_VERIFY_TOKEN_FAIL;
371     }
372 
373     ret = DeleteCredentialInfo(param.userId, param.credentialId, credentialInfo);
374     if (ret != RESULT_SUCCESS) {
375         LOG_ERROR("delete database info failed");
376         return RESULT_BAD_SIGN;
377     }
378     return ret;
379 }
380 
QueryCredentialFunc(int32_t userId,uint32_t authType,LinkedList ** creds)381 ResultCode QueryCredentialFunc(int32_t userId, uint32_t authType, LinkedList **creds)
382 {
383     if (creds == NULL) {
384         LOG_ERROR("creds is null");
385         return RESULT_BAD_PARAM;
386     }
387     CredentialCondition condition = {};
388     SetCredentialConditionUserId(&condition, userId);
389     if (authType != DEFAULT_AUTH_TYPE) {
390         SetCredentialConditionAuthType(&condition, authType);
391     }
392     *creds = QueryCredentialLimit(&condition);
393     if (*creds == NULL) {
394         LOG_ERROR("query credential failed");
395         return RESULT_UNKNOWN;
396     }
397     LOG_INFO("query credential success");
398     return RESULT_SUCCESS;
399 }
400 
GetUserInfoFunc(int32_t userId,uint64_t * secureUid,uint64_t * pinSubType,EnrolledInfoHal ** enrolledInfoArray,uint32_t * enrolledNum)401 ResultCode GetUserInfoFunc(int32_t userId, uint64_t *secureUid, uint64_t *pinSubType,
402     EnrolledInfoHal **enrolledInfoArray, uint32_t *enrolledNum)
403 {
404     if (secureUid == NULL || pinSubType == NULL || enrolledInfoArray == NULL || enrolledNum == NULL) {
405         LOG_ERROR("param is null");
406         return RESULT_BAD_PARAM;
407     }
408     ResultCode ret = GetSecureUid(userId, secureUid);
409     if (ret != RESULT_SUCCESS) {
410         LOG_ERROR("get secureUid failed");
411         return ret;
412     }
413     ret = GetPinSubType(userId, pinSubType);
414     if (ret != RESULT_SUCCESS) {
415         LOG_ERROR("get pinSubType failed");
416         return ret;
417     }
418     return GetEnrolledInfo(userId, enrolledInfoArray, enrolledNum);
419 }
420 
GetDeletedCredential(int32_t userId,CredentialInfoHal * deletedCredential)421 IAM_STATIC ResultCode GetDeletedCredential(int32_t userId, CredentialInfoHal *deletedCredential)
422 {
423     CredentialCondition condition = {};
424     SetCredentialConditionAuthType(&condition, PIN_AUTH);
425     SetCredentialConditionUserId(&condition, userId);
426     LinkedList *credList = QueryCredentialLimit(&condition);
427     if (credList == NULL || credList->head == NULL || credList->head->data == NULL) {
428         LOG_ERROR("query credential failed");
429         DestroyLinkedList(credList);
430         return RESULT_UNKNOWN;
431     }
432     if (credList->getSize(credList) != MAX_NUMBER_OF_PIN_PER_USER) {
433         LOG_ERROR("pin num is invalid");
434         DestroyLinkedList(credList);
435         return RESULT_UNKNOWN;
436     }
437     *deletedCredential = *((CredentialInfoHal *)credList->head->data);
438     DestroyLinkedList(credList);
439     return RESULT_SUCCESS;
440 }
441 
CheckResultValid(uint64_t scheduleId,int32_t userId)442 IAM_STATIC ResultCode CheckResultValid(uint64_t scheduleId, int32_t userId)
443 {
444     uint64_t currentScheduleId;
445     uint32_t scheduleAuthType;
446     ResultCode ret = GetEnrollScheduleInfo(&currentScheduleId, &scheduleAuthType);
447     if (ret != RESULT_SUCCESS || scheduleId != currentScheduleId) {
448         LOG_ERROR("schedule is mismatch");
449         return RESULT_GENERAL_ERROR;
450     }
451     ret = CheckSessionTimeout();
452     if (ret != RESULT_SUCCESS) {
453         LOG_ERROR("idm session is time out");
454         return ret;
455     }
456     int32_t userIdGet;
457     ret = GetUserId(&userIdGet);
458     if (ret != RESULT_SUCCESS || userId != userIdGet) {
459         LOG_ERROR("check userId failed");
460         return RESULT_REACH_LIMIT;
461     }
462     if (scheduleAuthType != PIN_AUTH) {
463         LOG_ERROR("only pin is allowed to be updated");
464         return RESULT_UNKNOWN;
465     }
466     return RESULT_SUCCESS;
467 }
468 
GetUpdateCredentialOutput(int32_t userId,const Buffer * rootSecret,const CredentialInfoHal * credentialInfo,UpdateCredentialOutput * output)469 IAM_STATIC ResultCode GetUpdateCredentialOutput(int32_t userId, const Buffer *rootSecret,
470     const CredentialInfoHal *credentialInfo, UpdateCredentialOutput *output)
471 {
472     if (credentialInfo->authType != PIN_AUTH && credentialInfo->authType != DEFAULT_AUTH_TYPE) {
473         LOG_ERROR("bad authType");
474         return RESULT_GENERAL_ERROR;
475     }
476     CredentialInfoHal credInfo = (*credentialInfo);
477     credInfo.authType = PIN_AUTH;
478 
479     output->credentialId = credInfo.credentialId;
480     output->rootSecret = CopyBuffer(rootSecret);
481     if (!IsBufferValid(output->rootSecret)) {
482         LOG_ERROR("copy rootSecret fail");
483         goto ERROR;
484     }
485     output->oldRootSecret = GetCacheRootSecret(userId);
486     if (!IsBufferValid(output->oldRootSecret)) {
487         LOG_ERROR("GetCacheRootSecret fail");
488         goto ERROR;
489     }
490     output->authToken = GetAuthTokenForPinEnroll(&credInfo, userId);
491     if (!IsBufferValid(output->authToken)) {
492         LOG_ERROR("authToken is invalid");
493         goto ERROR;
494     }
495     return RESULT_SUCCESS;
496 
497 ERROR:
498     DestoryBuffer(output->rootSecret);
499     output->rootSecret = NULL;
500     DestoryBuffer(output->oldRootSecret);
501     output->oldRootSecret = NULL;
502     DestoryBuffer(output->authToken);
503     output->authToken = NULL;
504     return RESULT_NO_MEMORY;
505 }
506 
UpdateCredentialFunc(int32_t userId,const Buffer * scheduleResult,UpdateCredentialOutput * output)507 ResultCode UpdateCredentialFunc(int32_t userId, const Buffer *scheduleResult, UpdateCredentialOutput *output)
508 {
509     if (!IsBufferValid(scheduleResult) || output == NULL) {
510         LOG_ERROR("param is invalid");
511         return RESULT_BAD_PARAM;
512     }
513     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
514     if (executorResultInfo == NULL) {
515         LOG_ERROR("executorResultInfo is null");
516         return RESULT_UNKNOWN;
517     }
518     ResultCode ret = CheckResultValid(executorResultInfo->scheduleId, userId);
519     if (ret != RESULT_SUCCESS) {
520         LOG_ERROR("check result failed");
521         goto EXIT;
522     }
523     ret = GetDeletedCredential(userId, &(output->deletedCredential));
524     if (ret != RESULT_SUCCESS) {
525         LOG_ERROR("get old credential failed");
526         goto EXIT;
527     }
528     const CoAuthSchedule *schedule = GetCoAuthSchedule(executorResultInfo->scheduleId);
529     if (schedule == NULL) {
530         LOG_ERROR("schedule is null");
531         ret = RESULT_UNKNOWN;
532         goto EXIT;
533     }
534     CredentialInfoHal credentialInfo;
535     GetInfoFromResult(&credentialInfo, executorResultInfo, schedule);
536     ret = AddCredentialInfo(userId, &credentialInfo, schedule->userType);
537     if (ret != RESULT_SUCCESS) {
538         LOG_ERROR("failed to add credential");
539         goto EXIT;
540     }
541     ret = GetUpdateCredentialOutput(userId, executorResultInfo->rootSecret, &credentialInfo, output);
542     if (ret != RESULT_SUCCESS) {
543         LOG_ERROR("GetUpdateCredentialOutputRootSecret fail");
544         goto EXIT;
545     }
546 
547 EXIT:
548     DestroyExecutorResultInfo(executorResultInfo);
549     return ret;
550 }
551 
QueryAllExtUserInfoFunc(UserInfoResult * userInfos,uint32_t userInfolen,uint32_t * userInfoCount)552 ResultCode QueryAllExtUserInfoFunc(UserInfoResult *userInfos, uint32_t userInfolen, uint32_t *userInfoCount)
553 {
554     ResultCode ret = GetAllExtUserInfo(userInfos, userInfolen, userInfoCount);
555     if (ret != RESULT_SUCCESS) {
556         LOG_ERROR("GetAllExtUserInfo failed");
557         return RESULT_BAD_PARAM;
558     }
559 
560     return RESULT_SUCCESS;
561 }
QueryCredentialByIdFunc(uint64_t credentialId,LinkedList ** creds)562 ResultCode QueryCredentialByIdFunc(uint64_t credentialId, LinkedList **creds)
563 {
564     if (creds == NULL) {
565         LOG_ERROR("creds is null");
566         return RESULT_BAD_PARAM;
567     }
568     CredentialCondition condition = {};
569     SetCredentialConditionCredentialId(&condition, credentialId);
570     SetCredentiaConditionNeedCachePin(&condition);
571     *creds = QueryCredentialLimit(&condition);
572     if (*creds == NULL) {
573         LOG_ERROR("query credential failed");
574         return RESULT_UNKNOWN;
575     }
576     LOG_INFO("query credential success");
577     return RESULT_SUCCESS;
578 }