• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 "account_related_group_auth.h"
17 #include "auth_session_common.h"
18 #include "auth_session_common_util.h"
19 #include "auth_session_util.h"
20 #include "common_defs.h"
21 #include "device_auth_defines.h"
22 #include "group_auth_data_operation.h"
23 #include "hc_dev_info.h"
24 #include "hc_log.h"
25 #include "hc_types.h"
26 #include "json_utils.h"
27 #include "string_util.h"
28 
29 static void OnAccountFinish(int64_t requestId, const CJson *authParam, const CJson *out,
30     const DeviceAuthCallback *callback);
31 static void OnAccountError(int64_t requestId, const AuthSession *session, int errorCode);
32 static int32_t FillAccountAuthInfo(int32_t osAccountId, const TrustedGroupEntry *entry,
33     const TrustedDeviceEntry *localAuthInfo, CJson *paramsData);
34 static void GetAccountCandidateGroup(int32_t osAccountId, const CJson *param,
35     QueryGroupParams *queryParams, GroupEntryVec *vec);
36 static int32_t GetAccountAuthParamForServer(const CJson *dataFromClient, ParamsVec *authParamsVec);
37 static int32_t GetAccountReqParams(const CJson *receiveData, CJson *reqParam);
38 static int32_t CombineAccountServerConfirms(const CJson *confirmationJson, CJson *dataFromClient);
39 
40 static AccountRelatedGroupAuth g_accountRelatedGroupAuth = {
41     .base.onFinish = OnAccountFinish,
42     .base.onError = OnAccountError,
43     .base.fillDeviceAuthInfo = FillAccountAuthInfo,
44     .base.getAuthParamForServer = GetAccountAuthParamForServer,
45     .base.getReqParams = GetAccountReqParams,
46     .base.combineServerConfirmParams = CombineAccountServerConfirms,
47     .base.authType = ACCOUNT_RELATED_GROUP_AUTH_TYPE,
48     .getAccountCandidateGroup = GetAccountCandidateGroup,
49 };
50 
GetSessionKeyForAccount(const CJson * sendToSelf,CJson * returnToSelf)51 static int32_t GetSessionKeyForAccount(const CJson *sendToSelf, CJson *returnToSelf)
52 {
53     int32_t keyLen = DEFAULT_RETURN_KEY_LENGTH;
54     uint8_t *sessionKey = (uint8_t *)HcMalloc(keyLen, 0);
55     if (sessionKey == NULL) {
56         LOGE("Failed to allocate memory for sessionKey!");
57         return HC_ERR_ALLOC_MEMORY;
58     }
59     int32_t res = HC_SUCCESS;
60     do {
61         if (GetByteFromJson(sendToSelf, FIELD_SESSION_KEY, sessionKey, keyLen) != HC_SUCCESS) {
62             LOGE("Failed to get sessionKey!");
63             res = HC_ERR_JSON_GET;
64             break;
65         }
66         if (AddByteToJson(returnToSelf, FIELD_SESSION_KEY, (const uint8_t *)sessionKey, keyLen) != HC_SUCCESS) {
67             LOGE("Failed to add sessionKey for onFinish!");
68             res = HC_ERR_JSON_FAIL;
69             break;
70         }
71     } while (0);
72     (void)memset_s(sessionKey, keyLen, 0, keyLen);
73     HcFree(sessionKey);
74     sessionKey = NULL;
75     return res;
76 }
77 
GetUserIdForAccount(const CJson * sendToSelf,CJson * returnToSelf)78 static int32_t GetUserIdForAccount(const CJson *sendToSelf, CJson *returnToSelf)
79 {
80     const char *peerUserId = GetStringFromJson(sendToSelf, FIELD_USER_ID);
81     if (peerUserId == NULL) {
82         LOGE("Failed to get peer uid!");
83         return HC_ERR_JSON_GET;
84     }
85     if (AddStringToJson(returnToSelf, FIELD_USER_ID, peerUserId) != HC_SUCCESS) {
86         LOGE("Failed to add peer uid!");
87         return HC_ERR_JSON_FAIL;
88     }
89     return HC_SUCCESS;
90 }
91 
IsPeerInAccountRelatedGroup(const TrustedGroupEntry * groupEntry,const char * peerUserId,GroupType type)92 static bool IsPeerInAccountRelatedGroup(const TrustedGroupEntry *groupEntry, const char *peerUserId, GroupType type)
93 {
94     const char *userIdInDb =
95         ((type == IDENTICAL_ACCOUNT_GROUP) ? StringGet(&(groupEntry->userId)) : StringGet(&(groupEntry->sharedUserId)));
96     if (userIdInDb == NULL) {
97         LOGD("Failed to get peer userId from db!");
98         return false;
99     }
100     if (IsUserIdEqual(userIdInDb, peerUserId)) {
101         LOGI("[Account auth]: the input peer-userId is in one across group, add across-group auth!");
102         return true;
103     }
104     return false;
105 }
106 
IsPeerInIdenticalGroup(int32_t osAccountId,const char * peerUserId)107 static bool IsPeerInIdenticalGroup(int32_t osAccountId, const char *peerUserId)
108 {
109     bool isGroupExist = false;
110     GroupEntryVec accountVec = CreateGroupEntryVec();
111     QueryGroupParams queryParams = InitQueryGroupParams();
112     queryParams.groupType = IDENTICAL_ACCOUNT_GROUP;
113     do {
114         if (QueryGroups(osAccountId, &queryParams, &accountVec) != HC_SUCCESS) {
115             LOGD("No identical-account group in db, no identical-account auth!");
116             break;
117         }
118         uint32_t index = 0;
119         TrustedGroupEntry **ptr = NULL;
120         while (index < accountVec.size(&accountVec)) {
121             ptr = accountVec.getp(&accountVec, index);
122             if ((ptr == NULL) || (*ptr == NULL)) {
123                 index++;
124                 continue;
125             }
126             if (IsPeerInAccountRelatedGroup(*ptr, peerUserId, IDENTICAL_ACCOUNT_GROUP)) {
127                 isGroupExist = true;
128                 break;
129             }
130             index++;
131         }
132     } while (0);
133     ClearGroupEntryVec(&accountVec);
134     return isGroupExist;
135 }
136 
GaGetAccountGroup(int32_t osAccountId,GroupType type,const char * peerUserId,QueryGroupParams * queryParams,GroupEntryVec * vec)137 static void GaGetAccountGroup(int32_t osAccountId, GroupType type, const char *peerUserId,
138     QueryGroupParams *queryParams, GroupEntryVec *vec)
139 {
140     LOGI("Try to get account group info, groupType: %d.", type);
141     queryParams->groupType = type;
142     if (QueryGroups(osAccountId, queryParams, vec) != HC_SUCCESS) {
143         LOGD("Database don't have local device's across-account group info!");
144         return;
145     }
146 
147     uint32_t index = 0;
148     TrustedGroupEntry **ptr = NULL;
149     while (index < vec->size(vec)) {
150         ptr = vec->getp(vec, index);
151         if ((ptr == NULL) || (*ptr == NULL)) {
152             index++;
153             continue;
154         }
155         if ((peerUserId == NULL) || IsPeerInAccountRelatedGroup(*ptr, peerUserId, type)) {
156             index++;
157             continue;
158         }
159         TrustedGroupEntry *tempEntry = NULL;
160         HC_VECTOR_POPELEMENT(vec, &tempEntry, index);
161         DestroyGroupEntry((TrustedGroupEntry *)tempEntry);
162     }
163     LOGI("The candidate account group size is:%d.", vec->size(vec));
164 }
165 
GetAccountCandidateGroup(int32_t osAccountId,const CJson * param,QueryGroupParams * queryParams,GroupEntryVec * vec)166 static void GetAccountCandidateGroup(int32_t osAccountId, const CJson *param,
167     QueryGroupParams *queryParams, GroupEntryVec *vec)
168 {
169     /* Compare userId with local uid in DB. */
170     bool identicalFlag = false;
171     bool acrossAccountFlag = false;
172     const char *peerUserId = GetStringFromJson(param, FIELD_USER_ID);
173     if (peerUserId != NULL) {
174         acrossAccountFlag = true;
175         identicalFlag = IsPeerInIdenticalGroup(osAccountId, peerUserId);
176     } else {
177         LOGD("userId is null in authParam.");
178         identicalFlag = true;
179     }
180 
181     if (identicalFlag) {
182         GaGetAccountGroup(osAccountId, IDENTICAL_ACCOUNT_GROUP, peerUserId, queryParams, vec);
183     } else if (acrossAccountFlag) {
184         GaGetAccountGroup(osAccountId, ACROSS_ACCOUNT_AUTHORIZE_GROUP, peerUserId, queryParams, vec);
185     }
186 }
187 
FillAccountCredentialInfo(int32_t osAccountId,const char * peerUdid,const char * groupId,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)188 static int32_t FillAccountCredentialInfo(int32_t osAccountId, const char *peerUdid, const char *groupId,
189     const TrustedDeviceEntry *localAuthInfo, CJson *paramsData)
190 {
191     TrustedDeviceEntry *peerDevInfo = CreateDeviceEntry();
192     if (peerDevInfo == NULL) {
193         LOGE("Failed to alloc memory for peerDevInfo!");
194         return HC_ERR_ALLOC_MEMORY;
195     }
196     int32_t localDevType = DEVICE_TYPE_CONTROLLER;
197     int32_t authCredential = localAuthInfo->credential;
198     int32_t res = GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, peerDevInfo);
199     if ((res != HC_SUCCESS) || (peerDevInfo->source == SELF_CREATED)) {
200         LOGI("Peer device's query result = %d, pass local device info to account authenticator.", res);
201         localDevType = DEVICE_TYPE_ACCESSORY; /* Controller has peer device info, which is added by caller. */
202     }
203     if ((res == HC_SUCCESS) && (peerDevInfo->credential == SYMMETRIC_CRED) &&
204         (peerDevInfo->source == IMPORTED_FROM_CLOUD)) {
205         LOGI("Peer trusted device is imported by cloud, invoke sym account auth.");
206         authCredential = SYMMETRIC_CRED;
207     }
208     DestroyDeviceEntry(peerDevInfo);
209     if (AddIntToJson(paramsData, FIELD_LOCAL_DEVICE_TYPE, localDevType) != HC_SUCCESS) {
210         LOGE("Failed to add self device type to json!");
211         return HC_ERR_JSON_ADD;
212     }
213     if (AddIntToJson(paramsData, FIELD_CREDENTIAL_TYPE, authCredential) != HC_SUCCESS) {
214         LOGE("Failed to add self credential type to json!");
215         return HC_ERR_JSON_ADD;
216     }
217     return HC_SUCCESS;
218 }
219 
FillAccountAuthInfo(int32_t osAccountId,const TrustedGroupEntry * entry,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)220 static int32_t FillAccountAuthInfo(int32_t osAccountId, const TrustedGroupEntry *entry,
221     const TrustedDeviceEntry *localAuthInfo, CJson *paramsData)
222 {
223     const char *peerUdid = GetStringFromJson(paramsData, FIELD_PEER_CONN_DEVICE_ID);
224     if (peerUdid == NULL) {
225         LOGE("Failed to get peer udid in the input data for account auth!");
226         return HC_ERR_INVALID_PARAMS;
227     }
228     const char *selfUserId = StringGet(&entry->userId);
229     const char *groupId = StringGet(&entry->id);
230     const char *selfDeviceId = StringGet(&(localAuthInfo->udid));
231     const char *selfDevId = StringGet(&(localAuthInfo->authId));
232     if ((selfUserId == NULL) || (groupId == NULL) || (selfDeviceId == NULL) || (selfDevId == NULL)) {
233         LOGE("Failed to get self account info for client in account-related auth!");
234         return HC_ERR_JSON_GET;
235     }
236     if (AddStringToJson(paramsData, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
237         LOGE("Failed to add self userId for client in account-related auth!");
238         return HC_ERR_JSON_FAIL;
239     }
240     if (AddStringToJson(paramsData, FIELD_SELF_DEVICE_ID, selfDeviceId) != HC_SUCCESS) {
241         LOGE("Failed to add self deviceId for client in account-related auth!");
242         return HC_ERR_JSON_FAIL;
243     }
244     if (AddStringToJson(paramsData, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
245         LOGE("Failed to add self devId for client in account-related auth!");
246         return HC_ERR_JSON_FAIL;
247     }
248     return FillAccountCredentialInfo(osAccountId, peerUdid, groupId, localAuthInfo, paramsData);
249 }
250 
IsDeviceImportedByCloud(int32_t osAccountId,const char * peerUdid,const char * groupId)251 static bool IsDeviceImportedByCloud(int32_t osAccountId,  const char *peerUdid, const char *groupId)
252 {
253     TrustedDeviceEntry *peerDeviceInfo = CreateDeviceEntry();
254     if (peerDeviceInfo == NULL) {
255         LOGE("Failed to alloc memory for peerDeviceInfo!");
256         return true;
257     }
258     if (GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, peerDeviceInfo) != HC_SUCCESS) {
259         LOGI("Peer trusted device is not in database.");
260         DestroyDeviceEntry(peerDeviceInfo);
261         return false;
262     }
263     uint8_t source = peerDeviceInfo->source;
264     DestroyDeviceEntry(peerDeviceInfo);
265     if (source == IMPORTED_FROM_CLOUD) {
266         LOGI("Peer trusted device is imported by cloud.");
267         return true;
268     }
269     return false;
270 }
271 
DeleteExistedDeviceInfoInDb(int32_t osAccountId,const CJson * authParam)272 static int32_t DeleteExistedDeviceInfoInDb(int32_t osAccountId, const CJson *authParam)
273 {
274     const char *peerUdid = GetStringFromJson(authParam, FIELD_PEER_CONN_DEVICE_ID);
275     if (peerUdid == NULL) {
276         LOGE("Failed to get peer udid!");
277         return HC_ERR_JSON_GET;
278     }
279     const char *groupId = GetStringFromJson(authParam, FIELD_GROUP_ID);
280     if (groupId == NULL) {
281         LOGE("Failed to get groupId from auth params when deleting device info!");
282         return HC_ERR_JSON_GET;
283     }
284     if (IsDeviceImportedByCloud(osAccountId, peerUdid, groupId)) {
285         LOGD("Peer trusted device is imported by cloud, we don't delete peer device's trusted relationship.");
286         return HC_SUCCESS;
287     }
288     QueryDeviceParams devParams = InitQueryDeviceParams();
289     devParams.groupId = groupId;
290     devParams.udid = peerUdid;
291     if (DelTrustedDevice(osAccountId, &devParams) != HC_SUCCESS) {
292         LOGE("Failed to delete peer device from database!");
293         return HC_ERR_DB;
294     }
295     if (SaveOsAccountDb(osAccountId) != HC_SUCCESS) {
296         return HC_ERR_DB;
297     }
298     LOGD("Success to delete peer account-related device in database.");
299     return HC_SUCCESS;
300 }
301 
OnAccountError(int64_t requestId,const AuthSession * session,int errorCode)302 static void OnAccountError(int64_t requestId, const AuthSession *session, int errorCode)
303 {
304     AuthSession *realSession = (AuthSession *)session;
305     const DeviceAuthCallback *callback = session->base.callback;
306     ParamsVec list = realSession->paramsList;
307     CJson *authParam = list.get(&list, realSession->currentIndex);
308     if (authParam == NULL) {
309         LOGE("The json data in session is null!");
310         return;
311     }
312     int32_t authForm = AUTH_FORM_INVALID_TYPE;
313     if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
314         LOGE("Failed to get auth type!");
315         return;
316     }
317 
318     /* If there is alternative group, do not return error. */
319     const char *altGroup = GetStringFromJson(authParam, FIELD_ALTERNATIVE);
320     if ((realSession->currentIndex < (list.size(&list) - 1)) || (altGroup != NULL)) {
321         LOGI("There are alternative groups.");
322         return;
323     }
324     int32_t osAccountId = ANY_OS_ACCOUNT;
325     if (GetIntFromJson(authParam, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
326         LOGE("Failed to get osAccountId for account!");
327         return;
328     }
329     (void)DeleteExistedDeviceInfoInDb(osAccountId, authParam);
330     if ((callback != NULL) && (callback->onError != NULL)) {
331         LOGI("Invoke OnAccountError!");
332         callback->onError(requestId, authForm, errorCode, NULL);
333     }
334 }
335 
GetAccountReqParams(const CJson * receiveData,CJson * reqParam)336 static int32_t GetAccountReqParams(const CJson *receiveData, CJson *reqParam)
337 {
338     const char *peerUserId = GetStringFromJson(receiveData, FIELD_USER_ID);
339     if (peerUserId == NULL) {
340         LOGE("Failed to get peer uid for server!");
341         return HC_ERR_JSON_GET;
342     }
343 
344     if (AddStringToJson(reqParam, FIELD_USER_ID, peerUserId) != HC_SUCCESS) {
345         LOGE("Failed to add peer uid!");
346         return HC_ERR_JSON_FAIL;
347     }
348     const char *peerDeviceId = GetStringFromJson(receiveData, FIELD_DEVICE_ID);
349     if (peerDeviceId == NULL) {
350         LOGE("Failed to get deviceId from the data transmitted by the client!");
351         return HC_ERR_JSON_GET;
352     }
353     if (AddStringToJson(reqParam, FIELD_DEVICE_ID, peerDeviceId) != HC_SUCCESS) {
354         LOGE("Failed to add reqParam: deviceId for onRequest!");
355         return HC_ERR_JSON_FAIL;
356     }
357     return HC_SUCCESS;
358 }
359 
CombineAccountServerConfirms(const CJson * confirmationJson,CJson * dataFromClient)360 static int32_t CombineAccountServerConfirms(const CJson *confirmationJson, CJson *dataFromClient)
361 {
362     bool isClient = false;
363     if (AddBoolToJson(dataFromClient, FIELD_IS_CLIENT, isClient) != HC_SUCCESS) {
364         LOGE("Failed to combine server param for isClient!");
365         return HC_ERR_JSON_FAIL;
366     }
367     const char *peerUdid = GetStringFromJson(confirmationJson, FIELD_PEER_CONN_DEVICE_ID);
368     if (peerUdid == NULL) {
369         LOGE("Failed to get peer udid from server confirm params!");
370         return HC_ERR_JSON_GET;
371     }
372     if (AddStringToJson(dataFromClient, FIELD_PEER_CONN_DEVICE_ID, peerUdid) != HC_SUCCESS) {
373         LOGE("Failed to combine server param for peerUdid!");
374         return HC_ERR_JSON_FAIL;
375     }
376     return HC_SUCCESS;
377 }
378 
QueryAuthGroupForServer(int32_t osAccountId,GroupEntryVec * accountVec,CJson * data)379 static int32_t QueryAuthGroupForServer(int32_t osAccountId, GroupEntryVec *accountVec, CJson *data)
380 {
381     const char *peerUserId = GetStringFromJson(data, FIELD_USER_ID);
382     if (peerUserId == NULL) {
383         LOGE("Failed to get peerUserId.");
384         return HC_ERR_JSON_GET;
385     }
386     int32_t authForm = AUTH_FORM_INVALID_TYPE;
387     if (GetIntFromJson(data, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
388         LOGE("Failed to get auth form for server!");
389         return HC_ERR_JSON_GET;
390     }
391     int32_t groupType = AuthFormToGroupType(authForm);
392     if (groupType == GROUP_TYPE_INVALID) {
393         LOGE("Invalid authForm, authForm = %d.", authForm);
394         return HC_ERR_INVALID_PARAMS;
395     }
396     QueryGroupParams queryParams = InitQueryGroupParams();
397     queryParams.groupType = groupType;
398     if (groupType == IDENTICAL_ACCOUNT_GROUP) {
399         queryParams.userId = peerUserId;
400     } else {
401         queryParams.sharedUserId = peerUserId;
402     }
403     int32_t res = QueryGroups(osAccountId, &queryParams, accountVec);
404     if (res != HC_SUCCESS) {
405         LOGE("Failed to query local device's account group info for server!");
406         return res;
407     }
408     if (accountVec->size(accountVec) == 0) {
409         LOGE("Database don't have local device's account group info for server!");
410         return HC_ERR_NO_CANDIDATE_GROUP;
411     }
412     return HC_SUCCESS;
413 }
414 
AddSelfUserId(const TrustedGroupEntry * groupEntry,CJson * dataFromClient)415 static int32_t AddSelfUserId(const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
416 {
417     const char *selfUserId = StringGet(&groupEntry->userId);
418     if (selfUserId == NULL) {
419         LOGE("Failed to get local userId info from db!");
420         return HC_ERR_DB;
421     }
422     if (AddStringToJson(dataFromClient, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
423         LOGE("Failed to add self userId for server in account-related auth!");
424         return HC_ERR_JSON_FAIL;
425     }
426     return HC_SUCCESS;
427 }
428 
AddGroupIdForServer(const TrustedGroupEntry * groupEntry,CJson * dataFromClient)429 static int32_t AddGroupIdForServer(const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
430 {
431     const char *groupId = StringGet(&groupEntry->id);
432     if (groupId == NULL) {
433         LOGE("Failed to get groupId info from db!");
434         return HC_ERR_DB;
435     }
436     if (AddStringToJson(dataFromClient, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
437         LOGE("Failed to add groupId for server in account-related auth!");
438         return HC_ERR_JSON_FAIL;
439     }
440     return HC_SUCCESS;
441 }
442 
AddSelfDevInfoForServer(int32_t osAccountId,const TrustedGroupEntry * groupEntry,CJson * dataFromClient)443 static int32_t AddSelfDevInfoForServer(int32_t osAccountId, const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
444 {
445     TrustedDeviceEntry *localDevInfo = CreateDeviceEntry();
446     if (localDevInfo == NULL) {
447         LOGE("Failed to allocate memory for localDevInfo for server!");
448         return HC_ERR_ALLOC_MEMORY;
449     }
450     int32_t res;
451     do {
452         const char *groupId = StringGet(&groupEntry->id);
453         if (groupId == NULL) {
454             LOGE("Failed to get groupId for server!");
455             res = HC_ERR_NULL_PTR;
456             break;
457         }
458         res = GaGetLocalDeviceInfo(osAccountId, groupId, localDevInfo);
459         const char *selfDevId = StringGet(&(localDevInfo->authId));
460         const char *selfUdid = StringGet(&(localDevInfo->udid));
461         if ((res != HC_SUCCESS) || (selfDevId == NULL) || (selfUdid == NULL)) {
462             LOGE("Failed to get self id info from db!");
463             res = HC_ERR_DB;
464             break;
465         }
466         if (AddStringToJson(dataFromClient, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
467             LOGE("Failed to add self devId for server in account-related auth!");
468             res = HC_ERR_JSON_ADD;
469             break;
470         }
471         if (AddStringToJson(dataFromClient, FIELD_SELF_DEVICE_ID, selfUdid) != HC_SUCCESS) {
472             LOGE("Failed to add self udid for server in account-related auth!");
473             res = HC_ERR_JSON_ADD;
474             break;
475         }
476         const char *peerUdid = GetStringFromJson(dataFromClient, FIELD_PEER_CONN_DEVICE_ID);
477         if (peerUdid == NULL) {
478             LOGE("Failed to get peer udid for server auth!");
479             res = HC_ERR_JSON_FAIL;
480             break;
481         }
482         res = FillAccountCredentialInfo(osAccountId, peerUdid, groupId, localDevInfo, dataFromClient);
483     } while (0);
484     DestroyDeviceEntry(localDevInfo);
485     return res;
486 }
487 
AddSelfAccountInfoForServer(CJson * dataFromClient)488 static int32_t AddSelfAccountInfoForServer(CJson *dataFromClient)
489 {
490     int32_t osAccountId = INVALID_OS_ACCOUNT;
491     if (GetIntFromJson(dataFromClient, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
492         LOGE("Failed to get osAccountId for server!");
493         return HC_ERR_JSON_GET;
494     }
495     GroupEntryVec accountVec = CreateGroupEntryVec();
496     int32_t res = QueryAuthGroupForServer(osAccountId, &accountVec, dataFromClient);
497     do {
498         if (res != HC_SUCCESS) {
499             LOGE("Failed to query account group info for server auth!");
500             break;
501         }
502         if (accountVec.size(&accountVec) == 0) {
503             LOGE("Database don't have local device's account group info for server!");
504             res = HC_ERR_NO_CANDIDATE_GROUP;
505             break;
506         }
507         TrustedGroupEntry *groupEntry = accountVec.get(&accountVec, 0);
508         if (groupEntry == NULL) {
509             LOGE("Local group info is null!");
510             res = HC_ERR_GROUP_NOT_EXIST;
511             break;
512         }
513         res = AddSelfUserId(groupEntry, dataFromClient);
514         if (res != HC_SUCCESS) {
515             break;
516         }
517         res = AddGroupIdForServer(groupEntry, dataFromClient);
518         if (res != HC_SUCCESS) {
519             break;
520         }
521         res = AddSelfDevInfoForServer(osAccountId, groupEntry, dataFromClient);
522     } while (0);
523     ClearGroupEntryVec(&accountVec);
524     return res;
525 }
526 
GetAccountAuthParamForServer(const CJson * dataFromClient,ParamsVec * authParamsVec)527 static int32_t GetAccountAuthParamForServer(const CJson *dataFromClient, ParamsVec *authParamsVec)
528 {
529     LOGI("Begin get account-related auth params for server.");
530     CJson *dupData = DuplicateJson(dataFromClient);
531     if (dupData == NULL) {
532         LOGE("Failed to create dupData for dataFromClient!");
533         return HC_ERR_JSON_FAIL;
534     }
535 
536     if (AddSelfAccountInfoForServer(dupData) != HC_SUCCESS) {
537         LOGE("Failed to add account info for server!");
538         FreeJson(dupData);
539         return HC_ERR_GROUP_NOT_EXIST;
540     }
541 
542     if (authParamsVec->pushBack(authParamsVec, (const void **)&dupData) == NULL) {
543         LOGE("Failed to push json data to vector in account-related auth!");
544         FreeJson(dupData);
545         return HC_ERR_ALLOC_MEMORY;
546     }
547     return HC_SUCCESS;
548 }
549 
AccountOnFinishToPeer(int64_t requestId,const CJson * out,const DeviceAuthCallback * callback)550 static int32_t AccountOnFinishToPeer(int64_t requestId, const CJson *out, const DeviceAuthCallback *callback)
551 {
552     int32_t res = HC_SUCCESS;
553     const CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
554     if (sendToPeer == NULL) {
555         LOGI("No need to transmit data to peer for account-related auth.");
556         return res;
557     }
558     char *sendToPeerStr = PackJsonToString(sendToPeer);
559     if (sendToPeerStr == NULL) {
560         LOGE("Failed to pack sendToPeerStr!");
561         return HC_ERR_ALLOC_MEMORY;
562     }
563     if ((callback != NULL) && (callback->onTransmit != NULL)) {
564         LOGD("Begin to transmit data to peer for auth in AccountOnFinishToPeer.");
565         if (!callback->onTransmit(requestId, (uint8_t *)sendToPeerStr, HcStrlen(sendToPeerStr) + 1)) {
566             LOGE("Failed to transmit data to peer!");
567             res = HC_ERR_TRANSMIT_FAIL;
568         }
569         LOGD("End to transmit data to peer for auth in AccountOnFinishToPeer.");
570     }
571     FreeJsonString(sendToPeerStr);
572     return res;
573 }
574 
PrepareTrustedDeviceInfo(const char * peerUdid,const char * groupId,const CJson * authParam,const CJson * out,TrustedDeviceEntry * devEntry)575 static int32_t PrepareTrustedDeviceInfo(const char *peerUdid, const char *groupId,
576     const CJson *authParam, const CJson *out, TrustedDeviceEntry *devEntry)
577 {
578     devEntry->source = SELF_CREATED;
579     const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
580     if (sendToSelf == NULL) {
581         LOGE("Failed to get sendToSelf data for account!");
582         return HC_ERR_JSON_GET;
583     }
584     int32_t credentialType = INVALID_CRED;
585     if (GetIntFromJson(sendToSelf, FIELD_CREDENTIAL_TYPE, &credentialType) != HC_SUCCESS) {
586         LOGE("Failed to get credentialType from json sendToSelf!");
587         return HC_ERR_JSON_GET;
588     }
589     devEntry->credential = credentialType;
590     const char *peerAuthId = GetStringFromJson(sendToSelf, FIELD_DEV_ID);
591     if (peerAuthId == NULL) {
592         LOGE("Failed to get peer authId for account!");
593         return HC_ERR_JSON_GET;
594     }
595     const char *peerUserId = GetStringFromJson(sendToSelf, FIELD_USER_ID);
596     if (peerUserId == NULL) {
597         LOGE("Failed to get peer userId!");
598         return HC_ERR_JSON_GET;
599     }
600     if (!StringSetPointer(&(devEntry->userId), peerUserId) ||
601         !StringSetPointer(&(devEntry->udid), peerUdid) ||
602         !StringSetPointer(&(devEntry->authId), peerAuthId) ||
603         !StringSetPointer(&(devEntry->groupId), groupId) ||
604         !StringSetPointer(&(devEntry->serviceType), groupId)) {
605         LOGE("Failed to add device info when adding a trusted device!");
606         return HC_ERR_MEMORY_COPY;
607     }
608     return HC_SUCCESS;
609 }
610 
AddTrustedDeviceForAccount(const CJson * authParam,const CJson * out)611 static int32_t AddTrustedDeviceForAccount(const CJson *authParam, const CJson *out)
612 {
613     int32_t osAccountId = ANY_OS_ACCOUNT;
614     if (GetIntFromJson(authParam, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
615         LOGE("Failed to get osAccountId for account!");
616         return HC_ERR_JSON_GET;
617     }
618     const char *peerUdid = GetStringFromJson(authParam, FIELD_PEER_CONN_DEVICE_ID);
619     if (peerUdid == NULL) {
620         LOGE("Failed to get peer udid when adding peer trusted device!");
621         return HC_ERR_JSON_GET;
622     }
623     const char *groupId = GetStringFromJson(authParam, FIELD_GROUP_ID);
624     if (groupId == NULL) {
625         LOGE("Failed to get groupId when adding peer trusted device!");
626         return HC_ERR_JSON_GET;
627     }
628     if (IsDeviceImportedByCloud(osAccountId, peerUdid, groupId)) {
629         LOGD("Peer trusted device is imported by cloud, we don't update peer device's trusted relationship.");
630         return HC_SUCCESS;
631     }
632     TrustedDeviceEntry *devEntry = CreateDeviceEntry();
633     if (devEntry == NULL) {
634         LOGE("Failed to allocate device entry memory!");
635         return HC_ERR_ALLOC_MEMORY;
636     }
637     int32_t res;
638     do {
639         res = PrepareTrustedDeviceInfo(peerUdid, groupId, authParam, out, devEntry);
640         if (res != HC_SUCCESS) {
641             LOGE("Failed to prepare trust device params!");
642             break;
643         }
644         res = AddTrustedDevice(osAccountId, devEntry);
645         if (res != HC_SUCCESS) {
646             LOGE("Failed to add trusted devices for account to database!");
647             break;
648         }
649         res = SaveOsAccountDb(osAccountId);
650     } while (0);
651     DestroyDeviceEntry(devEntry);
652     return res;
653 }
654 
PrepareAccountDataToSelf(const CJson * sendToSelf,CJson * returnToSelf)655 static int32_t PrepareAccountDataToSelf(const CJson *sendToSelf, CJson *returnToSelf)
656 {
657     int32_t res = GetSessionKeyForAccount(sendToSelf, returnToSelf);
658     if (res != HC_SUCCESS) {
659         LOGE("Failed to get session key info for account auth!");
660         return res;
661     }
662     res = GetUserIdForAccount(sendToSelf, returnToSelf);
663     if (res != HC_SUCCESS) {
664         LOGE("Failed to get user id for account auth!");
665     }
666     return res;
667 }
668 
AccountOnFinishToSelf(int64_t requestId,const CJson * authParam,const CJson * out,const DeviceAuthCallback * callback)669 static int32_t AccountOnFinishToSelf(int64_t requestId, const CJson *authParam, const CJson *out,
670     const DeviceAuthCallback *callback)
671 {
672     const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
673     if (sendToSelf == NULL) {
674         LOGE("No data to send to self for onFinish.");
675         return HC_ERR_LOST_DATA;
676     }
677 
678     CJson *returnToSelf = CreateJson();
679     if (returnToSelf == NULL) {
680         LOGE("Failed to create json for account-related auth in onFinish!");
681         return HC_ERR_ALLOC_MEMORY;
682     }
683     int32_t res = PrepareAccountDataToSelf(sendToSelf, returnToSelf);
684     if (res != HC_SUCCESS) {
685         LOGE("Failed to add account-related returnToSelf data!");
686         ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
687         FreeJson(returnToSelf);
688         return res;
689     }
690     char *returnStr = PackJsonToString(returnToSelf);
691     ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
692     FreeJson(returnToSelf);
693     if (returnStr == NULL) {
694         LOGE("Failed to pack return data to string!");
695         return HC_ERR_ALLOC_MEMORY;
696     }
697     do {
698         int32_t authForm = AUTH_FORM_INVALID_TYPE;
699         if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
700             LOGE("Failed to get auth type!");
701             res = HC_ERR_JSON_GET;
702             break;
703         }
704         if ((callback != NULL) && (callback->onFinish != NULL)) {
705             LOGD("Group auth call onFinish for account related auth.");
706             callback->onFinish(requestId, authForm, returnStr);
707         }
708     } while (0);
709     ClearAndFreeJsonString(returnStr);
710     return res;
711 }
712 
OnAccountFinish(int64_t requestId,const CJson * authParam,const CJson * out,const DeviceAuthCallback * callback)713 static void OnAccountFinish(int64_t requestId, const CJson *authParam, const CJson *out,
714     const DeviceAuthCallback *callback)
715 {
716     LOGI("Begin call onFinish for account-related auth.");
717     if (AccountOnFinishToPeer(requestId, out, callback) != HC_SUCCESS) {
718         LOGE("Failed to send data to peer when account-related auth finished!");
719         return;
720     }
721     if (ReturnSessionKey(requestId, authParam, out, callback) != HC_SUCCESS) {
722         LOGE("Failed to return session key for account-related auth!");
723         return;
724     }
725     if (AddTrustedDeviceForAccount(authParam, out) != HC_SUCCESS) {
726         LOGD("Failed to add peer trusted devices to database for account-related auth!");
727     }
728     if (AccountOnFinishToSelf(requestId, authParam, out, callback) != HC_SUCCESS) {
729         LOGE("Failed to send data to self when account-related auth finished!");
730         return;
731     }
732     LOGI("Call onFinish for account-related auth successfully.");
733 }
734 
GetAccountRelatedGroupAuth(void)735 BaseGroupAuth *GetAccountRelatedGroupAuth(void)
736 {
737     return (BaseGroupAuth *)&g_accountRelatedGroupAuth;
738 }