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, ©PeerData);
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 }