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 *)¶ms,
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 *)¶ms,
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 *)¶ms,
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 *)¶ms,
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, ×, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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