• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }