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