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