1 /*
2 * Copyright (c) 2021-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 "softbus_proxychannel_control.h"
17
18 #include <securec.h>
19 #include <string.h>
20
21 #include "auth_interface.h"
22 #include "cJSON.h"
23 #include "softbus_adapter_crypto.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_def.h"
26 #include "softbus_error_code.h"
27 #include "softbus_proxychannel_manager.h"
28 #include "softbus_proxychannel_message.h"
29 #include "softbus_proxychannel_transceiver.h"
30 #include "softbus_utils.h"
31 #include "trans_log.h"
32 #include "trans_event.h"
33
TransProxySendEncryptInnerMessage(ProxyChannelInfo * info,const char * inData,uint32_t inDataLen,ProxyMessageHead * msgHead,ProxyDataInfo * dataInfo)34 static int32_t TransProxySendEncryptInnerMessage(ProxyChannelInfo *info,
35 const char *inData, uint32_t inDataLen, ProxyMessageHead *msgHead, ProxyDataInfo *dataInfo)
36 {
37 uint32_t outPayLoadLen = inDataLen + OVERHEAD_LEN;
38 char *outPayLoad = (char *)SoftBusCalloc(outPayLoadLen);
39 if (outPayLoad == NULL) {
40 TRANS_LOGE(TRANS_CTRL, "malloc len failed");
41 return SOFTBUS_MALLOC_ERR;
42 }
43
44 AesGcmCipherKey cipherKey = { 0 };
45 cipherKey.keyLen = SESSION_KEY_LENGTH;
46 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, info->appInfo.sessionKey, SESSION_KEY_LENGTH) != EOK) {
47 TRANS_LOGE(TRANS_CTRL, "memcpy key error.");
48 SoftBusFree(outPayLoad);
49 return SOFTBUS_MEM_ERR;
50 }
51
52 int32_t ret =
53 SoftBusEncryptData(&cipherKey, (unsigned char *)inData, inDataLen, (unsigned char *)outPayLoad, &outPayLoadLen);
54 (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
55 if (ret != SOFTBUS_OK) {
56 TRANS_LOGE(TRANS_CTRL, "SoftBusEncryptData failed, ret=%{public}d", ret);
57 SoftBusFree(outPayLoad);
58 return SOFTBUS_ENCRYPT_ERR;
59 }
60
61 dataInfo->inData = (uint8_t *)outPayLoad;
62 dataInfo->inLen = outPayLoadLen;
63 if (TransProxyPackMessage(msgHead, info->authHandle, dataInfo) != SOFTBUS_OK) {
64 TRANS_LOGE(TRANS_CTRL, "pack msg error");
65 SoftBusFree(outPayLoad);
66 return SOFTBUS_TRANS_PROXY_PACKMSG_ERR;
67 }
68 ret = TransProxyTransSendMsg(
69 info->connId, dataInfo->outData, dataInfo->outLen, CONN_HIGH, info->appInfo.myData.pid);
70 if (ret != SOFTBUS_OK) {
71 TRANS_LOGE(TRANS_CTRL, "send encrypt msg failed");
72 }
73 SoftBusFree(outPayLoad);
74 return ret;
75 }
76
TransProxySendInnerMessage(ProxyChannelInfo * info,const char * payLoad,uint32_t payLoadLen,int32_t priority)77 int32_t TransProxySendInnerMessage(ProxyChannelInfo *info, const char *payLoad, uint32_t payLoadLen, int32_t priority)
78 {
79 if (info == NULL || payLoad == NULL) {
80 TRANS_LOGW(TRANS_CTRL, "invalid param.");
81 return SOFTBUS_INVALID_PARAM;
82 }
83
84 ProxyDataInfo dataInfo = { 0 };
85 ProxyMessageHead msgHead = { 0 };
86 msgHead.type = (PROXYCHANNEL_MSG_TYPE_NORMAL & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
87 msgHead.cipher = (msgHead.cipher | ENCRYPTED);
88 msgHead.myId = info->myId;
89 msgHead.peerId = info->peerId;
90
91 if ((info->appInfo.channelCapability & TRANS_CHANNEL_INNER_ENCRYPT) != 0) {
92 int32_t ret = TransProxySendEncryptInnerMessage(info, payLoad, payLoadLen, &msgHead, &dataInfo);
93 if (ret != SOFTBUS_OK) {
94 TRANS_LOGE(TRANS_CTRL, "send encrypt msg failed");
95 return ret;
96 }
97 } else {
98 dataInfo.inData = (uint8_t *)payLoad;
99 dataInfo.inLen = payLoadLen;
100 if (TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo) != SOFTBUS_OK) {
101 TRANS_LOGE(TRANS_CTRL, "pack msg error");
102 return SOFTBUS_TRANS_PROXY_PACKMSG_ERR;
103 }
104 return TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen,
105 priority, info->appInfo.myData.pid);
106 }
107 return SOFTBUS_OK;
108 }
109
ConvertConnectType2AuthLinkType(ConnectType type)110 static inline AuthLinkType ConvertConnectType2AuthLinkType(ConnectType type)
111 {
112 if (type == CONNECT_TCP) {
113 return AUTH_LINK_TYPE_WIFI;
114 } else if ((type == CONNECT_BLE) || (type == CONNECT_BLE_DIRECT)) {
115 return AUTH_LINK_TYPE_BLE;
116 } else if (type == CONNECT_BR) {
117 return AUTH_LINK_TYPE_BR;
118 } else {
119 return AUTH_LINK_TYPE_P2P;
120 }
121 }
122
SetCipherOfHandshakeMsg(ProxyChannelInfo * info,uint8_t * cipher)123 static int32_t SetCipherOfHandshakeMsg(ProxyChannelInfo *info, uint8_t *cipher)
124 {
125 AuthGetLatestIdByUuid(info->appInfo.peerData.deviceId, ConvertConnectType2AuthLinkType(info->type),
126 false, &info->authHandle);
127 if (info->authHandle.authId == AUTH_INVALID_ID) {
128 TRANS_LOGE(TRANS_CTRL, "get authId for cipher err");
129 return SOFTBUS_TRANS_PROXY_GET_AUTH_ID_FAILED;
130 }
131
132 int32_t ret = TransProxySetAuthHandleByChanId((int32_t)info->channelId, info->authHandle);
133 if (ret != SOFTBUS_OK) {
134 TRANS_LOGE(TRANS_CTRL, "set authHandle fail, ret=%{public}d", ret);
135 return ret;
136 }
137 AuthConnInfo connInfo;
138 (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
139 ret = AuthGetConnInfo(info->authHandle, &connInfo);
140 if (ret != SOFTBUS_OK) {
141 TRANS_LOGE(TRANS_CTRL, "get auth connInfo fail");
142 return ret;
143 }
144 bool isAuthServer = false;
145 ret = AuthGetServerSide(info->authHandle.authId, &isAuthServer);
146 if (ret != SOFTBUS_OK) {
147 TRANS_LOGE(TRANS_CTRL, "get auth server side fail");
148 return ret;
149 }
150
151 *cipher |= ENCRYPTED;
152 if (isAuthServer) {
153 *cipher |= AUTH_SERVER_SIDE;
154 }
155 if (connInfo.type == AUTH_LINK_TYPE_BLE) {
156 *cipher |= USE_BLE_CIPHER;
157 }
158 return SOFTBUS_OK;
159 }
160
TransProxyHandshake(ProxyChannelInfo * info)161 int32_t TransProxyHandshake(ProxyChannelInfo *info)
162 {
163 if (info == NULL) {
164 TRANS_LOGW(TRANS_CTRL, "invalid param.");
165 return SOFTBUS_INVALID_PARAM;
166 }
167 char *payLoad = NULL;
168 ProxyDataInfo dataInfo = {0};
169 ProxyMessageHead msgHead = {0};
170 msgHead.type = (PROXYCHANNEL_MSG_TYPE_HANDSHAKE & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
171 msgHead.cipher = CS_MODE;
172 if (info->appInfo.appType != APP_TYPE_AUTH) {
173 if (SetCipherOfHandshakeMsg(info, &msgHead.cipher) != SOFTBUS_OK) {
174 TRANS_LOGE(TRANS_CTRL, "set cipher fail");
175 return SOFTBUS_TRANS_PROXY_SET_CIPHER_FAILED;
176 }
177 }
178 msgHead.myId = info->myId;
179 msgHead.peerId = INVALID_CHANNEL_ID;
180 TRANS_LOGI(TRANS_CTRL, "handshake myChannelId=%{public}d, cipher=0x%{public}02x", msgHead.myId, msgHead.cipher);
181 payLoad = TransProxyPackHandshakeMsg(info);
182 if (payLoad == NULL) {
183 TRANS_LOGE(TRANS_CTRL, "pack handshake fail");
184 return SOFTBUS_TRANS_PROXY_PACK_HANDSHAKE_ERR;
185 }
186 dataInfo.inData = (uint8_t *)payLoad;
187 dataInfo.inLen = strlen(payLoad) + 1;
188 if (TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo) != SOFTBUS_OK) {
189 TRANS_LOGE(TRANS_CTRL, "pack handshake head fail");
190 cJSON_free(payLoad);
191 return SOFTBUS_TRANS_PROXY_PACK_HANDSHAKE_HEAD_ERR;
192 }
193 cJSON_free(payLoad);
194 dataInfo.inData = NULL;
195 int32_t ret = TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen,
196 CONN_HIGH, info->appInfo.myData.pid);
197 if (ret != SOFTBUS_OK) {
198 TRANS_LOGE(TRANS_CTRL, "send handshake buf fail");
199 return ret;
200 }
201 TransEventExtra extra = {
202 .channelId = info->myId,
203 .connectionId = (int32_t)info->connId,
204 .result = EVENT_STAGE_RESULT_OK
205 };
206 TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL, EVENT_STAGE_HANDSHAKE_START, extra);
207 return SOFTBUS_OK;
208 }
209
TransProxyAckHandshake(uint32_t connId,ProxyChannelInfo * chan,int32_t retCode)210 int32_t TransProxyAckHandshake(uint32_t connId, ProxyChannelInfo *chan, int32_t retCode)
211 {
212 if (chan == NULL) {
213 TRANS_LOGW(TRANS_CTRL, "invalid param.");
214 return SOFTBUS_INVALID_PARAM;
215 }
216 char *payLoad = NULL;
217 ProxyDataInfo dataInfo = {0};
218 ProxyMessageHead msgHead = {0};
219
220 msgHead.type = (PROXYCHANNEL_MSG_TYPE_HANDSHAKE_ACK & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
221 if (chan->appInfo.appType != APP_TYPE_AUTH) {
222 msgHead.cipher = (msgHead.cipher | ENCRYPTED);
223 }
224 msgHead.myId = chan->myId;
225 msgHead.peerId = chan->peerId;
226
227 if (retCode != SOFTBUS_OK) {
228 TRANS_LOGI(TRANS_CTRL,
229 "send handshake error msg errCode=%{public}d, myChannelId=%{public}d, peerChannelId=%{public}d",
230 retCode, chan->myId, chan->peerId);
231 payLoad = TransProxyPackHandshakeErrMsg(retCode);
232 } else {
233 TRANS_LOGI(TRANS_CTRL, "send handshake ack msg myChannelId=%{public}d, peerChannelId=%{public}d",
234 chan->myId, chan->peerId);
235 payLoad = TransProxyPackHandshakeAckMsg(chan);
236 }
237 if (payLoad == NULL) {
238 TRANS_LOGE(TRANS_CTRL, "pack handshake ack fail");
239 return SOFTBUS_TRANS_PROXY_PACKMSG_ERR;
240 }
241 dataInfo.inData = (uint8_t *)payLoad;
242 dataInfo.inLen = strlen(payLoad) + 1;
243 if (TransProxyPackMessage(&msgHead, chan->authHandle, &dataInfo) != SOFTBUS_OK) {
244 TRANS_LOGE(TRANS_CTRL, "pack handshake ack head fail");
245 cJSON_free(payLoad);
246 return SOFTBUS_TRANS_PROXY_PACKMSG_ERR;
247 }
248 cJSON_free(payLoad);
249 int32_t ret = TransProxyTransSendMsg(connId, dataInfo.outData, dataInfo.outLen,
250 CONN_HIGH, chan->appInfo.myData.pid);
251 TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_CTRL, "send handshakeack buf fail");
252 return SOFTBUS_OK;
253 }
254
TransProxyKeepalive(uint32_t connId,const ProxyChannelInfo * info)255 void TransProxyKeepalive(uint32_t connId, const ProxyChannelInfo *info)
256 {
257 if (info == NULL) {
258 TRANS_LOGW(TRANS_CTRL, "invalid param.");
259 return;
260 }
261
262 char *payLoad = NULL;
263 ProxyDataInfo dataInfo = {0};
264 ProxyMessageHead msgHead = {0};
265 msgHead.type = (PROXYCHANNEL_MSG_TYPE_KEEPALIVE & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
266 msgHead.myId = info->myId;
267 msgHead.peerId = info->peerId;
268 if (info->appInfo.appType != APP_TYPE_AUTH) {
269 msgHead.cipher = (msgHead.cipher | ENCRYPTED);
270 }
271
272 payLoad = TransProxyPackIdentity(info->identity);
273 if (payLoad == NULL) {
274 TRANS_LOGE(TRANS_CTRL, "pack keepalive fail");
275 return;
276 }
277 dataInfo.inData = (uint8_t *)payLoad;
278 dataInfo.inLen = strlen(payLoad) + 1;
279 if (TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo) != SOFTBUS_OK) {
280 TRANS_LOGE(TRANS_CTRL, "pack keepalive head fail");
281 cJSON_free(payLoad);
282 return;
283 }
284 cJSON_free(payLoad);
285 if (TransProxyTransSendMsg(connId, dataInfo.outData, dataInfo.outLen,
286 CONN_HIGH, info->appInfo.myData.pid) != SOFTBUS_OK) {
287 TRANS_LOGE(TRANS_CTRL, "send keepalive buf fail");
288 return;
289 }
290 }
291
TransProxyAckKeepalive(ProxyChannelInfo * info)292 int32_t TransProxyAckKeepalive(ProxyChannelInfo *info)
293 {
294 if (info == NULL) {
295 TRANS_LOGW(TRANS_CTRL, "invalid param.");
296 return SOFTBUS_INVALID_PARAM;
297 }
298 char *payLoad = NULL;
299 ProxyDataInfo dataInfo = {0};
300 ProxyMessageHead msgHead = {0};
301 msgHead.type = (PROXYCHANNEL_MSG_TYPE_KEEPALIVE_ACK & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
302 msgHead.myId = info->myId;
303 msgHead.peerId = info->peerId;
304 if (info->appInfo.appType != APP_TYPE_AUTH) {
305 msgHead.cipher = (msgHead.cipher | ENCRYPTED);
306 }
307
308 payLoad = TransProxyPackIdentity(info->identity);
309 if (payLoad == NULL) {
310 TRANS_LOGE(TRANS_CTRL, "pack keepalive ack fail");
311 return SOFTBUS_TRANS_PACK_LEEPALIVE_ACK_FAILED;
312 }
313 dataInfo.inData = (uint8_t *)payLoad;
314 dataInfo.inLen = strlen(payLoad) + 1;
315 int32_t ret = TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo);
316 if (ret != SOFTBUS_OK) {
317 TRANS_LOGE(TRANS_CTRL, "pack keepalive ack head fail");
318 cJSON_free(payLoad);
319 return ret;
320 }
321 cJSON_free(payLoad);
322 ret = TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen, CONN_HIGH, info->appInfo.myData.pid);
323 if (ret != SOFTBUS_OK) {
324 TRANS_LOGE(TRANS_CTRL, "send keepalive ack buf fail");
325 return ret;
326 }
327 return SOFTBUS_OK;
328 }
329
TransProxyResetPeer(ProxyChannelInfo * info)330 int32_t TransProxyResetPeer(ProxyChannelInfo *info)
331 {
332 if (info == NULL) {
333 TRANS_LOGW(TRANS_CTRL, "invalid param.");
334 return SOFTBUS_INVALID_PARAM;
335 }
336
337 char *payLoad = NULL;
338 ProxyDataInfo dataInfo = {0};
339 ProxyMessageHead msgHead = {0};
340 TRANS_LOGI(TRANS_CTRL, "send reset msg myChannelId=%{public}d, peerChannelId=%{public}d", info->myId, info->peerId);
341 msgHead.type = (PROXYCHANNEL_MSG_TYPE_RESET & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
342 msgHead.myId = info->myId;
343 msgHead.peerId = info->peerId;
344 if (info->appInfo.appType != APP_TYPE_AUTH) {
345 msgHead.cipher = (msgHead.cipher | ENCRYPTED);
346 }
347
348 payLoad = TransProxyPackIdentity(info->identity);
349 if (payLoad == NULL) {
350 TRANS_LOGE(TRANS_CTRL, "pack reset fail");
351 return SOFTBUS_TRANS_PACK_LEEPALIVE_ACK_FAILED;
352 }
353 dataInfo.inData = (uint8_t *)payLoad;
354 dataInfo.inLen = strlen(payLoad) + 1;
355 int32_t ret = TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo);
356 if (ret != SOFTBUS_OK) {
357 TRANS_LOGE(TRANS_CTRL, "pack reset head fail");
358 cJSON_free(payLoad);
359 return ret;
360 }
361 cJSON_free(payLoad);
362 ret = TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen, CONN_LOW, info->appInfo.myData.pid);
363 TransEventExtra extra = {
364 .socketName = info->appInfo.myData.sessionName,
365 .channelId = info->channelId,
366 .errcode = ret,
367 .result = EVENT_STAGE_RESULT_OK
368 };
369 if (ret != SOFTBUS_OK) {
370 TRANS_LOGE(TRANS_CTRL, "send reset buf fail");
371 extra.result = EVENT_STAGE_RESULT_FAILED;
372 TRANS_EVENT(EVENT_SCENE_TRANS_PROXY_RESET_PEER, EVENT_STAGE_TRANS_COMMON_ONE, extra);
373 return ret;
374 }
375 TRANS_EVENT(EVENT_SCENE_TRANS_PROXY_RESET_PEER, EVENT_STAGE_TRANS_COMMON_ONE, extra);
376 return SOFTBUS_OK;
377 }
378