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