1 /*
2 * Copyright (c) 2023-2025 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 "auth_hichain_adapter.h"
17
18 #include <string.h>
19
20 #include "auth_common.h"
21 #include "auth_log.h"
22 #include "auth_session_fsm.h"
23 #include "bus_center_manager.h"
24 #include "device_auth.h"
25 #include "device_auth_defines.h"
26 #include "lnn_ohos_account_adapter.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_error_code.h"
29 #include "softbus_json_utils.h"
30
31 #define AUTH_APPID "softbus_auth"
32 #define GROUP_ID "groupId"
33 #define GROUP_TYPE "groupType"
34 #define AUTH_ID "authId"
35 #define RETRY_TIMES 16
36 #define RETRY_MILLSECONDS 500
37 #define SAME_ACCOUNT_GROUY_TYPE 1
38 static const GroupAuthManager *g_hichain = NULL;
39 #define CUST_UDID_LEN 16
40 #define KEY_LENGTH 16 /* Note: WinPc's special nearby only support 128 bits key */
41 #define FIELD_META_NODE_TYPE "metaNodeType"
42 #define META_NODE_TYPE_PC "0x0C"
43
GenDeviceLevelParam(HiChainAuthParam * hiChainParam)44 char *GenDeviceLevelParam(HiChainAuthParam *hiChainParam)
45 {
46 if (hiChainParam == NULL) {
47 AUTH_LOGE(AUTH_HICHAIN, "parameter is null");
48 return NULL;
49 }
50
51 cJSON *msg = cJSON_CreateObject();
52 if (msg == NULL) {
53 AUTH_LOGE(AUTH_HICHAIN, "create json fail");
54 return NULL;
55 }
56 if (!AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, hiChainParam->udid) ||
57 !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
58 !AddBoolToJsonObject(msg, FIELD_IS_DEVICE_LEVEL, true) ||
59 !AddBoolToJsonObject(msg, FIELD_IS_CLIENT, true) ||
60 !AddBoolToJsonObject(msg, FIELD_IS_UDID_HASH, false) ||
61 !AddNumberToJsonObject(msg, FIELD_KEY_LENGTH, KEY_LENGTH)) {
62 AUTH_LOGE(AUTH_HICHAIN, "add json object fail");
63 cJSON_Delete(msg);
64 return NULL;
65 }
66 if (hiChainParam->deviceTypeId == TYPE_PC_ID) {
67 if (!AddStringToJsonObject(msg, FIELD_META_NODE_TYPE, META_NODE_TYPE_PC)) {
68 AUTH_LOGE(AUTH_HICHAIN, "add json meta node fail");
69 }
70 }
71 if (hiChainParam->userId != 0 && !AddNumberToJsonObject(msg, "peerOsAccountId", hiChainParam->userId)) {
72 AUTH_LOGE(AUTH_HICHAIN, "add json userId fail");
73 }
74 #ifdef AUTH_ACCOUNT
75 AUTH_LOGI(AUTH_HICHAIN, "in account auth mode");
76 if (!AddStringToJsonObject(msg, FIELD_UID_HASH, hiChainParam->uid)) {
77 AUTH_LOGE(AUTH_HICHAIN, "add uid into json fail");
78 cJSON_Delete(msg);
79 return NULL;
80 }
81 #endif
82 char *data = cJSON_PrintUnformatted(msg);
83 if (data == NULL) {
84 AUTH_LOGE(AUTH_HICHAIN, "cJSON_PrintUnformatted fail");
85 }
86 cJSON_Delete(msg);
87 return data;
88 }
89
InitHichain(void)90 static const GroupAuthManager *InitHichain(void)
91 {
92 int32_t ret = InitDeviceAuthService();
93 if (ret != 0) {
94 AUTH_LOGE(AUTH_INIT, "hichain InitDeviceAuthService failed err=%{public}d", ret);
95 return NULL;
96 }
97 const GroupAuthManager *gaIns = GetGaInstance();
98 if (gaIns == NULL) {
99 AUTH_LOGE(AUTH_INIT, "hichain GetGaInstance failed");
100 DestroyDeviceAuthService();
101 return NULL;
102 }
103 AUTH_LOGI(AUTH_INIT, "hichain init succ");
104 return gaIns;
105 }
106
RegChangeListener(const char * appId,DataChangeListener * listener)107 int32_t RegChangeListener(const char *appId, DataChangeListener *listener)
108 {
109 AUTH_CHECK_AND_RETURN_RET_LOGE(appId != NULL, SOFTBUS_INVALID_PARAM, AUTH_HICHAIN,
110 "appId is null");
111 AUTH_CHECK_AND_RETURN_RET_LOGE(listener != NULL, SOFTBUS_INVALID_PARAM, AUTH_HICHAIN,
112 "listener is null");
113 if (g_hichain == NULL) {
114 g_hichain = InitHichain();
115 }
116 AUTH_CHECK_AND_RETURN_RET_LOGE(g_hichain != NULL, SOFTBUS_AUTH_HICHAIN_INIT_FAIL, AUTH_HICHAIN,
117 "hichain not initialized");
118
119 const DeviceGroupManager *gmInstance = GetGmInstance();
120 AUTH_CHECK_AND_RETURN_RET_LOGE(gmInstance != NULL, SOFTBUS_AUTH_HICHAIN_INIT_FAIL, AUTH_HICHAIN,
121 "hichain GetGmInstance failed");
122
123 int32_t ret = gmInstance->regDataChangeListener(appId, listener);
124 AUTH_CHECK_AND_RETURN_RET_LOGE(ret == 0, SOFTBUS_AUTH_REG_DATA_FAIL, AUTH_HICHAIN,
125 "hichain regDataChangeListener failed=%{public}d", ret);
126
127 return SOFTBUS_OK;
128 }
129
UnregChangeListener(const char * appId)130 int32_t UnregChangeListener(const char *appId)
131 {
132 AUTH_CHECK_AND_RETURN_RET_LOGE(appId != NULL, SOFTBUS_INVALID_PARAM, AUTH_HICHAIN,
133 "appId is null");
134 const DeviceGroupManager *gmInstance = GetGmInstance();
135 AUTH_CHECK_AND_RETURN_RET_LOGE(gmInstance != NULL, SOFTBUS_AUTH_HICHAIN_INIT_FAIL, AUTH_HICHAIN,
136 "hichain GetGmInstance failed");
137 int32_t ret = gmInstance->unRegDataChangeListener(appId);
138 AUTH_CHECK_AND_RETURN_RET_LOGE(ret == 0, SOFTBUS_AUTH_UNREG_DATA_FAIL, AUTH_HICHAIN,
139 "hichain unRegDataChangeListener failed=%{public}d", ret);
140
141 return SOFTBUS_OK;
142 }
143
AuthDevice(int32_t userId,int64_t authReqId,const char * authParams,const DeviceAuthCallback * cb)144 int32_t AuthDevice(int32_t userId, int64_t authReqId, const char *authParams, const DeviceAuthCallback *cb)
145 {
146 (void)userId;
147
148 AUTH_CHECK_AND_RETURN_RET_LOGE(authParams != NULL && cb != NULL, SOFTBUS_INVALID_PARAM,
149 AUTH_HICHAIN, "authParams or cb is null");
150 if (g_hichain == NULL) {
151 g_hichain = InitHichain();
152 }
153 AUTH_CHECK_AND_RETURN_RET_LOGE(g_hichain != NULL, SOFTBUS_AUTH_HICHAIN_INIT_FAIL,
154 AUTH_HICHAIN, "hichain not initialized");
155
156 uint32_t authErrCode = 0;
157 for (int32_t i = 1; i < RETRY_TIMES; i++) {
158 int32_t ret = g_hichain->authDevice(ANY_OS_ACCOUNT, authReqId, authParams, cb);
159 if (ret == HC_SUCCESS) {
160 AUTH_LOGI(AUTH_HICHAIN, "hichain call authDevice success, times=%{public}d", i);
161 return SOFTBUS_OK;
162 }
163 (void)GetSoftbusHichainAuthErrorCode((uint32_t)ret, &authErrCode);
164 if (ret != HC_ERR_INVALID_PARAMS) {
165 AUTH_LOGE(AUTH_HICHAIN, "hichain call authDevice failed, err=%{public}d, authErrCode=%{public}d", ret,
166 authErrCode);
167 return authErrCode;
168 }
169 AUTH_LOGW(AUTH_HICHAIN,
170 "hichain retry call authDevice, current retry times=%{public}d, err=%{public}d", i, ret);
171 (void)SoftBusSleepMs(RETRY_MILLSECONDS);
172 }
173 return authErrCode;
174 }
175
ProcessAuthData(int64_t authSeq,const uint8_t * data,uint32_t len,DeviceAuthCallback * cb)176 int32_t ProcessAuthData(int64_t authSeq, const uint8_t *data, uint32_t len, DeviceAuthCallback *cb)
177 {
178 AUTH_CHECK_AND_RETURN_RET_LOGE(data != NULL && cb != NULL, SOFTBUS_INVALID_PARAM, AUTH_HICHAIN,
179 "data or cb is null");
180 if (g_hichain == NULL) {
181 g_hichain = InitHichain();
182 }
183 AUTH_CHECK_AND_RETURN_RET_LOGE(g_hichain != NULL, SOFTBUS_AUTH_HICHAIN_INIT_FAIL,
184 AUTH_HICHAIN, "hichain not initialized");
185
186 int32_t ret = g_hichain->processData(authSeq, data, len, cb);
187 if (ret != HC_SUCCESS) {
188 AUTH_LOGE(AUTH_HICHAIN, "hichain processData failed. ret=%{public}d", ret);
189 uint32_t authErrCode = 0;
190 (void)GetSoftbusHichainAuthErrorCode((uint32_t)ret, &authErrCode);
191 return authErrCode;
192 }
193
194 return SOFTBUS_OK;
195 }
196
CheckDeviceInGroupByType(const char * udid,const char * uuid,HichainGroup groupType)197 bool CheckDeviceInGroupByType(const char *udid, const char *uuid, HichainGroup groupType)
198 {
199 (void)udid;
200 (void)uuid;
201 (void)groupType;
202 return false;
203 }
204
DestroyDeviceAuth(void)205 void DestroyDeviceAuth(void)
206 {
207 DestroyDeviceAuthService();
208 g_hichain = NULL;
209 AUTH_LOGI(AUTH_HICHAIN, "hichain destroy succ");
210 }
211
IsTrustedDeviceInAGroup(const DeviceGroupManager * gmInstance,int32_t accountId,const char * groupId,const char * deviceId)212 static bool IsTrustedDeviceInAGroup(const DeviceGroupManager *gmInstance, int32_t accountId,
213 const char *groupId, const char *deviceId)
214 {
215 uint32_t deviceNum = 0;
216 char *returnDevInfoVec = NULL;
217 if (gmInstance->getTrustedDevices(accountId, AUTH_APPID, groupId, &returnDevInfoVec, &deviceNum) != SOFTBUS_OK) {
218 gmInstance->destroyInfo(&returnDevInfoVec);
219 AUTH_LOGE(AUTH_HICHAIN, "GetTrustedDevices fail");
220 return false;
221 }
222 if (deviceNum == 0) {
223 gmInstance->destroyInfo(&returnDevInfoVec);
224 AUTH_LOGI(AUTH_HICHAIN, "GetTrustedDevices zero");
225 return false;
226 }
227 cJSON *devJson = cJSON_Parse(returnDevInfoVec);
228 if (devJson == NULL) {
229 gmInstance->destroyInfo(&returnDevInfoVec);
230 AUTH_LOGE(AUTH_HICHAIN, "parse json fail");
231 return false;
232 }
233 int32_t devArraySize = cJSON_GetArraySize(devJson);
234 for (int32_t j = 0; j < devArraySize; j++) {
235 cJSON *devItem = cJSON_GetArrayItem(devJson, j);
236 char authId[UDID_BUF_LEN] = {0};
237 if (!GetJsonObjectStringItem(devItem, AUTH_ID, authId, UDID_BUF_LEN)) {
238 AUTH_LOGE(AUTH_HICHAIN, "AUTH_ID not found");
239 continue;
240 }
241 uint8_t udidHash[SHA_256_HASH_LEN] = {0};
242 char hashStr[CUST_UDID_LEN + 1] = {0};
243 if (SoftBusGenerateStrHash((const unsigned char *)authId, strlen(authId), udidHash) != SOFTBUS_OK) {
244 continue;
245 }
246 if (ConvertBytesToHexString(hashStr, CUST_UDID_LEN + 1, udidHash,
247 CUST_UDID_LEN / HEXIFY_UNIT_LEN) != SOFTBUS_OK) {
248 continue;
249 }
250 if (strncmp(hashStr, deviceId, strlen(deviceId)) == 0) {
251 cJSON_Delete(devJson);
252 gmInstance->destroyInfo(&returnDevInfoVec);
253 return true;
254 }
255 }
256 cJSON_Delete(devJson);
257 gmInstance->destroyInfo(&returnDevInfoVec);
258 return false;
259 }
260
HasTrustedRelationWithLocalDevice(const DeviceGroupManager * gmInstance,int32_t accountId,char * localUdid,const char * deviceId,bool isPointToPoint)261 static bool HasTrustedRelationWithLocalDevice(const DeviceGroupManager *gmInstance, int32_t accountId,
262 char *localUdid, const char *deviceId, bool isPointToPoint)
263 {
264 uint32_t groupNum = 0;
265 char *returnGroupVec = NULL;
266 if (gmInstance->getRelatedGroups(accountId, AUTH_APPID, localUdid, &returnGroupVec, &groupNum) != SOFTBUS_OK) {
267 AUTH_LOGE(AUTH_HICHAIN, "GetRelatedGroups fail, accountId=%{public}d", accountId);
268 gmInstance->destroyInfo(&returnGroupVec);
269 return false;
270 }
271 if (groupNum == 0) {
272 AUTH_LOGI(AUTH_HICHAIN, "GetRelatedGroups zero");
273 gmInstance->destroyInfo(&returnGroupVec);
274 return false;
275 }
276 cJSON *groupJson = cJSON_Parse(returnGroupVec);
277 if (groupJson == NULL) {
278 AUTH_LOGE(AUTH_HICHAIN, "parse json fail");
279 gmInstance->destroyInfo(&returnGroupVec);
280 return false;
281 }
282 int32_t groupArraySize = cJSON_GetArraySize(groupJson);
283 for (int32_t i = 0; i < groupArraySize; i++) {
284 cJSON *groupItem = cJSON_GetArrayItem(groupJson, i);
285 char groupId[UDID_BUF_LEN] = {0};
286 if (isPointToPoint) {
287 int groupType = 0;
288 if ((GetJsonObjectNumberItem(groupItem, GROUP_TYPE, &groupType) && groupType == SAME_ACCOUNT_GROUY_TYPE)) {
289 AUTH_LOGD(AUTH_HICHAIN, "ignore same account group");
290 continue;
291 }
292 }
293 if (!GetJsonObjectStringItem(groupItem, GROUP_ID, groupId, UDID_BUF_LEN)) {
294 AUTH_LOGE(AUTH_HICHAIN, "GROUP_ID not found");
295 continue;
296 }
297 if (IsTrustedDeviceInAGroup(gmInstance, accountId, groupId, deviceId)) {
298 cJSON_Delete(groupJson);
299 gmInstance->destroyInfo(&returnGroupVec);
300 return true;
301 }
302 }
303 cJSON_Delete(groupJson);
304 gmInstance->destroyInfo(&returnGroupVec);
305 return false;
306 }
307
IsPotentialTrustedDevice(TrustedRelationIdType idType,const char * deviceId,bool isPrecise,bool isPointToPoint)308 bool IsPotentialTrustedDevice(TrustedRelationIdType idType, const char *deviceId, bool isPrecise, bool isPointToPoint)
309 {
310 (void)idType;
311 (void)isPrecise;
312 if (deviceId == NULL) {
313 AUTH_LOGE(AUTH_HICHAIN, "deviceId is null");
314 return false;
315 }
316 const DeviceGroupManager *gmInstance = GetGmInstance();
317 if (gmInstance == NULL) {
318 AUTH_LOGE(AUTH_HICHAIN, "hichain GetGmInstance failed");
319 return false;
320 }
321
322 int32_t accountId = GetActiveOsAccountIds();
323 if (accountId <= 0) {
324 AUTH_LOGE(AUTH_HICHAIN, "accountId is invalid");
325 return false;
326 }
327
328 char localUdid[UDID_BUF_LEN] = {0};
329 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN) != SOFTBUS_OK) {
330 AUTH_LOGE(AUTH_HICHAIN, "get udid fail");
331 return false;
332 }
333 return HasTrustedRelationWithLocalDevice(gmInstance, accountId, localUdid, deviceId, isPointToPoint);
334 }
335
HichainGetJoinedGroups(int32_t groupType)336 uint32_t HichainGetJoinedGroups(int32_t groupType)
337 {
338 uint32_t groupCnt = 0;
339 char *accountGroups = NULL;
340
341 const DeviceGroupManager *gmInstance = GetGmInstance();
342 AUTH_CHECK_AND_RETURN_RET_LOGE(gmInstance != NULL, groupCnt, AUTH_HICHAIN, "hichain GetGmInstance failed");
343
344 if (gmInstance->getJoinedGroups(0, AUTH_APPID, (GroupType)groupType, &accountGroups, &groupCnt) != 0) {
345 AUTH_LOGE(AUTH_HICHAIN, "hichain getJoinedGroups groupCnt fail");
346 groupCnt = 0;
347 }
348 if (accountGroups != NULL) {
349 SoftBusFree(accountGroups);
350 }
351 return groupCnt;
352 }
353
IsSameAccountGroupDevice(void)354 bool IsSameAccountGroupDevice(void)
355 {
356 uint32_t groupNum = 0;
357 char *returnGroupVec = NULL;
358
359 const DeviceGroupManager *gmInstance = GetGmInstance();
360 if (gmInstance == NULL) {
361 AUTH_LOGE(AUTH_HICHAIN, "hichain GetGmInstance failed");
362 return false;
363 }
364 int32_t accountId = GetActiveOsAccountIds();
365 if (accountId <= 0) {
366 AUTH_LOGE(AUTH_HICHAIN, "accountId is invalid");
367 return false;
368 }
369
370 if (gmInstance->getJoinedGroups(accountId, AUTH_APPID, SAME_ACCOUNT_GROUY_TYPE, &returnGroupVec, &groupNum) !=
371 SOFTBUS_OK) {
372 AUTH_LOGE(AUTH_HICHAIN, "getJoinedGroups fail, accountId=%{public}d", accountId);
373 gmInstance->destroyInfo(&returnGroupVec);
374 return false;
375 }
376 if (groupNum == 0) {
377 AUTH_LOGE(AUTH_HICHAIN, "getJoinedGroups zero");
378 gmInstance->destroyInfo(&returnGroupVec);
379 return false;
380 } else {
381 AUTH_LOGI(AUTH_HICHAIN, "getJoinedGroups: %{public}d", groupNum);
382 gmInstance->destroyInfo(&returnGroupVec);
383 return true;
384 }
385 }
386
CancelRequest(int64_t authReqId,const char * appId)387 void CancelRequest(int64_t authReqId, const char *appId)
388 {
389 AUTH_CHECK_AND_RETURN_LOGE(appId != NULL, AUTH_HICHAIN, "appId is null");
390 if (g_hichain == NULL) {
391 g_hichain = InitHichain();
392 }
393 AUTH_CHECK_AND_RETURN_LOGE(g_hichain != NULL, AUTH_HICHAIN, "hichain not initialized");
394 g_hichain->cancelRequest(authReqId, appId);
395 }