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