• 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_common.h"
17 
18 #include <securec.h>
19 
20 #include "auth_log.h"
21 #include "bus_center_manager.h"
22 #include "message_handler.h"
23 #include "softbus_adapter_crypto.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_adapter_timer.h"
26 #include "softbus_base_listener.h"
27 #include "softbus_def.h"
28 #include "softbus_feature_config.h"
29 
30 #define TIME_SEC_TO_MSEC  1000L
31 #define TIME_MSEC_TO_USEC 1000L
32 
33 #define SEQ_NETWORK_ID_BITS 32
34 #define SEQ_TIME_STAMP_BITS 8
35 #define SEQ_TIME_STAMP_MASK 0xFFL
36 #define SEQ_INTEGER_BITS    24
37 #define SEQ_INTEGER_MAX     0xFFFFFF
38 
39 #define AUTH_SUPPORT_AS_SERVER_MASK 0x01
40 
41 /* ble network advdata take 8 bytes of UDID hash */
42 #define SHORT_HASH_LEN 8
43 
44 typedef struct {
45     EventType event;
46     RemoveCompareFunc cmpFunc;
47     void *param;
48 } EventRemoveInfo;
49 
50 static uint64_t g_uniqueId = 0;
51 static SoftBusMutex g_authLock;
52 static SoftBusHandler g_authHandler = { NULL, NULL, NULL };
53 
54 /* auth handler */
IsAuthHandlerInit(void)55 static bool IsAuthHandlerInit(void)
56 {
57     if (g_authHandler.looper == NULL || g_authHandler.looper->PostMessage == NULL ||
58         g_authHandler.looper->PostMessageDelay == NULL || g_authHandler.looper->RemoveMessageCustom == NULL) {
59         AUTH_LOGE(AUTH_INIT, "auth handler not init");
60         return false;
61     }
62     return true;
63 }
64 
DelAuthMessage(SoftBusMessage * msg)65 static void DelAuthMessage(SoftBusMessage *msg)
66 {
67     CHECK_NULL_PTR_RETURN_VOID(msg);
68     if (msg->obj != NULL) {
69         SoftBusFree(msg->obj);
70         msg->obj = NULL;
71     }
72     SoftBusFree(msg);
73 }
74 
NewAuthMessage(const uint8_t * obj,uint32_t size)75 static SoftBusMessage *NewAuthMessage(const uint8_t *obj, uint32_t size)
76 {
77     SoftBusMessage *msg = MallocMessage();
78     if (msg == NULL) {
79         AUTH_LOGE(AUTH_CONN, "malloc message fail");
80         return NULL;
81     }
82     msg->obj = NULL;
83     if (obj != NULL && size > 0) {
84         msg->obj = DupMemBuffer(obj, size);
85         if (msg->obj == NULL) {
86             AUTH_LOGE(AUTH_CONN, "dup data fail");
87             SoftBusFree(msg);
88             return NULL;
89         }
90     }
91     msg->handler = &g_authHandler;
92     msg->FreeMessage = DelAuthMessage;
93     return msg;
94 }
95 
HandleAuthMessage(SoftBusMessage * msg)96 static void HandleAuthMessage(SoftBusMessage *msg)
97 {
98     CHECK_NULL_PTR_RETURN_VOID(msg);
99     EventHandler handler = (EventHandler)(uintptr_t)msg->arg1;
100     if (handler == NULL) {
101         AUTH_LOGE(AUTH_CONN, "invalid event handler, event=%{public}d", msg->what);
102         return;
103     }
104     handler(msg->obj);
105 }
106 
107 
PostAuthEvent(EventType event,EventHandler handler,const void * obj,uint32_t size,uint64_t delayMs)108 int32_t PostAuthEvent(EventType event, EventHandler handler, const void *obj, uint32_t size, uint64_t delayMs)
109 {
110     if (!IsAuthHandlerInit()) {
111         return SOFTBUS_NO_INIT;
112     }
113     SoftBusMessage *msg = NewAuthMessage(obj, size);
114     if (msg == NULL) {
115         AUTH_LOGE(AUTH_CONN, "malloc fail, event=%{public}d", event);
116         return SOFTBUS_MALLOC_ERR;
117     }
118     msg->what = (int32_t)event;
119     msg->arg1 = (uint64_t)(uintptr_t)handler;
120     if (delayMs == 0) {
121         g_authHandler.looper->PostMessage(g_authHandler.looper, msg);
122     } else {
123         g_authHandler.looper->PostMessageDelay(g_authHandler.looper, msg, delayMs);
124     }
125     return SOFTBUS_OK;
126 }
127 
CustomFunc(const SoftBusMessage * msg,void * param)128 static int32_t CustomFunc(const SoftBusMessage *msg, void *param)
129 {
130     CHECK_NULL_PTR_RETURN_VALUE(msg, SOFTBUS_ERR);
131     CHECK_NULL_PTR_RETURN_VALUE(param, SOFTBUS_ERR);
132     EventRemoveInfo *info = (EventRemoveInfo *)param;
133     if (msg->what != (int32_t)info->event) {
134         AUTH_LOGE(AUTH_CONN, "msg->what and event inequality");
135         return SOFTBUS_ERR;
136     }
137     if (info->cmpFunc == NULL) {
138         AUTH_LOGE(AUTH_CONN, "cmpFunc is null");
139         return SOFTBUS_ERR;
140     }
141     return info->cmpFunc(msg->obj, info->param);
142 }
143 
RemoveAuthEvent(EventType event,RemoveCompareFunc func,void * param)144 int32_t RemoveAuthEvent(EventType event, RemoveCompareFunc func, void *param)
145 {
146     if (!IsAuthHandlerInit()) {
147         return SOFTBUS_NO_INIT;
148     }
149     EventRemoveInfo info = {
150         .event = event,
151         .cmpFunc = func,
152         .param = param,
153     };
154     g_authHandler.looper->RemoveMessageCustom(g_authHandler.looper, &g_authHandler, CustomFunc, &info);
155     return SOFTBUS_OK;
156 }
157 
158 /* auth lock */
RequireAuthLock(void)159 bool RequireAuthLock(void)
160 {
161     if (SoftBusMutexLock(&g_authLock) != SOFTBUS_OK) {
162         AUTH_LOGE(AUTH_CONN, "auth lock fail");
163         return false;
164     }
165     return true;
166 }
167 
ReleaseAuthLock(void)168 void ReleaseAuthLock(void)
169 {
170     if (SoftBusMutexUnlock(&g_authLock) != SOFTBUS_OK) {
171         AUTH_LOGE(AUTH_CONN, "auth unlock fail");
172     }
173 }
174 
175 /* auth config */
GetConfigSupportAsServer(void)176 bool GetConfigSupportAsServer(void)
177 {
178     uint32_t ability = 0;
179     if (SoftbusGetConfig(SOFTBUS_INT_AUTH_ABILITY_COLLECTION, (uint8_t *)(&ability), sizeof(ability)) != SOFTBUS_OK) {
180         AUTH_LOGE(AUTH_CONN, "get auth ability from config file fail");
181     }
182     AUTH_LOGI(AUTH_CONN, "auth ability=%{public}u", ability);
183     return ((ability & AUTH_SUPPORT_AS_SERVER_MASK) != 0);
184 }
185 
186 /* auth common function */
DupMemBuffer(const uint8_t * buf,uint32_t size)187 uint8_t *DupMemBuffer(const uint8_t *buf, uint32_t size)
188 {
189     if (buf == NULL || size == 0) {
190         AUTH_LOGE(AUTH_CONN, "param err");
191         return NULL;
192     }
193     uint8_t *dup = (uint8_t *)SoftBusMalloc(size);
194     if (dup == NULL) {
195         AUTH_LOGE(AUTH_CONN, "malloc err");
196         return NULL;
197     }
198     if (memcpy_s(dup, size, buf, size) != EOK) {
199         AUTH_LOGE(AUTH_CONN, "memcpy err");
200         SoftBusFree(dup);
201         return NULL;
202     }
203     return dup;
204 }
205 
UpdateUniqueId(void)206 static void UpdateUniqueId(void)
207 {
208     char networkId[NETWORK_ID_BUF_LEN] = { 0 };
209     if (LnnGetLocalStrInfo(STRING_KEY_NETWORKID, networkId, sizeof(networkId)) != SOFTBUS_OK) {
210         AUTH_LOGE(AUTH_CONN, "get local networkId fail");
211         return;
212     }
213     uint8_t hashId[SHA_256_HASH_LEN] = { 0 };
214     if (SoftBusGenerateStrHash((uint8_t *)networkId, strlen(networkId), hashId) != SOFTBUS_OK) {
215         AUTH_LOGE(AUTH_CONN, "GenerateStrHash fail");
216         return;
217     }
218     for (uint32_t i = 0; i < SEQ_NETWORK_ID_BITS / BYTES_BIT_NUM; i++) {
219         g_uniqueId = (g_uniqueId << BYTES_BIT_NUM) | hashId[i];
220     }
221     uint64_t timeStamp = GetCurrentTimeMs();
222     g_uniqueId = (g_uniqueId << SEQ_TIME_STAMP_BITS) | (SEQ_TIME_STAMP_MASK & timeStamp);
223 }
224 
GenSeq(bool isServer)225 int64_t GenSeq(bool isServer)
226 {
227     static uint32_t integer = 0;
228     if (integer >= SEQ_INTEGER_MAX) {
229         integer = 0;
230     }
231     if (integer == 0) {
232         UpdateUniqueId();
233     }
234     integer += SEQ_INTERVAL;
235     uint64_t seq = isServer ? (integer + 1) : integer;
236     /* |----NetworkIdHash(32)----|-----timeStamp(8)----|----AtomicInteger(24)----| */
237     seq = (g_uniqueId << SEQ_INTEGER_BITS) | (seq & SEQ_INTEGER_MAX);
238     return (int64_t)seq;
239 }
240 
GetCurrentTimeMs(void)241 uint64_t GetCurrentTimeMs(void)
242 {
243     SoftBusSysTime now = { 0 };
244     if (SoftBusGetTime(&now) != SOFTBUS_OK) {
245         AUTH_LOGE(AUTH_CONN, "SoftBusGetTime fail");
246         return 0;
247     }
248     return (uint64_t)now.sec * TIME_SEC_TO_MSEC + (uint64_t)now.usec / TIME_MSEC_TO_USEC;
249 }
250 
GetAuthSideStr(bool isServer)251 const char *GetAuthSideStr(bool isServer)
252 {
253     return isServer ? "server" : "client";
254 }
255 
CompareConnInfo(const AuthConnInfo * info1,const AuthConnInfo * info2,bool cmpShortHash)256 bool CompareConnInfo(const AuthConnInfo *info1, const AuthConnInfo *info2, bool cmpShortHash)
257 {
258     CHECK_NULL_PTR_RETURN_VALUE(info1, false);
259     CHECK_NULL_PTR_RETURN_VALUE(info2, false);
260     switch (info1->type) {
261         case AUTH_LINK_TYPE_WIFI:
262             if (info2->type == AUTH_LINK_TYPE_WIFI && strcmp(info1->info.ipInfo.ip, info2->info.ipInfo.ip) == 0) {
263                 return true;
264             }
265             break;
266         case AUTH_LINK_TYPE_BR:
267             if (info2->type == AUTH_LINK_TYPE_BR &&
268                 StrCmpIgnoreCase(info1->info.brInfo.brMac, info2->info.brInfo.brMac) == 0) {
269                 return true;
270             }
271             break;
272         case AUTH_LINK_TYPE_BLE:
273             if (info2->type == AUTH_LINK_TYPE_BLE &&
274                 (memcmp(info1->info.bleInfo.deviceIdHash, info2->info.bleInfo.deviceIdHash,
275                 (cmpShortHash ? SHORT_HASH_LEN : UDID_HASH_LEN)) == 0 ||
276                 StrCmpIgnoreCase(info1->info.bleInfo.bleMac, info2->info.bleInfo.bleMac) == 0)) {
277                 return true;
278             }
279             break;
280         case AUTH_LINK_TYPE_P2P:
281             if (info2->type == AUTH_LINK_TYPE_P2P && info1->info.ipInfo.port == info2->info.ipInfo.port &&
282                 strcmp(info1->info.ipInfo.ip, info2->info.ipInfo.ip) == 0) {
283                 return true;
284             }
285             break;
286         case AUTH_LINK_TYPE_ENHANCED_P2P:
287             if (info2->type == AUTH_LINK_TYPE_ENHANCED_P2P && info1->info.ipInfo.port == info2->info.ipInfo.port &&
288                 strcmp(info1->info.ipInfo.ip, info2->info.ipInfo.ip) == 0) {
289                 return true;
290             }
291             break;
292         default:
293             AUTH_LOGE(AUTH_CONN, "unexpected connType=%{public}d", info1->type);
294             return false;
295     }
296     return false;
297 }
298 
ConvertToConnectOption(const AuthConnInfo * connInfo,ConnectOption * option)299 int32_t ConvertToConnectOption(const AuthConnInfo *connInfo, ConnectOption *option)
300 {
301     CHECK_NULL_PTR_RETURN_VALUE(connInfo, SOFTBUS_INVALID_PARAM);
302     CHECK_NULL_PTR_RETURN_VALUE(option, SOFTBUS_INVALID_PARAM);
303     switch (connInfo->type) {
304         case AUTH_LINK_TYPE_BR:
305             option->type = CONNECT_BR;
306             if (strcpy_s(option->brOption.brMac, BT_MAC_LEN, connInfo->info.brInfo.brMac) != EOK) {
307                 AUTH_LOGE(AUTH_CONN, "copy brMac fail");
308                 return SOFTBUS_MEM_ERR;
309             }
310             break;
311         case AUTH_LINK_TYPE_BLE:
312             option->type = CONNECT_BLE;
313             if (strcpy_s(option->bleOption.bleMac, BT_MAC_LEN, connInfo->info.bleInfo.bleMac) != EOK ||
314                 memcpy_s(option->bleOption.deviceIdHash, UDID_HASH_LEN, connInfo->info.bleInfo.deviceIdHash,
315                     UDID_HASH_LEN) != EOK) {
316                 AUTH_LOGE(AUTH_CONN, "copy bleMac/deviceIdHash fail");
317                 return SOFTBUS_MEM_ERR;
318             }
319             option->bleOption.fastestConnectEnable = true;
320             option->bleOption.psm = connInfo->info.bleInfo.psm;
321             option->bleOption.protocol = connInfo->info.bleInfo.protocol;
322             break;
323         case AUTH_LINK_TYPE_P2P:
324             option->type = CONNECT_TCP;
325             if (strcpy_s(option->socketOption.addr, sizeof(option->socketOption.addr), connInfo->info.ipInfo.ip) !=
326                 EOK) {
327                 AUTH_LOGE(AUTH_CONN, "copy ip fail");
328                 return SOFTBUS_MEM_ERR;
329             }
330             option->socketOption.port = connInfo->info.ipInfo.port;
331             option->socketOption.moduleId = AUTH_P2P;
332             option->socketOption.protocol = LNN_PROTOCOL_IP;
333             option->socketOption.keepAlive = 1;
334             break;
335         case AUTH_LINK_TYPE_ENHANCED_P2P:
336             option->type = CONNECT_TCP;
337             if (strcpy_s(option->socketOption.addr, sizeof(option->socketOption.addr), connInfo->info.ipInfo.ip) !=
338                 EOK) {
339                 AUTH_LOGE(AUTH_CONN, "copy ip fail");
340                 return SOFTBUS_MEM_ERR;
341             }
342             option->socketOption.port = connInfo->info.ipInfo.port;
343             option->socketOption.moduleId = connInfo->info.ipInfo.moduleId;
344             option->socketOption.protocol = LNN_PROTOCOL_IP;
345             option->socketOption.keepAlive = 1;
346             break;
347         default:
348             AUTH_LOGE(AUTH_CONN, "unexpected connType=%{public}d", connInfo->type);
349             return SOFTBUS_ERR;
350     }
351     return SOFTBUS_OK;
352 }
353 
IsEnhanceP2pModuleId(ListenerModule moduleId)354 static bool IsEnhanceP2pModuleId(ListenerModule moduleId)
355 {
356     if (moduleId >= AUTH_ENHANCED_P2P_START && moduleId <= AUTH_ENHANCED_P2P_END) {
357         return true;
358     }
359     return false;
360 }
361 
ConvertToAuthConnInfo(const ConnectionInfo * info,AuthConnInfo * connInfo)362 int32_t ConvertToAuthConnInfo(const ConnectionInfo *info, AuthConnInfo *connInfo)
363 {
364     CHECK_NULL_PTR_RETURN_VALUE(info, SOFTBUS_INVALID_PARAM);
365     CHECK_NULL_PTR_RETURN_VALUE(connInfo, SOFTBUS_INVALID_PARAM);
366     switch (info->type) {
367         case CONNECT_TCP:
368             if (info->socketInfo.protocol != LNN_PROTOCOL_IP) {
369                 AUTH_LOGW(AUTH_CONN, "only support LNN_PROTOCOL_IP");
370                 return SOFTBUS_ERR;
371             }
372             if (IsEnhanceP2pModuleId(info->socketInfo.moduleId)) {
373                 connInfo->type = AUTH_LINK_TYPE_ENHANCED_P2P;
374             } else {
375                 connInfo->type = AUTH_LINK_TYPE_P2P;
376             }
377             connInfo->info.ipInfo.moduleId = info->socketInfo.moduleId;
378             connInfo->info.ipInfo.port = info->socketInfo.port;
379             if (strcpy_s(connInfo->info.ipInfo.ip, IP_LEN, info->socketInfo.addr) != EOK) {
380                 AUTH_LOGE(AUTH_CONN, "copy ip fail");
381                 return SOFTBUS_MEM_ERR;
382             }
383             break;
384         case CONNECT_BR:
385             connInfo->type = AUTH_LINK_TYPE_BR;
386             if (strcpy_s(connInfo->info.brInfo.brMac, BT_MAC_LEN, info->brInfo.brMac) != EOK) {
387                 AUTH_LOGE(AUTH_CONN, "copy brMac fail");
388                 return SOFTBUS_MEM_ERR;
389             }
390             break;
391         case CONNECT_BLE:
392             connInfo->type = AUTH_LINK_TYPE_BLE;
393             if (strcpy_s(connInfo->info.bleInfo.bleMac, BT_MAC_LEN, info->bleInfo.bleMac) != EOK ||
394                 memcpy_s(connInfo->info.bleInfo.deviceIdHash, UDID_HASH_LEN, info->bleInfo.deviceIdHash,
395                     UDID_HASH_LEN) != EOK) {
396                 AUTH_LOGE(AUTH_CONN, "copy bleMac/deviceIdHash fail");
397                 return SOFTBUS_MEM_ERR;
398             }
399             connInfo->info.bleInfo.protocol = info->bleInfo.protocol;
400             connInfo->info.bleInfo.psm = info->bleInfo.psm;
401             break;
402         default:
403             AUTH_LOGE(AUTH_CONN, "unexpected connType=%{public}d", info->type);
404             return SOFTBUS_ERR;
405     }
406     return SOFTBUS_OK;
407 }
408 
AuthCommonInit(void)409 int32_t AuthCommonInit(void)
410 {
411     g_authHandler.name = "AuthHandler";
412     g_authHandler.HandleMessage = HandleAuthMessage;
413     g_authHandler.looper = GetLooper(LOOP_TYPE_DEFAULT);
414 
415     if (SoftBusMutexInit(&g_authLock, NULL) != SOFTBUS_OK) {
416         AUTH_LOGE(AUTH_INIT, "auth mutex init fail");
417         return SOFTBUS_ERR;
418     }
419     return SOFTBUS_OK;
420 }
421 
AuthCommonDeinit(void)422 void AuthCommonDeinit(void)
423 {
424     g_authHandler.looper = NULL;
425     g_authHandler.HandleMessage = NULL;
426 
427     if (SoftBusMutexDestroy(&g_authLock) != SOFTBUS_OK) {
428         AUTH_LOGE(AUTH_INIT, "auth mutex destroy fail");
429     }
430 }
431 
GetPeerUdidByNetworkId(const char * networkId,char * udid)432 int32_t GetPeerUdidByNetworkId(const char *networkId, char *udid)
433 {
434     if (networkId == NULL || udid == NULL) {
435         AUTH_LOGW(AUTH_CONN, "param err");
436         return SOFTBUS_ERR;
437     }
438     NodeInfo *info = LnnRetrieveDeviceInfoByNetworkId(networkId);
439     if (info != NULL && info->deviceInfo.deviceUdid[0] != '\0') {
440         if (memcpy_s(udid, UDID_BUF_LEN, info->deviceInfo.deviceUdid, UDID_BUF_LEN) != EOK) {
441             return SOFTBUS_ERR;
442         }
443         return SOFTBUS_OK;
444     }
445     AUTH_LOGE(AUTH_CONN, "info or deviceUdid is null");
446     return SOFTBUS_ERR;
447 }