• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "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_event.h"
28 #include "softbus_adapter_mem.h"
29 #include "softbus_def.h"
30 #include "softbus_json_utils.h"
31 
32 #define AUTH_APPID "softbus_auth"
33 #define GROUPID_BUF_LEN 65
34 #define KEY_LENGTH 16 /* Note: WinPc's special nearby only support 128 bits key */
35 #define ONTRANSMIT_MAX_DATA_BUFFER_LEN 5120 /* 5 × 1024 */
36 
37 typedef struct {
38     char groupId[GROUPID_BUF_LEN];
39     GroupType groupType;
40 } GroupInfo;
41 
42 static TrustDataChangeListener g_dataChangeListener;
43 
GenDeviceLevelParam(const char * udid,const char * uid,bool isClient)44 static char *GenDeviceLevelParam(const char *udid, const char *uid, bool isClient)
45 {
46     cJSON *msg = cJSON_CreateObject();
47     if (msg == NULL) {
48         AUTH_LOGE(AUTH_HICHAIN, "create json fail");
49         return NULL;
50     }
51     if (!AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, udid) ||
52         !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
53         !AddBoolToJsonObject(msg, FIELD_IS_DEVICE_LEVEL, true) ||
54         !AddBoolToJsonObject(msg, FIELD_IS_CLIENT, isClient) ||
55         !AddBoolToJsonObject(msg, FIELD_IS_UDID_HASH, false) ||
56         !AddNumberToJsonObject(msg, FIELD_KEY_LENGTH, KEY_LENGTH)) {
57         AUTH_LOGE(AUTH_HICHAIN, "add json object fail");
58         cJSON_Delete(msg);
59         return NULL;
60     }
61 #ifdef AUTH_ACCOUNT
62     AUTH_LOGI(AUTH_HICHAIN, "in account auth mode");
63     if (!AddStringToJsonObject(msg, FIELD_UID_HASH, uid)) {
64         AUTH_LOGE(AUTH_HICHAIN, "add uid into json fail");
65         cJSON_Delete(msg);
66         return NULL;
67     }
68 #endif
69     char *data = cJSON_PrintUnformatted(msg);
70     if (data == NULL) {
71         AUTH_LOGE(AUTH_HICHAIN, "cJSON_PrintUnformatted fail");
72     }
73     cJSON_Delete(msg);
74     return data;
75 }
76 
OnTransmit(int64_t authSeq,const uint8_t * data,uint32_t len)77 static bool OnTransmit(int64_t authSeq, const uint8_t *data, uint32_t len)
78 {
79     AUTH_CHECK_AND_RETURN_RET_LOGE(len <= ONTRANSMIT_MAX_DATA_BUFFER_LEN, false, AUTH_HICHAIN,
80         "data len is invalid, len=%{public}u", len);
81     AUTH_LOGI(AUTH_HICHAIN, "hichain OnTransmit: authSeq=%{public}" PRId64 ", len=%{public}u", authSeq, len);
82     if (AuthSessionPostAuthData(authSeq, data, len) != SOFTBUS_OK) {
83         AUTH_LOGE(AUTH_HICHAIN, "hichain OnTransmit fail: authSeq=%{public}" PRId64, authSeq);
84         return false;
85     }
86     return true;
87 }
88 
DfxRecordLnnExchangekeyEnd(int64_t authSeq,int32_t reason)89 static void DfxRecordLnnExchangekeyEnd(int64_t authSeq, int32_t reason)
90 {
91     LnnEventExtra extra = { 0 };
92     LnnEventExtraInit(&extra);
93     extra.authId = (int32_t)authSeq;
94     extra.errcode = reason;
95     extra.result = (reason == SOFTBUS_OK) ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED;
96     LNN_EVENT(EVENT_SCENE_JOIN_LNN, EVENT_STAGE_AUTH_EXCHANGE_CIPHER, extra);
97 }
98 
OnSessionKeyReturned(int64_t authSeq,const uint8_t * sessionKey,uint32_t sessionKeyLen)99 static void OnSessionKeyReturned(int64_t authSeq, const uint8_t *sessionKey, uint32_t sessionKeyLen)
100 {
101     AUTH_LOGI(AUTH_HICHAIN, "hichain OnSessionKeyReturned: authSeq=%{public}" PRId64 ", len=%{public}u", authSeq,
102         sessionKeyLen);
103     if (sessionKey == NULL || sessionKeyLen > SESSION_KEY_LENGTH) {
104         DfxRecordLnnExchangekeyEnd(authSeq, SOFTBUS_AUTH_GET_SESSION_KEY_FAIL);
105         AUTH_LOGW(AUTH_HICHAIN, "invalid sessionKey");
106         return;
107     }
108     DfxRecordLnnExchangekeyEnd(authSeq, SOFTBUS_OK);
109     (void)AuthSessionSaveSessionKey(authSeq, sessionKey, sessionKeyLen);
110 }
111 
DfxRecordLnnEndHichainEnd(int64_t authSeq,int32_t reason)112 static void DfxRecordLnnEndHichainEnd(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_HICHAIN_END, extra);
120 }
121 
OnFinish(int64_t authSeq,int operationCode,const char * returnData)122 static void OnFinish(int64_t authSeq, int operationCode, const char *returnData)
123 {
124     (void)operationCode;
125     (void)returnData;
126     DfxRecordLnnEndHichainEnd(authSeq, SOFTBUS_OK);
127     AUTH_LOGI(AUTH_HICHAIN, "hichain OnFinish: authSeq=%{public}" PRId64, authSeq);
128     (void)AuthSessionHandleAuthFinish(authSeq);
129 }
130 
OnError(int64_t authSeq,int operationCode,int errCode,const char * errorReturn)131 static void OnError(int64_t authSeq, int operationCode, int errCode, const char *errorReturn)
132 {
133     (void)operationCode;
134     (void)errorReturn;
135     DfxRecordLnnEndHichainEnd(authSeq, errCode);
136     AUTH_LOGE(AUTH_HICHAIN, "hichain OnError: authSeq=%{public}" PRId64 ", errCode=%{public}d", authSeq, errCode);
137     (void)AuthSessionHandleAuthError(authSeq, SOFTBUS_AUTH_HICHAIN_AUTH_ERROR);
138 }
139 
OnRequest(int64_t authSeq,int operationCode,const char * reqParams)140 static char *OnRequest(int64_t authSeq, int operationCode, const char *reqParams)
141 {
142     (void)reqParams;
143     AUTH_LOGI(AUTH_HICHAIN, "hichain OnRequest: authSeq=%{public}" PRId64 ", operationCode=%{public}d", authSeq,
144         operationCode);
145     char udid[UDID_BUF_LEN] = {0};
146     if (AuthSessionGetUdid(authSeq, udid, sizeof(udid)) != SOFTBUS_OK) {
147         AUTH_LOGE(AUTH_HICHAIN, "get udid fail");
148         return NULL;
149     }
150     cJSON *msg = cJSON_CreateObject();
151     if (msg == NULL) {
152         return NULL;
153     }
154     char localUdid[UDID_BUF_LEN] = {0};
155     LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN);
156     if (!AddNumberToJsonObject(msg, FIELD_CONFIRMATION, REQUEST_ACCEPTED) ||
157         !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
158         !AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, udid) ||
159         !AddStringToJsonObject(msg, FIELD_DEVICE_ID, localUdid) ||
160         !AddBoolToJsonObject(msg, FIELD_IS_UDID_HASH, false)) {
161         AUTH_LOGE(AUTH_HICHAIN, "pack request msg fail");
162         cJSON_Delete(msg);
163         return NULL;
164     }
165     char *msgStr = cJSON_PrintUnformatted(msg);
166     if (msgStr == NULL) {
167         AUTH_LOGE(AUTH_HICHAIN, "cJSON_PrintUnformatted fail");
168         cJSON_Delete(msg);
169         return NULL;
170     }
171     cJSON_Delete(msg);
172     return msgStr;
173 }
174 
175 static DeviceAuthCallback g_hichainCallback = {
176     .onTransmit = OnTransmit,
177     .onSessionKeyReturned = OnSessionKeyReturned,
178     .onFinish = OnFinish,
179     .onError = OnError,
180     .onRequest = OnRequest
181 };
182 
ParseGroupInfo(const char * groupInfoStr,GroupInfo * groupInfo)183 static int32_t ParseGroupInfo(const char *groupInfoStr, GroupInfo *groupInfo)
184 {
185     cJSON *msg = cJSON_Parse(groupInfoStr);
186     if (msg == NULL) {
187         AUTH_LOGE(AUTH_HICHAIN, "parse json fail");
188         return SOFTBUS_PARSE_JSON_ERR;
189     }
190     if (!GetJsonObjectStringItem(msg, FIELD_GROUP_ID, groupInfo->groupId, GROUPID_BUF_LEN)) {
191         AUTH_LOGE(AUTH_HICHAIN, "get FIELD_GROUP_ID fail");
192         cJSON_Delete(msg);
193         return SOFTBUS_ERR;
194     }
195     int32_t groupType = 0;
196     if (!GetJsonObjectNumberItem(msg, FIELD_GROUP_TYPE, &groupType)) {
197         AUTH_LOGE(AUTH_HICHAIN, "get FIELD_GROUP_TYPE fail");
198         cJSON_Delete(msg);
199         return SOFTBUS_ERR;
200     }
201     groupInfo->groupType = (GroupType)groupType;
202     cJSON_Delete(msg);
203     return SOFTBUS_OK;
204 }
205 
OnGroupCreated(const char * groupInfo)206 static void OnGroupCreated(const char *groupInfo)
207 {
208     if (groupInfo == NULL) {
209         AUTH_LOGW(AUTH_HICHAIN, "invalid group info");
210         return;
211     }
212     GroupInfo info;
213     (void)memset_s(&info, sizeof(GroupInfo), 0, sizeof(GroupInfo));
214     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
215         return;
216     }
217     AUTH_LOGI(AUTH_HICHAIN, "hichain OnGroupCreated, type=%{public}d", info.groupType);
218     if (g_dataChangeListener.onGroupCreated != NULL) {
219         g_dataChangeListener.onGroupCreated(info.groupId, (int32_t)info.groupType);
220     }
221 }
222 
OnDeviceBound(const char * udid,const char * groupInfo)223 static void OnDeviceBound(const char *udid, const char *groupInfo)
224 {
225     if (udid == NULL || groupInfo == NULL) {
226         AUTH_LOGW(AUTH_HICHAIN, "invalid udid");
227         return;
228     }
229     AUTH_LOGI(AUTH_HICHAIN, "hichain onDeviceBound");
230     if (g_dataChangeListener.onDeviceBound != NULL) {
231         g_dataChangeListener.onDeviceBound(udid, groupInfo);
232     }
233 }
234 
OnGroupDeleted(const char * groupInfo)235 static void OnGroupDeleted(const char *groupInfo)
236 {
237     if (groupInfo == NULL) {
238         AUTH_LOGE(AUTH_HICHAIN, "invalid group info");
239         return;
240     }
241     GroupInfo info;
242     (void)memset_s(&info, sizeof(GroupInfo), 0, sizeof(GroupInfo));
243     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
244         return;
245     }
246     AUTH_LOGI(AUTH_HICHAIN, "hichain OnGroupDeleted, type=%{public}d", info.groupType);
247     if (g_dataChangeListener.onGroupDeleted != NULL) {
248         g_dataChangeListener.onGroupDeleted(info.groupId);
249     }
250 }
251 
OnDeviceNotTrusted(const char * udid)252 static void OnDeviceNotTrusted(const char *udid)
253 {
254     if (udid == NULL) {
255         AUTH_LOGW(AUTH_HICHAIN, "hichain get invalid udid");
256         return;
257     }
258     char *anonyUdid = NULL;
259     Anonymize(udid, &anonyUdid);
260     AUTH_LOGI(AUTH_HICHAIN, "hichain OnDeviceNotTrusted, udid=%{public}s", anonyUdid);
261     AnonymizeFree(anonyUdid);
262     if (g_dataChangeListener.onDeviceNotTrusted != NULL) {
263         g_dataChangeListener.onDeviceNotTrusted(udid);
264     }
265 }
266 
RegTrustDataChangeListener(const TrustDataChangeListener * listener)267 int32_t RegTrustDataChangeListener(const TrustDataChangeListener *listener)
268 {
269     if (listener == NULL) {
270         return SOFTBUS_INVALID_PARAM;
271     }
272     g_dataChangeListener = *listener;
273 
274     DataChangeListener hichainListener;
275     (void)memset_s(&hichainListener, sizeof(DataChangeListener), 0, sizeof(DataChangeListener));
276     hichainListener.onGroupCreated = OnGroupCreated;
277     hichainListener.onGroupDeleted = OnGroupDeleted;
278     hichainListener.onDeviceNotTrusted = OnDeviceNotTrusted;
279     hichainListener.onDeviceBound = OnDeviceBound;
280     if (RegChangeListener(AUTH_APPID, &hichainListener) != SOFTBUS_OK) {
281         AUTH_LOGE(AUTH_HICHAIN, "hichain regDataChangeListener fail");
282         return SOFTBUS_AUTH_REG_DATA_FAIL;
283     }
284     return SOFTBUS_OK;
285 }
286 
UnregTrustDataChangeListener(void)287 void UnregTrustDataChangeListener(void)
288 {
289     int32_t ret = UnregChangeListener(AUTH_APPID);
290     if (ret != SOFTBUS_OK) {
291         AUTH_LOGE(AUTH_HICHAIN, "hichain unRegDataChangeListener err=%{public}d", ret);
292     }
293     (void)memset_s(&g_dataChangeListener, sizeof(TrustDataChangeListener), 0, sizeof(TrustDataChangeListener));
294 }
295 
HichainStartAuth(int64_t authSeq,const char * udid,const char * uid)296 int32_t HichainStartAuth(int64_t authSeq, const char *udid, const char *uid)
297 {
298     if (udid == NULL || uid == NULL) {
299         AUTH_LOGE(AUTH_HICHAIN, "udid/uid is invalid");
300         return SOFTBUS_INVALID_PARAM;
301     }
302     char *authParams = GenDeviceLevelParam(udid, uid, true);
303     if (authParams == NULL) {
304         AUTH_LOGE(AUTH_HICHAIN, "generate auth param fail");
305         return SOFTBUS_ERR;
306     }
307     if (AuthDevice(authSeq, authParams, &g_hichainCallback) == SOFTBUS_OK) {
308         AUTH_LOGI(AUTH_HICHAIN, "hichain call authDevice succ");
309         cJSON_free(authParams);
310         return SOFTBUS_OK;
311     }
312     AUTH_LOGE(AUTH_HICHAIN, "hichain call authDevice failed");
313     cJSON_free(authParams);
314     return SOFTBUS_AUTH_START_ERR;
315 }
316 
HichainProcessData(int64_t authSeq,const uint8_t * data,uint32_t len)317 int32_t HichainProcessData(int64_t authSeq, const uint8_t *data, uint32_t len)
318 {
319     if (data == NULL) {
320         AUTH_LOGE(AUTH_HICHAIN, "data is null");
321         return SOFTBUS_INVALID_PARAM;
322     }
323     int32_t ret = ProcessAuthData(authSeq, data, len, &g_hichainCallback);
324     if (ret != SOFTBUS_OK) {
325         AUTH_LOGE(AUTH_HICHAIN, "hichain processData err=%{public}d", ret);
326         return ret;
327     }
328     return SOFTBUS_OK;
329 }
330 
HichainDestroy(void)331 void HichainDestroy(void)
332 {
333     UnregTrustDataChangeListener();
334     DestroyDeviceAuth();
335     AUTH_LOGI(AUTH_HICHAIN, "hichain destroy succ");
336 }
337 
HichainCancelRequest(int64_t authReqId)338 void HichainCancelRequest(int64_t authReqId)
339 {
340     CancelRequest(authReqId, AUTH_APPID);
341 }