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