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