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