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