• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "dev_session_v2.h"
17 
18 #include <inttypes.h>
19 #include "alg_loader.h"
20 #include "callback_manager.h"
21 #include "channel_manager.h"
22 #include "common_defs.h"
23 #include "creds_manager.h"
24 #include "group_data_manager.h"
25 #include "dev_session_util.h"
26 #include "hc_dev_info.h"
27 #include "hc_log.h"
28 #include "hc_types.h"
29 #include "performance_dumper.h"
30 
31 #include "auth_sub_session.h"
32 #include "iso_protocol.h"
33 #include "dl_speke_protocol.h"
34 #include "ec_speke_protocol.h"
35 
36 #include "expand_sub_session.h"
37 #include "auth_code_import.h"
38 #include "mk_agree.h"
39 #include "pseudonym_manager.h"
40 #include "pub_key_exchange.h"
41 #include "save_trusted_info.h"
42 #include "group_auth_data_operation.h"
43 #include "group_operation_common.h"
44 #include "account_task_manager.h"
45 #include "hisysevent_common.h"
46 
47 #define USER_ID_LEN 65
48 #define VERSION_2_0_0 "2.0.0"
49 
50 IMPLEMENT_HC_VECTOR(EventList, SessionEvent, 3)
51 IMPLEMENT_HC_VECTOR(AuthSubSessionList, AuthSubSession *, 1)
52 
53 typedef struct {
54     int32_t curState;
55     int32_t eventType;
56     int32_t (*processFunc)(SessionImpl *self, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy);
57     int32_t nextState;
58 } SessionStateNode;
59 
60 typedef struct {
61     uint32_t id;
62     int32_t strategy;
63     int32_t (*cmdGenerator)(SessionImpl *impl);
64 } CmdProcessor;
65 
66 typedef bool (*CmdInterceptor)(SessionImpl *impl, CmdProcessor processor);
67 
GetSelfUpgradeFlag(int32_t osAccountId,const char * groupId,bool * isSelfFromUpgrade)68 static int32_t GetSelfUpgradeFlag(int32_t osAccountId, const char *groupId, bool *isSelfFromUpgrade)
69 {
70     if (!IsGroupExistByGroupId(osAccountId, groupId)) {
71         LOGI("Group not exist, no need to get self upgrade flag.");
72         return HC_SUCCESS;
73     }
74     TrustedDeviceEntry *selfDeviceEntry = CreateDeviceEntry();
75     if (selfDeviceEntry == NULL) {
76         LOGE("Failed to create self device entry!");
77         return HC_ERR_ALLOC_MEMORY;
78     }
79     int32_t res = GaGetLocalDeviceInfo(osAccountId, groupId, selfDeviceEntry);
80     if (res != HC_SUCCESS) {
81         LOGE("Failed to get self device entry!");
82         DestroyDeviceEntry(selfDeviceEntry);
83         return res;
84     }
85     *isSelfFromUpgrade = selfDeviceEntry->upgradeFlag == 1;
86     DestroyDeviceEntry(selfDeviceEntry);
87     return HC_SUCCESS;
88 }
89 
CmdExchangePkGenerator(SessionImpl * impl)90 static int32_t CmdExchangePkGenerator(SessionImpl *impl)
91 {
92     int32_t userType;
93     if (GetIntFromJson(impl->context, FIELD_USER_TYPE, &userType) != HC_SUCCESS) {
94         LOGE("get userType from context fail.");
95         return HC_ERR_JSON_GET;
96     }
97     int32_t osAccountId;
98     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
99         LOGE("Failed to get osAccountId!");
100         return HC_ERR_JSON_GET;
101     }
102     const char *groupId = GetStringFromJson(impl->context, FIELD_GROUP_ID);
103     if (groupId == NULL) {
104         LOGE("Failed to get group id from context!");
105         return HC_ERR_JSON_GET;
106     }
107     const char *authId = GetStringFromJson(impl->context, FIELD_AUTH_ID);
108     if (authId == NULL) {
109         LOGE("Failed to get auth id from context!");
110         return HC_ERR_JSON_GET;
111     }
112     Uint8Buff authIdBuf = { (uint8_t *)authId, HcStrlen(authId) };
113     bool isSelfFromUpgrade = false;
114     int32_t res = GetSelfUpgradeFlag(osAccountId, groupId, &isSelfFromUpgrade);
115     if (res != HC_SUCCESS) {
116         return res;
117     }
118     PubKeyExchangeParams params = {
119         .userType = userType,
120         .appId = GROUP_MANAGER_PACKAGE_NAME,
121         .groupId = groupId,
122         .authId = authIdBuf,
123         .isSelfFromUpgrade = isSelfFromUpgrade,
124         .osAccountId = osAccountId
125     };
126     return impl->expandSubSession->addCmd(impl->expandSubSession, PUB_KEY_EXCHANGE_CMD_TYPE, (void *)&params,
127         (!impl->isClient), ABORT_IF_ERROR);
128 }
129 
CmdImportAuthCodeGenerator(SessionImpl * impl)130 static int32_t CmdImportAuthCodeGenerator(SessionImpl *impl)
131 {
132     int32_t osAccountId;
133     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
134         LOGE("Failed to get osAccountId!");
135         return HC_ERR_JSON_GET;
136     }
137     int32_t userType;
138     if (GetIntFromJson(impl->context, FIELD_USER_TYPE, &userType) != HC_SUCCESS) {
139         LOGE("get userType from context failed.");
140         return HC_ERR_JSON_GET;
141     }
142     const char *groupId = GetStringFromJson(impl->context, FIELD_GROUP_ID);
143     if (groupId == NULL) {
144         LOGE("Get groupId from context failed.");
145         return HC_ERR_JSON_GET;
146     }
147     const char *authId = GetStringFromJson(impl->context, FIELD_AUTH_ID);
148     if (authId == NULL) {
149         LOGE("Get authId from context failed.");
150         return HC_ERR_JSON_GET;
151     }
152     Uint8Buff authIdBuf = { (uint8_t *)authId, HcStrlen(authId) };
153     AuthCodeImportParams params = { userType, GROUP_MANAGER_PACKAGE_NAME, groupId, authIdBuf, osAccountId };
154     return impl->expandSubSession->addCmd(impl->expandSubSession, AUTH_CODE_IMPORT_CMD_TYPE, (void *)&params,
155         (!impl->isClient), ABORT_IF_ERROR);
156 }
157 
CmdSaveTrustedInfoGenerator(SessionImpl * impl)158 static int32_t CmdSaveTrustedInfoGenerator(SessionImpl *impl)
159 {
160     int32_t osAccountId;
161     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
162         LOGE("get osAccountId from context fail.");
163         return HC_ERR_JSON_GET;
164     }
165     int32_t credType = (impl->protocolEntity.protocolType == ALG_EC_SPEKE ? ASYMMETRIC_CRED : SYMMETRIC_CRED);
166     int32_t visibility = GROUP_VISIBILITY_PUBLIC;
167     (void)GetIntFromJson(impl->context, FIELD_GROUP_VISIBILITY, &visibility);
168     int32_t userType = DEVICE_TYPE_ACCESSORY;
169     (void)GetIntFromJson(impl->context, FIELD_USER_TYPE, &userType);
170     const char *appId = GetStringFromJson(impl->context, FIELD_APP_ID);
171     if (appId == NULL) {
172         LOGE("get appId from context fail.");
173         return HC_ERR_JSON_GET;
174     }
175     const char *groupId = GetStringFromJson(impl->context, FIELD_GROUP_ID);
176     if (groupId == NULL) {
177         LOGE("get groupId from context fail.");
178         return HC_ERR_JSON_GET;
179     }
180     const char *authId = GetStringFromJson(impl->context, FIELD_AUTH_ID);
181     if (authId == NULL) {
182         LOGE("get authId from context fail.");
183         return HC_ERR_JSON_GET;
184     }
185     bool isBind = false;
186     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
187     SaveTrustedInfoParams params = { osAccountId, credType, userType, visibility, appId, groupId, authId, isBind };
188     return impl->expandSubSession->addCmd(impl->expandSubSession, SAVE_TRUSTED_INFO_CMD_TYPE, (void *)&params,
189         (!impl->isClient), ABORT_IF_ERROR);
190 }
191 
CmdMkAgreeGenerator(SessionImpl * impl)192 static int32_t CmdMkAgreeGenerator(SessionImpl *impl)
193 {
194     int32_t osAccountId;
195     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
196         LOGE("Failed to get osAccountId!");
197         return HC_ERR_JSON_GET;
198     }
199     const char *peerInfo = GetStringFromJson(impl->context, FIELD_REAL_INFO);
200     if (peerInfo == NULL) {
201         LOGE("Failed to get peerInfo!");
202         return HC_ERR_JSON_GET;
203     }
204     const char *pdidIndex = GetStringFromJson(impl->context, FIELD_INDEX_KEY);
205     if (pdidIndex == NULL) {
206         LOGE("Failed to get pdidIndex!");
207         return HC_ERR_JSON_GET;
208     }
209     MkAgreeParams params = { osAccountId, peerInfo, pdidIndex };
210     return impl->expandSubSession->addCmd(impl->expandSubSession, MK_AGREE_CMD_TYPE, (void *)&params,
211         (!impl->isClient), CONTINUE_IF_ERROR);
212 }
213 
214 static const CmdProcessor CMDS_LIB[] = {
215     { CMD_EXCHANGE_PK, ABORT_IF_ERROR, CmdExchangePkGenerator },
216     { CMD_IMPORT_AUTH_CODE, ABORT_IF_ERROR, CmdImportAuthCodeGenerator },
217     { CMD_ADD_TRUST_DEVICE, ABORT_IF_ERROR, CmdSaveTrustedInfoGenerator },
218     { CMD_MK_AGREE, CONTINUE_IF_ERROR, CmdMkAgreeGenerator }
219 };
220 
InterceptNotSupportCmd(SessionImpl * impl,CmdProcessor processor)221 static bool InterceptNotSupportCmd(SessionImpl *impl, CmdProcessor processor)
222 {
223     (void)impl;
224     return !IsCmdSupport(processor.id);
225 }
226 
227 static const CmdInterceptor CMDS_INTERCEPTOR_LIB[] = {
228     InterceptNotSupportCmd,
229 };
230 
HasNextCredInfo(SessionImpl * impl)231 static inline bool HasNextCredInfo(SessionImpl *impl)
232 {
233     return impl->credCurIndex < impl->credTotalNum;
234 }
235 
ResetAuthSubSessionList(AuthSubSessionList * authSubSessionList)236 static void ResetAuthSubSessionList(AuthSubSessionList *authSubSessionList)
237 {
238     uint32_t index;
239     AuthSubSession **ptr;
240     FOR_EACH_HC_VECTOR(*authSubSessionList, index, ptr) {
241         AuthSubSession *authSubSesion = *ptr;
242         authSubSesion->destroy(authSubSesion);
243     }
244     authSubSessionList->clear(authSubSessionList);
245 }
246 
ResetSessionState(SessionImpl * impl)247 static void ResetSessionState(SessionImpl *impl)
248 {
249     ClearFreeUint8Buff(&impl->sessionKey);
250     if (HC_VECTOR_SIZE(&impl->credList) > 0) {
251         IdentityInfo *curCredInfo;
252         HC_VECTOR_POPELEMENT(&impl->credList, &curCredInfo, 0);
253         DestroyIdentityInfo(curCredInfo);
254     }
255     ResetAuthSubSessionList(&impl->authSubSessionList);
256     if (impl->expandSubSession != NULL) {
257         impl->expandSubSession->destroy(impl->expandSubSession);
258         impl->expandSubSession = NULL;
259     }
260     impl->protocolEntity.expandProcessCmds = 0;
261 }
262 
RestartSession(SessionImpl * impl,JumpPolicy * policy)263 static int32_t RestartSession(SessionImpl *impl, JumpPolicy *policy)
264 {
265     bool isSingleCred = false;
266     (void)GetBoolFromJson(impl->context, FIELD_IS_SINGLE_CRED, &isSingleCred);
267     if (!HasNextCredInfo(impl) || isSingleCred) {
268         LOGE("session has no next available credential, session failed.");
269         return HC_ERR_NO_CANDIDATE_GROUP;
270     }
271     RESET_PERFORM_DATA(impl->base.id);
272     ResetSessionState(impl);
273     if (impl->isClient) {
274         SessionEvent event = { START_EVENT, NULL };
275         HC_VECTOR_PUSHBACK(&impl->eventList, &event);
276         LOGI("push startEvent success.");
277     }
278     *policy = RESTART_STATE;
279     LOGI("restart session success.");
280     return HC_SUCCESS;
281 }
282 
ErrorInformPeer(int32_t errorCode,CJson * sessionMsg)283 static void ErrorInformPeer(int32_t errorCode, CJson *sessionMsg)
284 {
285     CJson *errMsg = CreateJson();
286     if (errMsg == NULL) {
287         LOGW("allocate errMsg memory fail.");
288         return;
289     }
290     if (AddIntToJson(errMsg, FIELD_ERROR_CODE, errorCode) != HC_SUCCESS) {
291         LOGW("add errorCode to errMsg fail.");
292         FreeJson(errMsg);
293         return;
294     }
295     (void)AddMsgToSessionMsg(SESSION_FAIL_EVENT, errMsg, sessionMsg);
296     FreeJson(errMsg);
297 }
298 
RemoveUnsupportedProtocols(IdentityInfo * cred)299 static void RemoveUnsupportedProtocols(IdentityInfo *cred)
300 {
301     uint32_t index = 0;
302     while (index < HC_VECTOR_SIZE(&cred->protocolVec)) {
303         ProtocolEntity *entity = cred->protocolVec.get(&cred->protocolVec, index);
304         if (IsProtocolSupport(entity->protocolType)) {
305             index++;
306             continue;
307         }
308         LOGI("remove unsupported protocol from credential information. [ProtocolType]: %" LOG_PUB "d",
309             entity->protocolType);
310         ProtocolEntity *popEntity = NULL;
311         HC_VECTOR_POPELEMENT(&cred->protocolVec, &popEntity, index);
312         HcFree(popEntity);
313     }
314 }
315 
CheckAllCredsValidity(SessionImpl * impl)316 static void CheckAllCredsValidity(SessionImpl *impl)
317 {
318     uint32_t index = 0;
319     while (index < HC_VECTOR_SIZE(&impl->credList)) {
320         IdentityInfo *cred = impl->credList.get(&impl->credList, index);
321         RemoveUnsupportedProtocols(cred);
322         uint32_t protocolNum = HC_VECTOR_SIZE(&cred->protocolVec);
323         if (protocolNum > 0) {
324             index++;
325             continue;
326         }
327         LOGW("remove credential without available protocol.");
328         IdentityInfo *popCred = NULL;
329         HC_VECTOR_POPELEMENT(&impl->credList, &popCred, index);
330         DestroyIdentityInfo(cred);
331     }
332 }
333 
GetAllCredsWithPeer(SessionImpl * impl)334 static int32_t GetAllCredsWithPeer(SessionImpl *impl)
335 {
336     int32_t res = GetCredInfosByPeerIdentity(impl->context, &impl->credList);
337     if (res != HC_SUCCESS) {
338         LOGE("failed to get creds with peer. [Res]: %" LOG_PUB "d", res);
339         return res;
340     }
341     CheckAllCredsValidity(impl);
342     uint32_t credNum = HC_VECTOR_SIZE(&impl->credList);
343     if (credNum == 0) {
344         LOGE("No valid credentials with peer.");
345         return HC_ERR_NO_CANDIDATE_GROUP;
346     }
347     impl->credCurIndex = 0;
348     impl->credTotalNum = credNum;
349     LOGI("Get creds with peer success. [CredNum]: %" LOG_PUB "u", credNum);
350     return HC_SUCCESS;
351 }
352 
AddCmdInfoToJsonArray(const CmdProcessor * cmdInfo,CJson * array,bool isTodoCmd)353 static int32_t AddCmdInfoToJsonArray(const CmdProcessor *cmdInfo, CJson *array, bool isTodoCmd)
354 {
355     CJson *cmd = CreateJson();
356     if (cmd == NULL) {
357         LOGE("allocate cmd memory fail.");
358         return HC_ERR_ALLOC_MEMORY;
359     }
360     if (AddIntToJson(cmd, FIELD_ID, cmdInfo->id) != HC_SUCCESS) {
361         LOGE("add cmdId to json fail.");
362         FreeJson(cmd);
363         return HC_ERR_JSON_ADD;
364     }
365     if (isTodoCmd && AddIntToJson(cmd, FIELD_TYPE, cmdInfo->strategy) != HC_SUCCESS) {
366         LOGE("add strategy to json fail.");
367         FreeJson(cmd);
368         return HC_ERR_JSON_ADD;
369     }
370     if (AddObjToArray(array, cmd) != HC_SUCCESS) {
371         LOGE("add cmd to array fail.");
372         FreeJson(cmd);
373         return HC_ERR_JSON_ADD;
374     }
375     return HC_SUCCESS;
376 }
377 
IsCmdIntercepted(SessionImpl * impl,CmdProcessor processor)378 static bool IsCmdIntercepted(SessionImpl *impl, CmdProcessor processor)
379 {
380     for (uint32_t i = 0; i < sizeof(CMDS_INTERCEPTOR_LIB) / sizeof(CMDS_INTERCEPTOR_LIB[0]); i++) {
381         if (CMDS_INTERCEPTOR_LIB[i](impl, processor)) {
382             LOGI("Command intercepted. [Interceptor]: %" LOG_PUB "u", i);
383             return true;
384         }
385     }
386     return false;
387 }
388 
AddTodoCmdsToAbility(SessionImpl * impl,ProtocolEntity * entity,CJson * ability)389 static int32_t AddTodoCmdsToAbility(SessionImpl *impl, ProtocolEntity *entity, CJson *ability)
390 {
391     CJson *todoCmds = CreateJsonArray();
392     if (todoCmds == NULL) {
393         LOGE("allocate todoCmds memory fail.");
394         return HC_ERR_ALLOC_MEMORY;
395     }
396     for (uint32_t i = 0; i < sizeof(CMDS_LIB) / sizeof(CMDS_LIB[0]); i++) {
397         if (((entity->expandProcessCmds & CMDS_LIB[i].id) == 0) || (IsCmdIntercepted(impl, CMDS_LIB[i]))) {
398             continue;
399         }
400         int32_t res = AddCmdInfoToJsonArray(&CMDS_LIB[i], todoCmds, true);
401         if (res != HC_SUCCESS) {
402             FreeJson(todoCmds);
403             return res;
404         }
405     }
406     if (AddObjToJson(ability, FIELD_TD_CMDS, todoCmds) != HC_SUCCESS) {
407         LOGE("add todoCmds to ability fail.");
408         FreeJson(todoCmds);
409         return HC_ERR_JSON_ADD;
410     }
411     FreeJson(todoCmds);
412     return HC_SUCCESS;
413 }
414 
AddCredAbilityToArray(SessionImpl * impl,ProtocolEntity * entity,CJson * abilityArray)415 static int32_t AddCredAbilityToArray(SessionImpl *impl, ProtocolEntity *entity, CJson *abilityArray)
416 {
417     CJson *ability = CreateJson();
418     if (ability == NULL) {
419         LOGE("allocate abilityArray memory fail.");
420         return HC_ERR_ALLOC_MEMORY;
421     }
422     if (AddIntToJson(ability, FIELD_PROTOCOL, entity->protocolType) != HC_SUCCESS) {
423         LOGE("add protocol to ability fail.");
424         FreeJson(ability);
425         return HC_ERR_JSON_ADD;
426     }
427     int32_t res = AddTodoCmdsToAbility(impl, entity, ability);
428     if (res != HC_SUCCESS) {
429         FreeJson(ability);
430         return res;
431     }
432     if (AddObjToArray(abilityArray, ability) != HC_SUCCESS) {
433         LOGE("add ability to abilityArray fail.");
434         FreeJson(ability);
435         return HC_ERR_JSON_ADD;
436     }
437     return HC_SUCCESS;
438 }
439 
AddAllCredAbilityToCredInfo(SessionImpl * impl,IdentityInfo * cred,CJson * credInfo)440 static int32_t AddAllCredAbilityToCredInfo(SessionImpl *impl, IdentityInfo *cred, CJson *credInfo)
441 {
442     CJson *abilityArray = CreateJsonArray();
443     if (abilityArray == NULL) {
444         LOGE("allocate abilityArray memory fail.");
445         return HC_ERR_ALLOC_MEMORY;
446     }
447     uint32_t index;
448     ProtocolEntity **ptr;
449     FOR_EACH_HC_VECTOR(cred->protocolVec, index, ptr) {
450         ProtocolEntity *entity = *ptr;
451         int32_t res = AddCredAbilityToArray(impl, entity, abilityArray);
452         if (res != HC_SUCCESS) {
453             FreeJson(abilityArray);
454             return res;
455         }
456     }
457     if (AddObjToJson(credInfo, FIELD_ABILITY, abilityArray) != HC_SUCCESS) {
458         LOGE("add ability to abilityArray fail.");
459         FreeJson(abilityArray);
460         return HC_ERR_JSON_ADD;
461     }
462     FreeJson(abilityArray);
463     return HC_SUCCESS;
464 }
465 
AddPreSharedCredInfo(SessionImpl * impl,IdentityInfo * cred,CJson * credInfo)466 static int32_t AddPreSharedCredInfo(SessionImpl *impl, IdentityInfo *cred, CJson *credInfo)
467 {
468     if (AddStringToJson(credInfo, FIELD_CRED_URL, (const char *)cred->proof.preSharedUrl.val) != HC_SUCCESS) {
469         LOGE("add preSharedUrl to json fail.");
470         return HC_ERR_JSON_ADD;
471     }
472     return AddAllCredAbilityToCredInfo(impl, cred, credInfo);
473 }
474 
AddCertCredInfo(SessionImpl * impl,IdentityInfo * cred,CJson * credInfo)475 static int32_t AddCertCredInfo(SessionImpl *impl, IdentityInfo *cred, CJson *credInfo)
476 {
477     if (AddIntToJson(credInfo, FIELD_SIGN_ALG, cred->proof.certInfo.signAlg) != HC_SUCCESS) {
478         LOGE("add signAlg to json fail.");
479         return HC_ERR_JSON_ADD;
480     }
481     int32_t res = HC_ERROR;
482     if (cred->proof.certInfo.isPseudonym) {
483         res = AddPkInfoWithPdid(impl->context, credInfo, impl->isCredAuth,
484             (const char *)cred->proof.certInfo.pkInfoStr.val);
485     }
486     if (res != HC_SUCCESS && AddStringToJson(credInfo, FIELD_PK_INFO,
487         (const char *)cred->proof.certInfo.pkInfoStr.val) != HC_SUCCESS) {
488         LOGE("add pkInfoStr to json fail.");
489         return HC_ERR_JSON_ADD;
490     }
491     if (AddByteToJson(credInfo, FIELD_PK_INFO_SIGNATURE, cred->proof.certInfo.pkInfoSignature.val,
492         cred->proof.certInfo.pkInfoSignature.length) != HC_SUCCESS) {
493         LOGE("add pkInfoSignature to json fail.");
494         return HC_ERR_JSON_ADD;
495     }
496     return AddAllCredAbilityToCredInfo(impl, cred, credInfo);
497 }
498 
AddCredInfoToEventData(SessionImpl * impl,IdentityInfo * cred,CJson * eventData)499 static int32_t AddCredInfoToEventData(SessionImpl *impl, IdentityInfo *cred, CJson *eventData)
500 {
501     if (AddIntToJson(eventData, FIELD_TYPE, cred->proofType) != HC_SUCCESS) {
502         LOGE("add credType to json fail.");
503         return HC_ERR_JSON_ADD;
504     }
505     if (cred->proofType == PRE_SHARED) {
506         return AddPreSharedCredInfo(impl, cred, eventData);
507     } else {
508         return AddCertCredInfo(impl, cred, eventData);
509     }
510 }
511 
GetPreSharedCredInfo(SessionImpl * impl,const CJson * credInfo,IdentityInfo ** selfCred)512 static int32_t GetPreSharedCredInfo(SessionImpl *impl, const CJson *credInfo, IdentityInfo **selfCred)
513 {
514     const char *preSharedUrl = GetStringFromJson(credInfo, FIELD_CRED_URL);
515     if (preSharedUrl == NULL) {
516         LOGE("get preSharedUrl from json fail.");
517         return HC_ERR_JSON_GET;
518     }
519     CJson *urlJson = CreateJsonFromString(preSharedUrl);
520     if (urlJson == NULL) {
521         LOGE("Failed to create url json!");
522         return HC_ERR_JSON_FAIL;
523     }
524     bool isDirectAuth = false;
525     (void)GetBoolFromJson(urlJson, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
526     if (AddBoolToJson(impl->context, FIELD_IS_DIRECT_AUTH, isDirectAuth) != HC_SUCCESS) {
527         LOGE("Faild to add isDirectAuth to context");
528         FreeJson(urlJson);
529         return HC_ERR_JSON_ADD;
530     }
531     FreeJson(urlJson);
532     Uint8Buff peerSharedUrl = { (uint8_t *)preSharedUrl, HcStrlen(preSharedUrl) + 1 };
533     IdentityInfo *info;
534     int32_t res = GetCredInfoByPeerUrl(impl->context, &peerSharedUrl, &info);
535     if (res != HC_SUCCESS) {
536         LOGE("get cred info by peer url fail.");
537         return res;
538     }
539     *selfCred = info;
540     return HC_SUCCESS;
541 }
542 
GetCertCredInfo(SessionImpl * impl,const CJson * credInfo,IdentityInfo ** selfCred)543 static int32_t GetCertCredInfo(SessionImpl *impl, const CJson *credInfo, IdentityInfo **selfCred)
544 {
545     int32_t res = CheckPeerPkInfoForPdid(impl->context, credInfo);
546     if (res != HC_SUCCESS) {
547         LOGE("Failed to check peer pkInfo!");
548         return res;
549     }
550     CertInfo cert;
551     res = GetPeerCertInfo(impl->context, credInfo, &cert);
552     if (res != HC_SUCCESS) {
553         LOGE("get peer cert fail.");
554         return res;
555     }
556     IdentityInfo *info;
557     res = GetCredInfoByPeerCert(impl->context, &cert, &info);
558     DestroyCertInfo(&cert);
559     if (res != HC_SUCCESS) {
560         LOGE("get cred info by peer url fail.");
561         return res;
562     }
563     *selfCred = info;
564     return HC_SUCCESS;
565 }
566 
GetSelfCredByInput(SessionImpl * impl,const CJson * inputData)567 static int32_t GetSelfCredByInput(SessionImpl *impl, const CJson *inputData)
568 {
569     int32_t credType;
570     if (GetIntFromJson(inputData, FIELD_TYPE, &credType) != HC_SUCCESS) {
571         LOGE("get cred type from json fail.");
572         return HC_ERR_JSON_GET;
573     }
574     int32_t res;
575     IdentityInfo *info = NULL;
576     if (credType == PRE_SHARED) {
577         res = GetPreSharedCredInfo(impl, inputData, &info);
578     } else {
579         res = GetCertCredInfo(impl, inputData, &info);
580     }
581     if (res != HC_SUCCESS) {
582         return res;
583     }
584     if (impl->credList.pushBackT(&impl->credList, info) == NULL) {
585         LOGE("push cred to list fail.");
586         DestroyIdentityInfo(info);
587         return HC_ERR_ALLOC_MEMORY;
588     }
589     return HC_SUCCESS;
590 }
591 
GenerateDevSessionSalt(SessionImpl * impl)592 static int32_t GenerateDevSessionSalt(SessionImpl *impl)
593 {
594     if (InitUint8Buff(&impl->salt, DEV_SESSION_SALT_LEN) != HC_SUCCESS) {
595         LOGE("Failed to alloc salt memory!");
596         return HC_ERR_ALLOC_MEMORY;
597     }
598     int32_t res = CalSalt(&impl->salt);
599     if (res != HC_SUCCESS) {
600         LOGE("Failed to generate salt!");
601         return res;
602     }
603     if (AddByteToJson(impl->context, FIELD_NONCE, impl->salt.val, impl->salt.length) != HC_SUCCESS) {
604         LOGE("Error occurs, add nonce byte to context fail!");
605         return HC_ERR_JSON_ADD;
606     }
607     if (AddByteToJson(impl->context, FIELD_SEED, impl->salt.val, impl->salt.length) != HC_SUCCESS) {
608         LOGE("Error occurs, add seed byte to context fail!");
609         return HC_ERR_JSON_ADD;
610     }
611     return HC_SUCCESS;
612 }
613 
AddSessionInfoToEventData(SessionImpl * impl,CJson * eventData)614 static int32_t AddSessionInfoToEventData(SessionImpl *impl, CJson *eventData)
615 {
616     if (AddStringToJson(eventData, FIELD_VR, VERSION_2_0_0) != HC_SUCCESS) {
617         LOGE("add version to json fail.");
618         return HC_ERR_JSON_ADD;
619     }
620     if (AddByteToJson(eventData, FIELD_SALT, impl->salt.val, impl->salt.length) != HC_SUCCESS) {
621         LOGE("add session salt to json fail.");
622         return HC_ERR_JSON_ADD;
623     }
624     if (AddIntToJson(eventData, FIELD_INDEX, impl->credCurIndex) != HC_SUCCESS) {
625         LOGE("add cred index to json fail.");
626         return HC_ERR_JSON_ADD;
627     }
628     if (AddIntToJson(eventData, FIELD_TOTAL, impl->credTotalNum) != HC_SUCCESS) {
629         LOGE("add cred num to json fail.");
630         return HC_ERR_JSON_ADD;
631     }
632     return HC_SUCCESS;
633 }
634 
635 /**
636  * @brief auth with credentials directly no need for abilities negotiation of two devices,
637  * so we set support commands empty here.
638  *
639  * @param eventData
640  * @return int32_t
641  */
AddSupportCmdsForDirectAuth(CJson * eventData)642 static int32_t AddSupportCmdsForDirectAuth(CJson *eventData)
643 {
644     // added empty spCmds array to eventData
645     CJson *supportCmds = CreateJsonArray();
646     if (supportCmds == NULL) {
647         LOGE("allocate supportCmds memory fail.");
648         return HC_ERR_ALLOC_MEMORY;
649     }
650     if (AddObjToJson(eventData, FIELD_SP_CMDS, supportCmds) != HC_SUCCESS) {
651         LOGE("add supportCmds to json fail.");
652         FreeJson(supportCmds);
653         return HC_ERR_JSON_ADD;
654     }
655     FreeJson(supportCmds);
656     return HC_SUCCESS;
657 }
658 
AddSupportCmdsToEventData(CJson * eventData)659 static int32_t AddSupportCmdsToEventData(CJson *eventData)
660 {
661     CJson *supportCmds = CreateJsonArray();
662     if (supportCmds == NULL) {
663         LOGE("allocate supportCmds memory fail.");
664         return HC_ERR_ALLOC_MEMORY;
665     }
666     for (uint32_t i = 0; i < sizeof(CMDS_LIB) / sizeof(CMDS_LIB[0]); i++) {
667         if (!IsCmdSupport(CMDS_LIB[i].id)) {
668             continue;
669         }
670         int32_t res = AddCmdInfoToJsonArray(&CMDS_LIB[i], supportCmds, false);
671         if (res != HC_SUCCESS) {
672             FreeJson(supportCmds);
673             return res;
674         }
675     }
676     if (AddObjToJson(eventData, FIELD_SP_CMDS, supportCmds) != HC_SUCCESS) {
677         LOGE("add supportCmds to json fail.");
678         FreeJson(supportCmds);
679         return HC_ERR_JSON_ADD;
680     }
681     FreeJson(supportCmds);
682     return HC_SUCCESS;
683 }
684 
GenerateHandshakeEventData(SessionImpl * impl,IdentityInfo * cred,CJson * eventData)685 static int32_t GenerateHandshakeEventData(SessionImpl *impl, IdentityInfo *cred, CJson *eventData)
686 {
687     int32_t res = AddSessionInfoToEventData(impl, eventData);
688     if (res != HC_SUCCESS) {
689         return res;
690     }
691     res = AddCredInfoToEventData(impl, cred, eventData);
692     if (res != HC_SUCCESS) {
693         LOGE("Failed to AddCredInfoToEventData.");
694         return res;
695     }
696     bool isDirectAuth = false;
697     (void)GetBoolFromJson(impl->context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
698     if (isDirectAuth) {
699         return AddSupportCmdsForDirectAuth(eventData);
700     } else {
701         return AddSupportCmdsToEventData(eventData);
702     }
703     return HC_SUCCESS;
704 }
705 
SetAuthProtectedMsg(SessionImpl * impl,const CJson * msgJson,bool isSelf)706 static int32_t SetAuthProtectedMsg(SessionImpl *impl, const CJson *msgJson, bool isSelf)
707 {
708     char *msgStr = PackJsonToString(msgJson);
709     if (msgStr == NULL) {
710         LOGE("convert msgJson to msgStr fail.");
711         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
712     }
713     Uint8Buff msg = { (uint8_t *)msgStr, HcStrlen(msgStr) + 1 };
714     int32_t res;
715     uint32_t index;
716     AuthSubSession **ptr;
717     FOR_EACH_HC_VECTOR(impl->authSubSessionList, index, ptr) {
718         AuthSubSession *authSubSession = *ptr;
719         if (isSelf) {
720             res = authSubSession->setSelfProtectedMsg(authSubSession, &msg);
721         } else {
722             res = authSubSession->setPeerProtectedMsg(authSubSession, &msg);
723         }
724         if (res != HC_SUCCESS) {
725             break;
726         }
727     }
728     FreeJsonString(msgStr);
729     return res;
730 }
731 
AddStartHandshakeMsg(SessionImpl * impl,IdentityInfo * cred,CJson * sessionMsg)732 static int32_t AddStartHandshakeMsg(SessionImpl *impl, IdentityInfo *cred, CJson *sessionMsg)
733 {
734     LOGI("Start handshake with peer. [CredIndex]: %" LOG_PUB "u, [CredTotalNum]: %" LOG_PUB "u", impl->credCurIndex,
735         impl->credTotalNum);
736     CJson *eventData = CreateJson();
737     if (eventData == NULL) {
738         LOGE("allocate eventData memory fail.");
739         return HC_ERR_ALLOC_MEMORY;
740     }
741     int32_t res = GenerateHandshakeEventData(impl, cred, eventData);
742     if (res != HC_SUCCESS) {
743         FreeJson(eventData);
744         return res;
745     }
746     res = SetAuthProtectedMsg(impl, eventData, true);
747     if (res != HC_SUCCESS) {
748         FreeJson(eventData);
749         return res;
750     }
751     res = AddMsgToSessionMsg(HAND_SHAKE_EVENT, eventData, sessionMsg);
752     FreeJson(eventData);
753     return res;
754 }
755 
AddAuthMsgToSessionMsg(AuthSubSession * authSubSession,CJson * authData,CJson * sessionMsg)756 static int32_t AddAuthMsgToSessionMsg(AuthSubSession *authSubSession, CJson *authData, CJson *sessionMsg)
757 {
758     CJson *eventData = CreateJson();
759     if (eventData == NULL) {
760         LOGE("allocate eventData memory fail.");
761         return HC_ERR_ALLOC_MEMORY;
762     }
763     if (AddIntToJson(eventData, FIELD_PROTOCOL, authSubSession->protocolType) != HC_SUCCESS) {
764         LOGE("add protocol to json fail.");
765         FreeJson(eventData);
766         return HC_ERR_JSON_ADD;
767     }
768     if (AddObjToJson(eventData, FIELD_AUTH_DATA, authData) != HC_SUCCESS) {
769         LOGE("add auth data to json fail.");
770         FreeJson(eventData);
771         return HC_ERR_JSON_ADD;
772     }
773     int32_t res = AddMsgToSessionMsg(AUTH_EVENT, eventData, sessionMsg);
774     FreeJson(eventData);
775     return res;
776 }
777 
AddAuthFirstMsg(AuthSubSession * authSubSession,CJson * sessionMsg,bool shouldReplace)778 static int32_t AddAuthFirstMsg(AuthSubSession *authSubSession, CJson *sessionMsg, bool shouldReplace)
779 {
780     CJson *authData = NULL;
781     int32_t res = authSubSession->start(authSubSession, &authData);
782     if (res != HC_SUCCESS) {
783         LOGE("process auth sub session fail. [Res]: %" LOG_PUB "d", res);
784         return res;
785     }
786     if (shouldReplace) {
787         res = ReplaceAuthIdWithRandom(authData);
788         if (res != HC_SUCCESS) {
789             LOGE("Replace auth id with random failed. [Res]: %" LOG_PUB "d", res);
790             FreeJson(authData);
791             return res;
792         }
793     }
794     res = AddAuthMsgToSessionMsg(authSubSession, authData, sessionMsg);
795     FreeJson(authData);
796     return res;
797 }
798 
AddAllAuthFirstMsg(SessionImpl * impl,CJson * sessionMsg,bool shouldReplace)799 static int32_t AddAllAuthFirstMsg(SessionImpl *impl, CJson *sessionMsg, bool shouldReplace)
800 {
801     uint32_t index;
802     AuthSubSession **ptr;
803     FOR_EACH_HC_VECTOR(impl->authSubSessionList, index, ptr) {
804         AuthSubSession *authSubSesion = *ptr;
805         int32_t res = AddAuthFirstMsg(authSubSesion, sessionMsg, shouldReplace);
806         if (res != HC_SUCCESS) {
807             return res;
808         }
809     }
810     return HC_SUCCESS;
811 }
812 
CreateIsoSubSession(SessionImpl * impl,const IdentityInfo * cred,AuthSubSession ** returnSubSession)813 static int32_t CreateIsoSubSession(SessionImpl *impl, const IdentityInfo *cred, AuthSubSession **returnSubSession)
814 {
815     if (cred->proofType == CERTIFICATED) {
816         LOGE("cert credential not support.");
817         return HC_ERR_UNSUPPORTED_VERSION;
818     }
819     const char *authId = GetStringFromJson(impl->context, FIELD_AUTH_ID);
820     if (authId == NULL) {
821         LOGE("Get auth id from context fail.");
822         return HC_ERR_JSON_GET;
823     }
824     int32_t osAccountId;
825     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
826         LOGE("Error occurs, failed to get osAccountId from context!");
827         return HC_ERR_JSON_GET;
828     }
829     Uint8Buff authIdBuff = { (uint8_t *)authId, HcStrlen(authId) + 1 };
830     IsoInitParams params = { authIdBuff, osAccountId };
831     AuthSubSession *authSubSession;
832     int32_t res = CreateAuthSubSession(PROTOCOL_TYPE_ISO, &params, impl->isClient, &authSubSession);
833     if (res != HC_SUCCESS) {
834         LOGE("create iso auth sub session fail. [Res]: %" LOG_PUB "d", res);
835         return res;
836     }
837     *returnSubSession = authSubSession;
838     LOGI("create ISO authSubSession success.");
839     return HC_SUCCESS;
840 }
841 
CreateDlSpekeSubSession(SessionImpl * impl,const IdentityInfo * cred,AuthSubSession ** returnSubSession)842 static int32_t CreateDlSpekeSubSession(SessionImpl *impl, const IdentityInfo *cred, AuthSubSession **returnSubSession)
843 {
844     if (impl->isCredAuth || cred->proofType == CERTIFICATED) {
845         LOGE("IS or Cert credential not support.");
846         return HC_ERR_UNSUPPORTED_VERSION;
847     }
848     int32_t osAccountId;
849     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
850         LOGE("Failed to get osAccountId!");
851         return HC_ERR_JSON_GET;
852     }
853     CJson *urlJson = CreateJsonFromString((const char *)cred->proof.preSharedUrl.val);
854     if (urlJson == NULL) {
855         LOGE("Failed to create preshared url json!");
856         return HC_ERR_JSON_CREATE;
857     }
858     int32_t trustType;
859     if (GetIntFromJson(urlJson, PRESHARED_URL_TRUST_TYPE, &trustType) != HC_SUCCESS) {
860         LOGE("Failed to get trust type!");
861         FreeJson(urlJson);
862         return HC_ERR_JSON_GET;
863     }
864     FreeJson(urlJson);
865     if (trustType != TRUST_TYPE_PIN) {
866         LOGE("Invalid trust type!");
867         return HC_ERR_UNSUPPORTED_VERSION;
868     }
869     const char *authId = GetStringFromJson(impl->context, FIELD_AUTH_ID);
870     if (authId == NULL) {
871         LOGE("Failed to get self authId!");
872         return HC_ERR_JSON_GET;
873     }
874     DlSpekePrimeMod primeMod = DL_SPEKE_PRIME_MOD_NONE;
875 #ifdef P2P_PAKE_DL_PRIME_LEN_384
876     primeMod = (uint32_t)primeMod | DL_SPEKE_PRIME_MOD_384;
877 #endif
878 #ifdef P2P_PAKE_DL_PRIME_LEN_256
879     primeMod = (uint32_t)primeMod | DL_SPEKE_PRIME_MOD_256;
880 #endif
881     DlSpekeInitParams params = { primeMod, { (uint8_t *)authId, HcStrlen(authId) + 1 }, osAccountId };
882     AuthSubSession *authSubSession;
883     int32_t res = CreateAuthSubSession(PROTOCOL_TYPE_DL_SPEKE, &params, impl->isClient, &authSubSession);
884     if (res != HC_SUCCESS) {
885         LOGE("create dl speke auth sub session fail. [Res]: %" LOG_PUB "d", res);
886         return res;
887     }
888     *returnSubSession = authSubSession;
889     LOGI("create dl speke auth sub session success.");
890     return HC_SUCCESS;
891 }
892 
CreateEcSpekeSubSession(SessionImpl * impl,const IdentityInfo * cred,AuthSubSession ** returnSubSession)893 static int32_t CreateEcSpekeSubSession(SessionImpl *impl, const IdentityInfo *cred, AuthSubSession **returnSubSession)
894 {
895     EcSpekeCurveType curveType = (cred->proofType == CERTIFICATED) ? CURVE_TYPE_256 : CURVE_TYPE_25519;
896     const char *authId = GetStringFromJson(impl->context, FIELD_AUTH_ID);
897     if (authId == NULL) {
898         LOGE("Error occurs, authId is NULL.");
899         return HC_ERR_JSON_GET;
900     }
901     int32_t osAccountId;
902     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
903         LOGE("Failed to get osAccountId from context!");
904         return HC_ERR_JSON_GET;
905     }
906     Uint8Buff authIdBuff = { (uint8_t *)authId, HcStrlen(authId) + 1 };
907     EcSpekeInitParams params = { curveType, authIdBuff, osAccountId };
908     AuthSubSession *authSubSession;
909     int32_t res = CreateAuthSubSession(PROTOCOL_TYPE_EC_SPEKE, &params, impl->isClient, &authSubSession);
910     if (res != HC_SUCCESS) {
911         LOGE("create ecspeke auth sub session fail. [Res]: %" LOG_PUB "d", res);
912         return res;
913     }
914     *returnSubSession = authSubSession;
915     LOGI("create EC_SPEKE authSubSession success.");
916     return HC_SUCCESS;
917 }
918 
AddP2PGroupInfoToContext(SessionImpl * impl,const TrustedGroupEntry * entry)919 static int32_t AddP2PGroupInfoToContext(SessionImpl *impl, const TrustedGroupEntry *entry)
920 {
921     if (AddStringToJson(impl->context, FIELD_GROUP_ID, StringGet(&entry->id)) != HC_SUCCESS) {
922         LOGE("add groupId to json fail.");
923         return HC_ERR_JSON_ADD;
924     }
925     if (AddIntToJson(impl->context, FIELD_OPERATION_CODE, AUTH_FORM_ACCOUNT_UNRELATED) != HC_SUCCESS) {
926         LOGE("add operationCode to json fail.");
927         return HC_ERR_JSON_ADD;
928     }
929     impl->base.opCode = AUTH_FORM_ACCOUNT_UNRELATED;
930     return HC_SUCCESS;
931 }
932 
AddIdenticalAccountGroupInfoToContext(SessionImpl * impl,const TrustedGroupEntry * entry)933 static int32_t AddIdenticalAccountGroupInfoToContext(SessionImpl *impl, const TrustedGroupEntry *entry)
934 {
935     if (AddStringToJson(impl->context, FIELD_GROUP_ID, StringGet(&entry->id)) != HC_SUCCESS) {
936         LOGE("add groupId to json fail.");
937         return HC_ERR_JSON_ADD;
938     }
939     if (AddIntToJson(impl->context, FIELD_OPERATION_CODE, AUTH_FORM_IDENTICAL_ACCOUNT) != HC_SUCCESS) {
940         LOGE("add operationCode to json fail.");
941         return HC_ERR_JSON_ADD;
942     }
943     if (AddStringToJson(impl->context, FIELD_USER_ID, StringGet(&entry->userId)) != HC_SUCCESS) {
944         LOGE("add userId to json fail.");
945         return HC_ERR_JSON_ADD;
946     }
947     impl->base.opCode = AUTH_FORM_IDENTICAL_ACCOUNT;
948     return HC_SUCCESS;
949 }
950 
AddAcrossAccountGroupInfoToContext(SessionImpl * impl,const TrustedGroupEntry * entry)951 static int32_t AddAcrossAccountGroupInfoToContext(SessionImpl *impl, const TrustedGroupEntry *entry)
952 {
953     if (AddStringToJson(impl->context, FIELD_GROUP_ID, StringGet(&entry->id)) != HC_SUCCESS) {
954         LOGE("add groupId to json fail.");
955         return HC_ERR_JSON_ADD;
956     }
957     if (AddIntToJson(impl->context, FIELD_OPERATION_CODE, AUTH_FORM_ACROSS_ACCOUNT) != HC_SUCCESS) {
958         LOGE("add operationCode to json fail.");
959         return HC_ERR_JSON_ADD;
960     }
961     if (AddStringToJson(impl->context, FIELD_USER_ID, StringGet(&entry->userId)) != HC_SUCCESS) {
962         LOGE("add userId to json fail.");
963         return HC_ERR_JSON_ADD;
964     }
965     if (AddStringToJson(impl->context, FIELD_SHARED_USER_ID, StringGet(&entry->sharedUserId)) != HC_SUCCESS) {
966         LOGE("add sharedUserId to json fail.");
967         return HC_ERR_JSON_ADD;
968     }
969     impl->base.opCode = AUTH_FORM_ACROSS_ACCOUNT;
970     return HC_SUCCESS;
971 }
972 
AddGroupInfoToContext(SessionImpl * impl,int32_t osAccountId,const char * groupId)973 static int32_t AddGroupInfoToContext(SessionImpl *impl, int32_t osAccountId, const char *groupId)
974 {
975     TrustedGroupEntry *entry = GetGroupEntryById(osAccountId, groupId);
976     if (entry == NULL) {
977         LOGE("The group cannot be found!");
978         return HC_ERR_GROUP_NOT_EXIST;
979     }
980     int32_t res;
981     if (entry->type == IDENTICAL_ACCOUNT_GROUP) {
982         res = AddIdenticalAccountGroupInfoToContext(impl, entry);
983     } else if (entry->type == PEER_TO_PEER_GROUP) {
984         res = AddP2PGroupInfoToContext(impl, entry);
985     } else {
986         res = AddAcrossAccountGroupInfoToContext(impl, entry);
987     }
988     DestroyGroupEntry(entry);
989     return res;
990 }
991 
AddDevInfoToContext(SessionImpl * impl,int32_t osAccountId,const char * groupId,const char * selfUdid)992 static int32_t AddDevInfoToContext(SessionImpl *impl, int32_t osAccountId, const char *groupId, const char *selfUdid)
993 {
994     TrustedDeviceEntry *deviceEntry = GetDeviceEntryById(osAccountId, selfUdid, true, groupId);
995     if (deviceEntry == NULL) {
996         LOGE("The trusted device is not found!");
997         return HC_ERR_DEVICE_NOT_EXIST;
998     }
999     if (AddStringToJson(impl->context, FIELD_AUTH_ID, StringGet(&deviceEntry->authId)) != HC_SUCCESS) {
1000         LOGE("add selfAuthId to context fail.");
1001         DestroyDeviceEntry(deviceEntry);
1002         return HC_ERR_ALLOC_MEMORY;
1003     }
1004     DestroyDeviceEntry(deviceEntry);
1005     return HC_SUCCESS;
1006 }
1007 
AddAuthInfoToContextByDb(SessionImpl * impl,const char * selfUdid,CJson * urlJson)1008 static int32_t AddAuthInfoToContextByDb(SessionImpl *impl, const char *selfUdid, CJson *urlJson)
1009 {
1010     int32_t osAccountId;
1011     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
1012         LOGE("get osAccountId from context fail.");
1013         return HC_ERR_JSON_GET;
1014     }
1015     const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
1016     if (groupId == NULL) {
1017         LOGE("Failed to get group id!");
1018         return HC_ERR_JSON_GET;
1019     }
1020     int32_t res = AddGroupInfoToContext(impl, osAccountId, groupId);
1021     if (res != HC_SUCCESS) {
1022         return res;
1023     }
1024     return AddDevInfoToContext(impl, osAccountId, groupId, selfUdid);
1025 }
1026 
AddAcrossAccountAuthInfoToContext(SessionImpl * impl,int32_t osAccountId,const char * peerUserId)1027 static int32_t AddAcrossAccountAuthInfoToContext(SessionImpl *impl, int32_t osAccountId, const char *peerUserId)
1028 {
1029     GroupEntryVec groupVec = CreateGroupEntryVec();
1030     QueryGroupParams queryParams = InitQueryGroupParams();
1031     queryParams.groupType = ACROSS_ACCOUNT_AUTHORIZE_GROUP;
1032     queryParams.sharedUserId = peerUserId;
1033     if (QueryGroups(osAccountId, &queryParams, &groupVec) != HC_SUCCESS || groupVec.size(&groupVec) <= 0) {
1034         LOGE("get across account group from db by peerUserId fail.");
1035         char selfUserId[USER_ID_LEN] = { 0 };
1036         (void)GetSelfUserId(osAccountId, selfUserId, USER_ID_LEN);
1037         if (AddStringToJson(impl->context, FIELD_GROUP_ID, selfUserId) != HC_SUCCESS) {
1038             LOGE("add groupId to context fail");
1039             ClearGroupEntryVec(&groupVec);
1040             return HC_ERR_JSON_ADD;
1041         }
1042     } else {
1043         TrustedGroupEntry *groupEntry = groupVec.get(&groupVec, 0);
1044         if (AddStringToJson(impl->context, FIELD_GROUP_ID, StringGet(&groupEntry->id)) != HC_SUCCESS) {
1045             LOGE("add groupId to context fail.");
1046             ClearGroupEntryVec(&groupVec);
1047             return HC_ERR_JSON_ADD;
1048         }
1049     }
1050     if (AddIntToJson(impl->context, FIELD_OPERATION_CODE, AUTH_FORM_ACROSS_ACCOUNT) != HC_SUCCESS) {
1051         LOGE("add operationCode to context fail.");
1052         ClearGroupEntryVec(&groupVec);
1053         return HC_ERR_JSON_ADD;
1054     }
1055     impl->base.opCode = AUTH_FORM_ACROSS_ACCOUNT;
1056     ClearGroupEntryVec(&groupVec);
1057     return HC_SUCCESS;
1058 }
1059 
AddIdenticalAccountAuthInfoToContext(SessionImpl * impl,int32_t osAccountId,const char * peerUserId)1060 static int32_t AddIdenticalAccountAuthInfoToContext(SessionImpl *impl, int32_t osAccountId, const char *peerUserId)
1061 {
1062     GroupEntryVec groupVec = CreateGroupEntryVec();
1063     QueryGroupParams queryParams = InitQueryGroupParams();
1064     queryParams.groupType = IDENTICAL_ACCOUNT_GROUP;
1065     queryParams.userId = peerUserId;
1066     if (QueryGroups(osAccountId, &queryParams, &groupVec) != HC_SUCCESS || groupVec.size(&groupVec) <= 0) {
1067         LOGE("get identical account group from db by peerUserId fail.");
1068         ClearGroupEntryVec(&groupVec);
1069         return HC_ERR_GROUP_NOT_EXIST;
1070     }
1071     TrustedGroupEntry *groupEntry = groupVec.get(&groupVec, 0);
1072     if (AddStringToJson(impl->context, FIELD_GROUP_ID, StringGet(&groupEntry->id)) != HC_SUCCESS) {
1073         LOGE("add groupId to context fail.");
1074         ClearGroupEntryVec(&groupVec);
1075         return HC_ERR_JSON_ADD;
1076     }
1077     if (AddIntToJson(impl->context, FIELD_OPERATION_CODE, AUTH_FORM_IDENTICAL_ACCOUNT) != HC_SUCCESS) {
1078         LOGE("add operationCode to context fail.");
1079         ClearGroupEntryVec(&groupVec);
1080         return HC_ERR_JSON_ADD;
1081     }
1082     impl->base.opCode = AUTH_FORM_IDENTICAL_ACCOUNT;
1083     ClearGroupEntryVec(&groupVec);
1084     return HC_SUCCESS;
1085 }
1086 
AddAuthInfoToContextByCert(SessionImpl * impl)1087 static int32_t AddAuthInfoToContextByCert(SessionImpl *impl)
1088 {
1089     int32_t osAccountId;
1090     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
1091         LOGE("get osAccountId from context fail.");
1092         return HC_ERR_JSON_GET;
1093     }
1094     const char *peerUserId = GetStringFromJson(impl->context, FIELD_USER_ID);
1095     if (peerUserId != NULL && !IsPeerSameUserId(osAccountId, peerUserId)) {
1096         return AddAcrossAccountAuthInfoToContext(impl, osAccountId, peerUserId);
1097     } else {
1098         return AddIdenticalAccountAuthInfoToContext(impl, osAccountId, peerUserId);
1099     }
1100 }
1101 
ISAddAuthInfoToContext(SessionImpl * impl,IdentityInfo * cred)1102 static int32_t ISAddAuthInfoToContext(SessionImpl *impl, IdentityInfo *cred)
1103 {
1104     char selfUdid[INPUT_UDID_LEN] = { 0 };
1105     int32_t res = HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
1106     if (res != HC_SUCCESS) {
1107         LOGE("Failed to get local udid!");
1108         return res;
1109     }
1110     PRINT_SENSITIVE_DATA("SelfUdid", selfUdid);
1111     if (cred->proofType == CERTIFICATED) {
1112         if (AddStringToJson(impl->context, FIELD_AUTH_ID, selfUdid) != HC_SUCCESS) {
1113             LOGE("Error occurs, add selfAuthId to json fail.");
1114             return HC_ERR_JSON_ADD;
1115         }
1116         return HC_SUCCESS;
1117     }
1118     CJson *urlJson = CreateJsonFromString((const char *)cred->proof.preSharedUrl.val);
1119     if (urlJson == NULL) {
1120         LOGE("Create urlJson from cred pre shared url fail.");
1121         return HC_ERR_JSON_CREATE;
1122     }
1123     int32_t trustType;
1124     if (GetIntFromJson(urlJson, PRESHARED_URL_TRUST_TYPE, &trustType) != HC_SUCCESS) {
1125         LOGE("Failed to get trust type from json!");
1126         FreeJson(urlJson);
1127         return HC_ERR_JSON_GET;
1128     }
1129     FreeJson(urlJson);
1130     if (trustType == TRUST_TYPE_PIN) {
1131         return HC_SUCCESS;
1132     }
1133     if (AddStringToJson(impl->context, FIELD_AUTH_ID, selfUdid) != HC_SUCCESS) {
1134         LOGE("Failed to add authId to params!");
1135         return HC_ERR_JSON_ADD;
1136     }
1137     return HC_SUCCESS;
1138 }
1139 
AddAuthInfoToContextByCred(SessionImpl * impl,IdentityInfo * cred)1140 static int32_t AddAuthInfoToContextByCred(SessionImpl *impl, IdentityInfo *cred)
1141 {
1142     char selfUdid[INPUT_UDID_LEN] = { 0 };
1143     int32_t res = HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
1144     if (res != HC_SUCCESS) {
1145         LOGE("Failed to get local udid!");
1146         return res;
1147     }
1148     PRINT_SENSITIVE_DATA("SelfUdid", selfUdid);
1149     bool isDirectAuth = false;
1150     (void)GetBoolFromJson(impl->context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
1151     if (cred->proofType == CERTIFICATED) {
1152         if (AddStringToJson(impl->context, FIELD_AUTH_ID, selfUdid) != HC_SUCCESS) {
1153             LOGE("add selfAuthId to json fail.");
1154             return HC_ERR_ALLOC_MEMORY;
1155         }
1156         return AddAuthInfoToContextByCert(impl);
1157     } else if (isDirectAuth) {  // auth with credentials directly
1158         if (AddStringToJson(impl->context, FIELD_AUTH_ID, selfUdid) != HC_SUCCESS) {
1159             LOGE("add selfAuthId to json fail.");
1160             return HC_ERR_ALLOC_MEMORY;
1161         }
1162         impl->base.opCode = AUTH_FORM_DIRECT_AUTH;
1163         DeleteItemFromJson(impl->context, FIELD_GROUP_ID);
1164         return HC_SUCCESS;
1165     }
1166     CJson *urlJson = CreateJsonFromString((const char *)cred->proof.preSharedUrl.val);
1167     if (urlJson == NULL) {
1168         LOGE("create urlJson from cred proof preSharedUrl fail.");
1169         return HC_ERR_JSON_CREATE;
1170     }
1171     int32_t trustType;
1172     if (GetIntFromJson(urlJson, PRESHARED_URL_TRUST_TYPE, &trustType) != HC_SUCCESS) {
1173         LOGE("Failed to get trust type from url json!");
1174         FreeJson(urlJson);
1175         return HC_ERR_JSON_GET;
1176     }
1177     if (trustType == TRUST_TYPE_PIN) {
1178         FreeJson(urlJson);
1179         return HC_SUCCESS;
1180     }
1181     res = AddAuthInfoToContextByDb(impl, selfUdid, urlJson);
1182     FreeJson(urlJson);
1183     return res;
1184 }
1185 
AddAuthSubSessionToVec(SessionImpl * impl,IdentityInfo * cred,ProtocolEntity * entity)1186 static int32_t AddAuthSubSessionToVec(SessionImpl *impl, IdentityInfo *cred, ProtocolEntity *entity)
1187 {
1188     int32_t res;
1189     AuthSubSession *authSubSession = NULL;
1190     if (entity->protocolType == ALG_EC_SPEKE) {
1191         res = CreateEcSpekeSubSession(impl, cred, &authSubSession);
1192     } else if (entity->protocolType == ALG_DL_SPEKE) {
1193         res = CreateDlSpekeSubSession(impl, cred, &authSubSession);
1194     } else {
1195         res = CreateIsoSubSession(impl, cred, &authSubSession);
1196     }
1197     if (res != HC_SUCCESS) {
1198         return res;
1199     }
1200     if (impl->authSubSessionList.pushBackT(&impl->authSubSessionList, authSubSession) == NULL) {
1201         LOGE("push authSubSession to authSubSessionList fail.");
1202         authSubSession->destroy(authSubSession);
1203         return HC_ERR_ALLOC_MEMORY;
1204     }
1205     return HC_SUCCESS;
1206 }
1207 
ClientCreateAuthSubSessionByCred(SessionImpl * impl,IdentityInfo * cred)1208 static int32_t ClientCreateAuthSubSessionByCred(SessionImpl *impl, IdentityInfo *cred)
1209 {
1210     uint32_t protocolNum = cred->protocolVec.size(&cred->protocolVec);
1211     if (protocolNum == 0) {
1212         LOGE("The credential does not have a valid protocol.");
1213         return HC_ERR_UNSUPPORTED_VERSION;
1214     }
1215     int32_t res = impl->isCredAuth? ISAddAuthInfoToContext(impl, cred)
1216         : AddAuthInfoToContextByCred(impl, cred);
1217     if (res != HC_SUCCESS) {
1218         return res;
1219     }
1220     uint32_t index;
1221     ProtocolEntity **ptr;
1222     FOR_EACH_HC_VECTOR(cred->protocolVec, index, ptr) {
1223         res = AddAuthSubSessionToVec(impl, cred, *ptr);
1224         if (res != HC_SUCCESS) {
1225             return res;
1226         }
1227     }
1228     return HC_SUCCESS;
1229 }
1230 
ProcStartEventInner(SessionImpl * impl,CJson * sessionMsg)1231 static int32_t ProcStartEventInner(SessionImpl *impl, CJson *sessionMsg)
1232 {
1233     int32_t res;
1234     if (impl->credTotalNum == 0) {
1235         res = GetAllCredsWithPeer(impl);
1236         if (res != HC_SUCCESS) {
1237             LOGE("get all credentials with peer device fail.");
1238             return res;
1239         }
1240         res = GenerateDevSessionSalt(impl);
1241         if (res != HC_SUCCESS) {
1242             return res;
1243         }
1244     }
1245     impl->credCurIndex += 1;
1246     IdentityInfo *curCred = HC_VECTOR_GET(&impl->credList, 0);
1247     bool isDirectAuth = curCred->IdInfoType == P2P_DIRECT_AUTH ? true : false;
1248     if (AddBoolToJson(impl->context, FIELD_IS_DIRECT_AUTH, isDirectAuth) != HC_SUCCESS) {
1249         LOGE("Failed to add isDirectAuth to context!");
1250         return HC_ERR_JSON_ADD;
1251     }
1252     res = ClientCreateAuthSubSessionByCred(impl, curCred);
1253     if (res != HC_SUCCESS) {
1254         return res;
1255     }
1256     res = AddStartHandshakeMsg(impl, curCred, sessionMsg);
1257     if (res != HC_SUCCESS) {
1258         return res;
1259     }
1260     /* auth with credentail directly no need replace auth id with random number */
1261     return AddAllAuthFirstMsg(impl, sessionMsg, (IsP2pAuth(curCred) && !isDirectAuth));
1262 }
1263 
GetSessionSaltFromInput(SessionImpl * impl,const CJson * inputData)1264 static int32_t GetSessionSaltFromInput(SessionImpl *impl, const CJson *inputData)
1265 {
1266     if (InitUint8Buff(&impl->salt, DEV_SESSION_SALT_LEN) != HC_SUCCESS) {
1267         LOGE("Allocate salt memory fail.");
1268         return HC_ERR_ALLOC_MEMORY;
1269     }
1270     if (GetByteFromJson(inputData, FIELD_SALT, impl->salt.val, impl->salt.length) != HC_SUCCESS) {
1271         LOGE("Get session salt data from input data fail.");
1272         return HC_ERR_JSON_GET;
1273     }
1274     if (AddByteToJson(impl->context, FIELD_NONCE, impl->salt.val, impl->salt.length) != HC_SUCCESS) {
1275         LOGE("Add salt data to context fail.");
1276         return HC_ERR_JSON_ADD;
1277     }
1278     if (AddByteToJson(impl->context, FIELD_SEED, impl->salt.val, impl->salt.length) != HC_SUCCESS) {
1279         LOGE("add seed to context fail.");
1280         return HC_ERR_JSON_ADD;
1281     }
1282     return HC_SUCCESS;
1283 }
1284 
GetSharedSecret(SessionImpl * impl,const CJson * inputData,IdentityInfo * selfCred,Uint8Buff * psk)1285 static int32_t GetSharedSecret(SessionImpl *impl, const CJson *inputData, IdentityInfo *selfCred, Uint8Buff *psk)
1286 {
1287     if (selfCred->proofType == PRE_SHARED) {
1288         return GetSharedSecretByUrl(impl->context, &selfCred->proof.preSharedUrl,
1289             impl->protocolEntity.protocolType, psk);
1290     }
1291     int32_t res = SetPeerInfoToContext(impl->context, impl->isCredAuth, inputData);
1292     if (res != HC_SUCCESS) {
1293         return res;
1294     }
1295     CertInfo peerCert;
1296     res = GetPeerCertInfo(impl->context, inputData, &peerCert);
1297     if (res != HC_SUCCESS) {
1298         return res;
1299     }
1300     if (impl->isCredAuth && (!HasAccountPlugin())) {
1301         LOGE("The account plugin used by IS is missing!");
1302         return HC_ERR_NOT_SUPPORT;
1303     }
1304     // verify and set psk "SHARED_KEY_ALIAS"
1305     res = GetSharedSecretByPeerCert(impl->context, &peerCert, impl->protocolEntity.protocolType, psk);
1306     DestroyCertInfo(&peerCert);
1307     return res;
1308 }
1309 
SetPeerUserIdToContext(CJson * context,const CJson * inputData,const IdentityInfo * cred)1310 static int32_t SetPeerUserIdToContext(CJson *context, const CJson *inputData, const IdentityInfo *cred)
1311 {
1312     if (cred->proofType != CERTIFICATED) {
1313         LOGI("credential type is not certificate, no need to set peer userId!");
1314         return HC_SUCCESS;
1315     }
1316     CertInfo peerCert;
1317     int32_t res = GetPeerCertInfo(context, inputData, &peerCert);
1318     if (res != HC_SUCCESS) {
1319         LOGE("Failed to get peer cert!");
1320         return res;
1321     }
1322     CJson *pkInfoJson = CreateJsonFromString((const char *)peerCert.pkInfoStr.val);
1323     DestroyCertInfo(&peerCert);
1324     if (pkInfoJson == NULL) {
1325         LOGE("Failed to create pkInfo json!");
1326         return HC_ERR_JSON_CREATE;
1327     }
1328     const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
1329     if (userId == NULL) {
1330         LOGE("Failed to get userId!");
1331         FreeJson(pkInfoJson);
1332         return HC_ERR_JSON_GET;
1333     }
1334     if (AddStringToJson(context, FIELD_USER_ID, userId) != HC_SUCCESS) {
1335         LOGE("Failed to add userId!");
1336         FreeJson(pkInfoJson);
1337         return HC_ERR_JSON_ADD;
1338     }
1339     FreeJson(pkInfoJson);
1340     return HC_SUCCESS;
1341 }
1342 
ServerCreateAuthSubSessionByCred(SessionImpl * impl,const CJson * inputData,IdentityInfo * cred)1343 static int32_t ServerCreateAuthSubSessionByCred(SessionImpl *impl, const CJson *inputData, IdentityInfo *cred)
1344 {
1345     int32_t res = SetPeerUserIdToContext(impl->context, inputData, cred);
1346     if (res != HC_SUCCESS) {
1347         return res;
1348     }
1349     res = impl->isCredAuth? ISAddAuthInfoToContext(impl, cred)
1350         : AddAuthInfoToContextByCred(impl, cred);
1351     if (res != HC_SUCCESS) {
1352         return res;
1353     }
1354     return AddAuthSubSessionToVec(impl, cred, &impl->protocolEntity);
1355 }
1356 
SyncCredState(SessionImpl * impl,const CJson * inputData)1357 static int32_t SyncCredState(SessionImpl *impl, const CJson *inputData)
1358 {
1359     int32_t credIndex;
1360     if (GetIntFromJson(inputData, FIELD_INDEX, &credIndex) != HC_SUCCESS) {
1361         LOGE("get credIndex from inputData fail.");
1362         return HC_ERR_JSON_GET;
1363     }
1364     int32_t credNum;
1365     if (GetIntFromJson(inputData, FIELD_TOTAL, &credNum) != HC_SUCCESS) {
1366         LOGE("get credNum from inputData fail.");
1367         return HC_ERR_JSON_GET;
1368     }
1369     impl->credCurIndex = (uint32_t)credIndex;
1370     impl->credTotalNum = (uint32_t)credNum;
1371     return HC_SUCCESS;
1372 }
1373 
GenerateHandshakeRspEventData(SessionImpl * impl,IdentityInfo * selfCred,CJson * eventData)1374 static int32_t GenerateHandshakeRspEventData(SessionImpl *impl, IdentityInfo *selfCred, CJson *eventData)
1375 {
1376     if (AddStringToJson(eventData, FIELD_VR, VERSION_2_0_0) != HC_SUCCESS) {
1377         LOGE("add version to json fail.");
1378         return HC_ERR_JSON_ADD;
1379     }
1380     int32_t res = AddCredInfoToEventData(impl, selfCred, eventData);
1381     if (res != HC_SUCCESS) {
1382         return res;
1383     }
1384     bool isDirectAuth = false;
1385     (void)GetBoolFromJson(impl->context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
1386     if (isDirectAuth) {
1387         return AddSupportCmdsForDirectAuth(eventData);
1388     } else {
1389         return AddSupportCmdsToEventData(eventData);
1390     }
1391 }
1392 
AddHandshakeRspMsg(SessionImpl * impl,IdentityInfo * selfCred,CJson * sessionMsg)1393 static int32_t AddHandshakeRspMsg(SessionImpl *impl, IdentityInfo *selfCred, CJson *sessionMsg)
1394 {
1395     CJson *eventData = CreateJson();
1396     if (eventData == NULL) {
1397         LOGE("allocate eventData memory fail.");
1398         return HC_ERR_ALLOC_MEMORY;
1399     }
1400     int32_t res = GenerateHandshakeRspEventData(impl, selfCred, eventData);
1401     if (res != HC_SUCCESS) {
1402         FreeJson(eventData);
1403         return res;
1404     }
1405     res = SetAuthProtectedMsg(impl, eventData, true);
1406     if (res != HC_SUCCESS) {
1407         FreeJson(eventData);
1408         return res;
1409     }
1410     res = AddMsgToSessionMsg(HAND_SHAKE_RSP_EVENT, eventData, sessionMsg);
1411     FreeJson(eventData);
1412     return res;
1413 }
1414 
IsPeerSupportCmd(int32_t cmdId,const CJson * supportCmds)1415 static bool IsPeerSupportCmd(int32_t cmdId, const CJson *supportCmds)
1416 {
1417     int32_t supportCmdsNum = GetItemNum(supportCmds);
1418     for (int32_t i = 0; i < supportCmdsNum; i++) {
1419         CJson *cmd = GetItemFromArray(supportCmds, i);
1420         if (cmd == NULL) {
1421             LOGE("get cmd from supportCmds fail.");
1422             return false;
1423         }
1424         int32_t id;
1425         if (GetIntFromJson(cmd, FIELD_ID, &id) != HC_SUCCESS) {
1426             LOGE("get cmd id from json fail.");
1427             return false;
1428         }
1429         if (id == cmdId) {
1430             return true;
1431         }
1432     }
1433     return false;
1434 }
1435 
SelfCmdsNegotiate(SessionImpl * impl,const CJson * supportCmds,const ProtocolEntity * selfProtocolEntity)1436 static int32_t SelfCmdsNegotiate(SessionImpl *impl, const CJson *supportCmds, const ProtocolEntity *selfProtocolEntity)
1437 {
1438     uint32_t selfCmds = 0;
1439     for (uint32_t i = 0; i < sizeof(CMDS_LIB) / sizeof(CMDS_LIB[0]); i++) {
1440         if (!IsCmdSupport(CMDS_LIB[i].id) || ((selfProtocolEntity->expandProcessCmds & CMDS_LIB[i].id) == 0)) {
1441             continue;
1442         }
1443         if (IsPeerSupportCmd(CMDS_LIB[i].id, supportCmds)) {
1444             selfCmds |= CMDS_LIB[i].id;
1445             continue;
1446         }
1447         if (CMDS_LIB[i].strategy == ABORT_IF_ERROR) {
1448             LOGW("The peer device does not support this cmd and it is not optional. [Cmd]: %" LOG_PUB "u",
1449                 CMDS_LIB[i].id);
1450             return HC_ERR_NOT_SUPPORT;
1451         }
1452     }
1453     impl->protocolEntity.expandProcessCmds |= selfCmds;
1454     LOGI("self todo cmds: %" LOG_PUB "u", selfCmds);
1455     return HC_SUCCESS;
1456 }
1457 
PeerCmdsNegotiate(SessionImpl * impl,const CJson * credAbility)1458 static int32_t PeerCmdsNegotiate(SessionImpl *impl, const CJson *credAbility)
1459 {
1460     CJson *todoCmds = GetObjFromJson(credAbility, FIELD_TD_CMDS);
1461     if (todoCmds == NULL) {
1462         LOGE("get todoCmds from ability fail.");
1463         return HC_ERR_JSON_GET;
1464     }
1465     uint32_t peerCmds = 0;
1466     int32_t todoCmdsNum = GetItemNum(todoCmds);
1467     for (int32_t i = 0; i < todoCmdsNum; i++) {
1468         CJson *cmd = GetItemFromArray(todoCmds, i);
1469         if (cmd == NULL) {
1470             LOGE("get cmd from todoCmds fail.");
1471             return HC_ERR_JSON_GET;
1472         }
1473         int32_t id;
1474         if (GetIntFromJson(cmd, FIELD_ID, &id) != HC_SUCCESS) {
1475             LOGE("get cmd id from json fail.");
1476             return HC_ERR_JSON_GET;
1477         }
1478         if (IsCmdSupport(id)) {
1479             peerCmds |= (uint32_t)id;
1480             continue;
1481         }
1482         int32_t strategy;
1483         if (GetIntFromJson(cmd, FIELD_TYPE, &strategy) != HC_SUCCESS) {
1484             LOGE("get strategy from json fail.");
1485             return HC_ERR_JSON_GET;
1486         }
1487         if (strategy == ABORT_IF_ERROR) {
1488             LOGW("The local device does not support this cmd and it is not optional. [Cmd]: %" LOG_PUB "d", id);
1489             return HC_ERR_NOT_SUPPORT;
1490         }
1491     }
1492     impl->protocolEntity.expandProcessCmds |= peerCmds;
1493     LOGI("peer todo cmds: %" LOG_PUB "u", peerCmds);
1494     return HC_SUCCESS;
1495 }
1496 
ProtocolEntityNegotiate(SessionImpl * impl,const CJson * abilityArray,const CJson * supportCmds,ProtocolEntity * selfProtocolEntity)1497 static int32_t ProtocolEntityNegotiate(SessionImpl *impl, const CJson *abilityArray, const CJson *supportCmds,
1498     ProtocolEntity *selfProtocolEntity)
1499 {
1500     int32_t abilityNum = GetItemNum(abilityArray);
1501     for (int32_t i = 0; i < abilityNum; i++) {
1502         CJson *credAbility = GetItemFromArray(abilityArray, i);
1503         if (credAbility == NULL) {
1504             LOGE("get cred ability from abilityArray fail.");
1505             return HC_ERR_JSON_GET;
1506         }
1507         int32_t protocol;
1508         if (GetIntFromJson(credAbility, FIELD_PROTOCOL, &protocol) != HC_SUCCESS) {
1509             LOGE("get protocol from ability fail.");
1510             return HC_ERR_JSON_GET;
1511         }
1512         if (protocol != (int32_t)selfProtocolEntity->protocolType) {
1513             continue;
1514         }
1515         int32_t res = PeerCmdsNegotiate(impl, credAbility);
1516         if (res != HC_SUCCESS) {
1517             return res;
1518         }
1519         res = SelfCmdsNegotiate(impl, supportCmds, selfProtocolEntity);
1520         if (res != HC_SUCCESS) {
1521             return res;
1522         }
1523         impl->protocolEntity.protocolType = protocol;
1524         LOGI("negotiate result: protocol: %" LOG_PUB "d, cmds: %" LOG_PUB "u", impl->protocolEntity.protocolType,
1525             impl->protocolEntity.expandProcessCmds);
1526         return HC_SUCCESS;
1527     }
1528     return HC_ERR_UNSUPPORTED_VERSION;
1529 }
1530 
CredNegotiate(SessionImpl * impl,const CJson * inputData,IdentityInfo * selfCred)1531 static int32_t CredNegotiate(SessionImpl *impl, const CJson *inputData, IdentityInfo *selfCred)
1532 {
1533     CJson *abilityArray = GetObjFromJson(inputData, FIELD_ABILITY);
1534     if (abilityArray == NULL) {
1535         LOGE("get ability array from json fail.");
1536         return HC_ERR_JSON_GET;
1537     }
1538     CJson *supportCmds = GetObjFromJson(inputData, FIELD_SP_CMDS);
1539     if (supportCmds == NULL) {
1540         LOGE("get supportCmds from json fail.");
1541         return HC_ERR_JSON_GET;
1542     }
1543     uint32_t index;
1544     ProtocolEntity **ptr;
1545     FOR_EACH_HC_VECTOR(selfCred->protocolVec, index, ptr) {
1546         ProtocolEntity *entity = *ptr;
1547         if (ProtocolEntityNegotiate(impl, abilityArray, supportCmds, entity) == HC_SUCCESS) {
1548             return HC_SUCCESS;
1549         }
1550     }
1551     LOGE("Credential negotiation failed.");
1552     return HC_ERR_UNSUPPORTED_VERSION;
1553 }
1554 
SetAuthPsk(SessionImpl * impl,const CJson * inputData,IdentityInfo * cred)1555 static int32_t SetAuthPsk(SessionImpl *impl, const CJson *inputData, IdentityInfo *cred)
1556 {
1557     AuthSubSession *curAuthSubSession = impl->authSubSessionList.get(&impl->authSubSessionList, 0);
1558     Uint8Buff psk;
1559     int32_t res = GetSharedSecret(impl, inputData, cred, &psk);
1560     if (res != HC_SUCCESS) {
1561         LOGE("get psk fail. [Res]: %" LOG_PUB "d", res);
1562         return res;
1563     }
1564     res = curAuthSubSession->setPsk(curAuthSubSession, &psk);
1565     ClearFreeUint8Buff(&psk);
1566     if (res != HC_SUCCESS) {
1567         LOGE("set psk fail.");
1568         return res;
1569     }
1570     return HC_SUCCESS;
1571 }
1572 
CheckAcceptRequest(const CJson * context)1573 static int32_t CheckAcceptRequest(const CJson *context)
1574 {
1575     uint32_t confirmation = REQUEST_REJECTED;
1576     (void)GetUnsignedIntFromJson(context, FIELD_CONFIRMATION, &confirmation);
1577     if (confirmation != REQUEST_ACCEPTED) {
1578         LOGE("The service rejects this request!");
1579         return HC_ERR_REQ_REJECTED;
1580     }
1581     LOGI("The service accepts this request!");
1582     return HC_SUCCESS;
1583 }
1584 
ProcHandshakeReqEventInner(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg)1585 static int32_t ProcHandshakeReqEventInner(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg)
1586 {
1587     int32_t res = CheckAcceptRequest(impl->context);
1588     if (res != HC_SUCCESS) {
1589         return res;
1590     }
1591     res = SyncCredState(impl, inputEvent->data);
1592     if (res != HC_SUCCESS) {
1593         return res;
1594     }
1595     LOGI("Recevice handshake with peer. [CredIndex]: %" LOG_PUB "u, [CredTotalNum]: %" LOG_PUB "u", impl->credCurIndex,
1596         impl->credTotalNum);
1597     res = GetSessionSaltFromInput(impl, inputEvent->data);
1598     if (res != HC_SUCCESS) {
1599         return res;
1600     }
1601     res = GetSelfCredByInput(impl, inputEvent->data);
1602     if (res != HC_SUCCESS) {
1603         LOGE("get cred by input fail.");
1604         return res;
1605     }
1606     CheckAllCredsValidity(impl);
1607     IdentityInfo *selfCred = HC_VECTOR_GET(&impl->credList, 0);
1608     bool isDirectAuth = selfCred->IdInfoType == P2P_DIRECT_AUTH ? true : false;
1609     if (AddBoolToJson(impl->context, FIELD_IS_DIRECT_AUTH, isDirectAuth) != HC_SUCCESS) {
1610         LOGE("Failed to add isDirectAuth to context!");
1611         return HC_ERR_JSON_ADD;
1612     }
1613     res = SetPeerAuthIdToContextIfNeeded(impl->context, impl->isCredAuth, selfCred);
1614     if (res != HC_SUCCESS) {
1615         return res;
1616     }
1617     res = CredNegotiate(impl, inputEvent->data, selfCred);
1618     if (res != HC_SUCCESS) {
1619         return res;
1620     }
1621     res = ServerCreateAuthSubSessionByCred(impl, inputEvent->data, selfCred);
1622     if (res != HC_SUCCESS) {
1623         return res;
1624     }
1625     res = SetAuthPsk(impl, inputEvent->data, selfCred);
1626     if (res != HC_SUCCESS) {
1627         return res;
1628     }
1629     res = SetAuthProtectedMsg(impl, inputEvent->data, false);
1630     if (res != HC_SUCCESS) {
1631         return res;
1632     }
1633     return AddHandshakeRspMsg(impl, selfCred, sessionMsg);
1634 }
1635 
GetAlgTypeByProtocolType(int32_t protocolType)1636 static ProtocolAlgType GetAlgTypeByProtocolType(int32_t protocolType)
1637 {
1638     if (protocolType == PROTOCOL_TYPE_EC_SPEKE) {
1639         return ALG_EC_SPEKE;
1640     } else if (protocolType == PROTOCOL_TYPE_DL_SPEKE) {
1641         return ALG_DL_SPEKE;
1642     } else {
1643         return ALG_ISO;
1644     }
1645 }
1646 
RemoveInvalidAuthSubSession(SessionImpl * impl)1647 static int32_t RemoveInvalidAuthSubSession(SessionImpl *impl)
1648 {
1649     uint32_t index = 0;
1650     while (index < HC_VECTOR_SIZE(&impl->authSubSessionList)) {
1651         AuthSubSession *authSubSesion = impl->authSubSessionList.get(&impl->authSubSessionList, index);
1652         ProtocolAlgType curProtocolType = GetAlgTypeByProtocolType(authSubSesion->protocolType);
1653         if (curProtocolType == impl->protocolEntity.protocolType) {
1654             index++;
1655             continue;
1656         }
1657         LOGI("remove invalid authSubSession. [ProtocolType]: %" LOG_PUB "d", curProtocolType);
1658         AuthSubSession *popAuthSubSession;
1659         HC_VECTOR_POPELEMENT(&impl->authSubSessionList, &popAuthSubSession, index);
1660         popAuthSubSession->destroy(popAuthSubSession);
1661     }
1662     return HC_SUCCESS;
1663 }
1664 
ProcHandshakeRspEventInner(SessionImpl * impl,SessionEvent * inputEvent)1665 static int32_t ProcHandshakeRspEventInner(SessionImpl *impl, SessionEvent *inputEvent)
1666 {
1667     IdentityInfo *selfCred = impl->credList.get(&impl->credList, 0);
1668     bool isDirectAuth = selfCred->IdInfoType == P2P_DIRECT_AUTH ? true : false;
1669     if (AddBoolToJson(impl->context, FIELD_IS_DIRECT_AUTH, isDirectAuth) != HC_SUCCESS) {
1670         LOGE("Failed to add isDirectAuth to context!");
1671         return HC_ERR_JSON_ADD;
1672     }
1673     int32_t res = SetPeerAuthIdToContextIfNeeded(impl->context, impl->isCredAuth, selfCred);
1674     if (res != HC_SUCCESS) {
1675         return res;
1676     }
1677     res = CredNegotiate(impl, inputEvent->data, selfCred);
1678     if (res != HC_SUCCESS) {
1679         return res;
1680     }
1681     res = RemoveInvalidAuthSubSession(impl);
1682     if (res != HC_SUCCESS) {
1683         return res;
1684     }
1685     res = SetAuthPsk(impl, inputEvent->data, selfCred);
1686     if (res != HC_SUCCESS) {
1687         return res;
1688     }
1689     return SetAuthProtectedMsg(impl, inputEvent->data, false);
1690 }
1691 
AddAllCmds(SessionImpl * impl)1692 static int32_t AddAllCmds(SessionImpl *impl)
1693 {
1694     uint32_t cmds = impl->protocolEntity.expandProcessCmds;
1695     for (uint32_t i = 0; i < sizeof(CMDS_LIB) / sizeof(CMDS_LIB[0]); i++) {
1696         if ((CMDS_LIB[i].id & cmds) != 0) {
1697             int32_t res = CMDS_LIB[i].cmdGenerator(impl);
1698             if (res != HC_SUCCESS) {
1699                 LOGE("add cmd fail. [CmdId]: %" LOG_PUB "u", CMDS_LIB[i].id);
1700                 return res;
1701             }
1702             LOGI("add cmd success. [CmdId]: %" LOG_PUB "u", CMDS_LIB[i].id);
1703         }
1704     }
1705     return HC_SUCCESS;
1706 }
1707 
CreateExpandSubSessionByCred(SessionImpl * impl)1708 static int32_t CreateExpandSubSessionByCred(SessionImpl *impl)
1709 {
1710     int32_t res = CreateExpandSubSession(&impl->salt, &impl->sessionKey, &impl->expandSubSession);
1711     if (res != HC_SUCCESS) {
1712         LOGE("create expand sub session fail.");
1713         return res;
1714     }
1715     return AddAllCmds(impl);
1716 }
1717 
StartExpandSubSession(ExpandSubSession * expandSubSession,CJson * sessionMsg)1718 static int32_t StartExpandSubSession(ExpandSubSession *expandSubSession, CJson *sessionMsg)
1719 {
1720     CJson *eventData = NULL;
1721     int32_t res = expandSubSession->start(expandSubSession, &eventData);
1722     if (res != HC_SUCCESS) {
1723         LOGE("create expand sub session fail.");
1724         return res;
1725     }
1726     res = AddMsgToSessionMsg(EXPAND_EVENT, eventData, sessionMsg);
1727     FreeJson(eventData);
1728     return res;
1729 }
1730 
ProcAuthSubSessionMsg(AuthSubSession * authSubSession,const CJson * receviedMsg,CJson * sessionMsg,bool shouldReplace)1731 static int32_t ProcAuthSubSessionMsg(AuthSubSession *authSubSession, const CJson *receviedMsg, CJson *sessionMsg,
1732     bool shouldReplace)
1733 {
1734     CJson *authData = NULL;
1735     int32_t res = authSubSession->process(authSubSession, receviedMsg, &authData);
1736     if (res != HC_SUCCESS) {
1737         LOGE("process auth sub session fail. [Res]: %" LOG_PUB "d", res);
1738         if (authData != NULL) {
1739             (void)AddAuthMsgToSessionMsg(authSubSession, authData, sessionMsg);
1740             FreeJson(authData);
1741         }
1742         return res;
1743     }
1744     if (authData == NULL) {
1745         return HC_SUCCESS;
1746     }
1747     if (shouldReplace) {
1748         res = ReplaceAuthIdWithRandom(authData);
1749         if (res != HC_SUCCESS) {
1750             FreeJson(authData);
1751             return res;
1752         }
1753     }
1754     res = AddAuthMsgToSessionMsg(authSubSession, authData, sessionMsg);
1755     FreeJson(authData);
1756     return res;
1757 }
1758 
OnAuthSubSessionFinish(SessionImpl * impl,AuthSubSession * authSubSession,CJson * sessionMsg)1759 static int32_t OnAuthSubSessionFinish(SessionImpl *impl, AuthSubSession *authSubSession, CJson *sessionMsg)
1760 {
1761     int32_t res = authSubSession->getSessionKey(authSubSession, &impl->sessionKey);
1762     if (res != HC_SUCCESS) {
1763         LOGE("get session key fail.");
1764         return res;
1765     }
1766     LOGI("auth sub session finish.");
1767     if (impl->protocolEntity.expandProcessCmds == 0) {
1768         return HC_SUCCESS;
1769     }
1770     res = CreateExpandSubSessionByCred(impl);
1771     if (res != HC_SUCCESS) {
1772         return res;
1773     }
1774     if (!impl->isClient) {
1775         res = StartExpandSubSession(impl->expandSubSession, sessionMsg);
1776         if (res != HC_SUCCESS) {
1777             return res;
1778         }
1779     }
1780     return HC_SUCCESS;
1781 }
1782 
ProcAuthEventInner(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,bool * isAuthFinish,bool isServerProcess)1783 static int32_t ProcAuthEventInner(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, bool *isAuthFinish,
1784     bool isServerProcess)
1785 {
1786     int32_t protocolType;
1787     if (GetIntFromJson(inputEvent->data, FIELD_PROTOCOL, &protocolType) != HC_SUCCESS) {
1788         LOGE("get protocol from json fail.");
1789         return HC_ERR_JSON_GET;
1790     }
1791     int32_t res = FillPeerAuthIdIfNeeded(impl->isClient, impl->context, (CJson *)inputEvent->data);
1792     if (res != HC_SUCCESS) {
1793         return res;
1794     }
1795     AuthSubSession *curAuthSubSession = impl->authSubSessionList.get(&impl->authSubSessionList, 0);
1796     if (protocolType != curAuthSubSession->protocolType) {
1797         LOGI("Protocol type mismatch. Ignore it. [ProtocolType]: %" LOG_PUB "d", protocolType);
1798         return HC_SUCCESS;
1799     }
1800     IdentityInfo *selfCred = HC_VECTOR_GET(&impl->credList, 0);
1801     bool isDirectAuth = selfCred->IdInfoType == P2P_DIRECT_AUTH ? true : false;
1802     if (AddBoolToJson(impl->context, FIELD_IS_DIRECT_AUTH, isDirectAuth) != HC_SUCCESS) {
1803         LOGE("Failed to add isDirectAuth to context!");
1804         return HC_ERR_JSON_ADD;
1805     }
1806     bool isP2pAuth = IsP2pAuth(selfCred);
1807     /* auth with credentail directly no need replace auth id with random number*/
1808     if (isServerProcess && isP2pAuth && !isDirectAuth) {
1809         res = ProcAuthSubSessionMsg(curAuthSubSession, inputEvent->data, sessionMsg, true);
1810     } else {
1811         res = ProcAuthSubSessionMsg(curAuthSubSession, inputEvent->data, sessionMsg, false);
1812     }
1813     if (res != HC_SUCCESS) {
1814         return res;
1815     }
1816     if (curAuthSubSession->state == AUTH_STATE_RUNNING) {
1817         *isAuthFinish = false;
1818         return HC_SUCCESS;
1819     }
1820     *isAuthFinish = true;
1821     return OnAuthSubSessionFinish(impl, curAuthSubSession, sessionMsg);
1822 }
1823 
ProcExpandEventInner(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,bool * isExpandFinish)1824 static int32_t ProcExpandEventInner(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg,
1825     bool *isExpandFinish)
1826 {
1827     CJson *expandData = NULL;
1828     int32_t res = impl->expandSubSession->process(impl->expandSubSession, inputEvent->data, &expandData);
1829     if (res != HC_SUCCESS) {
1830         LOGE("process expand sub session fail. [Res]: %" LOG_PUB "d", res);
1831         if (expandData != NULL) {
1832             (void)AddMsgToSessionMsg(EXPAND_EVENT, expandData, sessionMsg);
1833             FreeJson(expandData);
1834         }
1835         return res;
1836     }
1837     if (expandData != NULL) {
1838         res = AddMsgToSessionMsg(EXPAND_EVENT, expandData, sessionMsg);
1839         FreeJson(expandData);
1840         if (res != HC_SUCCESS) {
1841             return res;
1842         }
1843     }
1844     *isExpandFinish = impl->expandSubSession->state == EXPAND_STATE_FINISH;
1845     return HC_SUCCESS;
1846 }
1847 
ProcFailEvent(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,JumpPolicy * policy)1848 static int32_t ProcFailEvent(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy)
1849 {
1850     (void)sessionMsg;
1851     int32_t peerErrorCode = HC_ERR_PEER_ERROR;
1852     (void)GetIntFromJson(inputEvent->data, FIELD_ERROR_CODE, &peerErrorCode);
1853     LOGE("An exception occurred in the peer session. [Code]: %" LOG_PUB "d", peerErrorCode);
1854     return RestartSession(impl, policy) == HC_SUCCESS ? HC_SUCCESS : peerErrorCode;
1855 }
1856 
ProcStartEvent(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,JumpPolicy * policy)1857 static int32_t ProcStartEvent(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy)
1858 {
1859     (void)inputEvent;
1860     int32_t res = ProcStartEventInner(impl, sessionMsg);
1861     if (res != HC_SUCCESS) {
1862         ReportRadarEvent(res);
1863         return RestartSession(impl, policy) == HC_SUCCESS ? HC_SUCCESS : res;
1864     }
1865     LOGI("process start event success.");
1866     *policy = JUMP_TO_NEXT_STATE;
1867     return HC_SUCCESS;
1868 }
1869 
ProcHandshakeReqEvent(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,JumpPolicy * policy)1870 static int32_t ProcHandshakeReqEvent(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy)
1871 {
1872     int32_t res = ProcHandshakeReqEventInner(impl, inputEvent, sessionMsg);
1873     if (res != HC_SUCCESS) {
1874         ErrorInformPeer(res, sessionMsg);
1875         ReportRadarEvent(res);
1876         return RestartSession(impl, policy) == HC_SUCCESS ? HC_SUCCESS : res;
1877     }
1878     LOGI("process handshake request event success.");
1879     *policy = JUMP_TO_NEXT_STATE;
1880     return HC_SUCCESS;
1881 }
1882 
ProcHandshakeRspEvent(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,JumpPolicy * policy)1883 static int32_t ProcHandshakeRspEvent(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy)
1884 {
1885     int32_t res = ProcHandshakeRspEventInner(impl, inputEvent);
1886     if (res != HC_SUCCESS) {
1887         ErrorInformPeer(res, sessionMsg);
1888         ReportRadarEvent(res);
1889         return RestartSession(impl, policy) == HC_SUCCESS ? HC_SUCCESS : res;
1890     }
1891     LOGI("process handshake response event success.");
1892     *policy = JUMP_TO_NEXT_STATE;
1893     return HC_SUCCESS;
1894 }
1895 
ProcFirstAuthEvent(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,JumpPolicy * policy)1896 static int32_t ProcFirstAuthEvent(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy)
1897 {
1898     bool isAuthFinish = false;
1899     int32_t res = ProcAuthEventInner(impl, inputEvent, sessionMsg, &isAuthFinish, true);
1900     if (res != HC_SUCCESS) {
1901         ErrorInformPeer(res, sessionMsg);
1902         ReportRadarEvent(res);
1903 
1904         return RestartSession(impl, policy) == HC_SUCCESS ? HC_SUCCESS : res;
1905     }
1906     LOGI("process first auth event success.");
1907     *policy = JUMP_TO_NEXT_STATE;
1908     return HC_SUCCESS;
1909 }
1910 
ProcAuthEvent(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,JumpPolicy * policy)1911 static int32_t ProcAuthEvent(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy)
1912 {
1913     bool isAuthFinish = false;
1914     int32_t res = ProcAuthEventInner(impl, inputEvent, sessionMsg, &isAuthFinish, false);
1915     if (res != HC_SUCCESS) {
1916         ErrorInformPeer(res, sessionMsg);
1917         ReportRadarEvent(res);
1918         return RestartSession(impl, policy) == HC_SUCCESS ? HC_SUCCESS : res;
1919     }
1920     LOGI("process auth event success.");
1921     if (!isAuthFinish) {
1922         *policy = STAY_STATE;
1923     } else if (impl->protocolEntity.expandProcessCmds == 0) {
1924         *policy = JUMP_TO_FINISH_STATE;
1925     } else {
1926         *policy = JUMP_TO_NEXT_STATE;
1927     }
1928     return HC_SUCCESS;
1929 }
1930 
ProcExpandEvent(SessionImpl * impl,SessionEvent * inputEvent,CJson * sessionMsg,JumpPolicy * policy)1931 static int32_t ProcExpandEvent(SessionImpl *impl, SessionEvent *inputEvent, CJson *sessionMsg, JumpPolicy *policy)
1932 {
1933     bool isExpandFinsh = false;
1934     int32_t res = ProcExpandEventInner(impl, inputEvent, sessionMsg, &isExpandFinsh);
1935     if (res != HC_SUCCESS) {
1936         ReportRadarEvent(res);
1937         return RestartSession(impl, policy) == HC_SUCCESS ? HC_SUCCESS : res;
1938     }
1939     LOGI("process expand event success.");
1940     *policy = isExpandFinsh ? JUMP_TO_NEXT_STATE : STAY_STATE;
1941     return HC_SUCCESS;
1942 }
1943 
1944 static const SessionStateNode STATE_MACHINE[] = {
1945     { INIT_CLIENT_STATE, START_EVENT, ProcStartEvent, HAND_SHAKE_REQ_STATE },
1946     { INIT_SERVER_STATE, HAND_SHAKE_EVENT, ProcHandshakeReqEvent, HAND_SHAKE_RSP_STATE },
1947     { HAND_SHAKE_REQ_STATE, HAND_SHAKE_RSP_EVENT, ProcHandshakeRspEvent, AUTH_STATE },
1948     { HAND_SHAKE_RSP_STATE, AUTH_EVENT, ProcFirstAuthEvent, AUTH_STATE },
1949     { HAND_SHAKE_REQ_STATE, SESSION_FAIL_EVENT, ProcFailEvent, SESSION_FAIL_STATE },
1950     { HAND_SHAKE_RSP_STATE, SESSION_FAIL_EVENT, ProcFailEvent, SESSION_FAIL_STATE },
1951     { AUTH_STATE, AUTH_EVENT, ProcAuthEvent, EXPAND_STATE },
1952     { AUTH_STATE, SESSION_FAIL_EVENT, ProcFailEvent, SESSION_FAIL_STATE },
1953     { EXPAND_STATE, EXPAND_EVENT, ProcExpandEvent, SESSION_FINISH_STATE },
1954     { EXPAND_STATE, SESSION_FAIL_EVENT, ProcFailEvent, SESSION_FAIL_STATE },
1955 };
1956 
SessionSwitchState(SessionImpl * impl,SessionEvent * event,CJson * sessionMsg)1957 int32_t SessionSwitchState(SessionImpl *impl, SessionEvent *event, CJson *sessionMsg)
1958 {
1959     if (impl == NULL || event == NULL || sessionMsg == NULL) {
1960         LOGE("invalid params.");
1961         return HC_ERR_NULL_PTR;
1962     }
1963     for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
1964         if ((STATE_MACHINE[i].curState == impl->curState) && (STATE_MACHINE[i].eventType == event->type)) {
1965             JumpPolicy policy;
1966             int32_t preState = impl->curState;
1967             int32_t res = STATE_MACHINE[i].processFunc(impl, event, sessionMsg, &policy);
1968             if (res != HC_SUCCESS) {
1969                 LOGE("An error occurred. [Res]: %" LOG_PUB "d", res);
1970                 impl->curState = SESSION_FAIL_STATE;
1971                 return res;
1972             }
1973             if (policy == JUMP_TO_NEXT_STATE) {
1974                 impl->curState = STATE_MACHINE[i].nextState;
1975             } else if (policy == RESTART_STATE) {
1976                 impl->curState = impl->restartState;
1977             } else if (policy == JUMP_TO_FINISH_STATE) {
1978                 impl->curState = SESSION_FINISH_STATE;
1979             }
1980             LOGI("[Event]: %" LOG_PUB "d, [CurState]: %" LOG_PUB "d, [nextState]: %" LOG_PUB "d", event->type, preState,
1981                 impl->curState);
1982             return HC_SUCCESS;
1983         }
1984     }
1985     LOGI("Unsupported event type. Ignore process. [Event]: %" LOG_PUB "d, [CurState]: %" LOG_PUB "d", event->type,
1986         impl->curState);
1987     return HC_SUCCESS;
1988 }
1989 
1990 #ifndef  DEV_AUTH_FUNC_TEST
IsSupportSessionV2(void)1991 bool IsSupportSessionV2(void)
1992 {
1993     return true;
1994 }
1995 #endif
1996