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