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