1 /*
2 * Copyright (C) 2021-2022 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 "auth_session_common.h"
17 #include "account_related_group_auth.h"
18 #include "account_unrelated_group_auth.h"
19 #include "alg_defs.h"
20 #include "auth_session_util.h"
21 #include "common_defs.h"
22 #include "string_util.h"
23 #include "data_manager.h"
24 #include "dev_auth_module_manager.h"
25 #include "group_auth_data_operation.h"
26 #include "hc_dev_info.h"
27 #include "hc_log.h"
28 #include "json_utils.h"
29
30 #define MIN_PROTOCOL_VERSION "1.0.0"
31 IMPLEMENT_HC_VECTOR(ParamsVec, void *, 1)
32
IsGroupAvailable(int32_t osAccountId,const char * groupId,const char * pkgName)33 static bool IsGroupAvailable(int32_t osAccountId, const char *groupId, const char *pkgName)
34 {
35 if (GaIsGroupAccessible(osAccountId, groupId, pkgName)) {
36 return true;
37 }
38 LOGD("%s don't have enough right in group: %s, os account:%d!", pkgName, groupId, osAccountId);
39 return false;
40 }
41
AddGeneralParams(const char * groupId,int32_t groupType,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)42 static int32_t AddGeneralParams(const char *groupId, int32_t groupType, const TrustedDeviceEntry *localAuthInfo,
43 CJson *paramsData)
44 {
45 int32_t authForm = GroupTypeToAuthForm(groupType);
46 if (AddStringToJson(paramsData, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
47 LOGE("Failed to add groupId for client auth!");
48 return HC_ERR_JSON_FAIL;
49 }
50 if (AddIntToJson(paramsData, FIELD_AUTH_FORM, authForm) != HC_SUCCESS) {
51 LOGE("Failed to add authFrom for client auth!");
52 return HC_ERR_JSON_FAIL;
53 }
54 const char *serviceType = StringGet(&(localAuthInfo->serviceType));
55 if ((groupType == COMPATIBLE_GROUP) && (serviceType != NULL)) {
56 if (AddStringToJson(paramsData, FIELD_SERVICE_TYPE, serviceType) != HC_SUCCESS) {
57 LOGE("Failed to add serviceType for client compatible group auth!");
58 return HC_ERR_JSON_FAIL;
59 }
60 } else if (AddStringToJson(paramsData, FIELD_SERVICE_TYPE, groupId) != HC_SUCCESS) {
61 LOGE("Failed to add serviceType with groupId for client auth!");
62 return HC_ERR_JSON_FAIL;
63 }
64 return HC_SUCCESS;
65 }
66
ExtractAndAddParams(int32_t osAccountId,const char * groupId,const TrustedGroupEntry * groupInfo,CJson * paramsData)67 static int32_t ExtractAndAddParams(int32_t osAccountId, const char *groupId,
68 const TrustedGroupEntry *groupInfo, CJson *paramsData)
69 {
70 int32_t res;
71 TrustedDeviceEntry *localAuthInfo = CreateDeviceEntry();
72 if (localAuthInfo == NULL) {
73 LOGE("Failed to allocate memory for localAuthInfo!");
74 return HC_ERR_ALLOC_MEMORY;
75 }
76 int32_t groupType = groupInfo->type;
77 int32_t authForm = GroupTypeToAuthForm(groupType);
78 do {
79 res = GaGetLocalDeviceInfo(osAccountId, groupId, localAuthInfo);
80 if (res != HC_SUCCESS) {
81 break;
82 }
83 res = AddGeneralParams(groupId, groupType, localAuthInfo, paramsData);
84 if (res != HC_SUCCESS) {
85 LOGE("Failed to add general params!");
86 break;
87 }
88 BaseGroupAuth *groupAuth = GetGroupAuth(GetGroupAuthType(authForm));
89 if (groupAuth == NULL) {
90 LOGE("Failed to get group auth handle!");
91 break;
92 }
93 res = groupAuth->fillDeviceAuthInfo(osAccountId, groupInfo, localAuthInfo, paramsData);
94 if (res != HC_SUCCESS) {
95 LOGE("Failed to fill device auth info!");
96 break;
97 }
98 } while (0);
99 DestroyDeviceEntry(localAuthInfo);
100 return res;
101 }
102
FillAuthParams(int32_t osAccountId,const CJson * param,const GroupEntryVec * vec,ParamsVec * paramsVec)103 static int32_t FillAuthParams(int32_t osAccountId, const CJson *param,
104 const GroupEntryVec *vec, ParamsVec *paramsVec)
105 {
106 const char *peerUdid = GetStringFromJson(param, FIELD_PEER_CONN_DEVICE_ID);
107 const char *peerAuthId = GetStringFromJson(param, FIELD_PEER_ID_FROM_REQUEST);
108 if (peerAuthId == NULL) {
109 peerAuthId = GetStringFromJson(param, FIELD_PEER_AUTH_ID);
110 }
111 const char *pkgName = GetStringFromJson(param, FIELD_SERVICE_PKG_NAME);
112 if (pkgName == NULL) {
113 LOGE("Pkg name is null, can't extract params from db!");
114 return HC_ERR_NULL_PTR;
115 }
116 uint32_t index;
117 TrustedGroupEntry **ptr = NULL;
118 FOR_EACH_HC_VECTOR(*vec, index, ptr) {
119 if ((ptr == NULL) || (*ptr == NULL)) {
120 continue;
121 }
122 const TrustedGroupEntry *groupInfo = (TrustedGroupEntry *)(*ptr);
123 const char *groupId = StringGet(&(groupInfo->id));
124 if (groupId == NULL) {
125 continue;
126 }
127 if (!IsGroupAvailable(osAccountId, groupId, pkgName)) {
128 continue;
129 }
130 if (!GaIsDeviceInGroup(groupInfo->type, osAccountId, peerUdid, peerAuthId, groupId)) {
131 continue;
132 }
133 CJson *paramsData = DuplicateJson(param);
134 if (paramsData == NULL) {
135 LOGE("Failed to duplicate auth param data!");
136 return HC_ERR_JSON_FAIL;
137 }
138 int32_t res = ExtractAndAddParams(osAccountId, groupId, groupInfo, paramsData);
139 if (res != HC_SUCCESS) {
140 LOGE("Failed to extract and add param!");
141 FreeJson(paramsData);
142 continue;
143 }
144 paramsVec->pushBack(paramsVec, (const void **)¶msData);
145 }
146 return HC_SUCCESS;
147 }
148
GetCandidateGroupByOrder(int32_t osAccountId,const CJson * param,QueryGroupParams * queryParams,GroupEntryVec * vec)149 static void GetCandidateGroupByOrder(int32_t osAccountId, const CJson *param,
150 QueryGroupParams *queryParams, GroupEntryVec *vec)
151 {
152 BaseGroupAuth *groupAuth = GetGroupAuth(ACCOUNT_RELATED_GROUP_AUTH_TYPE);
153 if (groupAuth != NULL) {
154 AccountRelatedGroupAuth *realGroupAuth = (AccountRelatedGroupAuth *)groupAuth;
155 realGroupAuth->getAccountCandidateGroup(osAccountId, param, queryParams, vec);
156 }
157 queryParams->groupType = PEER_TO_PEER_GROUP;
158 if ((QueryGroups(osAccountId, queryParams, vec) != HC_SUCCESS) || (vec->size(vec) == 0)) {
159 LOGD("No peer to peer group in db.");
160 }
161 }
162
GetCandidateGroupInfo(int32_t osAccountId,const CJson * param,GroupEntryVec * vec)163 static void GetCandidateGroupInfo(int32_t osAccountId, const CJson *param, GroupEntryVec *vec)
164 {
165 LOGI("No input of groupId, extract group info without groupId.");
166 bool deviceLevelFlag = false;
167 bool isClient = true;
168 (void)GetBoolFromJson(param, FIELD_IS_DEVICE_LEVEL, &deviceLevelFlag);
169 if (GetBoolFromJson(param, FIELD_IS_CLIENT, &isClient) != HC_SUCCESS) {
170 LOGE("Failed to get the value: isClient!");
171 return;
172 }
173 QueryGroupParams queryParams = InitQueryGroupParams();
174 if (deviceLevelFlag && isClient) {
175 LOGI("Try to get device-level candidate groups for auth.");
176 } else {
177 queryParams.groupVisibility = GROUP_VISIBILITY_PUBLIC;
178 }
179 GetCandidateGroupByOrder(osAccountId, param, &queryParams, vec);
180 }
181
GetGroupInfoByGroupId(int32_t osAccountId,const char * groupId,GroupEntryVec * groupEntryVec)182 static void GetGroupInfoByGroupId(int32_t osAccountId, const char *groupId,
183 GroupEntryVec *groupEntryVec)
184 {
185 if (groupId == NULL) {
186 LOGE("GroupId is null!");
187 return;
188 }
189 QueryGroupParams queryParams = InitQueryGroupParams();
190 queryParams.groupId = groupId;
191 if (QueryGroups(osAccountId, &queryParams, groupEntryVec) != HC_SUCCESS) {
192 LOGE("Failed to query groups for groupId %s!", groupId);
193 return;
194 }
195 }
196
GetCandidateAuthInfo(int32_t osAccountId,const char * groupId,const CJson * param,ParamsVec * authParamsVec)197 static int32_t GetCandidateAuthInfo(int32_t osAccountId, const char *groupId,
198 const CJson *param, ParamsVec *authParamsVec)
199 {
200 GroupEntryVec vec = CreateGroupEntryVec();
201 if (groupId == NULL) {
202 GetCandidateGroupInfo(osAccountId, param, &vec);
203 } else {
204 GetGroupInfoByGroupId(osAccountId, groupId, &vec);
205 }
206 if (vec.size(&vec) == 0) {
207 LOGE("No satisfied candidate group!");
208 ClearGroupEntryVec(&vec);
209 return HC_ERR_NO_CANDIDATE_GROUP;
210 }
211 int32_t res = FillAuthParams(osAccountId, param, &vec, authParamsVec);
212 ClearGroupEntryVec(&vec);
213 return res;
214 }
215
AddGroupAuthTransmitData(const AuthSession * session,CJson * sendToPeer)216 static int32_t AddGroupAuthTransmitData(const AuthSession *session, CJson *sendToPeer)
217 {
218 ParamsVec list = session->paramsList;
219 CJson *authParam = list.get(&list, session->currentIndex);
220 if (authParam == NULL) {
221 LOGE("The json data in session is null!");
222 return HC_ERR_NULL_PTR;
223 }
224 bool isDeviceLevel = false;
225 /* Disable device-level auth. */
226 if (AddBoolToJson(sendToPeer, FIELD_IS_DEVICE_LEVEL, isDeviceLevel) != HC_SUCCESS) {
227 LOGE("Failed to add device level!");
228 return HC_ERR_JSON_FAIL;
229 }
230 bool isClient = true;
231 if (GetBoolFromJson(authParam, FIELD_IS_CLIENT, &isClient)) {
232 LOGE("Failed to get isClient!");
233 return HC_ERR_JSON_GET;
234 }
235 if (isClient && (session->currentIndex < (list.size(&list) - 1))) {
236 CJson *nextParam = list.get(&list, session->currentIndex + 1);
237 if (nextParam == NULL) {
238 LOGE("Failed to get next auth params!");
239 return HC_ERR_JSON_FAIL;
240 }
241 const char *altGroup = GetStringFromJson(nextParam, FIELD_SERVICE_TYPE);
242 if ((altGroup != NULL) && (AddStringToJson(sendToPeer, FIELD_ALTERNATIVE, altGroup) != HC_SUCCESS)) {
243 LOGE("Failed to add alternative group!");
244 return HC_ERR_JSON_FAIL;
245 }
246 }
247 return HC_SUCCESS;
248 }
249
ReturnTransmitData(const AuthSession * session,CJson * out)250 static int32_t ReturnTransmitData(const AuthSession *session, CJson *out)
251 {
252 CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
253 if (sendToPeer == NULL) {
254 LOGI("The transmit data to peer is null!");
255 return HC_ERR_JSON_GET;
256 }
257 CJson *authParam = (session->paramsList).get(&(session->paramsList), session->currentIndex);
258 if (authParam == NULL) {
259 LOGE("The json data in session is null!");
260 return HC_ERR_NULL_PTR;
261 }
262 int64_t requestId = 0;
263 if (GetByteFromJson(authParam, FIELD_REQUEST_ID, (uint8_t *)&requestId, sizeof(int64_t)) != HC_SUCCESS) {
264 LOGE("Failed to get request id!");
265 return HC_ERR_JSON_GET;
266 }
267
268 int32_t ret = AddGroupAuthTransmitData(session, sendToPeer);
269 if (ret != HC_SUCCESS) {
270 LOGE("Failed to add extra data!");
271 return ret;
272 }
273 char *outStr = PackJsonToString(sendToPeer);
274 if (outStr == NULL) {
275 LOGE("Failed to pack outStr for onTransmit!");
276 return HC_ERR_ALLOC_MEMORY;
277 }
278
279 const DeviceAuthCallback *callback = session->base.callback;
280 do {
281 if ((callback == NULL) || (callback->onTransmit == NULL)) {
282 LOGE("The callback for transmit is null!");
283 ret = HC_ERR_TRANSMIT_FAIL;
284 break;
285 }
286 LOGI("Start to transmit data to peer for auth!");
287 if (!callback->onTransmit(requestId, (uint8_t *)outStr, HcStrlen(outStr) + 1)) {
288 LOGE("Failed to transmit data to peer!");
289 ret = HC_ERR_TRANSMIT_FAIL;
290 }
291 LOGI("End transmit data to peer for auth!");
292 } while (0);
293 FreeJsonString(outStr);
294 return ret;
295 }
296
GetAuthParamsList(int32_t osAccountId,const CJson * param,ParamsVec * authParamsVec)297 int32_t GetAuthParamsList(int32_t osAccountId, const CJson *param, ParamsVec *authParamsVec)
298 {
299 const char *groupId = GetStringFromJson(param, FIELD_GROUP_ID);
300 if (groupId == NULL) {
301 groupId = GetStringFromJson(param, FIELD_SERVICE_TYPE);
302 }
303 return GetCandidateAuthInfo(osAccountId, groupId, param, authParamsVec);
304 }
305
ReturnFinishData(const AuthSession * session,const CJson * out)306 static void ReturnFinishData(const AuthSession *session, const CJson *out)
307 {
308 ParamsVec list = session->paramsList;
309 const CJson *authParam = list.get(&list, session->currentIndex);
310 if (authParam == NULL) {
311 LOGE("The json data in session is null!");
312 return;
313 }
314 int64_t requestId = 0;
315 if (GetByteFromJson(authParam, FIELD_REQUEST_ID, (uint8_t *)&requestId, sizeof(int64_t)) != HC_SUCCESS) {
316 LOGE("Failed to get request id!");
317 return;
318 }
319 int32_t authForm = AUTH_FORM_INVALID_TYPE;
320 if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
321 LOGE("Failed to get auth type!");
322 return;
323 }
324 BaseGroupAuth *groupAuth = GetGroupAuth(GetGroupAuthType(authForm));
325 if (groupAuth != NULL) {
326 groupAuth->onFinish(requestId, authParam, out, session->base.callback);
327 }
328 }
329
ReturnErrorToLocalBySession(const AuthSession * session,int errorCode)330 static void ReturnErrorToLocalBySession(const AuthSession *session, int errorCode)
331 {
332 ParamsVec list = session->paramsList;
333 CJson *authParam = list.get(&list, session->currentIndex);
334 int64_t requestId = 0;
335 int32_t authForm = AUTH_FORM_INVALID_TYPE;
336 if (authParam == NULL) {
337 LOGE("The json data in session is null!");
338 return;
339 }
340 if (GetByteFromJson(authParam, FIELD_REQUEST_ID, (uint8_t *)&requestId, sizeof(int64_t)) != HC_SUCCESS) {
341 LOGE("Failed to get request id!");
342 return;
343 }
344 if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
345 LOGD("Failed to get auth form, user default authForm!");
346 }
347
348 BaseGroupAuth *groupAuth = GetGroupAuth(GetGroupAuthType(authForm));
349 if (groupAuth != NULL) {
350 LOGE("Invoke ReturnErrorToLocalBySession for authForm:%d!", authForm);
351 groupAuth->onError(requestId, session, errorCode);
352 } else if ((session->base.callback != NULL) && (session->base.callback->onError != NULL)) {
353 LOGE("Invoke onError to local device.");
354 session->base.callback->onError(requestId, authForm, errorCode, NULL);
355 }
356 }
357
AddVersionMsgToPeer(CJson * errorToPeer)358 static int32_t AddVersionMsgToPeer(CJson *errorToPeer)
359 {
360 CJson *version = CreateJson();
361 if (version == NULL) {
362 LOGE("Failed to create json for version!");
363 return HC_ERR_JSON_CREATE;
364 }
365 CJson *payload = CreateJson();
366 if (payload == NULL) {
367 LOGE("Failed to create json for payload!");
368 FreeJson(version);
369 return HC_ERR_JSON_CREATE;
370 }
371 int32_t res = HC_SUCCESS;
372 do {
373 if (AddStringToJson(version, FIELD_MIN_VERSION, MIN_PROTOCOL_VERSION) != HC_SUCCESS) {
374 LOGE("Failed to add min version to json!");
375 res = HC_ERR_JSON_ADD;
376 break;
377 }
378 if (AddStringToJson(version, FIELD_CURRENT_VERSION, MIN_PROTOCOL_VERSION) != HC_SUCCESS) {
379 LOGE("Failed to add max version to json!");
380 res = HC_ERR_JSON_ADD;
381 break;
382 }
383 if (AddObjToJson(payload, FIELD_VERSION, version) != HC_SUCCESS) {
384 LOGE("Add version object to errorToPeer failed.");
385 res = HC_ERR_JSON_ADD;
386 break;
387 }
388 if (AddIntToJson(payload, FIELD_ERROR_CODE, -1) != HC_SUCCESS) {
389 LOGE("Failed to add errorCode for peer!");
390 res = HC_ERR_JSON_ADD;
391 break;
392 }
393 if (AddObjToJson(errorToPeer, FIELD_PAYLOAD, payload) != HC_SUCCESS) {
394 res = HC_ERR_JSON_ADD;
395 break;
396 }
397 } while (0);
398 FreeJson(version);
399 FreeJson(payload);
400 return res;
401 }
402
PrepareErrorMsgToPeer(CJson * errorToPeer)403 static int32_t PrepareErrorMsgToPeer(CJson *errorToPeer)
404 {
405 if (AddIntToJson(errorToPeer, FIELD_GROUP_ERROR_MSG, GROUP_ERR_MSG) != HC_SUCCESS) {
406 LOGE("Failed to add groupErrorMsg for peer!");
407 return HC_ERR_JSON_FAIL;
408 }
409 if (AddIntToJson(errorToPeer, FIELD_MESSAGE, GROUP_ERR_MSG) != HC_SUCCESS) {
410 LOGE("Failed to add message for peer!");
411 return HC_ERR_JSON_FAIL;
412 }
413 return AddVersionMsgToPeer(errorToPeer);
414 }
415
ReturnErrorToPeerBySession(const CJson * authParam,const DeviceAuthCallback * callback)416 static int32_t ReturnErrorToPeerBySession(const CJson *authParam, const DeviceAuthCallback *callback)
417 {
418 int64_t requestId = 0;
419 if (GetByteFromJson(authParam, FIELD_REQUEST_ID, (uint8_t *)&requestId, sizeof(int64_t)) != HC_SUCCESS) {
420 LOGE("Failed to get request ID!");
421 return HC_ERR_JSON_GET;
422 }
423 CJson *errorToPeer = CreateJson();
424 if (errorToPeer == NULL) {
425 LOGE("Failed to allocate memory for errorToPeer!");
426 return HC_ERR_ALLOC_MEMORY;
427 }
428 int32_t res = PrepareErrorMsgToPeer(errorToPeer);
429 if (res != HC_SUCCESS) {
430 FreeJson(errorToPeer);
431 return res;
432 }
433 char *errorToPeerStr = PackJsonToString(errorToPeer);
434 FreeJson(errorToPeer);
435 if (errorToPeerStr == NULL) {
436 LOGE("Failed to pack errorToPeer to string!");
437 return HC_ERR_ALLOC_MEMORY;
438 }
439
440 do {
441 if ((callback == NULL) || (callback->onTransmit == NULL)) {
442 LOGE("The callback of onTransmit is null!");
443 res = HC_ERR_NULL_PTR;
444 break;
445 }
446 LOGD("Begin transmit error msg to peer by session!");
447 if (!callback->onTransmit(requestId, (uint8_t *)errorToPeerStr, HcStrlen(errorToPeerStr) + 1)) {
448 LOGE("Failed to invoke onTransmit by session!");
449 res = HC_ERR_TRANSMIT_FAIL;
450 break;
451 }
452 LOGD("End transmit error msg to peer by session!");
453 } while (0);
454 FreeJsonString(errorToPeerStr);
455 return res;
456 }
457
ReturnErrorToPeerByTask(const CJson * sendToPeer,const CJson * authParam,const DeviceAuthCallback * callback)458 static int32_t ReturnErrorToPeerByTask(const CJson *sendToPeer, const CJson *authParam,
459 const DeviceAuthCallback *callback)
460 {
461 int64_t requestId = 0;
462 if (GetByteFromJson(authParam, FIELD_REQUEST_ID, (uint8_t *)&requestId, sizeof(int64_t)) != HC_SUCCESS) {
463 LOGE("Failed to get request id!");
464 return HC_ERR_JSON_FAIL;
465 }
466 char *sendToPeerStr = PackJsonToString(sendToPeer);
467 if (sendToPeerStr == NULL) {
468 LOGE("Failed to pack json to string!");
469 return HC_ERR_ALLOC_MEMORY;
470 }
471
472 int32_t res = HC_SUCCESS;
473 do {
474 if ((callback == NULL) || (callback->onTransmit == NULL)) {
475 LOGE("The callback of onTransmit is null!");
476 res = HC_ERR_NULL_PTR;
477 break;
478 }
479 LOGD("Begin transmit error msg to peer by task!");
480 if (!callback->onTransmit(requestId, (uint8_t *)sendToPeerStr, HcStrlen(sendToPeerStr) + 1)) {
481 LOGE("Failed to invoke onTransmit by task!");
482 res = HC_ERR_TRANSMIT_FAIL;
483 break;
484 }
485 LOGD("End transmit error msg to peer by task!");
486 } while (0);
487 FreeJsonString(sendToPeerStr);
488 return res;
489 }
490
HasAlternativeAuthGroup(const AuthSession * session)491 bool HasAlternativeAuthGroup(const AuthSession *session)
492 {
493 if (session->currentIndex >= session->paramsList.size(&session->paramsList) - 1) {
494 return false;
495 }
496 return true;
497 }
498
ProcessNextGroupIfPossible(AuthSession * session)499 static int32_t ProcessNextGroupIfPossible(AuthSession *session)
500 {
501 if (!HasAlternativeAuthGroup(session)) {
502 LOGD("There is no alternative auth group.");
503 return HC_ERR_NO_CANDIDATE_GROUP;
504 }
505 int32_t res;
506 session->currentIndex++;
507 CJson *paramInNextSession = (session->paramsList).get(&(session->paramsList), session->currentIndex);
508 if (paramInNextSession == NULL) {
509 LOGE("The json data in session is null!");
510 return HC_ERR_NULL_PTR;
511 }
512 CJson *outNext = CreateJson();
513 if (outNext == NULL) {
514 LOGE("Failed to create json for outNext!");
515 return HC_ERR_ALLOC_MEMORY;
516 }
517 do {
518 int32_t status = 0;
519 res = CreateAndProcessTask(session, paramInNextSession, outNext, &status);
520 if (res != HC_SUCCESS) {
521 break;
522 }
523 res = ProcessTaskStatusForAuth(session, paramInNextSession, outNext, status);
524 } while (0);
525 if (res != HC_SUCCESS) {
526 DestroyTask(session->curTaskId, GetAuthModuleType(paramInNextSession));
527 res = InformAuthError(session, outNext, res);
528 }
529 FreeJson(outNext);
530 return res;
531 }
532
ReturnSessionKey(int64_t requestId,const CJson * authParam,const CJson * out,const DeviceAuthCallback * callback)533 int32_t ReturnSessionKey(int64_t requestId, const CJson *authParam,
534 const CJson *out, const DeviceAuthCallback *callback)
535 {
536 int32_t keyLen = DEFAULT_RETURN_KEY_LENGTH;
537 (void)GetIntFromJson(authParam, FIELD_KEY_LENGTH, &keyLen);
538 uint8_t *sessionKey = (uint8_t *)HcMalloc(keyLen, 0);
539 if (sessionKey == NULL) {
540 LOGE("Failed to allocate memory for sessionKey!");
541 return HC_ERR_ALLOC_MEMORY;
542 }
543
544 int32_t res = HC_SUCCESS;
545 do {
546 if (GetByteFromJson(out, FIELD_SESSION_KEY, sessionKey, keyLen) != HC_SUCCESS) {
547 LOGE("Failed to get sessionKey!");
548 res = HC_ERR_JSON_GET;
549 break;
550 }
551 if ((callback == NULL) || (callback->onSessionKeyReturned == NULL)) {
552 LOGE("The callback of onSessionKeyReturned is null!");
553 res = HC_ERR_INVALID_PARAMS;
554 break;
555 }
556 LOGI("Begin invoke onSessionKeyReturned.");
557 callback->onSessionKeyReturned(requestId, sessionKey, keyLen);
558 LOGI("End invoke onSessionKeyReturned, res = %d.", res);
559 } while (0);
560 (void)memset_s(sessionKey, keyLen, 0, keyLen);
561 HcFree(sessionKey);
562 sessionKey = NULL;
563 return res;
564 }
565
DeleteCachedData(CJson * paramInSession)566 void DeleteCachedData(CJson *paramInSession)
567 {
568 DeleteItemFromJson(paramInSession, FIELD_PAYLOAD);
569 DeleteItemFromJson(paramInSession, FIELD_SELF_AUTH_ID);
570 DeleteItemFromJson(paramInSession, FIELD_OPERATION_CODE);
571 }
572
GetGroupAuthType(int32_t authForm)573 int32_t GetGroupAuthType(int32_t authForm)
574 {
575 switch (authForm) {
576 case AUTH_FORM_ACCOUNT_UNRELATED:
577 return ACCOUNT_UNRELATED_GROUP_AUTH_TYPE;
578 case AUTH_FORM_IDENTICAL_ACCOUNT:
579 return ACCOUNT_RELATED_GROUP_AUTH_TYPE;
580 case AUTH_FORM_ACROSS_ACCOUNT:
581 return ACCOUNT_RELATED_GROUP_AUTH_TYPE;
582 default:
583 LOGE("Invalid authForm!");
584 return INVALID_GROUP_AUTH_TYPE;
585 }
586 }
587
InformAuthError(AuthSession * session,const CJson * out,int errorCode)588 int32_t InformAuthError(AuthSession *session, const CJson *out, int errorCode)
589 {
590 ParamsVec list = session->paramsList;
591 CJson *paramInSession = list.get(&list, session->currentIndex);
592 if (paramInSession == NULL) {
593 LOGE("The json data in session is null!");
594 return HC_ERR_NULL_PTR;
595 }
596 if (out == NULL) {
597 (void)ReturnErrorToPeerBySession(paramInSession, session->base.callback);
598 LOGI("Out data is null, so assemble error msg to peer by auth session.");
599 return HC_ERR_INFORM_ERR;
600 }
601 const CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
602 if (sendToPeer != NULL) {
603 if (ReturnErrorToPeerByTask(sendToPeer, paramInSession, session->base.callback) != HC_SUCCESS) {
604 LOGE("Failed to return task's error msg to peer!");
605 return HC_ERR_INFORM_ERR;
606 }
607 }
608
609 if (ProcessNextGroupIfPossible(session) == HC_SUCCESS) {
610 LOGI("Start to process next candidate group.");
611 return HC_SUCCESS;
612 }
613
614 const char *altGroup = GetStringFromJson(paramInSession, FIELD_ALTERNATIVE);
615 if (altGroup == NULL) {
616 ReturnErrorToLocalBySession(session, errorCode);
617 }
618 return HC_ERR_INFORM_ERR;
619 }
620
ProcessDeviceLevel(const CJson * receiveData,CJson * authParam)621 void ProcessDeviceLevel(const CJson *receiveData, CJson *authParam)
622 {
623 bool receiveLevel = false;
624 bool authLevel = false;
625 (void)GetBoolFromJson(receiveData, FIELD_IS_DEVICE_LEVEL, &receiveLevel);
626 (void)GetBoolFromJson(authParam, FIELD_IS_DEVICE_LEVEL, &authLevel);
627 authLevel = receiveLevel && authLevel;
628 if (AddBoolToJson(authParam, FIELD_IS_DEVICE_LEVEL, authLevel) != HC_SUCCESS) {
629 LOGE("Failed to add device level to auth param!");
630 return;
631 }
632 }
633
ProcessTaskStatusForAuth(const AuthSession * session,const CJson * param,CJson * out,int32_t status)634 int32_t ProcessTaskStatusForAuth(const AuthSession *session, const CJson *param, CJson *out, int32_t status)
635 {
636 int32_t res = HC_SUCCESS;
637 switch (status) {
638 case IGNORE_MSG:
639 LOGD("Ignore this msg.");
640 break;
641 case CONTINUE:
642 res = ReturnTransmitData(session, out);
643 if (res != HC_SUCCESS) {
644 LOGE("Failed to transmit data to peer!");
645 InformLocalAuthError(param, session->base.callback);
646 }
647 break;
648 case FINISH:
649 ReturnFinishData(session, out);
650 ClearSensitiveStringInJson(out, FIELD_SESSION_KEY);
651 res = FINISH;
652 break;
653 default:
654 LOGE("Invalid status after process task!");
655 res = HC_ERR_INVALID_PARAMS;
656 break;
657 }
658 return res;
659 }
660
CreateAndProcessTask(AuthSession * session,CJson * paramInSession,CJson * out,int32_t * status)661 int32_t CreateAndProcessTask(AuthSession *session, CJson *paramInSession, CJson *out, int32_t *status)
662 {
663 int32_t moduleType = GetAuthModuleType(paramInSession);
664 if (moduleType == DAS_MODULE) {
665 const char *pkgName = GetStringFromJson(paramInSession, FIELD_SERVICE_PKG_NAME);
666 if (pkgName == NULL) {
667 LOGE("Pkg name is null!");
668 return HC_ERR_NULL_PTR;
669 }
670 if (AddStringToJson(paramInSession, FIELD_PKG_NAME, pkgName) != HC_SUCCESS) {
671 LOGE("Failed to add pkg name to json!");
672 return HC_ERR_JSON_FAIL;
673 }
674 }
675 session->curTaskId = 0;
676 int32_t res = CreateTask(&(session->curTaskId), paramInSession, out, moduleType);
677 if (res != HC_SUCCESS) {
678 LOGE("Failed to create task for auth!");
679 return res;
680 }
681 res = ProcessTask(session->curTaskId, paramInSession, out, status, moduleType);
682 DeleteCachedData(paramInSession);
683 if (res != HC_SUCCESS) {
684 DestroyTask(session->curTaskId, GetAuthModuleType(paramInSession));
685 LOGE("Failed to process task for auth!");
686 return res;
687 }
688 return HC_SUCCESS;
689 }
690
InformLocalAuthError(const CJson * authParam,const DeviceAuthCallback * callback)691 void InformLocalAuthError(const CJson *authParam, const DeviceAuthCallback *callback)
692 {
693 bool isClient = false;
694 (void)GetBoolFromJson(authParam, FIELD_IS_CLIENT, &isClient);
695 const char *altGroup = GetStringFromJson(authParam, FIELD_ALTERNATIVE);
696 if (!isClient && (altGroup != NULL)) { /* Server wait for next group auth. */
697 LOGI("Server wait for next group auth.");
698 return;
699 }
700 int64_t requestId = 0;
701 if (GetByteFromJson(authParam, FIELD_REQUEST_ID, (uint8_t *)&requestId, sizeof(int64_t)) != HC_SUCCESS) {
702 LOGE("Failed to get request id!");
703 return;
704 }
705 if ((callback != NULL) && (callback->onError != NULL)) {
706 LOGE("Invoke InformLocalAuthError!");
707 callback->onError(requestId, AUTH_FORM_INVALID_TYPE, HC_ERR_CREATE_SESSION_FAIL, NULL);
708 }
709 }
710
InformPeerAuthError(const CJson * authParam,const DeviceAuthCallback * callback)711 void InformPeerAuthError(const CJson *authParam, const DeviceAuthCallback *callback)
712 {
713 if (ReturnErrorToPeerBySession(authParam, callback) != HC_SUCCESS) {
714 LOGE("Failed to return error to peer by session!");
715 }
716 }
717
DestroyAuthSession(Session * session)718 void DestroyAuthSession(Session *session)
719 {
720 if (session == NULL) {
721 return;
722 }
723 AuthSession *realSession = (AuthSession *)session;
724 HcFree(realSession->base.appId);
725 realSession->base.appId = NULL;
726 CJson *paramInSession = (realSession->paramsList).get(&(realSession->paramsList), realSession->currentIndex);
727 if (paramInSession == NULL) {
728 LOGE("The json data in session is null!");
729 return;
730 }
731 DestroyTask(realSession->curTaskId, GetAuthModuleType(paramInSession));
732
733 uint32_t index;
734 void **paramsData = NULL;
735 FOR_EACH_HC_VECTOR(realSession->paramsList, index, paramsData) {
736 if (paramsData != NULL) {
737 FreeJson((CJson *)*paramsData);
738 }
739 }
740 DESTROY_HC_VECTOR(ParamsVec, &(realSession->paramsList));
741 HcFree(realSession);
742 realSession = NULL;
743 }
744
CreateAuthParamsVec(ParamsVec * vec)745 void CreateAuthParamsVec(ParamsVec *vec)
746 {
747 *vec = CREATE_HC_VECTOR(ParamsVec);
748 }
749
DestroyAuthParamsVec(ParamsVec * vec)750 void DestroyAuthParamsVec(ParamsVec *vec)
751 {
752 DESTROY_HC_VECTOR(ParamsVec, vec);
753 }
754