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 }