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 "account_auth_plugin_proxy.h"
18 #include "common_defs.h"
19 #include "device_auth_defines.h"
20 #include "group_auth_data_operation.h"
21 #include "hc_dev_info.h"
22 #include "hc_log.h"
23 #include "hc_time.h"
24 #include "hc_types.h"
25 #include "json_utils.h"
26 #include "performance_dumper.h"
27 #include "string_util.h"
28 #include "alg_loader.h"
29 #include "hisysevent_adapter.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 sessionKey!");
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("Failed to allocate memory for sessionKey!");
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 sessionKey!");
75 res = HC_ERR_JSON_GET;
76 break;
77 }
78 if ((callback == NULL) || (callback->onSessionKeyReturned == NULL)) {
79 LOGE("The callback of onSessionKeyReturned is null!");
80 res = HC_ERR_INVALID_PARAMS;
81 break;
82 }
83 LOGI("Begin invoke onSessionKeyReturned.");
84 UPDATE_PERFORM_DATA_BY_INPUT_INDEX(requestId, ON_SESSION_KEY_RETURN_TIME, HcGetCurTimeInMillis());
85 callback->onSessionKeyReturned(requestId, sessionKey, keyLen);
86 LOGI("End invoke onSessionKeyReturned, res = %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 allocate 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("Failed to get sessionKey!");
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("Failed to add sessionKey for onFinish!");
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 = %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 db, 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: %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 const char *groupId = StringGet(&tempEntry->id);
238 if (groupId != NULL) {
239 PRINT_SENSITIVE_DATA("GroupId", groupId);
240 }
241 HC_VECTOR_POPELEMENT(vec, &tempEntry, index);
242 DestroyGroupEntry((TrustedGroupEntry *)tempEntry);
243 }
244 LOGI("The candidate account group size is: %u", vec->size(vec));
245 }
246
GetAccountCandidateGroup(int32_t osAccountId,const CJson * param,QueryGroupParams * queryParams,GroupEntryVec * vec)247 static void GetAccountCandidateGroup(int32_t osAccountId, const CJson *param,
248 QueryGroupParams *queryParams, GroupEntryVec *vec)
249 {
250 /* Compare userId with local uid in DB. */
251 bool identicalFlag = false;
252 bool acrossAccountFlag = false;
253 const char *peerUserId = GetStringFromJson(param, FIELD_USER_ID);
254 if (peerUserId != NULL) {
255 acrossAccountFlag = true;
256 identicalFlag = IsPeerInIdenticalGroup(osAccountId, peerUserId);
257 } else {
258 LOGD("userId is null in authParam.");
259 identicalFlag = true;
260 }
261
262 if (identicalFlag) {
263 GaGetAccountGroup(osAccountId, IDENTICAL_ACCOUNT_GROUP, peerUserId, queryParams, vec);
264 } else if (acrossAccountFlag) {
265 GaGetAccountGroup(osAccountId, ACROSS_ACCOUNT_AUTHORIZE_GROUP, peerUserId, queryParams, vec);
266 }
267 }
268
FillAccountCredentialInfo(int32_t osAccountId,const char * peerUdid,const char * groupId,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)269 static int32_t FillAccountCredentialInfo(int32_t osAccountId, const char *peerUdid, const char *groupId,
270 const TrustedDeviceEntry *localAuthInfo, CJson *paramsData)
271 {
272 TrustedDeviceEntry *peerDevInfo = CreateDeviceEntry();
273 if (peerDevInfo == NULL) {
274 LOGE("Failed to alloc memory for peerDevInfo!");
275 return HC_ERR_ALLOC_MEMORY;
276 }
277 int32_t localDevType = DEVICE_TYPE_CONTROLLER;
278 int32_t authCredential = localAuthInfo->credential;
279 int32_t res = GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, peerDevInfo);
280 if ((res != HC_SUCCESS) || (peerDevInfo->source == SELF_CREATED)) {
281 LOGI("Peer device's query result = %d, pass local device info to account authenticator.", res);
282 localDevType = DEVICE_TYPE_ACCESSORY; /* Controller has peer device info, which is added by caller. */
283 }
284 if ((res == HC_SUCCESS) && (peerDevInfo->source == IMPORTED_FROM_CLOUD)) {
285 LOGI("Peer trusted device is imported by cloud, invoke sym account auth.");
286 authCredential = peerDevInfo->credential;
287 }
288 DestroyDeviceEntry(peerDevInfo);
289 if (AddIntToJson(paramsData, FIELD_LOCAL_DEVICE_TYPE, localDevType) != HC_SUCCESS) {
290 LOGE("Failed to add self device type to json!");
291 return HC_ERR_JSON_ADD;
292 }
293 if (AddIntToJson(paramsData, FIELD_CREDENTIAL_TYPE, authCredential) != HC_SUCCESS) {
294 LOGE("Failed to add self credential type to json!");
295 return HC_ERR_JSON_ADD;
296 }
297 return HC_SUCCESS;
298 }
299
FillAccountAuthInfo(int32_t osAccountId,const TrustedGroupEntry * entry,const TrustedDeviceEntry * localAuthInfo,CJson * paramsData)300 static int32_t FillAccountAuthInfo(int32_t osAccountId, const TrustedGroupEntry *entry,
301 const TrustedDeviceEntry *localAuthInfo, CJson *paramsData)
302 {
303 const char *peerUdid = GetStringFromJson(paramsData, FIELD_PEER_CONN_DEVICE_ID);
304 if (peerUdid == NULL) {
305 LOGE("Failed to get peer udid in the input data for account auth!");
306 return HC_ERR_INVALID_PARAMS;
307 }
308 const char *selfUserId = StringGet(&entry->userId);
309 const char *groupId = StringGet(&entry->id);
310 const char *selfDeviceId = StringGet(&(localAuthInfo->udid));
311 const char *selfDevId = StringGet(&(localAuthInfo->authId));
312 if ((selfUserId == NULL) || (groupId == NULL) || (selfDeviceId == NULL) || (selfDevId == NULL)) {
313 LOGE("Failed to get self account info for client in account-related auth!");
314 return HC_ERR_JSON_GET;
315 }
316 if (AddStringToJson(paramsData, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
317 LOGE("Failed to add self userId for client in account-related auth!");
318 return HC_ERR_JSON_FAIL;
319 }
320 if (AddStringToJson(paramsData, FIELD_SELF_DEVICE_ID, selfDeviceId) != HC_SUCCESS) {
321 LOGE("Failed to add self deviceId for client in account-related auth!");
322 return HC_ERR_JSON_FAIL;
323 }
324 if (AddStringToJson(paramsData, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
325 LOGE("Failed to add self devId for client in account-related auth!");
326 return HC_ERR_JSON_FAIL;
327 }
328 return FillAccountCredentialInfo(osAccountId, peerUdid, groupId, localAuthInfo, paramsData);
329 }
330
IsDeviceImportedByCloud(int32_t osAccountId,const char * peerUdid,const char * groupId)331 static bool IsDeviceImportedByCloud(int32_t osAccountId, const char *peerUdid, const char *groupId)
332 {
333 TrustedDeviceEntry *peerDeviceInfo = CreateDeviceEntry();
334 if (peerDeviceInfo == NULL) {
335 LOGE("Failed to alloc memory for peerDeviceInfo!");
336 return true;
337 }
338 if (GaGetTrustedDeviceEntryById(osAccountId, peerUdid, true, groupId, peerDeviceInfo) != HC_SUCCESS) {
339 LOGI("Peer trusted device is not in database.");
340 DestroyDeviceEntry(peerDeviceInfo);
341 return false;
342 }
343 uint8_t source = peerDeviceInfo->source;
344 DestroyDeviceEntry(peerDeviceInfo);
345 if (source == IMPORTED_FROM_CLOUD) {
346 LOGI("Peer trusted device is imported by cloud.");
347 return true;
348 }
349 return false;
350 }
351
CombineAccountServerConfirms(const CJson * confirmationJson,CJson * dataFromClient)352 static int32_t CombineAccountServerConfirms(const CJson *confirmationJson, CJson *dataFromClient)
353 {
354 bool isClient = false;
355 if (AddBoolToJson(dataFromClient, FIELD_IS_CLIENT, isClient) != HC_SUCCESS) {
356 LOGE("Failed to combine server param for isClient!");
357 return HC_ERR_JSON_FAIL;
358 }
359 const char *peerUdid = GetStringFromJson(confirmationJson, FIELD_PEER_CONN_DEVICE_ID);
360 if (peerUdid == NULL) {
361 LOGE("Failed to get peer udid from server confirm params!");
362 return HC_ERR_JSON_GET;
363 }
364 if (AddStringToJson(dataFromClient, FIELD_PEER_CONN_DEVICE_ID, peerUdid) != HC_SUCCESS) {
365 LOGE("Failed to combine server param for peerUdid!");
366 return HC_ERR_JSON_FAIL;
367 }
368 return HC_SUCCESS;
369 }
370
QueryAuthGroupForServer(int32_t osAccountId,GroupEntryVec * accountVec,CJson * data)371 static int32_t QueryAuthGroupForServer(int32_t osAccountId, GroupEntryVec *accountVec, CJson *data)
372 {
373 const char *peerUserId = GetStringFromJson(data, FIELD_USER_ID);
374 if (peerUserId == NULL) {
375 LOGE("Failed to get peerUserId.");
376 return HC_ERR_JSON_GET;
377 }
378 int32_t authForm = AUTH_FORM_INVALID_TYPE;
379 if (GetIntFromJson(data, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
380 LOGE("Failed to get auth form for server!");
381 return HC_ERR_JSON_GET;
382 }
383 int32_t groupType = AuthFormToGroupType(authForm);
384 if (groupType == GROUP_TYPE_INVALID) {
385 LOGE("Invalid authForm, authForm = %d.", authForm);
386 return HC_ERR_INVALID_PARAMS;
387 }
388 QueryGroupParams queryParams = InitQueryGroupParams();
389 queryParams.groupType = (uint32_t)groupType;
390 if (queryParams.groupType == IDENTICAL_ACCOUNT_GROUP) {
391 queryParams.userId = peerUserId;
392 } else {
393 queryParams.sharedUserId = peerUserId;
394 }
395 int32_t res = QueryGroups(osAccountId, &queryParams, accountVec);
396 if (res != HC_SUCCESS) {
397 LOGE("Failed to query local device's account group info for server!");
398 return res;
399 }
400 if (accountVec->size(accountVec) == 0) {
401 LOGE("Database don't have local device's account group info for server!");
402 return HC_ERR_NO_CANDIDATE_GROUP;
403 }
404 return HC_SUCCESS;
405 }
406
GetValueFromJsonStr(char * jsonStr,const char * key)407 static char *GetValueFromJsonStr(char *jsonStr, const char *key)
408 {
409 if (HcStrlen(jsonStr) > MAX_SERVICE_PEER_DATA_LENGTH) {
410 LOGE("Invalid peer data length!");
411 return NULL;
412 }
413 uint32_t keyLen = HcStrlen(key);
414 char *keyStr = (char *)HcMalloc(keyLen + PLACE_HOLDER_LENGTH, 0);
415 if (keyStr == NULL) {
416 LOGE("Failed to alloc memory for keyStr!");
417 return NULL;
418 }
419 if (sprintf_s(keyStr, keyLen + PLACE_HOLDER_LENGTH, JSON_KEY_FORMAT, key) <= 0) {
420 LOGE("Failed to convert key to string!");
421 HcFree(keyStr);
422 return NULL;
423 }
424 char *nextPtr = NULL;
425 char *value = NULL;
426 char *subVal = strtok_s(jsonStr, COMMA_SEPARATOR, &nextPtr);
427 while (subVal != NULL) {
428 if (strstr(subVal, keyStr) != NULL) {
429 value = strstr(subVal, COLON_SEPARATOR);
430 if (value != NULL) {
431 value++;
432 }
433 break;
434 }
435 subVal = strtok_s(NULL, COMMA_SEPARATOR, &nextPtr);
436 }
437 HcFree(keyStr);
438 return value;
439 }
440
GetPeerUserIdFromReceivedData(const CJson * data,char ** peerUserId)441 static int32_t GetPeerUserIdFromReceivedData(const CJson *data, char **peerUserId)
442 {
443 const char *peerData = GetStringFromJson(data, FIELD_PLUGIN_EXT_DATA);
444 if (peerData == NULL) {
445 LOGE("Failed to get peerData from data!");
446 return HC_ERR_JSON_GET;
447 }
448 char *copyPeerData = NULL;
449 int32_t res = DeepCopyString(peerData, ©PeerData);
450 if (res != HC_SUCCESS) {
451 LOGE("Failed to deep copy peerData!");
452 return res;
453 }
454 char *userId = GetValueFromJsonStr(copyPeerData, FIELD_USER_ID);
455 if (userId == NULL) {
456 LOGE("Failed to get userId from peer data!");
457 HcFree(copyPeerData);
458 return HC_ERR_JSON_GET;
459 }
460 uint8_t userIdHash[SHA256_LEN] = { 0 };
461 Uint8Buff hashBuff = { userIdHash, sizeof(userIdHash) };
462 Uint8Buff hashMsgBuff = { (uint8_t *)userId, HcStrlen(userId) };
463 res = GetLoaderInstance()->sha256(&hashMsgBuff, &hashBuff);
464 HcFree(copyPeerData);
465 if (res != HC_SUCCESS) {
466 LOGE("Failed to get hash for userId!");
467 return res;
468 }
469 uint32_t hexLen = hashBuff.length * BYTE_TO_HEX_OPER_LENGTH + 1;
470 *peerUserId = (char *)HcMalloc(hexLen, 0);
471 if (*peerUserId == NULL) {
472 LOGE("Failed to alloc memory for peer userId!");
473 return HC_ERR_ALLOC_MEMORY;
474 }
475 res = ByteToHexString(hashBuff.val, hashBuff.length, *peerUserId, hexLen);
476 if (res != HC_SUCCESS) {
477 LOGE("Failed to convert hash to hex string!");
478 HcFree(*peerUserId);
479 *peerUserId = NULL;
480 return res;
481 }
482 return HC_SUCCESS;
483 }
484
QueryGroupForAccountPlugin(int32_t osAccountId,GroupEntryVec * accountVec,CJson * data)485 static int32_t QueryGroupForAccountPlugin(int32_t osAccountId, GroupEntryVec *accountVec, CJson *data)
486 {
487 char *peerUserId = NULL;
488 int32_t res = GetPeerUserIdFromReceivedData(data, &peerUserId);
489 if (res != HC_SUCCESS) {
490 return res;
491 }
492 do {
493 int32_t authForm = AUTH_FORM_INVALID_TYPE;
494 if (GetIntFromJson(data, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
495 LOGE("Failed to get auth form for server!");
496 res = HC_ERR_JSON_GET;
497 break;
498 }
499 int32_t groupType = AuthFormToGroupType(authForm);
500 if (groupType == GROUP_TYPE_INVALID) {
501 LOGE("Invalid authForm: %d.", authForm);
502 res = HC_ERR_INVALID_PARAMS;
503 break;
504 }
505 QueryGroupParams queryParams = InitQueryGroupParams();
506 queryParams.groupType = (uint32_t)groupType;
507 if (queryParams.groupType == IDENTICAL_ACCOUNT_GROUP) {
508 queryParams.userId = peerUserId;
509 } else {
510 queryParams.sharedUserId = peerUserId;
511 }
512 res = QueryGroups(osAccountId, &queryParams, accountVec);
513 } while (0);
514 HcFree(peerUserId);
515 return res;
516 }
517
AddSelfUserId(const TrustedGroupEntry * groupEntry,CJson * dataFromClient)518 static int32_t AddSelfUserId(const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
519 {
520 const char *selfUserId = StringGet(&groupEntry->userId);
521 if (selfUserId == NULL) {
522 LOGE("Failed to get local userId info from db!");
523 return HC_ERR_DB;
524 }
525 if (AddStringToJson(dataFromClient, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
526 LOGE("Failed to add self userId for server in account-related auth!");
527 return HC_ERR_JSON_FAIL;
528 }
529 return HC_SUCCESS;
530 }
531
AddGroupIdForServer(const TrustedGroupEntry * groupEntry,CJson * dataFromClient)532 static int32_t AddGroupIdForServer(const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
533 {
534 const char *groupId = StringGet(&groupEntry->id);
535 if (groupId == NULL) {
536 LOGE("Failed to get groupId info from db!");
537 return HC_ERR_DB;
538 }
539 if (AddStringToJson(dataFromClient, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
540 LOGE("Failed to add groupId for server in account-related auth!");
541 return HC_ERR_JSON_FAIL;
542 }
543 return HC_SUCCESS;
544 }
545
AddSelfDevInfoForServer(int32_t osAccountId,const TrustedGroupEntry * groupEntry,CJson * dataFromClient)546 static int32_t AddSelfDevInfoForServer(int32_t osAccountId, const TrustedGroupEntry *groupEntry, CJson *dataFromClient)
547 {
548 TrustedDeviceEntry *localDevInfo = CreateDeviceEntry();
549 if (localDevInfo == NULL) {
550 LOGE("Failed to allocate memory for localDevInfo for server!");
551 return HC_ERR_ALLOC_MEMORY;
552 }
553 int32_t res;
554 do {
555 const char *groupId = StringGet(&groupEntry->id);
556 if (groupId == NULL) {
557 LOGE("Failed to get groupId for server!");
558 res = HC_ERR_NULL_PTR;
559 break;
560 }
561 res = GaGetLocalDeviceInfo(osAccountId, groupId, localDevInfo);
562 const char *selfDevId = StringGet(&(localDevInfo->authId));
563 const char *selfUdid = StringGet(&(localDevInfo->udid));
564 if ((res != HC_SUCCESS) || (selfDevId == NULL) || (selfUdid == NULL)) {
565 LOGE("Failed to get self id info from db!");
566 res = HC_ERR_DB;
567 break;
568 }
569 if (AddStringToJson(dataFromClient, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
570 LOGE("Failed to add self devId for server in account-related auth!");
571 res = HC_ERR_JSON_ADD;
572 break;
573 }
574 if (AddStringToJson(dataFromClient, FIELD_SELF_DEVICE_ID, selfUdid) != HC_SUCCESS) {
575 LOGE("Failed to add self udid for server in account-related auth!");
576 res = HC_ERR_JSON_ADD;
577 break;
578 }
579 const char *peerUdid = GetStringFromJson(dataFromClient, FIELD_PEER_CONN_DEVICE_ID);
580 if (peerUdid == NULL) {
581 LOGE("Failed to get peer udid for server auth!");
582 res = HC_ERR_JSON_FAIL;
583 break;
584 }
585 res = FillAccountCredentialInfo(osAccountId, peerUdid, groupId, localDevInfo, dataFromClient);
586 } while (0);
587 DestroyDeviceEntry(localDevInfo);
588 return res;
589 }
590
AddServerParamsForAccountPlugin(CJson * dataFromClient)591 static int32_t AddServerParamsForAccountPlugin(CJson *dataFromClient)
592 {
593 int32_t osAccountId = INVALID_OS_ACCOUNT;
594 if (GetIntFromJson(dataFromClient, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
595 LOGE("Failed to get osAccountId!");
596 return HC_ERR_JSON_GET;
597 }
598 GroupEntryVec accountVec = CreateGroupEntryVec();
599 int32_t res = QueryGroupForAccountPlugin(osAccountId, &accountVec, dataFromClient);
600 if (res != HC_SUCCESS) {
601 LOGE("Failed to query group!");
602 ClearGroupEntryVec(&accountVec);
603 return res;
604 }
605 if (accountVec.size(&accountVec) == 0) {
606 // if group not found by peer userId, no need to add groupId to params, return success.
607 LOGE("Group size is 0!");
608 ClearGroupEntryVec(&accountVec);
609 return HC_SUCCESS;
610 }
611 TrustedGroupEntry *groupEntry = accountVec.get(&accountVec, 0);
612 if (groupEntry == NULL) {
613 LOGE("Group entry is null!");
614 ClearGroupEntryVec(&accountVec);
615 return HC_ERR_GROUP_NOT_EXIST;
616 }
617 res = AddGroupIdForServer(groupEntry, dataFromClient);
618 ClearGroupEntryVec(&accountVec);
619 return res;
620 }
621
AddSelfAccountInfoForServer(CJson * dataFromClient)622 static int32_t AddSelfAccountInfoForServer(CJson *dataFromClient)
623 {
624 int32_t osAccountId = INVALID_OS_ACCOUNT;
625 if (GetIntFromJson(dataFromClient, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
626 LOGE("Failed to get osAccountId for server!");
627 return HC_ERR_JSON_GET;
628 }
629 GroupEntryVec accountVec = CreateGroupEntryVec();
630 int32_t res = QueryAuthGroupForServer(osAccountId, &accountVec, dataFromClient);
631 do {
632 if (res != HC_SUCCESS) {
633 LOGE("Failed to query account group info for server auth!");
634 break;
635 }
636 if (accountVec.size(&accountVec) == 0) {
637 LOGE("Database don't have local device's account group info for server!");
638 res = HC_ERR_NO_CANDIDATE_GROUP;
639 break;
640 }
641 TrustedGroupEntry *groupEntry = accountVec.get(&accountVec, 0);
642 if (groupEntry == NULL) {
643 LOGE("Local group info is null!");
644 res = HC_ERR_GROUP_NOT_EXIST;
645 break;
646 }
647 res = AddSelfUserId(groupEntry, dataFromClient);
648 if (res != HC_SUCCESS) {
649 break;
650 }
651 res = AddGroupIdForServer(groupEntry, dataFromClient);
652 if (res != HC_SUCCESS) {
653 break;
654 }
655 res = AddSelfDevInfoForServer(osAccountId, groupEntry, dataFromClient);
656 } while (0);
657 ClearGroupEntryVec(&accountVec);
658 return res;
659 }
660
GetAuthParamsVecForServer(const CJson * dataFromClient,ParamsVecForAuth * authParamsVec)661 static int32_t GetAuthParamsVecForServer(const CJson *dataFromClient, ParamsVecForAuth *authParamsVec)
662 {
663 LOGI("Begin get account-related auth params for server.");
664 CJson *dupData = DuplicateJson(dataFromClient);
665 if (dupData == NULL) {
666 LOGE("Failed to create dupData for dataFromClient!");
667 return HC_ERR_JSON_FAIL;
668 }
669
670 int32_t res;
671 if (HasAccountAuthPlugin() == HC_SUCCESS) {
672 res = AddServerParamsForAccountPlugin(dupData);
673 } else {
674 res = AddSelfAccountInfoForServer(dupData);
675 }
676 if (res != HC_SUCCESS) {
677 LOGE("Failed to add account server params!");
678 FreeJson(dupData);
679 return res;
680 }
681
682 if (authParamsVec->pushBack(authParamsVec, (const void **)&dupData) == NULL) {
683 LOGE("Failed to push json data to vector in account-related auth!");
684 FreeJson(dupData);
685 return HC_ERR_ALLOC_MEMORY;
686 }
687 return HC_SUCCESS;
688 }
689
AccountOnFinishToPeer(int64_t requestId,const CJson * out,const DeviceAuthCallback * callback)690 static int32_t AccountOnFinishToPeer(int64_t requestId, const CJson *out, const DeviceAuthCallback *callback)
691 {
692 int32_t res = HC_SUCCESS;
693 CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
694 if (sendToPeer == NULL) {
695 LOGI("No need to transmit data to peer for account-related auth.");
696 return res;
697 }
698 if (AddBoolToJson(sendToPeer, FIELD_IS_DEVICE_LEVEL, false) != HC_SUCCESS) {
699 LOGE("Failed to add device level flag!");
700 return HC_ERR_JSON_ADD;
701 }
702 char *sendToPeerStr = PackJsonToString(sendToPeer);
703 if (sendToPeerStr == NULL) {
704 LOGE("Failed to pack sendToPeerStr!");
705 return HC_ERR_ALLOC_MEMORY;
706 }
707 if ((callback != NULL) && (callback->onTransmit != NULL)) {
708 LOGD("Begin to transmit data to peer for auth in AccountOnFinishToPeer.");
709 UPDATE_PERFORM_DATA_BY_SELF_INDEX(requestId, HcGetCurTimeInMillis());
710 if (!callback->onTransmit(requestId, (uint8_t *)sendToPeerStr, HcStrlen(sendToPeerStr) + 1)) {
711 LOGE("Failed to transmit data to peer!");
712 res = HC_ERR_TRANSMIT_FAIL;
713 }
714 LOGD("End to transmit data to peer for auth in AccountOnFinishToPeer.");
715 }
716 FreeJsonString(sendToPeerStr);
717 return res;
718 }
719
PrepareTrustedDeviceInfo(const char * peerUdid,const char * groupId,const CJson * out,TrustedDeviceEntry * devEntry)720 static int32_t PrepareTrustedDeviceInfo(const char *peerUdid, const char *groupId,
721 const CJson *out, TrustedDeviceEntry *devEntry)
722 {
723 devEntry->source = SELF_CREATED;
724 const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
725 if (sendToSelf == NULL) {
726 LOGE("Failed to get sendToSelf data for account!");
727 return HC_ERR_JSON_GET;
728 }
729 int32_t credentialType = INVALID_CRED;
730 if (GetIntFromJson(sendToSelf, FIELD_CREDENTIAL_TYPE, &credentialType) != HC_SUCCESS) {
731 LOGE("Failed to get credentialType from json sendToSelf!");
732 return HC_ERR_JSON_GET;
733 }
734 devEntry->credential = credentialType;
735 const char *peerAuthId = GetStringFromJson(sendToSelf, FIELD_DEV_ID);
736 if (peerAuthId == NULL) {
737 LOGE("Failed to get peer authId for account!");
738 return HC_ERR_JSON_GET;
739 }
740 const char *peerUserId = GetStringFromJson(sendToSelf, FIELD_USER_ID);
741 if (peerUserId == NULL) {
742 LOGE("Failed to get peer userId!");
743 return HC_ERR_JSON_GET;
744 }
745 if (!StringSetPointer(&(devEntry->userId), peerUserId) ||
746 !StringSetPointer(&(devEntry->udid), peerUdid) ||
747 !StringSetPointer(&(devEntry->authId), peerAuthId) ||
748 !StringSetPointer(&(devEntry->groupId), groupId) ||
749 !StringSetPointer(&(devEntry->serviceType), groupId)) {
750 LOGE("Failed to add device info when adding a trusted device!");
751 return HC_ERR_MEMORY_COPY;
752 }
753 return HC_SUCCESS;
754 }
755
AddTrustedDeviceForAccount(const CJson * authParam,const CJson * out)756 static int32_t AddTrustedDeviceForAccount(const CJson *authParam, const CJson *out)
757 {
758 int32_t osAccountId = ANY_OS_ACCOUNT;
759 if (GetIntFromJson(authParam, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
760 LOGE("Failed to get osAccountId for account!");
761 return HC_ERR_JSON_GET;
762 }
763 const char *peerUdid = GetStringFromJson(authParam, FIELD_PEER_CONN_DEVICE_ID);
764 if (peerUdid == NULL) {
765 LOGE("Failed to get peer udid when adding peer trusted device!");
766 return HC_ERR_JSON_GET;
767 }
768 const char *groupId = GetStringFromJson(authParam, FIELD_GROUP_ID);
769 if (groupId == NULL) {
770 LOGE("Failed to get groupId when adding peer trusted device!");
771 return HC_ERR_JSON_GET;
772 }
773 if (IsDeviceImportedByCloud(osAccountId, peerUdid, groupId)) {
774 LOGD("Peer trusted device is imported by cloud, we don't update peer device's trusted relationship.");
775 return HC_SUCCESS;
776 }
777 TrustedDeviceEntry *devEntry = CreateDeviceEntry();
778 if (devEntry == NULL) {
779 LOGE("Failed to allocate device entry memory!");
780 return HC_ERR_ALLOC_MEMORY;
781 }
782 int32_t res;
783 do {
784 res = PrepareTrustedDeviceInfo(peerUdid, groupId, out, devEntry);
785 if (res != HC_SUCCESS) {
786 LOGE("Failed to prepare trust device params!");
787 break;
788 }
789 res = AddTrustedDevice(osAccountId, devEntry);
790 if (res != HC_SUCCESS) {
791 LOGE("Failed to add trusted devices for account to database!");
792 break;
793 }
794 res = SaveOsAccountDb(osAccountId);
795 } while (0);
796 DestroyDeviceEntry(devEntry);
797 return res;
798 }
799
PrepareAccountDataToSelf(const CJson * sendToSelf,CJson * returnToSelf)800 static int32_t PrepareAccountDataToSelf(const CJson *sendToSelf, CJson *returnToSelf)
801 {
802 int32_t res = GetSessionKeyForAccount(sendToSelf, returnToSelf);
803 if (res != HC_SUCCESS) {
804 LOGE("Failed to get session key info for account auth!");
805 return res;
806 }
807 res = GetUserIdForAccount(sendToSelf, returnToSelf);
808 if (res != HC_SUCCESS) {
809 LOGE("Failed to get user id for account auth!");
810 }
811 return res;
812 }
813
ReportV1RelatedAuthCallEvent(int64_t requestId,const CJson * authParam)814 static void ReportV1RelatedAuthCallEvent(int64_t requestId, const CJson *authParam)
815 {
816 #ifdef DEV_AUTH_HIVIEW_ENABLE
817 DevAuthCallEvent eventData;
818 eventData.appId = SOFTBUS_APP_ID;
819 eventData.funcName = AUTH_DEV_EVENT;
820 eventData.osAccountId = DEFAULT_OS_ACCOUNT;
821 (void)GetIntFromJson(authParam, FIELD_OS_ACCOUNT_ID, &eventData.osAccountId);
822 eventData.callResult = DEFAULT_CALL_RESULT;
823 eventData.processCode = PROCESS_AUTH_V1;
824 eventData.credType = DEFAULT_CRED_TYPE;
825 eventData.groupType = IDENTICAL_ACCOUNT_GROUP;
826 eventData.executionTime = GET_TOTAL_CONSUME_TIME_BY_REQ_ID(requestId);
827 eventData.extInfo = DEFAULT_EXT_INFO;
828 DEV_AUTH_REPORT_CALL_EVENT(eventData);
829 return;
830 #endif
831 (void)requestId;
832 (void)authParam;
833 return;
834 }
835
AccountOnFinishToSelf(int64_t requestId,const CJson * authParam,const CJson * out,const DeviceAuthCallback * callback)836 static int32_t AccountOnFinishToSelf(int64_t requestId, const CJson *authParam, const CJson *out,
837 const DeviceAuthCallback *callback)
838 {
839 const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
840 if (sendToSelf == NULL) {
841 LOGE("No data to send to self for onFinish.");
842 return HC_ERR_LOST_DATA;
843 }
844
845 CJson *returnToSelf = CreateJson();
846 if (returnToSelf == NULL) {
847 LOGE("Failed to create json for account-related auth in onFinish!");
848 return HC_ERR_ALLOC_MEMORY;
849 }
850 int32_t res = PrepareAccountDataToSelf(sendToSelf, returnToSelf);
851 if (res != HC_SUCCESS) {
852 LOGE("Failed to add account-related returnToSelf data!");
853 ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
854 FreeJson(returnToSelf);
855 return res;
856 }
857 char *returnStr = PackJsonToString(returnToSelf);
858 ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
859 FreeJson(returnToSelf);
860 if (returnStr == NULL) {
861 LOGE("Failed to pack return data to string!");
862 return HC_ERR_ALLOC_MEMORY;
863 }
864 do {
865 int32_t authForm = AUTH_FORM_INVALID_TYPE;
866 if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
867 LOGE("Failed to get auth type!");
868 res = HC_ERR_JSON_GET;
869 break;
870 }
871 if ((callback != NULL) && (callback->onFinish != NULL)) {
872 LOGD("Group auth call onFinish for account related auth.");
873 UPDATE_PERFORM_DATA_BY_INPUT_INDEX(requestId, ON_FINISH_TIME, HcGetCurTimeInMillis());
874 callback->onFinish(requestId, authForm, returnStr);
875 }
876 } while (0);
877 ClearAndFreeJsonString(returnStr);
878 ReportV1RelatedAuthCallEvent(requestId, authParam);
879 return res;
880 }
881
OnAccountFinish(int64_t requestId,const CJson * authParam,const CJson * out,const DeviceAuthCallback * callback)882 static void OnAccountFinish(int64_t requestId, const CJson *authParam, const CJson *out,
883 const DeviceAuthCallback *callback)
884 {
885 LOGI("Begin call onFinish for account-related auth.");
886 if (AccountOnFinishToPeer(requestId, out, callback) != HC_SUCCESS) {
887 LOGE("Failed to send data to peer when account-related auth finished!");
888 return;
889 }
890 if (ReturnSessionKey(requestId, out, callback) != HC_SUCCESS) {
891 LOGE("Failed to return session key for account-related auth!");
892 return;
893 }
894 if (AddTrustedDeviceForAccount(authParam, out) != HC_SUCCESS) {
895 LOGD("Failed to add peer trusted devices to database for account-related auth!");
896 }
897 if (AccountOnFinishToSelf(requestId, authParam, out, callback) != HC_SUCCESS) {
898 LOGE("Failed to send data to self when account-related auth finished!");
899 return;
900 }
901 LOGI("Call onFinish for account-related auth successfully.");
902 }
903
GetAccountRelatedGroupAuth(void)904 BaseGroupAuth *GetAccountRelatedGroupAuth(void)
905 {
906 return (BaseGroupAuth *)&g_accountRelatedGroupAuth;
907 }