1 /*
2  * Copyright (c) 2022-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.h"
17 
18 #include <securec.h>
19 
20 #include "anonymizer.h"
21 #include "auth_common.h"
22 #include "auth_hichain_adapter.h"
23 #include "auth_log.h"
24 #include "auth_session_fsm.h"
25 #include "bus_center_manager.h"
26 #include "device_auth.h"
27 #include "lnn_async_callback_utils.h"
28 #include "lnn_event.h"
29 #include "lnn_net_builder.h"
30 #include "softbus_adapter_mem.h"
31 #include "softbus_def.h"
32 #include "softbus_json_utils.h"
33 
34 #define AUTH_APPID "softbus_auth"
35 #define GROUPID_BUF_LEN 65
36 #define KEY_LENGTH 16 /* Note: WinPc's special nearby only support 128 bits key */
37 #define ONTRANSMIT_MAX_DATA_BUFFER_LEN 5120 /* 5 × 1024 */
38 #define PC_AUTH_ERRCODE                36870
39 
40 #define HICHAIN_DAS_ERRCODE_MIN    0xF0000001
41 #define HICHAIN_DAS_ERRCODE_MAX    0xF00010FF
42 #define HICHAIN_COMMON_ERRCODE_MIN 0x0001
43 #define HICHAIN_COMMON_ERRCODE_MAX 0xFFFF
44 #define MASK_HIGH_4BIT             0xF000
45 #define MASK_LOW_8BIT              0x00FF
46 #define MASK_LOW_16BIT             0xFFFF
47 #define ERRCODE_OR_BIT             0x1000
48 #define ERRCODE_SHIFT_21BIT        21
49 #define ERRCODE_SHIFT_16BIT        16
50 #define ERRCODE_SHIFT_12BIT        12
51 #define ERRCODE_SHIFT_8BIT         8
52 #define SHORT_UDID_HASH_LEN        8
53 
54 typedef struct {
55     char groupId[GROUPID_BUF_LEN];
56     GroupType groupType;
57 } GroupInfo;
58 
59 typedef struct {
60     int32_t errCode;
61     uint32_t errorReturnLen;
62     uint8_t data[0];
63 } ProofInfo;
64 
65 static TrustDataChangeListener g_dataChangeListener;
66 
GenDeviceLevelParam(const char * udid,const char * uid,bool isClient)67 static char *GenDeviceLevelParam(const char *udid, const char *uid, bool isClient)
68 {
69     cJSON *msg = cJSON_CreateObject();
70     if (msg == NULL) {
71         AUTH_LOGE(AUTH_HICHAIN, "create json fail");
72         return NULL;
73     }
74     if (!AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, udid) ||
75         !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
76         !AddBoolToJsonObject(msg, FIELD_IS_DEVICE_LEVEL, true) ||
77         !AddBoolToJsonObject(msg, FIELD_IS_CLIENT, isClient) ||
78         !AddBoolToJsonObject(msg, FIELD_IS_UDID_HASH, false) ||
79         !AddNumberToJsonObject(msg, FIELD_KEY_LENGTH, KEY_LENGTH)) {
80         AUTH_LOGE(AUTH_HICHAIN, "add json object fail");
81         cJSON_Delete(msg);
82         return NULL;
83     }
84 #ifdef AUTH_ACCOUNT
85     AUTH_LOGI(AUTH_HICHAIN, "in account auth mode");
86     if (!AddStringToJsonObject(msg, FIELD_UID_HASH, uid)) {
87         AUTH_LOGE(AUTH_HICHAIN, "add uid into json fail");
88         cJSON_Delete(msg);
89         return NULL;
90     }
91 #endif
92     char *data = cJSON_PrintUnformatted(msg);
93     if (data == NULL) {
94         AUTH_LOGE(AUTH_HICHAIN, "cJSON_PrintUnformatted fail");
95     }
96     cJSON_Delete(msg);
97     return data;
98 }
99 
OnTransmit(int64_t authSeq,const uint8_t * data,uint32_t len)100 static bool OnTransmit(int64_t authSeq, const uint8_t *data, uint32_t len)
101 {
102     AUTH_CHECK_AND_RETURN_RET_LOGE(len <= ONTRANSMIT_MAX_DATA_BUFFER_LEN, false, AUTH_HICHAIN,
103         "data len is invalid, len=%{public}u", len);
104     AUTH_LOGI(AUTH_HICHAIN, "hichain OnTransmit: authSeq=%{public}" PRId64 ", len=%{public}u", authSeq, len);
105     if (AuthSessionPostAuthData(authSeq, data, len) != SOFTBUS_OK) {
106         AUTH_LOGE(AUTH_HICHAIN, "hichain OnTransmit fail: authSeq=%{public}" PRId64, authSeq);
107         return false;
108     }
109     return true;
110 }
111 
DfxRecordLnnExchangekeyEnd(int64_t authSeq,int32_t reason)112 static void DfxRecordLnnExchangekeyEnd(int64_t authSeq, int32_t reason)
113 {
114     LnnEventExtra extra = { 0 };
115     LnnEventExtraInit(&extra);
116     extra.authId = (int32_t)authSeq;
117     extra.errcode = reason;
118     extra.result = (reason == SOFTBUS_OK) ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED;
119     LNN_EVENT(EVENT_SCENE_JOIN_LNN, EVENT_STAGE_AUTH_EXCHANGE_CIPHER, extra);
120 }
121 
OnSessionKeyReturned(int64_t authSeq,const uint8_t * sessionKey,uint32_t sessionKeyLen)122 static void OnSessionKeyReturned(int64_t authSeq, const uint8_t *sessionKey, uint32_t sessionKeyLen)
123 {
124     AUTH_LOGI(AUTH_HICHAIN, "hichain OnSessionKeyReturned: authSeq=%{public}" PRId64 ", len=%{public}u", authSeq,
125         sessionKeyLen);
126     if (sessionKey == NULL || sessionKeyLen > SESSION_KEY_LENGTH) {
127         DfxRecordLnnExchangekeyEnd(authSeq, SOFTBUS_AUTH_GET_SESSION_KEY_FAIL);
128         AUTH_LOGW(AUTH_HICHAIN, "invalid sessionKey");
129         return;
130     }
131     DfxRecordLnnExchangekeyEnd(authSeq, SOFTBUS_OK);
132     (void)AuthSessionSaveSessionKey(authSeq, sessionKey, sessionKeyLen);
133 }
134 
DfxRecordLnnEndHichainEnd(int64_t authSeq,int32_t reason)135 static void DfxRecordLnnEndHichainEnd(int64_t authSeq, int32_t reason)
136 {
137     LnnEventExtra extra = { 0 };
138     LnnEventExtraInit(&extra);
139     extra.authId = (int32_t)authSeq;
140     extra.errcode = reason;
141     extra.result = (reason == SOFTBUS_OK) ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED;
142     LNN_EVENT(EVENT_SCENE_JOIN_LNN, EVENT_STAGE_AUTH_HICHAIN_END, extra);
143 }
144 
OnFinish(int64_t authSeq,int operationCode,const char * returnData)145 static void OnFinish(int64_t authSeq, int operationCode, const char *returnData)
146 {
147     (void)operationCode;
148     (void)returnData;
149     DfxRecordLnnEndHichainEnd(authSeq, SOFTBUS_OK);
150     AUTH_LOGI(AUTH_HICHAIN, "hichain OnFinish: authSeq=%{public}" PRId64, authSeq);
151     (void)AuthSessionHandleAuthFinish(authSeq);
152 }
153 
GetSoftbusHichainAuthErrorCode(uint32_t hichainErrCode,uint32_t * softbusErrCode)154 void GetSoftbusHichainAuthErrorCode(uint32_t hichainErrCode, uint32_t *softbusErrCode)
155 {
156     if (hichainErrCode >= HICHAIN_DAS_ERRCODE_MIN && hichainErrCode <= HICHAIN_DAS_ERRCODE_MAX) {
157         *softbusErrCode = hichainErrCode & MASK_LOW_16BIT;
158         *softbusErrCode = -(((SOFTBUS_SUB_SYSTEM) << ERRCODE_SHIFT_21BIT) |
159             ((AUTH_SUB_MODULE_CODE) << ERRCODE_SHIFT_16BIT) | (*softbusErrCode | ERRCODE_OR_BIT));
160     } else if (hichainErrCode >= HICHAIN_COMMON_ERRCODE_MIN && hichainErrCode <= HICHAIN_COMMON_ERRCODE_MAX) {
161         uint32_t high4bit = 0;
162         uint32_t tempCode = 0;
163         high4bit = hichainErrCode & MASK_HIGH_4BIT;
164         high4bit = high4bit >> ERRCODE_SHIFT_12BIT;
165         tempCode = hichainErrCode & MASK_LOW_8BIT;
166         *softbusErrCode = -(((SOFTBUS_SUB_SYSTEM) << ERRCODE_SHIFT_21BIT) |
167             ((AUTH_SUB_MODULE_CODE) << ERRCODE_SHIFT_16BIT) | (tempCode | (high4bit << ERRCODE_SHIFT_8BIT)));
168     } else {
169         *softbusErrCode = hichainErrCode;
170         AUTH_LOGI(AUTH_HICHAIN, "unknow hichain errcode=%{public}d", hichainErrCode);
171     }
172 }
173 
GetDeviceSideFlag(int64_t authSeq,bool * flag)174 static int32_t GetDeviceSideFlag(int64_t authSeq, bool *flag)
175 {
176     if (!RequireAuthLock()) {
177         return SOFTBUS_LOCK_ERR;
178     }
179     AuthFsm *authFsm = GetAuthFsmByAuthSeq(authSeq);
180     if (authFsm == NULL) {
181         AUTH_LOGE(AUTH_HICHAIN, "auth fsm not found");
182         ReleaseAuthLock();
183         return SOFTBUS_AUTH_NOT_FOUND;
184     }
185     *flag = authFsm->info.isServer;
186     AUTH_LOGI(AUTH_HICHAIN, "find authFsm success, side=%{public}s", GetAuthSideStr(*flag));
187     ReleaseAuthLock();
188     return SOFTBUS_OK;
189 }
190 
CheckErrReturnValidity(const char * errorReturn)191 static int32_t CheckErrReturnValidity(const char *errorReturn)
192 {
193     cJSON *json = cJSON_Parse(errorReturn);
194     if (json == NULL) {
195         AUTH_LOGE(AUTH_HICHAIN, "parse json fail");
196         return SOFTBUS_PARSE_JSON_ERR;
197     }
198     cJSON_Delete(json);
199     return SOFTBUS_OK;
200 }
201 
ProcessAuthFailCallBack(void * para)202 static void ProcessAuthFailCallBack(void *para)
203 {
204     if (para == NULL) {
205         AUTH_LOGE(AUTH_HICHAIN, "invalid para");
206         return;
207     }
208     ProofInfo *proofInfo = (ProofInfo *)para;
209     if (AuthFailNotifyProofInfo(proofInfo->errCode, (char *)proofInfo->data, proofInfo->errorReturnLen) != SOFTBUS_OK) {
210         AUTH_LOGE(AUTH_HICHAIN, "AuthFailNotifyProofInfo fail");
211         SoftBusFree(proofInfo);
212         return;
213     }
214     SoftBusFree(proofInfo);
215 }
216 
NotifyAuthFailEvent(int32_t errCode,const char * errorReturn)217 static void NotifyAuthFailEvent(int32_t errCode, const char *errorReturn)
218 {
219     uint32_t errorReturnLen = strlen(errorReturn) + 1;
220     char *anonyErrorReturn = NULL;
221     Anonymize(errorReturn, &anonyErrorReturn);
222     AUTH_LOGW(AUTH_HICHAIN, "errorReturn=%{public}s, errorReturnLen=%{public}u, errCode=%{public}d",
223         AnonymizeWrapper(anonyErrorReturn), errorReturnLen, errCode);
224     AnonymizeFree(anonyErrorReturn);
225 
226     ProofInfo *proofInfo = (ProofInfo *)SoftBusCalloc(sizeof(ProofInfo) + errorReturnLen);
227     if (proofInfo == NULL) {
228         AUTH_LOGE(AUTH_HICHAIN, "proofInfo calloc fail");
229         return;
230     }
231     if (memcpy_s(proofInfo->data, errorReturnLen, (uint8_t *)errorReturn, errorReturnLen) != EOK) {
232         AUTH_LOGE(AUTH_HICHAIN, "memcpy_s errorReturn fail");
233         SoftBusFree(proofInfo);
234         return;
235     }
236     proofInfo->errorReturnLen = errorReturnLen;
237     proofInfo->errCode = errCode;
238     if (LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), ProcessAuthFailCallBack, (void *)proofInfo, 0) !=
239         SOFTBUS_OK) {
240         AUTH_LOGE(AUTH_HICHAIN, "set async ProcessAuthFailCallBack callback fail");
241         SoftBusFree(proofInfo);
242         return;
243     }
244 }
245 
NotifyPcAuthFail(int64_t authSeq,int errCode,const char * errorReturn)246 static void NotifyPcAuthFail(int64_t authSeq, int errCode, const char *errorReturn)
247 {
248     if (errorReturn != NULL && CheckErrReturnValidity(errorReturn) == SOFTBUS_OK) {
249         if (errCode == PC_AUTH_ERRCODE) {
250             NotifyAuthFailEvent(errCode, errorReturn);
251         }
252         if (errCode == PC_PROOF_NON_CONSISTENT_ERRCODE) {
253             bool flag = false;
254             if (GetDeviceSideFlag(authSeq, &flag) == SOFTBUS_OK && flag) {
255                 NotifyAuthFailEvent(errCode, errorReturn);
256             }
257         }
258     }
259     return;
260 }
261 
OnError(int64_t authSeq,int operationCode,int errCode,const char * errorReturn)262 static void OnError(int64_t authSeq, int operationCode, int errCode, const char *errorReturn)
263 {
264     (void)operationCode;
265     DfxRecordLnnEndHichainEnd(authSeq, errCode);
266     uint32_t authErrCode = 0;
267     (void)GetSoftbusHichainAuthErrorCode((uint32_t)errCode, &authErrCode);
268     AUTH_LOGE(AUTH_HICHAIN, "hichain OnError: authSeq=%{public}" PRId64 ", errCode=%{public}d authErrCode=%{public}d",
269         authSeq, errCode, authErrCode);
270     NotifyPcAuthFail(authSeq, errCode, errorReturn);
271     (void)AuthSessionHandleAuthError(authSeq, authErrCode);
272 }
273 
OnRequest(int64_t authSeq,int operationCode,const char * reqParams)274 static char *OnRequest(int64_t authSeq, int operationCode, const char *reqParams)
275 {
276     (void)reqParams;
277     AUTH_LOGI(AUTH_HICHAIN, "hichain OnRequest: authSeq=%{public}" PRId64 ", operationCode=%{public}d", authSeq,
278         operationCode);
279     char udid[UDID_BUF_LEN] = {0};
280     if (AuthSessionGetUdid(authSeq, udid, sizeof(udid)) != SOFTBUS_OK) {
281         AUTH_LOGE(AUTH_HICHAIN, "get udid fail");
282         return NULL;
283     }
284     cJSON *msg = cJSON_CreateObject();
285     if (msg == NULL) {
286         return NULL;
287     }
288     char localUdid[UDID_BUF_LEN] = {0};
289     LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN);
290     if (!AddNumberToJsonObject(msg, FIELD_CONFIRMATION, REQUEST_ACCEPTED) ||
291         !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
292         !AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, udid) ||
293         !AddStringToJsonObject(msg, FIELD_DEVICE_ID, localUdid) ||
294         !AddBoolToJsonObject(msg, FIELD_IS_UDID_HASH, false)) {
295         AUTH_LOGE(AUTH_HICHAIN, "pack request msg fail");
296         cJSON_Delete(msg);
297         return NULL;
298     }
299     char *msgStr = cJSON_PrintUnformatted(msg);
300     if (msgStr == NULL) {
301         AUTH_LOGE(AUTH_HICHAIN, "cJSON_PrintUnformatted fail");
302         cJSON_Delete(msg);
303         return NULL;
304     }
305     cJSON_Delete(msg);
306     return msgStr;
307 }
308 
309 static DeviceAuthCallback g_hichainCallback = {
310     .onTransmit = OnTransmit,
311     .onSessionKeyReturned = OnSessionKeyReturned,
312     .onFinish = OnFinish,
313     .onError = OnError,
314     .onRequest = OnRequest
315 };
316 
GetUdidHash(const char * udid,char * udidHash)317 static int32_t GetUdidHash(const char *udid, char *udidHash)
318 {
319     if (udid == NULL || udidHash == NULL) {
320         AUTH_LOGE(AUTH_HICHAIN, "param error");
321         return SOFTBUS_INVALID_PARAM;
322     }
323     int32_t rc = SOFTBUS_OK;
324     uint8_t hash[UDID_HASH_LEN] = { 0 };
325     rc = SoftBusGenerateStrHash((uint8_t *)udid, strlen(udid), hash);
326     if (rc != SOFTBUS_OK) {
327         AUTH_LOGE(AUTH_HICHAIN, "generate udidhash fail");
328         return rc;
329     }
330     rc = ConvertBytesToHexString(udidHash, HB_SHORT_UDID_HASH_HEX_LEN + 1, hash, SHORT_UDID_HASH_LEN);
331     if (rc != SOFTBUS_OK) {
332         AUTH_LOGE(AUTH_HICHAIN, "convert bytes to string fail");
333         return rc;
334     }
335     return SOFTBUS_OK;
336 }
337 
DeletePcRestrictNode(const char * udid)338 static void DeletePcRestrictNode(const char *udid)
339 {
340     char peerUdidHash[HB_SHORT_UDID_HASH_HEX_LEN + 1] = { 0 };
341     uint32_t count = 0;
342 
343     if (GetUdidHash(udid, peerUdidHash) == SOFTBUS_OK && GetNodeFromPcRestrictMap(peerUdidHash, &count) == SOFTBUS_OK) {
344         DeleteNodeFromPcRestrictMap(peerUdidHash);
345         char *anonyUdid = NULL;
346         Anonymize(udid, &anonyUdid);
347         AUTH_LOGI(AUTH_HICHAIN, "delete restrict node success. udid=%{public}s", AnonymizeWrapper(anonyUdid));
348         AnonymizeFree(anonyUdid);
349     }
350 }
351 
ParseGroupInfo(const char * groupInfoStr,GroupInfo * groupInfo)352 static int32_t ParseGroupInfo(const char *groupInfoStr, GroupInfo *groupInfo)
353 {
354     cJSON *msg = cJSON_Parse(groupInfoStr);
355     if (msg == NULL) {
356         AUTH_LOGE(AUTH_HICHAIN, "parse json fail");
357         return SOFTBUS_PARSE_JSON_ERR;
358     }
359     if (!GetJsonObjectStringItem(msg, FIELD_GROUP_ID, groupInfo->groupId, GROUPID_BUF_LEN)) {
360         AUTH_LOGE(AUTH_HICHAIN, "get FIELD_GROUP_ID fail");
361         cJSON_Delete(msg);
362         return SOFTBUS_ERR;
363     }
364     int32_t groupType = 0;
365     if (!GetJsonObjectNumberItem(msg, FIELD_GROUP_TYPE, &groupType)) {
366         AUTH_LOGE(AUTH_HICHAIN, "get FIELD_GROUP_TYPE fail");
367         cJSON_Delete(msg);
368         return SOFTBUS_ERR;
369     }
370     groupInfo->groupType = (GroupType)groupType;
371     cJSON_Delete(msg);
372     return SOFTBUS_OK;
373 }
374 
OnGroupCreated(const char * groupInfo)375 static void OnGroupCreated(const char *groupInfo)
376 {
377     if (groupInfo == NULL) {
378         AUTH_LOGW(AUTH_HICHAIN, "invalid group info");
379         return;
380     }
381     GroupInfo info;
382     (void)memset_s(&info, sizeof(GroupInfo), 0, sizeof(GroupInfo));
383     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
384         return;
385     }
386     AUTH_LOGI(AUTH_HICHAIN, "hichain OnGroupCreated, type=%{public}d", info.groupType);
387     if (g_dataChangeListener.onGroupCreated != NULL) {
388         g_dataChangeListener.onGroupCreated(info.groupId, (int32_t)info.groupType);
389     }
390 }
391 
OnDeviceBound(const char * udid,const char * groupInfo)392 static void OnDeviceBound(const char *udid, const char *groupInfo)
393 {
394     if (udid == NULL || groupInfo == NULL) {
395         AUTH_LOGW(AUTH_HICHAIN, "invalid udid");
396         return;
397     }
398     GroupInfo info;
399     (void)memset_s(&info, sizeof(GroupInfo), 0, sizeof(GroupInfo));
400     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
401         return;
402     }
403     char *anonyUdid = NULL;
404     Anonymize(udid, &anonyUdid);
405     AUTH_LOGI(AUTH_HICHAIN, "hichain onDeviceBound, udid=%{public}s, type=%{public}d",
406         AnonymizeWrapper(anonyUdid), info.groupType);
407     AnonymizeFree(anonyUdid);
408     if (info.groupType == AUTH_IDENTICAL_ACCOUNT_GROUP) {
409         AUTH_LOGI(AUTH_HICHAIN, "ignore same account udid");
410         DeletePcRestrictNode(udid);
411         return;
412     }
413     char localUdid[UDID_BUF_LEN] = { 0 };
414     LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN);
415     if (strcmp(localUdid, udid) == 0) {
416         AUTH_LOGI(AUTH_HICHAIN, "ignore local udid");
417         return;
418     }
419     if (g_dataChangeListener.onDeviceBound != NULL) {
420         g_dataChangeListener.onDeviceBound(udid, groupInfo);
421     }
422 }
423 
OnGroupDeleted(const char * groupInfo)424 static void OnGroupDeleted(const char *groupInfo)
425 {
426     if (groupInfo == NULL) {
427         AUTH_LOGE(AUTH_HICHAIN, "invalid group info");
428         return;
429     }
430     GroupInfo info;
431     (void)memset_s(&info, sizeof(GroupInfo), 0, sizeof(GroupInfo));
432     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
433         return;
434     }
435     AUTH_LOGI(AUTH_HICHAIN, "hichain OnGroupDeleted, type=%{public}d", info.groupType);
436     if (g_dataChangeListener.onGroupDeleted != NULL) {
437         g_dataChangeListener.onGroupDeleted(info.groupId, info.groupType);
438     }
439 }
440 
OnDeviceNotTrusted(const char * udid)441 static void OnDeviceNotTrusted(const char *udid)
442 {
443     if (udid == NULL) {
444         AUTH_LOGW(AUTH_HICHAIN, "hichain get invalid udid");
445         return;
446     }
447     char *anonyUdid = NULL;
448     Anonymize(udid, &anonyUdid);
449     AUTH_LOGI(AUTH_HICHAIN, "hichain OnDeviceNotTrusted, udid=%{public}s", anonyUdid);
450     AnonymizeFree(anonyUdid);
451     if (g_dataChangeListener.onDeviceNotTrusted != NULL) {
452         g_dataChangeListener.onDeviceNotTrusted(udid);
453     }
454 }
455 
RegTrustDataChangeListener(const TrustDataChangeListener * listener)456 int32_t RegTrustDataChangeListener(const TrustDataChangeListener *listener)
457 {
458     if (listener == NULL) {
459         return SOFTBUS_INVALID_PARAM;
460     }
461     g_dataChangeListener = *listener;
462 
463     DataChangeListener hichainListener;
464     (void)memset_s(&hichainListener, sizeof(DataChangeListener), 0, sizeof(DataChangeListener));
465     hichainListener.onGroupCreated = OnGroupCreated;
466     hichainListener.onGroupDeleted = OnGroupDeleted;
467     hichainListener.onDeviceNotTrusted = OnDeviceNotTrusted;
468     hichainListener.onDeviceBound = OnDeviceBound;
469     if (RegChangeListener(AUTH_APPID, &hichainListener) != SOFTBUS_OK) {
470         AUTH_LOGE(AUTH_HICHAIN, "hichain regDataChangeListener fail");
471         return SOFTBUS_AUTH_REG_DATA_FAIL;
472     }
473     return SOFTBUS_OK;
474 }
475 
UnregTrustDataChangeListener(void)476 void UnregTrustDataChangeListener(void)
477 {
478     int32_t ret = UnregChangeListener(AUTH_APPID);
479     if (ret != SOFTBUS_OK) {
480         AUTH_LOGE(AUTH_HICHAIN, "hichain unRegDataChangeListener err=%{public}d", ret);
481     }
482     (void)memset_s(&g_dataChangeListener, sizeof(TrustDataChangeListener), 0, sizeof(TrustDataChangeListener));
483 }
484 
HichainStartAuth(int64_t authSeq,const char * udid,const char * uid)485 int32_t HichainStartAuth(int64_t authSeq, const char *udid, const char *uid)
486 {
487     if (udid == NULL || uid == NULL) {
488         AUTH_LOGE(AUTH_HICHAIN, "udid/uid is invalid");
489         return SOFTBUS_INVALID_PARAM;
490     }
491     char *authParams = GenDeviceLevelParam(udid, uid, true);
492     if (authParams == NULL) {
493         AUTH_LOGE(AUTH_HICHAIN, "generate auth param fail");
494         return SOFTBUS_CREATE_JSON_ERR;
495     }
496     int32_t ret = AuthDevice(authSeq, authParams, &g_hichainCallback);
497     if (ret == SOFTBUS_OK) {
498         AUTH_LOGI(AUTH_HICHAIN, "hichain call authDevice succ");
499         cJSON_free(authParams);
500         return SOFTBUS_OK;
501     }
502     AUTH_LOGE(AUTH_HICHAIN, "hichain call authDevice failed");
503     cJSON_free(authParams);
504     return ret;
505 }
506 
HichainProcessData(int64_t authSeq,const uint8_t * data,uint32_t len)507 int32_t HichainProcessData(int64_t authSeq, const uint8_t *data, uint32_t len)
508 {
509     if (data == NULL) {
510         AUTH_LOGE(AUTH_HICHAIN, "data is null");
511         return SOFTBUS_INVALID_PARAM;
512     }
513     int32_t ret = ProcessAuthData(authSeq, data, len, &g_hichainCallback);
514     if (ret != SOFTBUS_OK) {
515         AUTH_LOGE(AUTH_HICHAIN, "hichain processData err=%{public}d", ret);
516         return ret;
517     }
518     return SOFTBUS_OK;
519 }
520 
HichainDestroy(void)521 void HichainDestroy(void)
522 {
523     UnregTrustDataChangeListener();
524     DestroyDeviceAuth();
525     AUTH_LOGI(AUTH_HICHAIN, "hichain destroy succ");
526 }
527 
HichainCancelRequest(int64_t authReqId)528 void HichainCancelRequest(int64_t authReqId)
529 {
530     CancelRequest(authReqId, AUTH_APPID);
531 }
532