• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-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 "account_related_group_auth.h"
17 #include "common_defs.h"
18 #include "device_auth_defines.h"
19 #include "group_auth_data_operation.h"
20 #include "hc_dev_info.h"
21 #include "hc_log.h"
22 #include "hc_time.h"
23 #include "hc_types.h"
24 #include "json_utils.h"
25 #include "performance_dumper.h"
26 #include "string_util.h"
27 #include "alg_loader.h"
28 #include "hisysevent_adapter.h"
29 #include "account_task_manager.h"
30 
31 #define UID_HEX_STRING_LEN_MAX 64
32 #define UID_HEX_STRING_LEN_MIN 10
33 #define MAX_SERVICE_PEER_DATA_LENGTH 2048
34 #define PLACE_HOLDER_LENGTH 4
35 #define COMMA_SEPARATOR ","
36 #define COLON_SEPARATOR ":"
37 #define JSON_KEY_FORMAT "\"%s\":"
38 
39 static void OnAccountFinish(int64_t requestId, const CJson *authParam, const CJson *out,
40     const DeviceAuthCallback *callback);
41 static int32_t FillAccountAuthInfo(int32_t osAccountId, const TrustedGroupEntry *entry,
42     const TrustedDeviceEntry *localAuthInfo, CJson *paramsData);
43 static void GetAccountCandidateGroup(int32_t osAccountId, const CJson *param,
44     QueryGroupParams *queryParams, GroupEntryVec *vec);
45 static int32_t GetAuthParamsVecForServer(const CJson *dataFromClient, ParamsVecForAuth *authParamsVec);
46 static int32_t CombineAccountServerConfirms(const CJson *confirmationJson, CJson *dataFromClient);
47 
48 static AccountRelatedGroupAuth g_accountRelatedGroupAuth = {
49     .base.onFinish = OnAccountFinish,
50     .base.fillDeviceAuthInfo = FillAccountAuthInfo,
51     .base.getAuthParamsVecForServer = GetAuthParamsVecForServer,
52     .base.combineServerConfirmParams = CombineAccountServerConfirms,
53     .base.authType = ACCOUNT_RELATED_GROUP_AUTH_TYPE,
54     .getAccountCandidateGroup = GetAccountCandidateGroup,
55 };
56 
ReturnSessionKey(int64_t requestId,const CJson * out,const DeviceAuthCallback * callback)57 static int32_t ReturnSessionKey(int64_t requestId, const CJson *out, const DeviceAuthCallback *callback)
58 {
59     const char *returnSessionKeyStr = GetStringFromJson(out, FIELD_SESSION_KEY);
60     if (returnSessionKeyStr == NULL) {
61         LOGE("Failed to get session key from json!");
62         return HC_ERR_JSON_GET;
63     }
64     uint32_t keyLen = (HcStrlen(returnSessionKeyStr) / BYTE_TO_HEX_OPER_LENGTH);
65     uint8_t *sessionKey = (uint8_t *)HcMalloc(keyLen, 0);
66     if (sessionKey == NULL) {
67         LOGE("HcMalloc failed.");
68         return HC_ERR_ALLOC_MEMORY;
69     }
70 
71     int32_t res = HC_SUCCESS;
72     do {
73         if (GetByteFromJson(out, FIELD_SESSION_KEY, sessionKey, keyLen) != HC_SUCCESS) {
74             LOGE("Failed to get session key from json!");
75             res = HC_ERR_JSON_GET;
76             break;
77         }
78         if ((callback == NULL) || (callback->onSessionKeyReturned == NULL)) {
79             LOGE("The callback or callback onSessionKeyReturned is NULL!");
80             res = HC_ERR_INVALID_PARAMS;
81             break;
82         }
83         LOGI("Begin execute onSessionKeyReturned!");
84         UPDATE_PERFORM_DATA_BY_INPUT_INDEX(requestId, ON_SESSION_KEY_RETURN_TIME, HcGetCurTimeInMillis());
85         callback->onSessionKeyReturned(requestId, sessionKey, keyLen);
86         LOGI("End execute onSessionKeyReturned, res = %" LOG_PUB "d.", res);
87     } while (0);
88     (void)memset_s(sessionKey, keyLen, 0, keyLen);
89     HcFree(sessionKey);
90     sessionKey = NULL;
91     return res;
92 }
93 
GetSessionKeyForAccount(const CJson * sendToSelf,CJson * returnToSelf)94 static int32_t GetSessionKeyForAccount(const CJson *sendToSelf, CJson *returnToSelf)
95 {
96     int32_t keyLen = DEFAULT_RETURN_KEY_LENGTH;
97     uint8_t *sessionKey = (uint8_t *)HcMalloc(keyLen, 0);
98     if (sessionKey == NULL) {
99         LOGE("Failed to malloc memory for sessionKey!");
100         return HC_ERR_ALLOC_MEMORY;
101     }
102     int32_t res = HC_SUCCESS;
103     do {
104         if (GetByteFromJson(sendToSelf, FIELD_SESSION_KEY, sessionKey, keyLen) != HC_SUCCESS) {
105             LOGE("Get session key from sendToSelf failed!");
106             res = HC_ERR_JSON_GET;
107             break;
108         }
109         if (AddByteToJson(returnToSelf, FIELD_SESSION_KEY, (const uint8_t *)sessionKey, keyLen) != HC_SUCCESS) {
110             LOGE("Add session key for onFinish from json failed!");
111             res = HC_ERR_JSON_FAIL;
112             break;
113         }
114     } while (0);
115     (void)memset_s(sessionKey, keyLen, 0, keyLen);
116     HcFree(sessionKey);
117     sessionKey = NULL;
118     return res;
119 }
120 
GetUserIdForAccount(const CJson * sendToSelf,CJson * returnToSelf)121 static int32_t GetUserIdForAccount(const CJson *sendToSelf, CJson *returnToSelf)
122 {
123     const char *peerUserId = GetStringFromJson(sendToSelf, FIELD_USER_ID);
124     if (peerUserId == NULL) {
125         LOGE("Failed to get peer uid!");
126         return HC_ERR_JSON_GET;
127     }
128     if (AddStringToJson(returnToSelf, FIELD_USER_ID, peerUserId) != HC_SUCCESS) {
129         LOGE("Failed to add peer uid!");
130         return HC_ERR_JSON_FAIL;
131     }
132     return HC_SUCCESS;
133 }
134 
IsPeerUidLenValid(uint32_t peerUserIdLen)135 static bool IsPeerUidLenValid(uint32_t peerUserIdLen)
136 {
137     if ((peerUserIdLen < UID_HEX_STRING_LEN_MIN) || (peerUserIdLen > UID_HEX_STRING_LEN_MAX)) {
138         LOGE("The input userId len is invalid, input userId in hex string len = %" LOG_PUB "d", peerUserIdLen);
139         return false;
140     }
141     return true;
142 }
143 
IsUserIdEqual(const char * userIdInDb,const char * peerUserIdInDb)144 static bool IsUserIdEqual(const char *userIdInDb, const char *peerUserIdInDb)
145 {
146     char *peerUidToUpper = NULL;
147     if (ToUpperCase(peerUserIdInDb, &peerUidToUpper) != HC_SUCCESS) {
148         LOGE("Failed to convert the input userId to upper case!");
149         return false;
150     }
151     uint32_t userIdInDbLen = HcStrlen(userIdInDb);
152     uint32_t peerUserIdLen = HcStrlen(peerUserIdInDb);
153     if (!IsPeerUidLenValid(peerUserIdLen)) {
154         HcFree(peerUidToUpper);
155         peerUidToUpper = NULL;
156         return false;
157     }
158     uint32_t cmpLen = (userIdInDbLen > peerUserIdLen) ? peerUserIdLen : userIdInDbLen;
159     if (memcmp(userIdInDb, peerUidToUpper, cmpLen) == EOK) {
160         HcFree(peerUidToUpper);
161         peerUidToUpper = NULL;
162         return true;
163     }
164     HcFree(peerUidToUpper);
165     peerUidToUpper = NULL;
166     return false;
167 }
168 
IsPeerInAccountRelatedGroup(const TrustedGroupEntry * groupEntry,const char * peerUserId,GroupType type)169 static bool IsPeerInAccountRelatedGroup(const TrustedGroupEntry *groupEntry, const char *peerUserId, GroupType type)
170 {
171     const char *userIdInDb =
172         ((type == IDENTICAL_ACCOUNT_GROUP) ? StringGet(&(groupEntry->userId)) : StringGet(&(groupEntry->sharedUserId)));
173     if (userIdInDb == NULL) {
174         LOGD("Failed to get peer userId from db!");
175         return false;
176     }
177     if (IsUserIdEqual(userIdInDb, peerUserId)) {
178         LOGI("[Account auth]: The input peer-userId is in one account group, add account-group auth!");
179         return true;
180     }
181     return false;
182 }
183 
IsPeerInIdenticalGroup(int32_t osAccountId,const char * peerUserId)184 static bool IsPeerInIdenticalGroup(int32_t osAccountId, const char *peerUserId)
185 {
186     bool isGroupExist = false;
187     GroupEntryVec accountVec = CreateGroupEntryVec();
188     QueryGroupParams queryParams = InitQueryGroupParams();
189     queryParams.groupType = IDENTICAL_ACCOUNT_GROUP;
190     do {
191         if (QueryGroups(osAccountId, &queryParams, &accountVec) != HC_SUCCESS) {
192             LOGD("No identical-account group in dataBase, no identical-account auth!");
193             break;
194         }
195         uint32_t index = 0;
196         TrustedGroupEntry **ptr = NULL;
197         while (index < accountVec.size(&accountVec)) {
198             ptr = accountVec.getp(&accountVec, index);
199             if ((ptr == NULL) || (*ptr == NULL)) {
200                 index++;
201                 continue;
202             }
203             if (IsPeerInAccountRelatedGroup(*ptr, peerUserId, IDENTICAL_ACCOUNT_GROUP)) {
204                 isGroupExist = true;
205                 break;
206             }
207             index++;
208         }
209     } while (0);
210     ClearGroupEntryVec(&accountVec);
211     return isGroupExist;
212 }
213 
GaGetAccountGroup(int32_t osAccountId,GroupType type,const char * peerUserId,QueryGroupParams * queryParams,GroupEntryVec * vec)214 static void GaGetAccountGroup(int32_t osAccountId, GroupType type, const char *peerUserId,
215     QueryGroupParams *queryParams, GroupEntryVec *vec)
216 {
217     LOGI("Try to get account group info, groupType: %" LOG_PUB "d.", type);
218     queryParams->groupType = type;
219     if (QueryGroups(osAccountId, queryParams, vec) != HC_SUCCESS) {
220         LOGD("Database don't have local device's across-account group info!");
221         return;
222     }
223 
224     uint32_t index = 0;
225     TrustedGroupEntry **ptr = NULL;
226     while (index < vec->size(vec)) {
227         ptr = vec->getp(vec, index);
228         if ((ptr == NULL) || (*ptr == NULL)) {
229             index++;
230             continue;
231         }
232         if ((peerUserId == NULL) || IsPeerInAccountRelatedGroup(*ptr, peerUserId, type)) {
233             index++;
234             continue;
235         }
236         TrustedGroupEntry *tempEntry = NULL;
237         HC_VECTOR_POPELEMENT(vec, &tempEntry, index);
238         DestroyGroupEntry((TrustedGroupEntry *)tempEntry);
239     }
240     LOGI("The candidate account group size is: %" LOG_PUB "u", vec->size(vec));
241 }
242 
GetAccountCandidateGroup(int32_t osAccountId,const CJson * param,QueryGroupParams * queryParams,GroupEntryVec * vec)243 static void GetAccountCandidateGroup(int32_t osAccountId, const CJson *param,
244     QueryGroupParams *queryParams, GroupEntryVec *vec)
245 {
246     /* Compare userId with local uid in DB. */
247     bool identicalFlag = false;
248     bool acrossAccountFlag = false;
249     const char *peerUserId = GetStringFromJson(param, FIELD_USER_ID);
250     if (peerUserId != NULL) {
251         acrossAccountFlag = true;
252         identicalFlag = IsPeerInIdenticalGroup(osAccountId, peerUserId);
253     } else {
254         LOGD("userId is null in authParam.");
255         identicalFlag = true;
256     }
257 
258     if (identicalFlag) {
259         GaGetAccountGroup(osAccountId, IDENTICAL_ACCOUNT_GROUP, peerUserId, queryParams, vec);
260     } else if (acrossAccountFlag) {
261         GaGetAccountGroup(osAccountId, ACROSS_ACCOUNT_AUTHORIZE_GROUP, peerUserId, queryParams, vec);
262     }
263 }
264 
FillAccountCredentialInfo(int32_t osAccountId,const char * peerUdid,const char * groupId,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)265 static int32_t FillAccountCredentialInfo(int32_t osAccountId, const char *peerUdid, const char *groupId,
266     const TrustedDeviceEntry *localAuthInfo, CJson *paramsData)
267 {
268     TrustedDeviceEntry *peerDevInfo = CreateDeviceEntry();
269     if (peerDevInfo == NULL) {
270         LOGE("Failed to alloc memory for peerDevInfo!");
271         return HC_ERR_ALLOC_MEMORY;
272     }
273     int32_t localDevType = DEVICE_TYPE_CONTROLLER;
274     int32_t authCredential = localAuthInfo->credential;
275     int32_t res = GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, peerDevInfo);
276     if ((res != HC_SUCCESS) || (peerDevInfo->source == SELF_CREATED)) {
277         LOGI("Peer device's query result = %" LOG_PUB "d, pass local device info to account authenticator.", res);
278         localDevType = DEVICE_TYPE_ACCESSORY; /* Controller has peer device info, which is added by caller. */
279     }
280     if ((res == HC_SUCCESS) && (peerDevInfo->source == IMPORTED_FROM_CLOUD)) {
281         LOGI("Peer trusted device is imported by cloud, invoke sym account auth.");
282         authCredential = peerDevInfo->credential;
283     }
284     DestroyDeviceEntry(peerDevInfo);
285     if (AddIntToJson(paramsData, FIELD_LOCAL_DEVICE_TYPE, localDevType) != HC_SUCCESS) {
286         LOGE("Failed to add self device type to json!");
287         return HC_ERR_JSON_ADD;
288     }
289     if (AddIntToJson(paramsData, FIELD_CREDENTIAL_TYPE, authCredential) != HC_SUCCESS) {
290         LOGE("Failed to add self credential type to json!");
291         return HC_ERR_JSON_ADD;
292     }
293     return HC_SUCCESS;
294 }
295 
FillAccountAuthInfo(int32_t osAccountId,const TrustedGroupEntry * entry,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)296 static int32_t FillAccountAuthInfo(int32_t osAccountId, const TrustedGroupEntry *entry,
297     const TrustedDeviceEntry *localAuthInfo, CJson *paramsData)
298 {
299     const char *peerUdid = GetStringFromJson(paramsData, FIELD_PEER_CONN_DEVICE_ID);
300     if (peerUdid == NULL) {
301         LOGE("Failed to get peer udid in the input data for account auth!");
302         return HC_ERR_INVALID_PARAMS;
303     }
304     const char *selfUserId = StringGet(&entry->userId);
305     const char *groupId = StringGet(&entry->id);
306     const char *selfDeviceId = StringGet(&(localAuthInfo->udid));
307     const char *selfDevId = StringGet(&(localAuthInfo->authId));
308     if ((selfUserId == NULL) || (groupId == NULL) || (selfDeviceId == NULL) || (selfDevId == NULL)) {
309         LOGE("Failed to get self account info for client in account-related auth!");
310         return HC_ERR_JSON_GET;
311     }
312     if (AddStringToJson(paramsData, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
313         LOGE("Failed to add self userId for client in account-related auth!");
314         return HC_ERR_JSON_FAIL;
315     }
316     if (AddStringToJson(paramsData, FIELD_SELF_DEVICE_ID, selfDeviceId) != HC_SUCCESS) {
317         LOGE("Failed to add self deviceId for client in account-related auth!");
318         return HC_ERR_JSON_FAIL;
319     }
320     if (AddStringToJson(paramsData, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
321         LOGE("Failed to add self devId for client in account-related auth!");
322         return HC_ERR_JSON_FAIL;
323     }
324     return FillAccountCredentialInfo(osAccountId, peerUdid, groupId, localAuthInfo, paramsData);
325 }
326 
IsDeviceImportedByCloud(int32_t osAccountId,const char * peerUdid,const char * groupId)327 static bool IsDeviceImportedByCloud(int32_t osAccountId,  const char *peerUdid, const char *groupId)
328 {
329     TrustedDeviceEntry *peerDeviceInfo = CreateDeviceEntry();
330     if (peerDeviceInfo == NULL) {
331         LOGE("Failed to alloc memory for peerDeviceInfo!");
332         return true;
333     }
334     if (GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, peerDeviceInfo) != HC_SUCCESS) {
335         LOGI("Peer trusted device is not in database.");
336         DestroyDeviceEntry(peerDeviceInfo);
337         return false;
338     }
339     uint8_t source = peerDeviceInfo->source;
340     DestroyDeviceEntry(peerDeviceInfo);
341     if (source == IMPORTED_FROM_CLOUD) {
342         LOGI("Peer trusted device is imported by cloud.");
343         return true;
344     }
345     return false;
346 }
347 
CombineAccountServerConfirms(const CJson * confirmationJson,CJson * dataFromClient)348 static int32_t CombineAccountServerConfirms(const CJson *confirmationJson, CJson *dataFromClient)
349 {
350     bool isClient = false;
351     if (AddBoolToJson(dataFromClient, FIELD_IS_CLIENT, isClient) != HC_SUCCESS) {
352         LOGE("Failed to combine server param for isClient!");
353         return HC_ERR_JSON_FAIL;
354     }
355     const char *peerUdid = GetStringFromJson(confirmationJson, FIELD_PEER_CONN_DEVICE_ID);
356     if (peerUdid == NULL) {
357         LOGE("Failed to get peer udid from server confirm params!");
358         return HC_ERR_JSON_GET;
359     }
360     if (AddStringToJson(dataFromClient, FIELD_PEER_CONN_DEVICE_ID, peerUdid) != HC_SUCCESS) {
361         LOGE("Failed to combine server param for peerUdid!");
362         return HC_ERR_JSON_FAIL;
363     }
364     return HC_SUCCESS;
365 }
366 
QueryAuthGroupForServer(int32_t osAccountId,GroupEntryVec * accountVec,CJson * data)367 static int32_t QueryAuthGroupForServer(int32_t osAccountId, GroupEntryVec *accountVec, CJson *data)
368 {
369     const char *peerUserId = GetStringFromJson(data, FIELD_USER_ID);
370     if (peerUserId == NULL) {
371         LOGE("Failed to get peerUserId.");
372         return HC_ERR_JSON_GET;
373     }
374     int32_t authForm = AUTH_FORM_INVALID_TYPE;
375     if (GetIntFromJson(data, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
376         LOGE("Failed to get auth form for server!");
377         return HC_ERR_JSON_GET;
378     }
379     int32_t groupType = AuthFormToGroupType(authForm);
380     if (groupType == GROUP_TYPE_INVALID) {
381         LOGE("Invalid authForm, authForm = %" LOG_PUB "d.", authForm);
382         return HC_ERR_INVALID_PARAMS;
383     }
384     QueryGroupParams queryParams = InitQueryGroupParams();
385     queryParams.groupType = (uint32_t)groupType;
386     if (queryParams.groupType == IDENTICAL_ACCOUNT_GROUP) {
387         queryParams.userId = peerUserId;
388     } else {
389         queryParams.sharedUserId = peerUserId;
390     }
391     int32_t res = QueryGroups(osAccountId, &queryParams, accountVec);
392     if (res != HC_SUCCESS) {
393         LOGE("Failed to query local device's account group info for server!");
394         return res;
395     }
396     if (accountVec->size(accountVec) == 0) {
397         LOGE("Database don't have local device's account group info for server!");
398         return HC_ERR_NO_CANDIDATE_GROUP;
399     }
400     return HC_SUCCESS;
401 }
402 
GetValueFromJsonStr(char * jsonStr,const char * key)403 static char *GetValueFromJsonStr(char *jsonStr, const char *key)
404 {
405     if (HcStrlen(jsonStr) > MAX_SERVICE_PEER_DATA_LENGTH) {
406         LOGE("Invalid peer data length!");
407         return NULL;
408     }
409     uint32_t keyLen = HcStrlen(key);
410     char *keyStr = (char *)HcMalloc(keyLen + PLACE_HOLDER_LENGTH, 0);
411     if (keyStr == NULL) {
412         LOGE("Failed to alloc memory for keyStr!");
413         return NULL;
414     }
415     if (sprintf_s(keyStr, keyLen + PLACE_HOLDER_LENGTH, JSON_KEY_FORMAT, key) <= 0) {
416         LOGE("Failed to convert key to string!");
417         HcFree(keyStr);
418         return NULL;
419     }
420     char *nextPtr = NULL;
421     char *value = NULL;
422     char *subVal = strtok_s(jsonStr, COMMA_SEPARATOR, &nextPtr);
423     while (subVal != NULL) {
424         if (strstr(subVal, keyStr) != NULL) {
425             value = strstr(subVal, COLON_SEPARATOR);
426             if (value != NULL) {
427                 value++;
428             }
429             break;
430         }
431         subVal = strtok_s(NULL, COMMA_SEPARATOR, &nextPtr);
432     }
433     HcFree(keyStr);
434     return value;
435 }
436 
GetPeerUserIdFromReceivedData(const CJson * data,char ** peerUserId)437 static int32_t GetPeerUserIdFromReceivedData(const CJson *data, char **peerUserId)
438 {
439     const char *peerData = GetStringFromJson(data, FIELD_PLUGIN_EXT_DATA);
440     if (peerData == NULL) {
441         LOGE("Failed to get peerData from data!");
442         return HC_ERR_JSON_GET;
443     }
444     char *copyPeerData = NULL;
445     int32_t res = DeepCopyString(peerData, &copyPeerData);
446     if (res != HC_SUCCESS) {
447         LOGE("Failed to deep copy peerData!");
448         return res;
449     }
450     char *userId = GetValueFromJsonStr(copyPeerData, FIELD_USER_ID);
451     if (userId == NULL) {
452         LOGE("Failed to get userId from peer data!");
453         HcFree(copyPeerData);
454         return HC_ERR_JSON_GET;
455     }
456     uint8_t userIdHash[SHA256_LEN] = { 0 };
457     Uint8Buff hashBuff = { userIdHash, sizeof(userIdHash) };
458     Uint8Buff hashMsgBuff = { (uint8_t *)userId, HcStrlen(userId) };
459     res = GetLoaderInstance()->sha256(&hashMsgBuff, &hashBuff);
460     HcFree(copyPeerData);
461     if (res != HC_SUCCESS) {
462         LOGE("Failed to get hash for userId!");
463         return res;
464     }
465     uint32_t hexLen = hashBuff.length * BYTE_TO_HEX_OPER_LENGTH + 1;
466     *peerUserId = (char *)HcMalloc(hexLen, 0);
467     if (*peerUserId == NULL) {
468         LOGE("Failed to alloc memory for peer userId!");
469         return HC_ERR_ALLOC_MEMORY;
470     }
471     res = ByteToHexString(hashBuff.val, hashBuff.length, *peerUserId, hexLen);
472     if (res != HC_SUCCESS) {
473         LOGE("Failed to convert hash to hex string!");
474         HcFree(*peerUserId);
475         *peerUserId = NULL;
476         return res;
477     }
478     return HC_SUCCESS;
479 }
480 
QueryGroupForAccountPlugin(int32_t osAccountId,GroupEntryVec * accountVec,CJson * data)481 static int32_t QueryGroupForAccountPlugin(int32_t osAccountId, GroupEntryVec *accountVec, CJson *data)
482 {
483     char *peerUserId = NULL;
484     int32_t res = GetPeerUserIdFromReceivedData(data, &peerUserId);
485     if (res != HC_SUCCESS) {
486         return res;
487     }
488     do {
489         int32_t authForm = AUTH_FORM_INVALID_TYPE;
490         if (GetIntFromJson(data, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
491             LOGE("Failed to get auth form for server!");
492             res = HC_ERR_JSON_GET;
493             break;
494         }
495         int32_t groupType = AuthFormToGroupType(authForm);
496         if (groupType == GROUP_TYPE_INVALID) {
497             LOGE("Invalid authForm: %" LOG_PUB "d.", authForm);
498             res = HC_ERR_INVALID_PARAMS;
499             break;
500         }
501         QueryGroupParams queryParams = InitQueryGroupParams();
502         queryParams.groupType = (uint32_t)groupType;
503         if (queryParams.groupType == IDENTICAL_ACCOUNT_GROUP) {
504             queryParams.userId = peerUserId;
505         } else {
506             queryParams.sharedUserId = peerUserId;
507         }
508         res = QueryGroups(osAccountId, &queryParams, accountVec);
509     } while (0);
510     HcFree(peerUserId);
511     return res;
512 }
513 
AddSelfUserId(const TrustedGroupEntry * groupEntry,CJson * dataFromClient)514 static int32_t AddSelfUserId(const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
515 {
516     const char *selfUserId = StringGet(&groupEntry->userId);
517     if (selfUserId == NULL) {
518         LOGE("Failed to get local userId info from db!");
519         return HC_ERR_DB;
520     }
521     if (AddStringToJson(dataFromClient, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
522         LOGE("Failed to add self userId for server in account-related auth!");
523         return HC_ERR_JSON_FAIL;
524     }
525     return HC_SUCCESS;
526 }
527 
AddGroupIdForServer(const TrustedGroupEntry * groupEntry,CJson * dataFromClient)528 static int32_t AddGroupIdForServer(const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
529 {
530     const char *groupId = StringGet(&groupEntry->id);
531     if (groupId == NULL) {
532         LOGE("Failed to get groupId info from db!");
533         return HC_ERR_DB;
534     }
535     if (AddStringToJson(dataFromClient, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
536         LOGE("Failed to add groupId for server in account-related auth!");
537         return HC_ERR_JSON_FAIL;
538     }
539     return HC_SUCCESS;
540 }
541 
AddSelfDevInfoForServer(int32_t osAccountId,const TrustedGroupEntry * groupEntry,CJson * dataFromClient)542 static int32_t AddSelfDevInfoForServer(int32_t osAccountId, const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
543 {
544     TrustedDeviceEntry *localDevInfo = CreateDeviceEntry();
545     if (localDevInfo == NULL) {
546         LOGE("Failed to allocate memory for localDevInfo for server!");
547         return HC_ERR_ALLOC_MEMORY;
548     }
549     int32_t res;
550     do {
551         const char *groupId = StringGet(&groupEntry->id);
552         if (groupId == NULL) {
553             LOGE("Failed to get groupId for server!");
554             res = HC_ERR_NULL_PTR;
555             break;
556         }
557         res = GaGetLocalDeviceInfo(osAccountId, groupId, localDevInfo);
558         const char *selfDevId = StringGet(&(localDevInfo->authId));
559         const char *selfUdid = StringGet(&(localDevInfo->udid));
560         if ((res != HC_SUCCESS) || (selfDevId == NULL) || (selfUdid == NULL)) {
561             LOGE("Failed to get self id info from db!");
562             res = HC_ERR_DB;
563             break;
564         }
565         if (AddStringToJson(dataFromClient, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
566             LOGE("Failed to add self devId for server in account-related auth!");
567             res = HC_ERR_JSON_ADD;
568             break;
569         }
570         if (AddStringToJson(dataFromClient, FIELD_SELF_DEVICE_ID, selfUdid) != HC_SUCCESS) {
571             LOGE("Failed to add self udid for server in account-related auth!");
572             res = HC_ERR_JSON_ADD;
573             break;
574         }
575         const char *peerUdid = GetStringFromJson(dataFromClient, FIELD_PEER_CONN_DEVICE_ID);
576         if (peerUdid == NULL) {
577             LOGE("Failed to get peer udid for server auth!");
578             res = HC_ERR_JSON_FAIL;
579             break;
580         }
581         res = FillAccountCredentialInfo(osAccountId, peerUdid, groupId, localDevInfo, dataFromClient);
582     } while (0);
583     DestroyDeviceEntry(localDevInfo);
584     return res;
585 }
586 
AddServerParamsForAccountPlugin(CJson * dataFromClient)587 static void AddServerParamsForAccountPlugin(CJson *dataFromClient)
588 {
589     int32_t osAccountId = INVALID_OS_ACCOUNT;
590     if (GetIntFromJson(dataFromClient, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
591         LOGE("Failed to get osAccountId!");
592         return;
593     }
594     GroupEntryVec accountVec = CreateGroupEntryVec();
595     if (QueryGroupForAccountPlugin(osAccountId, &accountVec, dataFromClient) != HC_SUCCESS) {
596         LOGE("Failed to query group!");
597         ClearGroupEntryVec(&accountVec);
598         return;
599     }
600     if (accountVec.size(&accountVec) == 0) {
601         LOGE("Group size is 0!");
602         ClearGroupEntryVec(&accountVec);
603         return;
604     }
605     TrustedGroupEntry *groupEntry = accountVec.get(&accountVec, 0);
606     if (groupEntry == NULL) {
607         LOGE("Group entry is null!");
608         ClearGroupEntryVec(&accountVec);
609         return;
610     }
611     (void)AddGroupIdForServer(groupEntry, dataFromClient);
612     ClearGroupEntryVec(&accountVec);
613 }
614 
AddSelfAccountInfoForServer(CJson * dataFromClient)615 static int32_t AddSelfAccountInfoForServer(CJson *dataFromClient)
616 {
617     int32_t osAccountId = INVALID_OS_ACCOUNT;
618     if (GetIntFromJson(dataFromClient, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
619         LOGE("Failed to get osAccountId for server!");
620         return HC_ERR_JSON_GET;
621     }
622     GroupEntryVec accountVec = CreateGroupEntryVec();
623     int32_t res = QueryAuthGroupForServer(osAccountId, &accountVec, dataFromClient);
624     do {
625         if (res != HC_SUCCESS) {
626             LOGE("Failed to query account group info for server auth!");
627             break;
628         }
629         if (accountVec.size(&accountVec) == 0) {
630             LOGE("Database don't have local device's account group info for server!");
631             res = HC_ERR_NO_CANDIDATE_GROUP;
632             break;
633         }
634         TrustedGroupEntry *groupEntry = accountVec.get(&accountVec, 0);
635         if (groupEntry == NULL) {
636             LOGE("Local group info is null!");
637             res = HC_ERR_GROUP_NOT_EXIST;
638             break;
639         }
640         res = AddSelfUserId(groupEntry, dataFromClient);
641         if (res != HC_SUCCESS) {
642             break;
643         }
644         res = AddGroupIdForServer(groupEntry, dataFromClient);
645         if (res != HC_SUCCESS) {
646             break;
647         }
648         res = AddSelfDevInfoForServer(osAccountId, groupEntry, dataFromClient);
649     } while (0);
650     ClearGroupEntryVec(&accountVec);
651     return res;
652 }
653 
GetAuthParamsVecForServer(const CJson * dataFromClient,ParamsVecForAuth * authParamsVec)654 static int32_t GetAuthParamsVecForServer(const CJson *dataFromClient, ParamsVecForAuth *authParamsVec)
655 {
656     LOGI("Begin get account-related auth params for server.");
657     CJson *dupData = DuplicateJson(dataFromClient);
658     if (dupData == NULL) {
659         LOGE("Failed to create dupData for dataFromClient!");
660         return HC_ERR_JSON_FAIL;
661     }
662 
663     int32_t res = HC_SUCCESS;
664     if (HasAccountPlugin()) {
665         // Try to add groupId to auth params. If add fail, ignore it.
666         AddServerParamsForAccountPlugin(dupData);
667     } else {
668         res = AddSelfAccountInfoForServer(dupData);
669     }
670     if (res != HC_SUCCESS) {
671         LOGE("Failed to add account server params!");
672         FreeJson(dupData);
673         return res;
674     }
675 
676     if (authParamsVec->pushBack(authParamsVec, (const void **)&dupData) == NULL) {
677         LOGE("Failed to push json data to vector in account-related auth!");
678         FreeJson(dupData);
679         return HC_ERR_ALLOC_MEMORY;
680     }
681     return HC_SUCCESS;
682 }
683 
AccountOnFinishToPeer(int64_t requestId,const CJson * out,const DeviceAuthCallback * callback)684 static int32_t AccountOnFinishToPeer(int64_t requestId, const CJson *out, const DeviceAuthCallback *callback)
685 {
686     int32_t res = HC_SUCCESS;
687     CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
688     if (sendToPeer == NULL) {
689         LOGI("No need to transmit data to peer for account-related auth.");
690         return res;
691     }
692     if (AddBoolToJson(sendToPeer, FIELD_IS_DEVICE_LEVEL, false) != HC_SUCCESS) {
693         LOGE("Failed to add device level flag!");
694         return HC_ERR_JSON_ADD;
695     }
696     char *sendToPeerStr = PackJsonToString(sendToPeer);
697     if (sendToPeerStr == NULL) {
698         LOGE("Failed to pack sendToPeerStr!");
699         return HC_ERR_ALLOC_MEMORY;
700     }
701     if ((callback != NULL) && (callback->onTransmit != NULL)) {
702         LOGD("Begin to transmit data to peer for auth in AccountOnFinishToPeer.");
703         UPDATE_PERFORM_DATA_BY_SELF_INDEX(requestId, HcGetCurTimeInMillis());
704         if (!callback->onTransmit(requestId, (uint8_t *)sendToPeerStr, HcStrlen(sendToPeerStr) + 1)) {
705             LOGE("Failed to transmit data to peer!");
706             res = HC_ERR_TRANSMIT_FAIL;
707         }
708         LOGD("End to transmit data to peer for auth in AccountOnFinishToPeer.");
709     }
710     FreeJsonString(sendToPeerStr);
711     return res;
712 }
713 
PrepareTrustedDeviceInfo(const char * peerUdid,const char * groupId,const CJson * out,TrustedDeviceEntry * devEntry)714 static int32_t PrepareTrustedDeviceInfo(const char *peerUdid, const char *groupId,
715     const CJson *out, TrustedDeviceEntry *devEntry)
716 {
717     devEntry->source = SELF_CREATED;
718     const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
719     if (sendToSelf == NULL) {
720         LOGE("Failed to get sendToSelf data for account!");
721         return HC_ERR_JSON_GET;
722     }
723     int32_t credentialType = INVALID_CRED;
724     if (GetIntFromJson(sendToSelf, FIELD_CREDENTIAL_TYPE, &credentialType) != HC_SUCCESS) {
725         LOGE("Failed to get credentialType from json sendToSelf!");
726         return HC_ERR_JSON_GET;
727     }
728     devEntry->credential = credentialType;
729     const char *peerAuthId = GetStringFromJson(sendToSelf, FIELD_DEV_ID);
730     if (peerAuthId == NULL) {
731         LOGE("Failed to get peer authId for account!");
732         return HC_ERR_JSON_GET;
733     }
734     const char *peerUserId = GetStringFromJson(sendToSelf, FIELD_USER_ID);
735     if (peerUserId == NULL) {
736         LOGE("Failed to get peer userId!");
737         return HC_ERR_JSON_GET;
738     }
739     if (!StringSetPointer(&(devEntry->userId), peerUserId) ||
740         !StringSetPointer(&(devEntry->udid), peerUdid) ||
741         !StringSetPointer(&(devEntry->authId), peerAuthId) ||
742         !StringSetPointer(&(devEntry->groupId), groupId) ||
743         !StringSetPointer(&(devEntry->serviceType), groupId)) {
744         LOGE("Failed to add device info when adding a trusted device!");
745         return HC_ERR_MEMORY_COPY;
746     }
747     return HC_SUCCESS;
748 }
749 
AddTrustedDeviceForAccount(const CJson * authParam,const CJson * out)750 static int32_t AddTrustedDeviceForAccount(const CJson *authParam, const CJson *out)
751 {
752     int32_t osAccountId = ANY_OS_ACCOUNT;
753     if (GetIntFromJson(authParam, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
754         LOGE("Failed to get osAccountId for account!");
755         return HC_ERR_JSON_GET;
756     }
757     const char *peerUdid = GetStringFromJson(authParam, FIELD_PEER_CONN_DEVICE_ID);
758     if (peerUdid == NULL) {
759         LOGE("Failed to get peer udid when adding peer trusted device!");
760         return HC_ERR_JSON_GET;
761     }
762     const char *groupId = GetStringFromJson(authParam, FIELD_GROUP_ID);
763     if (groupId == NULL) {
764         LOGE("Failed to get groupId when adding peer trusted device!");
765         return HC_ERR_JSON_GET;
766     }
767     if (IsDeviceImportedByCloud(osAccountId, peerUdid, groupId)) {
768         LOGD("Peer trusted device is imported by cloud, we don't update peer device's trusted relationship.");
769         return HC_SUCCESS;
770     }
771     TrustedDeviceEntry *devEntry = CreateDeviceEntry();
772     if (devEntry == NULL) {
773         LOGE("Failed to allocate device entry memory!");
774         return HC_ERR_ALLOC_MEMORY;
775     }
776     int32_t res;
777     do {
778         res = PrepareTrustedDeviceInfo(peerUdid, groupId, out, devEntry);
779         if (res != HC_SUCCESS) {
780             LOGE("Failed to prepare trust device params!");
781             break;
782         }
783         res = AddTrustedDevice(osAccountId, devEntry);
784         if (res != HC_SUCCESS) {
785             LOGE("Failed to add trusted devices for account to database!");
786             break;
787         }
788         res = SaveOsAccountDb(osAccountId);
789     } while (0);
790     DestroyDeviceEntry(devEntry);
791     return res;
792 }
793 
PrepareAccountDataToSelf(const CJson * sendToSelf,CJson * returnToSelf)794 static int32_t PrepareAccountDataToSelf(const CJson *sendToSelf, CJson *returnToSelf)
795 {
796     int32_t res = GetSessionKeyForAccount(sendToSelf, returnToSelf);
797     if (res != HC_SUCCESS) {
798         LOGE("Failed to get session key info for account auth!");
799         return res;
800     }
801     res = GetUserIdForAccount(sendToSelf, returnToSelf);
802     if (res != HC_SUCCESS) {
803         LOGE("Failed to get user id for account auth!");
804     }
805     return res;
806 }
807 
ReportV1RelatedAuthCallEvent(int64_t requestId,const CJson * authParam)808 static void ReportV1RelatedAuthCallEvent(int64_t requestId, const CJson *authParam)
809 {
810 #ifdef DEV_AUTH_HIVIEW_ENABLE
811     DevAuthCallEvent eventData;
812     eventData.appId = SOFTBUS_APP_ID;
813     eventData.callResult = DEFAULT_CALL_RESULT;
814     eventData.processCode = PROCESS_AUTH_V1;
815     eventData.osAccountId = DEFAULT_OS_ACCOUNT;
816     eventData.funcName = AUTH_DEV_EVENT;
817     (void)GetIntFromJson(authParam, FIELD_OS_ACCOUNT_ID, &eventData.osAccountId);
818     eventData.credType = DEFAULT_CRED_TYPE;
819     eventData.groupType = IDENTICAL_ACCOUNT_GROUP;
820     eventData.executionTime = GET_TOTAL_CONSUME_TIME_BY_REQ_ID(requestId);
821     eventData.extInfo = DEFAULT_EXT_INFO;
822     DEV_AUTH_REPORT_CALL_EVENT(eventData);
823     return;
824 #endif
825     (void)requestId;
826     (void)authParam;
827     return;
828 }
829 
AccountOnFinishToSelf(int64_t requestId,const CJson * authParam,const CJson * out,const DeviceAuthCallback * callback)830 static int32_t AccountOnFinishToSelf(int64_t requestId, const CJson *authParam, const CJson *out,
831     const DeviceAuthCallback *callback)
832 {
833     const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
834     if (sendToSelf == NULL) {
835         LOGE("No data to send to self for onFinish.");
836         return HC_ERR_LOST_DATA;
837     }
838 
839     CJson *returnToSelf = CreateJson();
840     if (returnToSelf == NULL) {
841         LOGE("Failed to create json for account-related auth in onFinish!");
842         return HC_ERR_ALLOC_MEMORY;
843     }
844     int32_t res = PrepareAccountDataToSelf(sendToSelf, returnToSelf);
845     if (res != HC_SUCCESS) {
846         LOGE("Failed to add account-related returnToSelf data!");
847         ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
848         FreeJson(returnToSelf);
849         return res;
850     }
851     char *returnStr = PackJsonToString(returnToSelf);
852     ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
853     FreeJson(returnToSelf);
854     if (returnStr == NULL) {
855         LOGE("Failed to pack return data to string!");
856         return HC_ERR_ALLOC_MEMORY;
857     }
858     do {
859         int32_t authForm = AUTH_FORM_INVALID_TYPE;
860         if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
861             LOGE("Failed to get auth type!");
862             res = HC_ERR_JSON_GET;
863             break;
864         }
865         if ((callback != NULL) && (callback->onFinish != NULL)) {
866             LOGD("Group auth call onFinish for account related auth.");
867             UPDATE_PERFORM_DATA_BY_INPUT_INDEX(requestId, ON_FINISH_TIME, HcGetCurTimeInMillis());
868             callback->onFinish(requestId, authForm, returnStr);
869         }
870     } while (0);
871     ClearAndFreeJsonString(returnStr);
872     ReportV1RelatedAuthCallEvent(requestId, authParam);
873     return res;
874 }
875 
OnAccountFinish(int64_t requestId,const CJson * authParam,const CJson * out,const DeviceAuthCallback * callback)876 static void OnAccountFinish(int64_t requestId, const CJson *authParam, const CJson *out,
877     const DeviceAuthCallback *callback)
878 {
879     LOGI("Begin call onFinish for account-related auth.");
880     if (AccountOnFinishToPeer(requestId, out, callback) != HC_SUCCESS) {
881         LOGE("Failed to send data to peer when account-related auth finished!");
882         return;
883     }
884     if (ReturnSessionKey(requestId, out, callback) != HC_SUCCESS) {
885         LOGE("Failed to return session key for account-related auth!");
886         return;
887     }
888     if (AddTrustedDeviceForAccount(authParam, out) != HC_SUCCESS) {
889         LOGD("Failed to add peer trusted devices to database for account-related auth!");
890     }
891     if (AccountOnFinishToSelf(requestId, authParam, out, callback) != HC_SUCCESS) {
892         LOGE("Failed to send data to self when account-related auth finished!");
893         return;
894     }
895     LOGI("Call onFinish for account-related auth successfully.");
896 }
897 
GetAccountRelatedGroupAuth(void)898 BaseGroupAuth *GetAccountRelatedGroupAuth(void)
899 {
900     return (BaseGroupAuth *)&g_accountRelatedGroupAuth;
901 }