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