• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "tlssocket_exec.h"
17 
18 #include <string>
19 #include <vector>
20 
21 #include <napi/native_api.h>
22 #include <securec.h>
23 
24 #include "context_key.h"
25 #include "event_list.h"
26 #include "napi_utils.h"
27 #include "netstack_log.h"
28 #include "socket_error.h"
29 #include "socket_exec_common.h"
30 #include "socks5_utils.h"
31 #include "tls_socket.h"
32 
33 #ifdef IOS_PLATFORM
34 #define SO_PROTOCOL 38
35 #endif
36 
37 namespace OHOS {
38 namespace NetStack {
39 namespace TlsSocket {
40 namespace {
41 constexpr const char *CERTIFICATA_DATA = "data";
42 constexpr const char *CERTIFICATA_ENCODING_FORMAT = "encodingFormat";
43 } // namespace
44 
TLSSocketThrowException(TLSInitContext * context,int32_t errorCode)45 static inline void TLSSocketThrowException(TLSInitContext *context, int32_t errorCode)
46 {
47     context->SetNeedThrowException(true);
48     context->SetError(errorCode, MakeErrorMessage(errorCode));
49 }
50 
IsTCPSocket(int sockFD)51 static inline bool IsTCPSocket(int sockFD)
52 {
53     int optval;
54     socklen_t optlen = sizeof(optval);
55 
56     if (getsockopt(sockFD, SOL_SOCKET, SO_PROTOCOL, &optval, &optlen) != 0) {
57         return false;
58     }
59     return optval == IPPROTO_TCP;
60 }
61 
IsConnected(int sockFD)62 static inline bool IsConnected(int sockFD)
63 {
64     sockaddr_storage addr{};
65     socklen_t len = sizeof(addr);
66     return getpeername(sockFD, reinterpret_cast<sockaddr *>(&addr), &len) == 0;
67 }
68 
ExecInit(TLSInitContext * context)69 bool TLSSocketExec::ExecInit(TLSInitContext *context)
70 {
71     auto manager = context->GetSharedManager();
72     if (manager == nullptr) {
73         NETSTACK_LOGE("manager is nullptr");
74         TLSSocketThrowException(context, SYSTEM_INTERNAL_ERROR);
75         return false;
76     }
77 
78     auto sockFd = static_cast<int>(reinterpret_cast<uint64_t>(context->extManager_->GetData()));
79     if (sockFd <= 0 || !IsTCPSocket(sockFd)) {
80         NETSTACK_LOGE("invalid tcp socket fd");
81         TLSSocketThrowException(context, TLS_ERR_SOCK_INVALID_FD);
82         return false;
83     }
84 
85     if (!IsConnected(sockFd)) {
86         NETSTACK_LOGE("tcp socket is not connected");
87         TLSSocketThrowException(context, TLS_ERR_SOCK_NOT_CONNECT);
88         return false;
89     }
90 
91     auto tlsSocket = new (std::nothrow) std::shared_ptr<TLSSocket>;
92     if (tlsSocket == nullptr) {
93         NETSTACK_LOGE("new TLSSocket failed, no enough memory");
94         TLSSocketThrowException(context, SYSTEM_INTERNAL_ERROR);
95         return false;
96     }
97     *tlsSocket = std::make_shared<TLSSocket>(sockFd);
98     manager->SetData(tlsSocket);
99 
100     std::string events[] = {EVENT_MESSAGE, EVENT_ERROR, EVENT_CONNECT, EVENT_CLOSE};
101     for (auto event : events) {
102         context->extManager_->DeleteListener(event);
103     }
104 
105     context->extManager_->SetData(reinterpret_cast<void *>(-1));
106     context->extManager_->WaitForRcvThdExit();
107     return true;
108 }
109 
ExecGetCertificate(GetCertificateContext * context)110 bool TLSSocketExec::ExecGetCertificate(GetCertificateContext *context)
111 {
112     auto manager = context->GetSharedManager();
113     if (manager == nullptr) {
114         NETSTACK_LOGE("manager is nullptr");
115         return false;
116     }
117     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
118     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
119     if (tlsSocket == nullptr) {
120         NETSTACK_LOGE("ExecGetCertificate tlsSocket is null");
121         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
122         return false;
123     }
124     auto shared = *tlsSocket;
125     if (!shared) {
126         NETSTACK_LOGE("ExecGetCertificate tlsSocket is null");
127         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
128         return false;
129     }
130     lock.unlock();
131     shared->GetCertificate([&context](int32_t errorNumber, const X509CertRawData &cert) {
132         context->localCert_ = cert;
133         context->errorNumber_ = errorNumber;
134         if (errorNumber != TLSSOCKET_SUCCESS) {
135             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
136         }
137     });
138     return context->errorNumber_ == TLSSOCKET_SUCCESS;
139 }
140 
InitSocks5TlsInstance(TLSConnectContext * context,std::shared_ptr<TLSSocket> shared)141 static std::shared_ptr<Socks5::Socks5TlsInstance> InitSocks5TlsInstance(
142     TLSConnectContext *context, std::shared_ptr<TLSSocket> shared)
143 {
144     const std::shared_ptr<Socks5::Socks5Option> opt{std::make_shared<Socks5::Socks5Option>()};
145     opt->username_ = context->proxyOptions_->username_;
146     opt->password_ = context->proxyOptions_->password_;
147     opt->proxyAddress_.netAddress_ = context->proxyOptions_->address_;
148     socklen_t len;
149     shared->ExecTlsGetAddr(opt->proxyAddress_.netAddress_, &opt->proxyAddress_.addrV4_, &opt->proxyAddress_.addrV6_,
150         &opt->proxyAddress_.addr_, &len);
151     if (opt->proxyAddress_.addr_ == nullptr) {
152         NETSTACK_LOGE("addr family error, address invalid");
153         const int ADDRESS_INVALID = 99;
154         context->SetError(ADDRESS_INVALID, "addr family error, address invalid");
155         return nullptr;
156     }
157 
158     auto socks5Tls = std::make_shared<Socks5::Socks5TlsInstance>(shared->GetSocketFd());
159     socks5Tls->SetDestAddress(context->connectOptions_.GetNetAddress());
160     socks5Tls->SetSocks5Option(opt);
161     return socks5Tls;
162 }
163 
HandleTcpProxyOptions(TLSConnectContext * context,std::shared_ptr<TLSSocket> shared)164 static int HandleTcpProxyOptions(TLSConnectContext *context, std::shared_ptr<TLSSocket> shared)
165 {
166     auto eventMgr = context->GetSharedManager();
167     if (eventMgr == nullptr) {
168         NETSTACK_LOGE("event manager is null");
169         return -1;
170     }
171 
172     if (context->proxyOptions_->type_ != Socket::ProxyType::SOCKS5) {
173         NETSTACK_LOGE("unsupport proxy type");
174         return 0;
175     }
176 
177     auto socks5Tls = eventMgr->GetProxyData();
178     if (socks5Tls == nullptr) {
179         socks5Tls = InitSocks5TlsInstance(context, shared);
180         if (socks5Tls == nullptr) {
181             return -1;
182         }
183         socks5Tls->SetSocks5Instance(socks5Tls);
184         eventMgr->SetProxyData(socks5Tls);
185     }
186 
187     if (!socks5Tls->IsConnected()) {
188         if (!socks5Tls->Connect()) {
189             Socks5::Socks5Utils::SetProxyAuthError(context, socks5Tls);
190             return -1;
191         }
192     }
193     shared->ExecTlsSetSockBlockFlag(shared->GetSocketFd(), false);
194     return 0;
195 }
196 
ExecConnect(TLSConnectContext * context)197 bool TLSSocketExec::ExecConnect(TLSConnectContext *context)
198 {
199     if (context == nullptr) {
200         NETSTACK_LOGE("context is nullptr");
201         return false;
202     }
203     context->connectOptions_.address_.SetRawAddress(ConvertAddressToIp(
204         context->connectOptions_.address_.GetAddress(), context->connectOptions_.address_.GetSaFamily()));
205     auto manager = context->GetSharedManager();
206     if (manager == nullptr) {
207         NETSTACK_LOGE("manager is nullptr");
208         return false;
209     }
210     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
211     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
212     if (tlsSocket == nullptr) {
213         NETSTACK_LOGE("ExecConnect tlsSocket is null");
214         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
215         return false;
216     }
217     auto shared = *tlsSocket;
218     if (!shared) {
219         NETSTACK_LOGE("ExecConnect tlsSocket is null");
220         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
221         return false;
222     }
223     lock.unlock();
224     if (!shared->IsExtSock() && context->proxyOptions_ != nullptr) {
225         if (HandleTcpProxyOptions(context, shared) != 0) {
226             return false;
227         }
228     }
229     shared->Connect(context->connectOptions_, [&context](int32_t errorNumber) {
230         context->errorNumber_ = errorNumber;
231         if (errorNumber != TLSSOCKET_SUCCESS) {
232             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
233         }
234     });
235     return context->errorNumber_ == TLSSOCKET_SUCCESS;
236 }
237 
ExecGetCipherSuites(GetCipherSuitesContext * context)238 bool TLSSocketExec::ExecGetCipherSuites(GetCipherSuitesContext *context)
239 {
240     auto manager = context->GetSharedManager();
241     if (manager == nullptr) {
242         NETSTACK_LOGE("manager is nullptr");
243         return false;
244     }
245     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
246     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
247     if (tlsSocket == nullptr) {
248         NETSTACK_LOGE("ExecGetCipherSuites tlsSocket is null");
249         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
250         return false;
251     }
252     auto shared = *tlsSocket;
253     if (!shared) {
254         NETSTACK_LOGE("ExecGetCipherSuites tlsSocket is null");
255         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
256         return false;
257     }
258     lock.unlock();
259     shared->GetCipherSuite([&context](int32_t errorNumber, const std::vector<std::string> &suite) {
260         context->cipherSuites_ = suite;
261         context->errorNumber_ = errorNumber;
262         if (errorNumber != TLSSOCKET_SUCCESS) {
263             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
264         }
265     });
266     return context->errorNumber_ == TLSSOCKET_SUCCESS;
267 }
268 
ExecGetRemoteCertificate(GetRemoteCertificateContext * context)269 bool TLSSocketExec::ExecGetRemoteCertificate(GetRemoteCertificateContext *context)
270 {
271     auto manager = context->GetSharedManager();
272     if (manager == nullptr) {
273         NETSTACK_LOGE("manager is nullptr");
274         return false;
275     }
276     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
277     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
278     if (tlsSocket == nullptr) {
279         NETSTACK_LOGE("ExecGetRemoteCertificate tlsSocket is null");
280         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
281         return false;
282     }
283     auto shared = *tlsSocket;
284     if (!shared) {
285         NETSTACK_LOGE("ExecGetRemoteCertificate tlsSocket is null");
286         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
287         return false;
288     }
289     lock.unlock();
290     shared->GetRemoteCertificate([&context](int32_t errorNumber, const X509CertRawData &cert) {
291         context->remoteCert_ = cert;
292         context->errorNumber_ = errorNumber;
293         if (errorNumber != TLSSOCKET_SUCCESS) {
294             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
295         }
296     });
297     return context->errorNumber_ == TLSSOCKET_SUCCESS;
298 }
299 
ExecGetProtocol(GetProtocolContext * context)300 bool TLSSocketExec::ExecGetProtocol(GetProtocolContext *context)
301 {
302     auto manager = context->GetSharedManager();
303     if (manager == nullptr) {
304         NETSTACK_LOGE("manager is nullptr");
305         return false;
306     }
307     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
308     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
309     if (tlsSocket == nullptr) {
310         NETSTACK_LOGE("ExecGetProtocol tlsSocket is null");
311         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
312         return false;
313     }
314     auto shared = *tlsSocket;
315     if (!shared) {
316         NETSTACK_LOGE("ExecGetRemoteCertificate tlsSocket is null");
317         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
318         return false;
319     }
320     lock.unlock();
321     shared->GetProtocol([&context](int32_t errorNumber, const std::string &protocol) {
322         context->protocol_ = protocol;
323         context->errorNumber_ = errorNumber;
324         if (errorNumber != TLSSOCKET_SUCCESS) {
325             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
326         }
327     });
328     return context->errorNumber_ == TLSSOCKET_SUCCESS;
329 }
330 
ExecGetSignatureAlgorithms(GetSignatureAlgorithmsContext * context)331 bool TLSSocketExec::ExecGetSignatureAlgorithms(GetSignatureAlgorithmsContext *context)
332 {
333     auto manager = context->GetSharedManager();
334     if (manager == nullptr) {
335         NETSTACK_LOGE("manager is nullptr");
336         return false;
337     }
338     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
339     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
340     if (tlsSocket == nullptr) {
341         NETSTACK_LOGE("ExecGetSignatureAlgorithms tlsSocket is null");
342         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
343         return false;
344     }
345     auto shared = *tlsSocket;
346     if (!shared) {
347         NETSTACK_LOGE("ExecGetRemoteCertificate tlsSocket is null");
348         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
349         return false;
350     }
351     lock.unlock();
352     shared->GetSignatureAlgorithms([&context](int32_t errorNumber, const std::vector<std::string> &algorithms) {
353         context->signatureAlgorithms_ = algorithms;
354         context->errorNumber_ = errorNumber;
355         if (errorNumber != TLSSOCKET_SUCCESS) {
356             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
357         }
358     });
359     return context->errorNumber_ == TLSSOCKET_SUCCESS;
360 }
361 
ExecSend(TLSSendContext * context)362 bool TLSSocketExec::ExecSend(TLSSendContext *context)
363 {
364     auto manager = context->GetSharedManager();
365     if (manager == nullptr) {
366         NETSTACK_LOGE("manager is nullptr");
367         return false;
368     }
369     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
370     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
371     if (tlsSocket == nullptr) {
372         NETSTACK_LOGE("ExecSend tlsSocket is null");
373         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
374         return false;
375     }
376     Socket::TCPSendOptions tcpSendOptions;
377     tcpSendOptions.SetData(context->data_);
378     auto shared = *tlsSocket;
379     if (!shared) {
380         NETSTACK_LOGE("ExecGetRemoteCertificate tlsSocket is null");
381         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
382         return false;
383     }
384     lock.unlock();
385     shared->Send(tcpSendOptions, [&context](int32_t errorNumber) {
386         context->errorNumber_ = errorNumber;
387         if (errorNumber != TLSSOCKET_SUCCESS) {
388             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
389         }
390     });
391     return context->errorNumber_ == TLSSOCKET_SUCCESS;
392 }
393 
ExecClose(TLSNapiContext * context)394 bool TLSSocketExec::ExecClose(TLSNapiContext *context)
395 {
396     auto manager = context->GetSharedManager();
397     if (manager == nullptr) {
398         NETSTACK_LOGE("manager is nullptr");
399         return false;
400     }
401     std::unique_lock<std::shared_mutex> lock(manager->GetDataMutex());
402     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
403     if (tlsSocket == nullptr) {
404         NETSTACK_LOGE("ExecClose tlsSocket is null");
405         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
406         return false;
407     }
408     auto shared = *tlsSocket;
409     if (!shared) {
410         NETSTACK_LOGE("ExecGetRemoteCertificate tlsSocket is null");
411         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
412         delete tlsSocket;
413         manager->SetData(nullptr);
414         return false;
415     }
416     shared->Close([&context](int32_t errorNumber) {
417         context->errorNumber_ = errorNumber;
418         if (errorNumber != TLSSOCKET_SUCCESS) {
419             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
420         }
421     });
422     delete tlsSocket;
423     manager->SetData(nullptr);
424     return context->errorNumber_ == TLSSOCKET_SUCCESS;
425 }
426 
ExecBind(TLSBindContext * context)427 bool TLSSocketExec::ExecBind(TLSBindContext *context)
428 {
429     auto manager = context->GetSharedManager();
430     if (manager == nullptr) {
431         NETSTACK_LOGE("manager is nullptr");
432         return false;
433     }
434     std::unique_lock<std::shared_mutex> lock(manager->GetDataMutex());
435     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
436     if (tlsSocket != nullptr) {
437         NETSTACK_LOGI("TLSSocket has been constructed");
438         return true;
439     }
440 
441     tlsSocket = new (std::nothrow) std::shared_ptr<TLSSocket>;
442     if (tlsSocket == nullptr) {
443         NETSTACK_LOGE("new TLSSocket failed, no enough memory");
444         return false;
445     }
446     auto shared = std::make_shared<TLSSocket>();
447     if (!shared) {
448         delete tlsSocket;
449         return false;
450     }
451     *tlsSocket = shared;
452     shared->Bind(context->address_, [&context](int32_t errorNumber) {
453         context->errorNumber_ = errorNumber;
454         if (errorNumber != TLSSOCKET_SUCCESS) {
455             std::string errorString = MakeErrorMessage(errorNumber);
456             context->SetError(errorNumber, errorString);
457         }
458     });
459     manager->SetData(tlsSocket);
460     return context->errorNumber_ == TLSSOCKET_SUCCESS;
461 }
462 
ExecGetRemoteAddress(TLSGetRemoteAddressContext * context)463 bool TLSSocketExec::ExecGetRemoteAddress(TLSGetRemoteAddressContext *context)
464 {
465     auto manager = context->GetSharedManager();
466     if (manager == nullptr) {
467         NETSTACK_LOGE("manager is nullptr");
468         return false;
469     }
470     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
471     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
472     if (tlsSocket == nullptr) {
473         NETSTACK_LOGE("ExecGetRemoteAddress tlsSocket is null");
474         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
475         return false;
476     }
477     auto shared = *tlsSocket;
478     if (!shared) {
479         NETSTACK_LOGE("ExecGetRemoteAddress tlsSocket is null");
480         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
481         return false;
482     }
483     lock.unlock();
484     shared->GetRemoteAddress([&context](int32_t errorNumber, const Socket::NetAddress address) {
485         context->address_ = address;
486         context->errorNumber_ = errorNumber;
487         if (errorNumber != TLSSOCKET_SUCCESS) {
488             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
489         }
490     });
491     return context->errorNumber_ == TLSSOCKET_SUCCESS;
492 }
493 
SetContext(TLSGetLocalAddressContext * context)494 void TLSSocketExec::SetContext(TLSGetLocalAddressContext *context)
495 {
496     context->SetNeedThrowException(true);
497     context->SetError(TlsSocket::TlsSocketError::TLS_ERR_NO_BIND,
498         TlsSocket::MakeErrorMessage(TlsSocket::TlsSocketError::TLS_ERR_NO_BIND));
499 }
500 
ExecGetLocalAddress(TLSGetLocalAddressContext * context)501 bool TLSSocketExec::ExecGetLocalAddress(TLSGetLocalAddressContext *context)
502 {
503     if (context == nullptr) {
504         return false;
505     }
506     auto manager = context->GetSharedManager();
507     if (manager == nullptr) {
508         SetContext(context);
509         return false;
510     }
511     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
512     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
513     if (tlsSocket == nullptr) {
514         context->SetError(TlsSocket::TlsSocketError::TLS_ERR_NO_BIND,
515                           TlsSocket::MakeErrorMessage(TlsSocket::TlsSocketError::TLS_ERR_NO_BIND));
516         return false;
517     }
518     auto shared = *tlsSocket;
519     if (!shared) {
520         context->SetError(TlsSocket::TlsSocketError::TLS_ERR_NO_BIND,
521                           TlsSocket::MakeErrorMessage(TlsSocket::TlsSocketError::TLS_ERR_NO_BIND));
522         return false;
523     }
524     lock.unlock();
525     auto listenSocketFD = shared->GetSocketFd();
526     struct sockaddr_storage addr {};
527     socklen_t addrLen = sizeof(addr);
528     if (getsockname(listenSocketFD, (struct sockaddr *)&addr, &addrLen) == -1) {
529         context->SetNeedThrowException(true);
530         context->SetErrorCode(errno);
531         return false;
532     }
533 
534     char ipStr[INET6_ADDRSTRLEN] = {0};
535     Socket::NetAddress localAddress;
536     if (addr.ss_family == AF_INET) {
537         auto *addr_in = (struct sockaddr_in *)&addr;
538         inet_ntop(AF_INET, &addr_in->sin_addr, ipStr, sizeof(ipStr));
539         localAddress.SetFamilyBySaFamily(AF_INET);
540         localAddress.SetRawAddress(ipStr);
541         localAddress.SetPort(ntohs(addr_in->sin_port));
542         shared->SetLocalAddress(localAddress);
543     } else if (addr.ss_family == AF_INET6) {
544         auto *addr_in6 = (struct sockaddr_in6 *)&addr;
545         inet_ntop(AF_INET6, &addr_in6->sin6_addr, ipStr, sizeof(ipStr));
546         localAddress.SetFamilyBySaFamily(AF_INET6);
547         localAddress.SetRawAddress(ipStr);
548         localAddress.SetPort(ntohs(addr_in6->sin6_port));
549         shared->SetLocalAddress(localAddress);
550     }
551     return true;
552 }
553 
ExecGetState(TLSGetStateContext * context)554 bool TLSSocketExec::ExecGetState(TLSGetStateContext *context)
555 {
556     auto manager = context->GetSharedManager();
557     if (manager == nullptr) {
558         NETSTACK_LOGE("manager is nullptr");
559         context->SetError(TLS_ERR_SYS_EINVAL, MakeErrorMessage(TLS_ERR_SYS_EINVAL));
560         return false;
561     }
562     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
563     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
564     if (tlsSocket == nullptr) {
565         NETSTACK_LOGE("ExecGetState tlsSocket is null");
566         return true;
567     }
568     auto shared = *tlsSocket;
569     if (!shared) {
570         return true;
571     }
572     lock.unlock();
573     shared->GetState([&context](int32_t errorNumber, const Socket::SocketStateBase state) {
574         context->state_ = state;
575         context->errorNumber_ = errorNumber;
576         if (errorNumber != TLSSOCKET_SUCCESS) {
577             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
578         }
579     });
580     return context->errorNumber_ == TLSSOCKET_SUCCESS;
581 }
582 
ExecSetExtraOptions(TLSSetExtraOptionsContext * context)583 bool TLSSocketExec::ExecSetExtraOptions(TLSSetExtraOptionsContext *context)
584 {
585     auto manager = context->GetSharedManager();
586     if (manager == nullptr) {
587         NETSTACK_LOGE("manager is nullptr");
588         return false;
589     }
590     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
591     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
592     if (tlsSocket == nullptr) {
593         NETSTACK_LOGE("ExecSetExtraOptions tlsSocket is null");
594         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
595         return false;
596     }
597     auto shared = *tlsSocket;
598     if (!shared) {
599         NETSTACK_LOGE("ExecSetExtraOptions tlsSocket is null");
600         context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
601         return false;
602     }
603     lock.unlock();
604     shared->SetExtraOptions(context->options_, [&context](int32_t errorNumber) {
605         context->errorNumber_ = errorNumber;
606         if (errorNumber != TLSSOCKET_SUCCESS) {
607             context->SetError(errorNumber, MakeErrorMessage(errorNumber));
608         }
609     });
610     return context->errorNumber_ == TLSSOCKET_SUCCESS;
611 }
612 
ExecGetSocketFd(TLSGetSocketFdContext * context)613 bool TLSSocketExec::ExecGetSocketFd(TLSGetSocketFdContext *context)
614 {
615     auto manager = context->GetSharedManager();
616     if (manager == nullptr) {
617         NETSTACK_LOGE("manager is nullptr");
618         return false;
619     }
620     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
621     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
622     if (tlsSocket == nullptr) {
623         NETSTACK_LOGE("ExecGetSocketFd tlsSocket is null");
624         context->sockFd_= -1;
625         return true;
626     }
627     auto shared = *tlsSocket;
628     if (!shared) {
629         NETSTACK_LOGE("ExecGetSocketFd tlsSocket is null");
630         context->sockFd_= -1;
631         return true;
632     }
633     lock.unlock();
634     context->sockFd_= shared->GetSocketFd();
635     return true;
636 }
637 
GetSocketFdCallback(TLSGetSocketFdContext * context)638 napi_value TLSSocketExec::GetSocketFdCallback(TLSGetSocketFdContext *context)
639 {
640     if (context->sockFd_ < 0) {
641         return NapiUtils::GetUndefined(context->GetEnv());
642     }
643     return NapiUtils::CreateInt32(context->GetEnv(), context->sockFd_);
644 }
645 
GetCertificateCallback(GetCertificateContext * context)646 napi_value TLSSocketExec::GetCertificateCallback(GetCertificateContext *context)
647 {
648     void *data = nullptr;
649     napi_value arrayBuffer = NapiUtils::CreateArrayBuffer(context->GetEnv(), context->localCert_.data.Length(), &data);
650     if (data != nullptr && arrayBuffer != nullptr) {
651         if (memcpy_s(data, context->localCert_.data.Length(),
652                      reinterpret_cast<const uint8_t *>(context->localCert_.data.Data()),
653                      context->localCert_.data.Length()) != EOK) {
654             NETSTACK_LOGE("memcpy_s failed!");
655             return NapiUtils::GetUndefined(context->GetEnv());
656         }
657     }
658     napi_value outData = nullptr;
659     napi_create_typedarray(context->GetEnv(), napi_uint8_array, context->localCert_.data.Length(), arrayBuffer, 0,
660                            &outData);
661     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
662     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
663         return NapiUtils::GetUndefined(context->GetEnv());
664     }
665     NapiUtils::SetNamedProperty(context->GetEnv(), obj, CERTIFICATA_DATA, outData);
666     NapiUtils::SetInt32Property(context->GetEnv(), obj, CERTIFICATA_ENCODING_FORMAT,
667                                 context->localCert_.encodingFormat);
668     return obj;
669 }
670 
ConnectCallback(TLSConnectContext * context)671 napi_value TLSSocketExec::ConnectCallback(TLSConnectContext *context)
672 {
673     return NapiUtils::GetUndefined(context->GetEnv());
674 }
675 
GetCipherSuitesCallback(GetCipherSuitesContext * context)676 napi_value TLSSocketExec::GetCipherSuitesCallback(GetCipherSuitesContext *context)
677 {
678     napi_value cipherSuites = NapiUtils::CreateArray(context->GetEnv(), 0);
679     int index = 0;
680     for (const auto &cipher : context->cipherSuites_) {
681         napi_value cipherSuite = NapiUtils::CreateStringUtf8(context->GetEnv(), cipher);
682         NapiUtils::SetArrayElement(context->GetEnv(), cipherSuites, index++, cipherSuite);
683     }
684     return cipherSuites;
685 }
686 
GetRemoteCertificateCallback(GetRemoteCertificateContext * context)687 napi_value TLSSocketExec::GetRemoteCertificateCallback(GetRemoteCertificateContext *context)
688 {
689     void *data = nullptr;
690     napi_value arrayBuffer = NapiUtils::CreateArrayBuffer(context->GetEnv(), context->remoteCert_.data.Length(), &data);
691     if (data != nullptr && arrayBuffer != nullptr) {
692         if (memcpy_s(data, context->remoteCert_.data.Length(),
693                      reinterpret_cast<const uint8_t *>(context->remoteCert_.data.Data()),
694                      context->remoteCert_.data.Length()) != EOK) {
695             NETSTACK_LOGE("memcpy_s failed!");
696             return NapiUtils::GetUndefined(context->GetEnv());
697         }
698     }
699     napi_value outData = nullptr;
700     napi_create_typedarray(context->GetEnv(), napi_uint8_array, context->remoteCert_.data.Length(), arrayBuffer, 0,
701                            &outData);
702     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
703     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
704         return NapiUtils::GetUndefined(context->GetEnv());
705     }
706     NapiUtils::SetNamedProperty(context->GetEnv(), obj, CERTIFICATA_DATA, outData);
707     NapiUtils::SetInt32Property(context->GetEnv(), obj, CERTIFICATA_ENCODING_FORMAT,
708                                 context->remoteCert_.encodingFormat);
709     return obj;
710 }
711 
GetProtocolCallback(GetProtocolContext * context)712 napi_value TLSSocketExec::GetProtocolCallback(GetProtocolContext *context)
713 {
714     return NapiUtils::CreateStringUtf8(context->GetEnv(), context->protocol_);
715 }
716 
GetSignatureAlgorithmsCallback(GetSignatureAlgorithmsContext * context)717 napi_value TLSSocketExec::GetSignatureAlgorithmsCallback(GetSignatureAlgorithmsContext *context)
718 {
719     napi_value signatureAlgorithms = NapiUtils::CreateArray(context->GetEnv(), 0);
720     int index = 0;
721     for (const auto &algorithm : context->signatureAlgorithms_) {
722         napi_value signatureAlgorithm = NapiUtils::CreateStringUtf8(context->GetEnv(), algorithm);
723         NapiUtils::SetArrayElement(context->GetEnv(), signatureAlgorithms, index++, signatureAlgorithm);
724     }
725     return signatureAlgorithms;
726 }
727 
SendCallback(TLSSendContext * context)728 napi_value TLSSocketExec::SendCallback(TLSSendContext *context)
729 {
730     return NapiUtils::GetUndefined(context->GetEnv());
731 }
732 
CloseCallback(TLSNapiContext * context)733 napi_value TLSSocketExec::CloseCallback(TLSNapiContext *context)
734 {
735     auto manager = context->GetSharedManager();
736     if (manager != nullptr) {
737         NETSTACK_LOGD("tls socket close, delete js ref");
738         manager->DeleteEventReference(context->GetEnv());
739     }
740     return NapiUtils::GetUndefined(context->GetEnv());
741 }
742 
BindCallback(TLSBindContext * context)743 napi_value TLSSocketExec::BindCallback(TLSBindContext *context)
744 {
745     context->EmitSharedManager(EVENT_LISTENING, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
746         NapiUtils::GetUndefined(context->GetEnv())));
747     return NapiUtils::GetUndefined(context->GetEnv());
748 }
749 
GetStateCallback(TLSGetStateContext * context)750 napi_value TLSSocketExec::GetStateCallback(TLSGetStateContext *context)
751 {
752     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
753     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
754         return NapiUtils::GetUndefined(context->GetEnv());
755     }
756     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->state_.IsBound());
757     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->state_.IsClose());
758     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->state_.IsConnected());
759     return obj;
760 }
761 
GetRemoteAddressCallback(TLSGetRemoteAddressContext * context)762 napi_value TLSSocketExec::GetRemoteAddressCallback(TLSGetRemoteAddressContext *context)
763 {
764     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
765     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
766         return NapiUtils::GetUndefined(context->GetEnv());
767     }
768     NapiUtils::SetStringPropertyUtf8(context->GetEnv(), obj, KEY_ADDRESS, context->address_.GetAddress());
769     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_FAMILY, context->address_.GetJsValueFamily());
770     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_PORT, context->address_.GetPort());
771     return obj;
772 }
773 
GetLocalAddressCallback(TLSGetLocalAddressContext * context)774 napi_value TLSSocketExec::GetLocalAddressCallback(TLSGetLocalAddressContext *context)
775 {
776     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
777     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
778         return NapiUtils::GetUndefined(context->GetEnv());
779     }
780     auto manager = context->GetSharedManager();
781     if (manager == nullptr) {
782         NETSTACK_LOGE("manager is nullptr");
783         return obj;
784     }
785     std::shared_lock<std::shared_mutex> lock(manager->GetDataMutex());
786     auto tlsSocket = reinterpret_cast<std::shared_ptr<TLSSocket> *>(manager->GetData());
787     if (tlsSocket == nullptr) {
788         NETSTACK_LOGE("get localAddress callback tlsSocketServer is null");
789         return obj;
790     }
791     auto env = context->GetEnv();
792     auto shared = *tlsSocket;
793     if (!shared) {
794         return obj;
795     }
796     lock.unlock();
797     NapiUtils::SetStringPropertyUtf8(env, obj, KEY_ADDRESS, shared->GetLocalAddress().GetAddress());
798     NapiUtils::SetUint32Property(env, obj, KEY_FAMILY, shared->GetLocalAddress().GetJsValueFamily());
799     NapiUtils::SetUint32Property(env, obj, KEY_PORT, shared->GetLocalAddress().GetPort());
800     return obj;
801 }
802 
SetExtraOptionsCallback(TLSSetExtraOptionsContext * context)803 napi_value TLSSocketExec::SetExtraOptionsCallback(TLSSetExtraOptionsContext *context)
804 {
805     return NapiUtils::GetUndefined(context->GetEnv());
806 }
807 
808 } // namespace TlsSocket
809 } // namespace NetStack
810 } // namespace OHOS
811