1 /*
2 * Copyright (c) 2025 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 #include "auth_pre_link.h"
16
17 #include <securec.h>
18 #include <stdatomic.h>
19 #include "anonymizer.h"
20 #include "auth_connection.h"
21 #include "auth_deviceprofile.h"
22 #include "auth_log.h"
23 #include "auth_request.h"
24 #include "auth_session_message.h"
25 #include "bus_center_manager.h"
26 #include "device_profile_listener.h"
27 #include "legacy/softbus_adapter_hitrace.h"
28 #include "g_enhance_lnn_func.h"
29 #include "g_enhance_lnn_func_pack.h"
30 #include "lnn_app_bind_interface.h"
31 #include "lnn_decision_db.h"
32 #include "lnn_heartbeat_ctrl.h"
33 #include "lnn_local_net_ledger.h"
34 #include "lnn_ohos_account_adapter.h"
35 #include "lnn_map.h"
36 #include "lnn_net_builder.h"
37 #include "softbus_adapter_mem.h"
38 #include "softbus_init_common.h"
39 #include "wifi_direct_manager.h"
40
41 #define AUTH_GEN_CERT_PARA_EXPIRE_TIME 500
42 #define AUTH_GEN_CERT_PARA_TIME 10
43
44 static SoftBusList g_authPreLinkList;
45 static SoftBusList g_authGenCertParallelList;
46 static bool g_isInitAuthPreLinkList = false;
47 static bool g_isInitAuthGenCertList = false;
48
AuthGenCertParallelLock(void)49 static int32_t AuthGenCertParallelLock(void)
50 {
51 return SoftBusMutexLock(&g_authGenCertParallelList.lock);
52 }
53
AuthGenCertParallelUnLock(void)54 static void AuthGenCertParallelUnLock(void)
55 {
56 (void)SoftBusMutexUnlock(&g_authGenCertParallelList.lock);
57 }
58
InitAuthGenCertParallelList(void)59 int32_t InitAuthGenCertParallelList(void)
60 {
61 if (g_isInitAuthGenCertList) {
62 return SOFTBUS_OK;
63 }
64 if (SoftBusMutexInit(&g_authGenCertParallelList.lock, NULL) != SOFTBUS_OK) {
65 AUTH_LOGE(AUTH_CONN, "auth gen cert parallel init fail");
66 return SOFTBUS_NO_INIT;
67 }
68 ListInit(&g_authGenCertParallelList.list);
69 g_authGenCertParallelList.cnt = 0;
70 g_isInitAuthGenCertList = true;
71 return SOFTBUS_OK;
72 }
73
IsAuthGenCertParaNodeExist(int32_t requestId)74 static bool IsAuthGenCertParaNodeExist(int32_t requestId)
75 {
76 if (AuthGenCertParallelLock() != SOFTBUS_OK) {
77 AUTH_LOGE(AUTH_CONN, "auth generate certificate parallel lock fail");
78 return false;
79 }
80 AuthGenCertNode *item = NULL;
81 LIST_FOR_EACH_ENTRY(item, &g_authGenCertParallelList.list, AuthGenCertNode, node) {
82 if (item->requestId == requestId) {
83 AuthGenCertParallelUnLock();
84 return true;
85 }
86 }
87 AuthGenCertParallelUnLock();
88 return false;
89 }
90
AddAuthGenCertParaNode(int32_t requestId)91 int32_t AddAuthGenCertParaNode(int32_t requestId)
92 {
93 if (IsAuthGenCertParaNodeExist(requestId)) {
94 AUTH_LOGE(AUTH_CONN, "auth gen cert parallel node exists");
95 return SOFTBUS_ALREADY_EXISTED;
96 }
97 AuthGenCertNode *item = (AuthGenCertNode *)SoftBusCalloc(sizeof(AuthGenCertNode));
98 if (item == NULL) {
99 AUTH_LOGE(AUTH_CONN, "item malloc fail");
100 return SOFTBUS_MALLOC_ERR;
101 }
102
103 item->requestId = requestId;
104 item->isValid = false;
105 item->softbusCertChain = NULL;
106 atomic_store_explicit(&item->isParallelGen, 1, memory_order_release);
107 if (AuthGenCertParallelLock() != SOFTBUS_OK) {
108 AUTH_LOGE(AUTH_CONN, "auth generate certificate parallel lock fail");
109 SoftBusFree(item);
110 return SOFTBUS_LOCK_ERR;
111 }
112 ListAdd(&g_authGenCertParallelList.list, &item->node);
113 g_authGenCertParallelList.cnt++;
114 AuthGenCertParallelUnLock();
115 AUTH_LOGI(AUTH_CONN, "create new gencert parallel, authreq=%{public}d", requestId);
116 return SOFTBUS_OK;
117 }
118
FindAuthGenCertParaNodeById(int32_t requestId,AuthGenCertNode ** genCertParaNode)119 static int32_t FindAuthGenCertParaNodeById(int32_t requestId, AuthGenCertNode **genCertParaNode)
120 {
121 if (genCertParaNode == NULL) {
122 AUTH_LOGE(AUTH_CONN, "genCertParaNode pointer is null");
123 return SOFTBUS_INVALID_PARAM;
124 }
125 if (AuthGenCertParallelLock() != SOFTBUS_OK) {
126 AUTH_LOGE(AUTH_CONN, "auth generate certificate parallel lock fail");
127 return SOFTBUS_LOCK_ERR;
128 }
129 AuthGenCertNode *item = NULL;
130 LIST_FOR_EACH_ENTRY(item, &g_authGenCertParallelList.list, AuthGenCertNode, node) {
131 if (item->requestId == requestId) {
132 *genCertParaNode = item;
133 AuthGenCertParallelUnLock();
134 return SOFTBUS_OK;
135 }
136 }
137 AuthGenCertParallelUnLock();
138 return SOFTBUS_NOT_FIND;
139 }
140
UpdateAuthGenCertParaNode(int32_t requestId,bool isValid,SoftbusCertChain * softbusCertChain)141 int32_t UpdateAuthGenCertParaNode(int32_t requestId, bool isValid, SoftbusCertChain *softbusCertChain)
142 {
143 AUTH_CHECK_AND_RETURN_RET_LOGE(softbusCertChain != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "CertChain is NULL");
144 if (AuthGenCertParallelLock() != SOFTBUS_OK) {
145 AUTH_LOGE(AUTH_CONN, "auth generate certificate parallel lock fail");
146 return SOFTBUS_LOCK_ERR;
147 }
148 AuthGenCertNode *item = NULL;
149 LIST_FOR_EACH_ENTRY(item, &g_authGenCertParallelList.list, AuthGenCertNode, node) {
150 if (item->requestId == requestId) {
151 item->isValid = isValid;
152 item->softbusCertChain = softbusCertChain;
153 atomic_store_explicit(&item->isParallelGen, 0, memory_order_release);
154 AuthGenCertParallelUnLock();
155 return SOFTBUS_OK;
156 }
157 }
158 AuthGenCertParallelUnLock();
159 return SOFTBUS_NOT_FIND;
160 }
161
FindAndWaitAuthGenCertParaNodeById(int32_t requestId,AuthGenCertNode ** genCertParaNode)162 int32_t FindAndWaitAuthGenCertParaNodeById(int32_t requestId, AuthGenCertNode **genCertParaNode)
163 {
164 AUTH_CHECK_AND_RETURN_RET_LOGE(genCertParaNode != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "CertParaNode is NULL");
165 int32_t ret = 0;
166 int32_t totalSleepMs = 0;
167 ret = FindAuthGenCertParaNodeById(requestId, genCertParaNode);
168 if (ret != SOFTBUS_OK) {
169 return ret;
170 }
171 if ((*genCertParaNode)->softbusCertChain == NULL) {
172 DelAuthGenCertParaNodeById(requestId);
173 *genCertParaNode = NULL;
174 return SOFTBUS_AUTH_TIMEOUT;
175 }
176 while (((*genCertParaNode)->isParallelGen) && totalSleepMs < AUTH_GEN_CERT_PARA_EXPIRE_TIME) {
177 SoftBusSleepMs(AUTH_GEN_CERT_PARA_TIME);
178 totalSleepMs += AUTH_GEN_CERT_PARA_TIME;
179 }
180 if (totalSleepMs >= AUTH_GEN_CERT_PARA_EXPIRE_TIME || (*genCertParaNode)->isValid == false) {
181 DelAuthGenCertParaNodeById(requestId);
182 *genCertParaNode = NULL;
183 return SOFTBUS_AUTH_TIMEOUT;
184 }
185 if (*genCertParaNode == NULL) {
186 return SOFTBUS_AUTH_TIMEOUT;
187 }
188 return SOFTBUS_OK;
189 }
190
DelAuthGenCertParaNodeById(int32_t requestId)191 void DelAuthGenCertParaNodeById(int32_t requestId)
192 {
193 if (AuthGenCertParallelLock() != SOFTBUS_OK) {
194 AUTH_LOGE(AUTH_CONN, "auth generate certificate parallel lock fail");
195 return;
196 }
197 AuthGenCertNode *item = NULL;
198 AuthGenCertNode *next = NULL;
199 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authGenCertParallelList.list, AuthGenCertNode, node) {
200 if (item->requestId == requestId) {
201 ListDelete(&item->node);
202 FreeSoftbusChainPacked(item->softbusCertChain);
203 SoftBusFree(item->softbusCertChain);
204 item->softbusCertChain = NULL;
205 SoftBusFree(item);
206 g_authGenCertParallelList.cnt--;
207 AuthGenCertParallelUnLock();
208 return;
209 }
210 }
211 AuthGenCertParallelUnLock();
212 }
213
DeinitAuthGenCertParallelList(void)214 void DeinitAuthGenCertParallelList(void)
215 {
216 if (AuthGenCertParallelLock() != SOFTBUS_OK) {
217 AUTH_LOGE(AUTH_CONN, "auth generate certificate parallel lock fail");
218 return;
219 }
220 AuthGenCertNode *item = NULL;
221 AuthGenCertNode *next = NULL;
222 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authGenCertParallelList.list, AuthGenCertNode, node) {
223 ListDelete(&item->node);
224 FreeSoftbusChainPacked(item->softbusCertChain);
225 SoftBusFree(item->softbusCertChain);
226 item->softbusCertChain = NULL;
227 SoftBusFree(item);
228 if (g_authGenCertParallelList.cnt == 0) {
229 AUTH_LOGI(AUTH_CONN, "auth gencert parallel list cnt is 0.");
230 } else {
231 g_authGenCertParallelList.cnt--;
232 }
233 }
234 g_isInitAuthGenCertList = false;
235 AuthGenCertParallelUnLock();
236 SoftBusMutexDestroy(&g_authGenCertParallelList.lock);
237 }
238
AuthPreLinkLock(void)239 static int32_t AuthPreLinkLock(void)
240 {
241 return SoftBusMutexLock(&g_authPreLinkList.lock);
242 }
243
AuthPreLinkUnlock(void)244 static void AuthPreLinkUnlock(void)
245 {
246 (void)SoftBusMutexUnlock(&g_authPreLinkList.lock);
247 }
248
InitAuthPreLinkList(void)249 int32_t InitAuthPreLinkList(void)
250 {
251 if (g_isInitAuthPreLinkList) {
252 return SOFTBUS_OK;
253 }
254 if (SoftBusMutexInit(&g_authPreLinkList.lock, NULL) != SOFTBUS_OK) {
255 AUTH_LOGE(AUTH_CONN, "auth pre link init fail");
256 return SOFTBUS_NO_INIT;
257 }
258 ListInit(&g_authPreLinkList.list);
259 g_authPreLinkList.cnt = 0;
260 g_isInitAuthPreLinkList = true;
261 return SOFTBUS_OK;
262 }
263
PreLinkCheckHasPtk(const char * uuid)264 static bool PreLinkCheckHasPtk(const char *uuid)
265 {
266 if (uuid == NULL) {
267 AUTH_LOGE(AUTH_FSM, "uuid is null");
268 return false;
269 }
270 struct WifiDirectManager *wdMgr = GetWifiDirectManager();
271 if (wdMgr == NULL || wdMgr->linkHasPtk == NULL) {
272 AUTH_LOGE(AUTH_FSM, "get wifiDirect mgr fail");
273 return false;
274 }
275 if (wdMgr->linkHasPtk(uuid)) {
276 return true;
277 }
278 return false;
279 }
280
IsAuthPreLinkNodeExist(uint32_t requestId)281 bool IsAuthPreLinkNodeExist(uint32_t requestId)
282 {
283 if (AuthPreLinkLock() != SOFTBUS_OK) {
284 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
285 return false;
286 }
287 AuthPreLinkNode *item = NULL;
288 LIST_FOR_EACH_ENTRY(item, &g_authPreLinkList.list, AuthPreLinkNode, node) {
289 if (item->requestId == requestId && item->connAddr.type == CONNECTION_ADDR_SESSION_WITH_KEY) {
290 AuthPreLinkUnlock();
291 return true;
292 }
293 }
294 AuthPreLinkUnlock();
295 return false;
296 }
297
AuthPreLinkCheckNeedPtk(uint32_t requestId,const char * uuid)298 bool AuthPreLinkCheckNeedPtk(uint32_t requestId, const char *uuid)
299 {
300 return IsAuthPreLinkNodeExist(requestId) && !PreLinkCheckHasPtk(uuid);
301 }
302
AddToAuthPreLinkList(uint32_t requestId,int32_t fd,ConnectionAddr * connAddr)303 int32_t AddToAuthPreLinkList(uint32_t requestId, int32_t fd, ConnectionAddr *connAddr)
304 {
305 if (IsAuthPreLinkNodeExist(requestId)) {
306 AUTH_LOGE(AUTH_CONN, "auth pre link exists");
307 return SOFTBUS_ALREADY_EXISTED;
308 }
309 AuthPreLinkNode *item = (AuthPreLinkNode *)SoftBusCalloc(sizeof(AuthPreLinkNode));
310 if (item == NULL) {
311 AUTH_LOGE(AUTH_CONN, "item malloc fail");
312 return SOFTBUS_MALLOC_ERR;
313 }
314 if (connAddr != NULL) {
315 if (memcpy_s(&item->connAddr, sizeof(ConnectionAddr), connAddr, sizeof(ConnectionAddr)) != EOK) {
316 AUTH_LOGE(AUTH_CONN, "copy connection addr failed");
317 }
318 }
319
320 item->fd = fd;
321 item->requestId = requestId;
322 item->connAddr.type = CONNECTION_ADDR_SESSION_WITH_KEY;
323 if (AuthPreLinkLock() != SOFTBUS_OK) {
324 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
325 SoftBusFree(item);
326 return SOFTBUS_LOCK_ERR;
327 }
328 ListAdd(&g_authPreLinkList.list, &item->node);
329 g_authPreLinkList.cnt++;
330 AuthPreLinkUnlock();
331 AUTH_LOGI(AUTH_CONN, "create new auth reuse key node, requestId=%{public}d, fd=%{public}u", requestId, fd);
332 return SOFTBUS_OK;
333 }
334
FindAuthPreLinkNodeById(uint32_t requestId,AuthPreLinkNode * reuseNode)335 int32_t FindAuthPreLinkNodeById(uint32_t requestId, AuthPreLinkNode *reuseNode)
336 {
337 AUTH_CHECK_AND_RETURN_RET_LOGE(reuseNode != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "reuseNode is NULL");
338 if (AuthPreLinkLock() != SOFTBUS_OK) {
339 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
340 return SOFTBUS_LOCK_ERR;
341 }
342 AuthPreLinkNode *item = NULL;
343 LIST_FOR_EACH_ENTRY(item, &g_authPreLinkList.list, AuthPreLinkNode, node) {
344 if (item->requestId == requestId && item->connAddr.type == CONNECTION_ADDR_SESSION_WITH_KEY) {
345 if (memcpy_s(reuseNode, sizeof(AuthPreLinkNode), item, sizeof(AuthPreLinkNode)) != EOK) {
346 AUTH_LOGE(AUTH_CONN, "copy AuthPreLinkNode failed");
347 AuthPreLinkUnlock();
348 return SOFTBUS_MEM_ERR;
349 }
350 AuthPreLinkUnlock();
351 return SOFTBUS_OK;
352 }
353 }
354 AuthPreLinkUnlock();
355 return SOFTBUS_NOT_FIND;
356 }
357
FindAuthPreLinkNodeByUuid(const char * uuid,AuthPreLinkNode * preLinkNode)358 int32_t FindAuthPreLinkNodeByUuid(const char *uuid, AuthPreLinkNode *preLinkNode)
359 {
360 AUTH_CHECK_AND_RETURN_RET_LOGE(uuid != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "uuid is NULL");
361 AUTH_CHECK_AND_RETURN_RET_LOGE(preLinkNode != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "uuid is NULL");
362 if (AuthPreLinkLock() != SOFTBUS_OK) {
363 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
364 return SOFTBUS_LOCK_ERR;
365 }
366 AuthPreLinkNode *item = NULL;
367 LIST_FOR_EACH_ENTRY(item, &g_authPreLinkList.list, AuthPreLinkNode, node) {
368 if (memcmp(item->uuid, uuid, UUID_BUF_LEN) == 0) {
369 if (memcpy_s(preLinkNode, sizeof(AuthPreLinkNode), item, sizeof(AuthPreLinkNode)) != EOK) {
370 AUTH_LOGE(AUTH_CONN, "copy AuthPreLinkNode failed");
371 AuthPreLinkUnlock();
372 return SOFTBUS_MEM_ERR;
373 }
374 AuthPreLinkUnlock();
375 return SOFTBUS_OK;
376 }
377 }
378 AuthPreLinkUnlock();
379 return SOFTBUS_NOT_FIND;
380 }
381
UpdateAuthPreLinkUuidById(uint32_t requestId,char * uuid)382 int32_t UpdateAuthPreLinkUuidById(uint32_t requestId, char *uuid)
383 {
384 AUTH_CHECK_AND_RETURN_RET_LOGE(uuid != NULL, SOFTBUS_INVALID_PARAM, AUTH_CONN, "uuid is NULL");
385 if (AuthPreLinkLock() != SOFTBUS_OK) {
386 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
387 return SOFTBUS_LOCK_ERR;
388 }
389 AuthPreLinkNode *item = NULL;
390 LIST_FOR_EACH_ENTRY(item, &g_authPreLinkList.list, AuthPreLinkNode, node) {
391 if (item->requestId == requestId && item->connAddr.type == CONNECTION_ADDR_SESSION_WITH_KEY) {
392 if (memcpy_s(item->uuid, UUID_BUF_LEN, uuid, UUID_BUF_LEN) != EOK) {
393 AUTH_LOGE(AUTH_CONN, "memcpy uuid failed");
394 AuthPreLinkUnlock();
395 return SOFTBUS_MEM_ERR;
396 }
397 AuthPreLinkUnlock();
398 return SOFTBUS_OK;
399 }
400 }
401 AuthPreLinkUnlock();
402 return SOFTBUS_NOT_FIND;
403 }
404
DelAuthPreLinkById(uint32_t requestId)405 void DelAuthPreLinkById(uint32_t requestId)
406 {
407 if (AuthPreLinkLock() != SOFTBUS_OK) {
408 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
409 return;
410 }
411 AuthPreLinkNode *item = NULL;
412 AuthPreLinkNode *next = NULL;
413 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authPreLinkList.list, AuthPreLinkNode, node) {
414 if (item->requestId == requestId) {
415 ListDelete(&item->node);
416 g_authPreLinkList.cnt--;
417 SoftBusFree(item);
418 AuthPreLinkUnlock();
419 return;
420 }
421 }
422 AuthPreLinkUnlock();
423 }
424
DelAuthPreLinkByUuid(char * uuid)425 void DelAuthPreLinkByUuid(char *uuid)
426 {
427 AUTH_CHECK_AND_RETURN_LOGE(uuid != NULL, AUTH_CONN, "uuid is NULL");
428 if (AuthPreLinkLock() != SOFTBUS_OK) {
429 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
430 return;
431 }
432 AuthPreLinkNode *item = NULL;
433 AuthPreLinkNode *next = NULL;
434 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authPreLinkList.list, AuthPreLinkNode, node) {
435 if (memcmp(item->uuid, uuid, UUID_BUF_LEN) == 0) {
436 ListDelete(&item->node);
437 g_authPreLinkList.cnt--;
438 SoftBusFree(item);
439 AuthPreLinkUnlock();
440 return;
441 }
442 }
443 AuthPreLinkUnlock();
444 }
445
DeinitAuthPreLinkList(void)446 void DeinitAuthPreLinkList(void)
447 {
448 AuthPreLinkNode *item = NULL;
449 AuthPreLinkNode *next = NULL;
450 if (AuthPreLinkLock() != SOFTBUS_OK) {
451 AUTH_LOGE(AUTH_CONN, "auth pre link lock fail");
452 return;
453 }
454 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authPreLinkList.list, AuthPreLinkNode, node) {
455 ListDelete(&item->node);
456 g_authPreLinkList.cnt--;
457 SoftBusFree(item);
458 }
459 g_isInitAuthPreLinkList = false;
460 AuthPreLinkUnlock();
461 (void)SoftBusMutexDestroy(&g_authPreLinkList.lock);
462 }