• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 **)&paramsData);
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 }