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