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