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_auth_funcs.h"
17 
18 #include <math.h>
19 #include "securec.h"
20 
21 #include "auth_level.h"
22 #include "adaptor_algorithm.h"
23 #include "adaptor_log.h"
24 #include "adaptor_time.h"
25 #include "auth_token_signer.h"
26 #include "context_manager.h"
27 #include "executor_message.h"
28 #include "hmac_key.h"
29 #include "idm_database.h"
30 #include "idm_session.h"
31 #include "udid_manager.h"
32 
33 #ifdef IAM_TEST_ENABLE
34 #define IAM_STATIC
35 #else
36 #define IAM_STATIC static
37 #endif
38 
39 // Used to cache screenLock auth token plain.
40 IAM_STATIC UnlockAuthResultCache g_unlockAuthResult = {false, 0, {}};
41 // Used to cache any caller auth token plain.
42 IAM_STATIC UnlockAuthResultCache g_anyAuthResult = {false, 0, {}};
43 
GenerateSolutionFunc(AuthParamHal param,LinkedList ** schedules)44 ResultCode GenerateSolutionFunc(AuthParamHal param, LinkedList **schedules)
45 {
46     if (schedules == NULL) {
47         LOG_ERROR("schedules is null");
48         return RESULT_BAD_PARAM;
49     }
50     UserAuthContext *authContext = NULL;
51     ResultCode result = GenerateAuthContext(param, &authContext);
52     if (result != RESULT_SUCCESS) {
53         LOG_ERROR("GenerateAuthContext fail %{public}d", result);
54         return result;
55     }
56     if (authContext == NULL) {
57         LOG_ERROR("authContext is null");
58         return RESULT_GENERAL_ERROR;
59     }
60     if (!authContext->isExpiredReturnSuccess && authContext->authExpiredSysTime != NO_CHECK_PIN_EXPIRED_PERIOD) {
61         uint64_t nowTime = GetReeTime();
62         if (nowTime > authContext->authExpiredSysTime) {
63             LOG_ERROR("pin is expired");
64             return RESULT_PIN_EXPIRED;
65         }
66     }
67     ResultCode ret = CopySchedules(authContext, schedules);
68     if (ret != RESULT_SUCCESS) {
69         DestroyContext(authContext);
70         return ret;
71     }
72     return ret;
73 }
74 
CacheUnlockAuthResult(int32_t userId,const UserAuthTokenHal * unlockToken)75 IAM_STATIC void CacheUnlockAuthResult(int32_t userId, const UserAuthTokenHal *unlockToken)
76 {
77     (void)memset_s(&g_unlockAuthResult, sizeof(UnlockAuthResultCache), 0, sizeof(UnlockAuthResultCache));
78     g_unlockAuthResult.isCached = true;
79     g_unlockAuthResult.userId = userId;
80     g_unlockAuthResult.authToken = *unlockToken;
81 }
82 
CacheAnyAuthResult(int32_t userId,const UserAuthTokenHal * unlockToken)83 IAM_STATIC void CacheAnyAuthResult(int32_t userId, const UserAuthTokenHal *unlockToken)
84 {
85     (void)memset_s(&g_anyAuthResult, sizeof(UnlockAuthResultCache), 0, sizeof(UnlockAuthResultCache));
86     g_anyAuthResult.isCached = true;
87     g_anyAuthResult.userId = userId;
88     g_anyAuthResult.authToken = *unlockToken;
89 }
90 
SetAuthResult(uint64_t credentialId,const UserAuthContext * context,const ExecutorResultInfo * info,AuthResult * result)91 IAM_STATIC void SetAuthResult(uint64_t credentialId,
92     const UserAuthContext *context, const ExecutorResultInfo *info, AuthResult *result)
93 {
94     result->credentialId = credentialId;
95     result->userId = context->userId;
96     result->authType = context->authType;
97     result->freezingTime = info->freezingTime;
98     result->remainTimes = info->remainTimes;
99     result->result = info->result;
100 }
101 
GetExpiredInfoForResult(const UserAuthContext * context,AuthResult * result)102 IAM_STATIC ResultCode GetExpiredInfoForResult(const UserAuthContext *context, AuthResult *result)
103 {
104     if (context == NULL || result == NULL) {
105         LOG_INFO("bad param");
106         return RESULT_BAD_PARAM;
107     }
108     if (context->authExpiredSysTime == NO_CHECK_PIN_EXPIRED_PERIOD) {
109         LOG_INFO("pinExpiredPeriod is not set");
110         result->pinExpiredInfo = NO_SET_PIN_EXPIRED_PERIOD;
111         return RESULT_SUCCESS;
112     }
113     uint64_t currentTime = GetReeTime();
114     if (currentTime < context->authExpiredSysTime) {
115         // MAX_JS_NUMBER_VALUE is 2^50.
116         const uint64_t MAX_JS_NUMBER_VALUE = 1125899906842624;
117         result->pinExpiredInfo = MAX_JS_NUMBER_VALUE;
118         if (context->authExpiredSysTime - currentTime < MAX_JS_NUMBER_VALUE) {
119             result->pinExpiredInfo = context->authExpiredSysTime - currentTime;
120         }
121         LOG_INFO("pin is not expired");
122         return RESULT_SUCCESS;
123     }
124     result->pinExpiredInfo = 0;
125     if (!context->isExpiredReturnSuccess) {
126         LOG_ERROR("pin is expired");
127         return RESULT_PIN_EXPIRED;
128     }
129     LOG_INFO("caller is screenLock or setting");
130     return RESULT_SUCCESS;
131 }
132 
HandleAuthSuccessResult(const UserAuthContext * context,const ExecutorResultInfo * info,AuthResult * result,UserAuthTokenHal * authToken)133 IAM_STATIC ResultCode HandleAuthSuccessResult(const UserAuthContext *context, const ExecutorResultInfo *info,
134     AuthResult *result, UserAuthTokenHal *authToken)
135 {
136     EnrolledStateHal enrolledState = {};
137     if (GetEnrolledState(context->userId, context->authType, &enrolledState) == RESULT_SUCCESS) {
138         result->credentialDigest = enrolledState.credentialDigest;
139         result->credentialCount = enrolledState.credentialCount;
140     }
141     if (result->result == RESULT_SUCCESS && context->authType == PIN_AUTH &&
142         memcmp(context->localUdid, context->collectorUdid, sizeof(context->localUdid)) == 0) {
143         result->rootSecret = CopyBuffer(info->rootSecret);
144         if (!IsBufferValid(result->rootSecret)) {
145             LOG_ERROR("rootSecret is invalid");
146             return RESULT_NO_MEMORY;
147         }
148         CacheRootSecret(context->userId, result->rootSecret);
149     }
150     ResultCode ret = GetExpiredInfoForResult(context, result);
151     if (ret != RESULT_SUCCESS) {
152         LOG_ERROR("GetExpiredInfoForResult failed");
153         return ret;
154     }
155     if (context->authIntent == UNLOCK) {
156         LOG_INFO("cache unlock auth result");
157         CacheUnlockAuthResult(context->userId, authToken);
158     }
159     LOG_INFO("cache any auth result");
160     CacheAnyAuthResult(context->userId, authToken);
161     return RESULT_SUCCESS;
162 }
163 
SetAuthResultMsgToAttribute(Attribute * attribute,AuthResult * result,uint64_t scheduleId,Uint8Array authToken)164 IAM_STATIC ResultCode SetAuthResultMsgToAttribute(Attribute *attribute, AuthResult *result,
165     uint64_t scheduleId, Uint8Array authToken)
166 {
167     ResultCode ret = SetAttributeUint64(attribute, ATTR_SCHEDULE_ID, scheduleId);
168     if (ret != RESULT_SUCCESS) {
169         LOG_ERROR("SetAttributeUint64 scheduleId failed");
170         return ret;
171     }
172     ret = SetAttributeInt32(attribute, ATTR_RESULT, result->result);
173     if (ret != RESULT_SUCCESS) {
174         LOG_ERROR("SetAttributeInt32 result failed");
175         return ret;
176     }
177     ret = SetAttributeInt32(attribute, ATTR_LOCKOUT_DURATION, result->freezingTime);
178     if (ret != RESULT_SUCCESS) {
179         LOG_ERROR("SetAttributeInt32 freezingTime failed");
180         return ret;
181     }
182     ret = SetAttributeInt32(attribute, ATTR_REMAIN_ATTEMPTS, result->remainTimes);
183     if (ret != RESULT_SUCCESS) {
184         LOG_ERROR("SetAttributeInt32 remainTimes failed");
185         return ret;
186     }
187     ret = SetAttributeInt32(attribute, ATTR_USER_ID, result->userId);
188     if (ret != RESULT_SUCCESS) {
189         LOG_ERROR("SetAttributeInt32 userId failed");
190         return ret;
191     }
192     ret = SetAttributeUint8Array(attribute, ATTR_TOKEN, authToken);
193     if (ret != RESULT_SUCCESS) {
194         LOG_ERROR("SetAttributeUint8Array for authToken fail");
195     }
196     return ret;
197 }
198 
GenerateRemoteAuthResultMsg(AuthResult * result,uint64_t scheduleId,Uint8Array collectorUdid,UserAuthTokenHal * authToken)199 IAM_STATIC ResultCode GenerateRemoteAuthResultMsg(AuthResult *result, uint64_t scheduleId, Uint8Array collectorUdid,
200     UserAuthTokenHal *authToken)
201 {
202     Attribute *attribute = NULL;
203     Uint8Array retInfo = {};
204     ResultCode funcRet = RESULT_GENERAL_ERROR;
205     do {
206         attribute = CreateEmptyAttribute();
207         retInfo = (Uint8Array){ Malloc(MAX_EXECUTOR_MSG_LEN), MAX_EXECUTOR_MSG_LEN };
208         if (attribute == NULL || retInfo.data == NULL) {
209             LOG_ERROR("create attribute or malloc failed");
210             break;
211         }
212 
213         Uint8Array authTokenIn = { (uint8_t *)(&authToken), sizeof(UserAuthTokenHal) };
214         if (SetAuthResultMsgToAttribute(attribute, result, scheduleId, authTokenIn) != RESULT_SUCCESS) {
215             LOG_ERROR("SetAuthResultMsgToAttribute failed");
216             break;
217         }
218 
219         SignParam signParam = {
220             .needSignature = true,
221             .keyType = KEY_TYPE_CROSS_DEVICE,
222             .peerUdid = collectorUdid
223         };
224         if (GetAttributeExecutorMsg(attribute, &retInfo, signParam) != RESULT_SUCCESS) {
225             LOG_ERROR("GetAttributeExecutorMsg failed");
226             break;
227         }
228         result->remoteAuthResultMsg = CreateBufferByData(retInfo.data, retInfo.len);
229         funcRet = RESULT_SUCCESS;
230     } while (0);
231 
232     FreeAttribute(&attribute);
233     Free(retInfo.data);
234     return funcRet;
235 }
236 
RequestAuthResultFuncInner(UserAuthContext * userAuthContext,ExecutorResultInfo * executorResultInfo,UserAuthTokenHal * authToken,AuthResult * result)237 IAM_STATIC ResultCode RequestAuthResultFuncInner(UserAuthContext *userAuthContext,
238     ExecutorResultInfo *executorResultInfo, UserAuthTokenHal *authToken, AuthResult *result)
239 {
240     ResultCode ret = RESULT_SUCCESS;
241     Uint8Array collectorUdid = { userAuthContext->collectorUdid, sizeof(userAuthContext->collectorUdid) };
242     if (!IsLocalUdid(collectorUdid)) {
243         ret = GenerateRemoteAuthResultMsg(result, executorResultInfo->scheduleId, collectorUdid, authToken);
244         if (ret != RESULT_SUCCESS) {
245             LOG_ERROR("generate remote auth result failed");
246             return ret;
247         }
248     }
249 
250     if (executorResultInfo->result == RESULT_SUCCESS) {
251         ret = HandleAuthSuccessResult(userAuthContext, executorResultInfo, result, authToken);
252         if (ret != RESULT_SUCCESS) {
253             LOG_ERROR("handle auth success result failed");
254             return ret;
255         }
256     }
257     return ret;
258 }
259 
RequestAuthResultFunc(uint64_t contextId,const Buffer * scheduleResult,UserAuthTokenHal * authToken,AuthResult * result)260 ResultCode RequestAuthResultFunc(uint64_t contextId, const Buffer *scheduleResult, UserAuthTokenHal *authToken,
261     AuthResult *result)
262 {
263     if (!IsBufferValid(scheduleResult) || authToken == NULL || result == NULL || result->rootSecret != NULL) {
264         LOG_ERROR("param is invalid");
265         DestroyContextbyId(contextId);
266         return RESULT_BAD_PARAM;
267     }
268 
269     UserAuthContext *userAuthContext = GetContext(contextId);
270     if (userAuthContext == NULL) {
271         LOG_ERROR("context is not found");
272         return RESULT_GENERAL_ERROR;
273     }
274 
275     ExecutorResultInfo *executorResultInfo = CreateExecutorResultInfo(scheduleResult);
276     if (executorResultInfo == NULL) {
277         LOG_ERROR("CreateExecutorResultInfo fail");
278         DestroyContext(userAuthContext);
279         return RESULT_GENERAL_ERROR;
280     }
281 
282     uint64_t credentialId;
283     ResultCode ret = FillInContext(userAuthContext, &credentialId, executorResultInfo, SCHEDULE_MODE_AUTH);
284     if (ret != RESULT_SUCCESS) {
285         LOG_ERROR("FillInContext fail");
286         goto EXIT;
287     }
288 
289     if (executorResultInfo->result == RESULT_SUCCESS) {
290         ret = GetAuthTokenDataAndSign(userAuthContext, credentialId, SCHEDULE_MODE_AUTH, authToken);
291         if (ret != RESULT_SUCCESS) {
292             LOG_ERROR("sign token failed");
293             goto EXIT;
294         }
295     }
296     SetAuthResult(credentialId, userAuthContext, executorResultInfo, result);
297     if (RequestAuthResultFuncInner(userAuthContext, executorResultInfo, authToken, result) != RESULT_SUCCESS) {
298         LOG_ERROR("RequestAuthResultFuncInner failed");
299         goto EXIT;
300     }
301 
302 EXIT:
303     DestroyExecutorResultInfo(executorResultInfo);
304     DestroyContext(userAuthContext);
305     return ret;
306 }
307 
GetEnrolledStateFunc(int32_t userId,uint32_t authType,EnrolledStateHal * enrolledStateHal)308 ResultCode GetEnrolledStateFunc(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal)
309 {
310     ResultCode ret = GetEnrolledState(userId, authType, enrolledStateHal);
311     if (ret != RESULT_SUCCESS) {
312         LOG_ERROR("GetEnrolledState failed");
313         return ret;
314     }
315 
316     return RESULT_SUCCESS;
317 }
318 
CheckReuseUnlockTokenValid(const ReuseUnlockParamHal * info,UnlockAuthResultCache authResultCache)319 IAM_STATIC ResultCode CheckReuseUnlockTokenValid(const ReuseUnlockParamHal *info, UnlockAuthResultCache authResultCache)
320 {
321     if (!authResultCache.isCached) {
322         LOG_ERROR("invalid cached unlock token");
323         return RESULT_GENERAL_ERROR;
324     }
325     if ((authResultCache.authToken.tokenDataPlain.authMode != SCHEDULE_MODE_AUTH)
326         || (authResultCache.authToken.tokenDataPlain.tokenType != TOKEN_TYPE_LOCAL_AUTH)) {
327         LOG_ERROR("need local auth");
328         return RESULT_VERIFY_TOKEN_FAIL;
329     }
330     uint64_t time = GetSystemTime();
331     if (time < authResultCache.authToken.tokenDataPlain.time) {
332         LOG_ERROR("bad system time");
333         return RESULT_GENERAL_ERROR;
334     }
335     if ((time - authResultCache.authToken.tokenDataPlain.time) > REUSED_UNLOCK_TOKEN_PERIOD) {
336         (void)memset_s(&authResultCache, sizeof(UnlockAuthResultCache), 0, sizeof(UnlockAuthResultCache));
337         authResultCache.isCached = false;
338         LOG_ERROR("cached unlock token is time out");
339         return RESULT_TOKEN_TIMEOUT;
340     }
341     if ((time - authResultCache.authToken.tokenDataPlain.time) > info->reuseUnlockResultDuration) {
342         LOG_ERROR("reuse unlock check reuseUnlockResultDuration fail");
343         return RESULT_TOKEN_TIMEOUT;
344     }
345     if (info->userId != authResultCache.userId) {
346         LOG_ERROR("reuse unlock check userId fail");
347         return RESULT_GENERAL_ERROR;
348     }
349     if (info->authTrustLevel > authResultCache.authToken.tokenDataPlain.authTrustLevel) {
350         LOG_ERROR("reuse unlock check authTrustLevel fail");
351         return RESULT_GENERAL_ERROR;
352     }
353     if (info->reuseUnlockResultMode == AUTH_TYPE_RELEVANT ||
354         info->reuseUnlockResultMode == CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT) {
355         for (uint32_t i = 0; i < info->authTypeSize; i++) {
356             if (info->authTypes[i] == authResultCache.authToken.tokenDataPlain.authType) {
357                 return RESULT_SUCCESS;
358             }
359         }
360         LOG_ERROR("reuse unlock check authType fail");
361         return RESULT_GENERAL_ERROR;
362     }
363     return RESULT_SUCCESS;
364 }
365 
GetReuseUnlockResult(const ReuseUnlockParamHal * info,ReuseUnlockResult * reuseResult)366 IAM_STATIC ResultCode GetReuseUnlockResult(const ReuseUnlockParamHal *info, ReuseUnlockResult *reuseResult)
367 {
368     UnlockAuthResultCache authResultCache = {};
369     if (info->reuseUnlockResultMode == AUTH_TYPE_RELEVANT || info->reuseUnlockResultMode == AUTH_TYPE_IRRELEVANT) {
370         authResultCache = g_unlockAuthResult;
371     } else if (info->reuseUnlockResultMode == CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT ||
372         info->reuseUnlockResultMode == CALLER_IRRELEVANT_AUTH_TYPE_IRRELEVANT) {
373         authResultCache = g_anyAuthResult;
374     }
375     uint32_t ret = CheckReuseUnlockTokenValid(info, authResultCache);
376     if (ret != RESULT_SUCCESS) {
377         LOG_ERROR("check unlock token fail");
378         return ret;
379     }
380     *((UserAuthTokenHal *)reuseResult->token) = authResultCache.authToken;
381     reuseResult->authType = authResultCache.authToken.tokenDataPlain.authType;
382     ((UserAuthTokenHal *)reuseResult->token)->tokenDataPlain.authMode = SCHEDULE_MODE_REUSE_UNLOCK_AUTH_RESULT;
383     ((UserAuthTokenHal *)reuseResult->token)->tokenDataPlain.tokenType = TOKEN_TYPE_LOCAL_RESIGN;
384     if (memcpy_s(((UserAuthTokenHal *)reuseResult->token)->tokenDataPlain.challenge, CHALLENGE_LEN, info->challenge,
385         CHALLENGE_LEN) != EOK) {
386         LOG_ERROR("challenge copy failed");
387         return RESULT_BAD_COPY;
388     }
389     ret = GetEnrolledState(info->userId, reuseResult->authType, &reuseResult->enrolledState);
390     if (ret == RESULT_NOT_ENROLLED) {
391         LOG_ERROR("GetEnrolledState result not enrolled");
392         (void)memset_s(&reuseResult->enrolledState, sizeof(EnrolledStateHal), 0, sizeof(EnrolledStateHal));
393         ret = RESULT_SUCCESS;
394     }
395     return ret;
396 }
397 
CheckReuseUnlockResultFunc(const ReuseUnlockParamHal * info,ReuseUnlockResult * reuseResult)398 ResultCode CheckReuseUnlockResultFunc(const ReuseUnlockParamHal *info, ReuseUnlockResult *reuseResult)
399 {
400     if (info == NULL || reuseResult == NULL || info->reuseUnlockResultDuration == 0 ||
401         info->reuseUnlockResultDuration > REUSED_UNLOCK_TOKEN_PERIOD ||
402         (info->reuseUnlockResultMode != AUTH_TYPE_RELEVANT && info->reuseUnlockResultMode != AUTH_TYPE_IRRELEVANT &&
403         info->reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_RELEVANT &&
404         info->reuseUnlockResultMode != CALLER_IRRELEVANT_AUTH_TYPE_IRRELEVANT)) {
405         LOG_ERROR("CheckReuseUnlockResultFunc bad param");
406         return RESULT_BAD_PARAM;
407     }
408     ResultCode ret = GetReuseUnlockResult(info, reuseResult);
409     if (ret != RESULT_SUCCESS) {
410         LOG_ERROR("get reuse unlock result failed");
411         (void)memset_s(reuseResult, sizeof(ReuseUnlockResult), 0, sizeof(ReuseUnlockResult));
412         return ret;
413     }
414     ret = ReuseUnlockTokenSign((UserAuthTokenHal *)reuseResult->token);
415     if (ret != RESULT_SUCCESS) {
416         LOG_ERROR("reuse unlock token sign failed");
417         (void)memset_s(reuseResult, sizeof(ReuseUnlockResult), 0, sizeof(ReuseUnlockResult));
418         return ret;
419     }
420     return ret;
421 }
422 
SetGlobalConfigParamFunc(GlobalConfigParamHal * param)423 ResultCode SetGlobalConfigParamFunc(GlobalConfigParamHal *param)
424 {
425     if (param == NULL) {
426         LOG_ERROR("bad param");
427         return RESULT_BAD_PARAM;
428     }
429     ResultCode ret = SaveGlobalConfigParam(param);
430     if (ret != RESULT_SUCCESS) {
431         LOG_ERROR("Save globalConfigParam failed");
432     }
433     return ret;
434 }
435 
GetAvailableStatusFunc(int32_t userId,int32_t authType,uint32_t authTrustLevel,int32_t * checkResult)436 void GetAvailableStatusFunc(int32_t userId, int32_t authType, uint32_t authTrustLevel, int32_t *checkResult)
437 {
438     (*checkResult) = CheckAtlByExecutorAndCred(userId, authType, authTrustLevel);
439     if ((*checkResult) != RESULT_SUCCESS) {
440         LOG_ERROR("CheckAtlByExecutorAndCred failed");
441         return;
442     }
443 
444     PinExpiredInfo expiredInfo = {};
445     (*checkResult) = GetPinExpiredInfo(userId, &expiredInfo);
446     if ((*checkResult) != RESULT_SUCCESS) {
447         LOG_ERROR("GetPinExpiredInfo failed");
448         return;
449     }
450     if (expiredInfo.pinExpiredPeriod == NO_CHECK_PIN_EXPIRED_PERIOD) {
451         LOG_ERROR("pinExpiredPeriod is not set");
452         (*checkResult) = RESULT_SUCCESS;
453         return;
454     }
455     uint64_t nowTime = GetReeTime();
456     if (nowTime > expiredInfo.pinExpiredPeriod + expiredInfo.pinEnrolledSysTime) {
457         LOG_ERROR("pin is expired");
458         (*checkResult) = RESULT_PIN_EXPIRED;
459         return;
460     }
461     (*checkResult) = RESULT_SUCCESS;
462     return;
463 }
464 
GenerateScheduleFunc(const Buffer * tlv,Uint8Array remoteUdid,ScheduleInfoParam * scheduleInfo)465 ResultCode GenerateScheduleFunc(const Buffer *tlv, Uint8Array remoteUdid, ScheduleInfoParam *scheduleInfo)
466 {
467     if (!IsBufferValid(tlv) || IS_ARRAY_NULL(remoteUdid) || (scheduleInfo == NULL)) {
468         LOG_ERROR("param is invalid");
469         return RESULT_BAD_PARAM;
470     }
471     ResultCode result = CreateScheduleInfo(tlv, remoteUdid, scheduleInfo);
472     if (result != RESULT_SUCCESS) {
473         LOG_ERROR("CreateScheduleInfo failed");
474     }
475     return result;
476 }
477 
GenerateAuthResultFunc(const Buffer * tlv,AuthResultParam * authResultInfo)478 ResultCode GenerateAuthResultFunc(const Buffer *tlv, AuthResultParam *authResultInfo)
479 {
480     if (!IsBufferValid(tlv) || (authResultInfo == NULL)) {
481         LOG_ERROR("param is invalid");
482         return RESULT_BAD_PARAM;
483     }
484     ResultCode result = CreateAuthResultInfo(tlv, authResultInfo);
485     if (result != RESULT_SUCCESS) {
486         LOG_ERROR("CreateAuthResultInfo failed");
487     }
488     return result;
489 }
490 
GetExecutorInfoLinkedList(uint32_t authType,uint32_t executorRole,LinkedList * allExecutorInfoList)491 ResultCode GetExecutorInfoLinkedList(uint32_t authType, uint32_t executorRole, LinkedList *allExecutorInfoList)
492 {
493     IF_TRUE_LOGE_AND_RETURN_VAL(allExecutorInfoList == NULL, RESULT_BAD_PARAM);
494     uint8_t localUdidData[UDID_LEN] = { 0 };
495     Uint8Array localUdid = { localUdidData, UDID_LEN };
496     bool getLocalUdidRet = GetLocalUdid(&localUdid);
497     IF_TRUE_LOGE_AND_RETURN_VAL(!getLocalUdidRet, RESULT_GENERAL_ERROR);
498 
499     ExecutorCondition condition = {};
500     SetExecutorConditionAuthType(&condition, authType);
501     SetExecutorConditionExecutorRole(&condition, executorRole);
502     SetExecutorConditionDeviceUdid(&condition, localUdid);
503 
504     LinkedList *executorList = QueryExecutor(&condition);
505     if (executorList == NULL) {
506         LOG_ERROR("query executor failed");
507         return RESULT_UNKNOWN;
508     }
509     if (executorList->getSize(executorList) == 0) {
510         LOG_ERROR("executor is not found");
511         DestroyLinkedList(executorList);
512         return RESULT_TYPE_NOT_SUPPORT;
513     }
514     LinkedListNode *temp = executorList->head;
515     while (temp != NULL) {
516         ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)temp->data;
517         if (executorInfo == NULL) {
518             LOG_ERROR("executorInfo is invalid");
519             DestroyLinkedList(executorList);
520             return RESULT_UNKNOWN;
521         }
522         ExecutorInfoHal *copiedExecutorInfo = CopyExecutorInfo(executorInfo);
523         if (executorInfo == NULL) {
524             LOG_ERROR("copiedExecutorInfo is invalid");
525             DestroyLinkedList(executorList);
526             return RESULT_UNKNOWN;
527         }
528         if (allExecutorInfoList->insert(allExecutorInfoList, copiedExecutorInfo) != RESULT_SUCCESS) {
529             LOG_ERROR("insert executor info failed");
530             DestroyLinkedList(executorList);
531             return RESULT_GENERAL_ERROR;
532         }
533         temp = temp->next;
534     }
535     DestroyLinkedList(executorList);
536     return RESULT_SUCCESS;
537 }
538 
GetSignExecutorInfoFuncInner(Uint8Array peerUdid,LinkedList * executorList,Uint8Array executorInfoTlvMsg,Uint8Array * executorInfoArray,uint32_t executorInfoArraySize)539 static Buffer *GetSignExecutorInfoFuncInner(Uint8Array peerUdid, LinkedList *executorList,
540     Uint8Array executorInfoTlvMsg, Uint8Array *executorInfoArray, uint32_t executorInfoArraySize)
541 {
542     LinkedListNode *temp = executorList->head;
543     uint32_t index = 0;
544     while (temp != NULL) {
545         ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)temp->data;
546         if (executorInfo == NULL) {
547             LOG_ERROR("executorInfo is invalid");
548             return NULL;
549         }
550         if (index >= executorInfoArraySize) {
551             LOG_ERROR("executor size is invalid");
552             return NULL;
553         }
554         ResultCode result = GetExecutorInfoMsg(executorInfo, &executorInfoArray[index]);
555         if (result != RESULT_SUCCESS) {
556             LOG_ERROR("get executor info msg fail");
557             return NULL;
558         }
559         index++;
560         temp = temp->next;
561     }
562     ResultCode result = GetMultiDataSerializedMsg(executorInfoArray, executorInfoArraySize, &executorInfoTlvMsg);
563     if (result != RESULT_SUCCESS) {
564         LOG_ERROR("GetMultiDataSerializedMsg failed");
565         return NULL;
566     }
567     return GetExecutorInfoTlv(executorInfoTlvMsg, peerUdid);
568 }
569 
GetSignExecutorInfoFunc(Uint8Array peerUdid,LinkedList * executorList)570 Buffer *GetSignExecutorInfoFunc(Uint8Array peerUdid, LinkedList *executorList)
571 {
572     if (IS_ARRAY_NULL(peerUdid) || executorList == NULL) {
573         LOG_ERROR("params is null");
574         return NULL;
575     }
576     if (executorList->getSize(executorList) == 0) {
577         LOG_ERROR("executor is unregistered");
578         return NULL;
579     }
580     if (executorList->size > UINT32_MAX / sizeof(Uint8Array)) {
581         LOG_ERROR("invalid executorList size");
582         return NULL;
583     }
584 
585     Uint8Array executorInfoTlvMsg = { Malloc(MAX_EXECUTOR_MSG_LEN), MAX_EXECUTOR_MSG_LEN };
586     IF_TRUE_LOGE_AND_RETURN_VAL(executorInfoTlvMsg.data == NULL, NULL);
587 
588     Uint8Array executorInfoArray[executorList->size];
589     bool mallocOk = true;
590     for (uint32_t i = 0; i < executorList->size; i++) {
591         executorInfoArray[i] = (Uint8Array){ Malloc(MAX_EXECUTOR_MSG_LEN), MAX_EXECUTOR_MSG_LEN };
592         if (executorInfoArray[i].data == NULL) {
593             LOG_ERROR("malloc fail");
594             mallocOk = false;
595             continue;
596         }
597     }
598 
599     Buffer *signedExecutorInfo = NULL;
600     if (mallocOk) {
601         signedExecutorInfo = GetSignExecutorInfoFuncInner(peerUdid, executorList,
602             executorInfoTlvMsg, executorInfoArray, executorList->size);
603     }
604 
605     Free(executorInfoTlvMsg.data);
606     for (uint32_t i = 0; i < executorList->size; i++) {
607         Free(executorInfoArray[i].data);
608     }
609 
610     return signedExecutorInfo;
611 }
612 
DestroyAuthResult(AuthResult * authResult)613 void DestroyAuthResult(AuthResult *authResult)
614 {
615     if (authResult == NULL) {
616         return;
617     }
618     DestoryBuffer(authResult->rootSecret);
619     DestoryBuffer(authResult->remoteAuthResultMsg);
620     (void)memset_s(authResult, sizeof(AuthResult), 0, sizeof(AuthResult));
621 }