1 /*
2 * Copyright (c) 2021-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_module.h"
17
18 #include <initializer_list>
19 #include <napi/native_common.h>
20
21 #include "common_context.h"
22 #include "event_manager.h"
23 #include "module_template.h"
24 #include "monitor.h"
25 #include "napi_utils.h"
26 #include "netstack_log.h"
27 #include "tls.h"
28 #include "tls_bind_context.h"
29 #include "tls_connect_context.h"
30 #include "tls_extra_context.h"
31 #include "tls_napi_context.h"
32 #include "tls_send_context.h"
33 #include "tls_init_context.h"
34 #include "tlssocket_async_work.h"
35
36 namespace OHOS {
37 namespace NetStack {
38 namespace TlsSocket {
39 namespace {
40 static constexpr const char *PROTOCOL_TLSV13 = "TLSv13";
41 static constexpr const char *PROTOCOL_TLSV12 = "TLSv12";
42
Finalize(napi_env,void * data,void *)43 void Finalize(napi_env, void *data, void *)
44 {
45 NETSTACK_LOGI("tls socket is finalized");
46 auto sharedManager = reinterpret_cast<std::shared_ptr<EventManager> *>(data);
47 delete sharedManager;
48 }
49 } // namespace
50
GetCertificate(napi_env env,napi_callback_info info)51 napi_value TLSSocketModuleExports::TLSSocket::GetCertificate(napi_env env, napi_callback_info info)
52 {
53 return ModuleTemplate::InterfaceWithSharedManager<GetCertificateContext>(env, info, FUNCTION_GET_CERTIFICATE,
54 nullptr, TLSSocketAsyncWork::ExecGetCertificate, TLSSocketAsyncWork::GetCertificateCallback);
55 }
56
GetProtocol(napi_env env,napi_callback_info info)57 napi_value TLSSocketModuleExports::TLSSocket::GetProtocol(napi_env env, napi_callback_info info)
58 {
59 return ModuleTemplate::InterfaceWithSharedManager<GetCipherSuitesContext>(env, info, FUNCTION_GET_PROTOCOL,
60 nullptr, TLSSocketAsyncWork::ExecGetProtocol, TLSSocketAsyncWork::GetProtocolCallback);
61 }
62
Connect(napi_env env,napi_callback_info info)63 napi_value TLSSocketModuleExports::TLSSocket::Connect(napi_env env, napi_callback_info info)
64 {
65 return ModuleTemplate::InterfaceWithSharedManager<TLSConnectContext>(
66 env, info, FUNCTION_CONNECT, nullptr, TLSSocketAsyncWork::ExecConnect, TLSSocketAsyncWork::ConnectCallback);
67 }
68
GetCipherSuites(napi_env env,napi_callback_info info)69 napi_value TLSSocketModuleExports::TLSSocket::GetCipherSuites(napi_env env, napi_callback_info info)
70 {
71 return ModuleTemplate::InterfaceWithSharedManager<GetCipherSuitesContext>(env, info, FUNCTION_GET_CIPHER_SUITE,
72 nullptr, TLSSocketAsyncWork::ExecGetCipherSuites, TLSSocketAsyncWork::GetCipherSuitesCallback);
73 }
74
GetRemoteCertificate(napi_env env,napi_callback_info info)75 napi_value TLSSocketModuleExports::TLSSocket::GetRemoteCertificate(napi_env env, napi_callback_info info)
76 {
77 return ModuleTemplate::InterfaceWithSharedManager<GetRemoteCertificateContext>(env, info,
78 FUNCTION_GET_REMOTE_CERTIFICATE, nullptr, TLSSocketAsyncWork::ExecGetRemoteCertificate,
79 TLSSocketAsyncWork::GetRemoteCertificateCallback);
80 }
81
GetSignatureAlgorithms(napi_env env,napi_callback_info info)82 napi_value TLSSocketModuleExports::TLSSocket::GetSignatureAlgorithms(napi_env env, napi_callback_info info)
83 {
84 return ModuleTemplate::InterfaceWithSharedManager<GetSignatureAlgorithmsContext>(
85 env, info, FUNCTION_GET_SIGNATURE_ALGORITHMS, nullptr, TLSSocketAsyncWork::ExecGetSignatureAlgorithms,
86 TLSSocketAsyncWork::GetSignatureAlgorithmsCallback);
87 }
88
Send(napi_env env,napi_callback_info info)89 napi_value TLSSocketModuleExports::TLSSocket::Send(napi_env env, napi_callback_info info)
90 {
91 return ModuleTemplate::InterfaceWithSharedManager<TLSSendContext>(env, info, FUNCTION_SEND, nullptr,
92 TLSSocketAsyncWork::ExecSend, TLSSocketAsyncWork::SendCallback);
93 }
94
Close(napi_env env,napi_callback_info info)95 napi_value TLSSocketModuleExports::TLSSocket::Close(napi_env env, napi_callback_info info)
96 {
97 return ModuleTemplate::InterfaceWithSharedManager<TLSNapiContext>(env, info,
98 FUNCTION_CLOSE, nullptr, TLSSocketAsyncWork::ExecClose,
99 TLSSocketAsyncWork::CloseCallback);
100 }
101
Bind(napi_env env,napi_callback_info info)102 napi_value TLSSocketModuleExports::TLSSocket::Bind(napi_env env, napi_callback_info info)
103 {
104 return ModuleTemplate::InterfaceWithSharedManager<TLSBindContext>(env, info, FUNCTION_BIND, nullptr,
105 TLSSocketAsyncWork::ExecBind, TLSSocketAsyncWork::BindCallback);
106 }
107
GetState(napi_env env,napi_callback_info info)108 napi_value TLSSocketModuleExports::TLSSocket::GetState(napi_env env, napi_callback_info info)
109 {
110 return ModuleTemplate::InterfaceWithSharedManager<TLSGetStateContext>(
111 env, info, FUNCTION_GET_STATE, nullptr, TLSSocketAsyncWork::ExecGetState, TLSSocketAsyncWork::GetStateCallback);
112 }
113
GetRemoteAddress(napi_env env,napi_callback_info info)114 napi_value TLSSocketModuleExports::TLSSocket::GetRemoteAddress(napi_env env, napi_callback_info info)
115 {
116 return ModuleTemplate::InterfaceWithSharedManager<TLSGetRemoteAddressContext>(env, info,
117 FUNCTION_GET_REMOTE_ADDRESS, nullptr, TLSSocketAsyncWork::ExecGetRemoteAddress,
118 TLSSocketAsyncWork::GetRemoteAddressCallback);
119 }
120
GetLocalAddress(napi_env env,napi_callback_info info)121 napi_value TLSSocketModuleExports::TLSSocket::GetLocalAddress(napi_env env, napi_callback_info info)
122 {
123 return ModuleTemplate::InterfaceWithSharedManager<TLSGetLocalAddressContext>(env, info, FUNCTION_GET_LOCAL_ADDRESS,
124 nullptr, TLSSocketAsyncWork::ExecGetLocalAddress, TLSSocketAsyncWork::GetLocalAddressCallback);
125 }
126
SetExtraOptions(napi_env env,napi_callback_info info)127 napi_value TLSSocketModuleExports::TLSSocket::SetExtraOptions(napi_env env, napi_callback_info info)
128 {
129 return ModuleTemplate::InterfaceWithSharedManager<TLSSetExtraOptionsContext>(env, info, FUNCTION_BIND, nullptr,
130 TLSSocketAsyncWork::ExecSetExtraOptions,
131 TLSSocketAsyncWork::SetExtraOptionsCallback);
132 }
133
On(napi_env env,napi_callback_info info)134 napi_value TLSSocketModuleExports::TLSSocket::On(napi_env env, napi_callback_info info)
135 {
136 return DelayedSingleton<Monitor>::GetInstance()->On(env, info);
137 }
138
Off(napi_env env,napi_callback_info info)139 napi_value TLSSocketModuleExports::TLSSocket::Off(napi_env env, napi_callback_info info)
140 {
141 return DelayedSingleton<Monitor>::GetInstance()->Off(env, info);
142 }
143
GetSocketFd(napi_env env,napi_callback_info info)144 napi_value TLSSocketModuleExports::TLSSocket::GetSocketFd(napi_env env, napi_callback_info info)
145 {
146 return ModuleTemplate::InterfaceWithSharedManager<TLSGetSocketFdContext>(env, info, FUNCTION_GET_SOCKET_FD, nullptr,
147 TLSSocketAsyncWork::ExecGetSocketFd,
148 TLSSocketAsyncWork::GetSocketFdCallback);
149 }
150
DefineTLSSocketClass(napi_env env,napi_value exports)151 void TLSSocketModuleExports::DefineTLSSocketClass(napi_env env, napi_value exports)
152 {
153 std::initializer_list<napi_property_descriptor> functions = {
154 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_CERTIFICATE, TLSSocket::GetCertificate),
155 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_REMOTE_CERTIFICATE, TLSSocket::GetRemoteCertificate),
156 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_SIGNATURE_ALGORITHMS, TLSSocket::GetSignatureAlgorithms),
157 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_PROTOCOL, TLSSocket::GetProtocol),
158 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_CONNECT, TLSSocket::Connect),
159 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_CIPHER_SUITE, TLSSocket::GetCipherSuites),
160 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_SEND, TLSSocket::Send),
161 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_CLOSE, TLSSocket::Close),
162 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_BIND, TLSSocket::Bind),
163 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_STATE, TLSSocket::GetState),
164 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_REMOTE_ADDRESS, TLSSocket::GetRemoteAddress),
165 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_LOCAL_ADDRESS, TLSSocket::GetLocalAddress),
166 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_SET_EXTRA_OPTIONS, TLSSocket::SetExtraOptions),
167 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_ON, TLSSocket::On),
168 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_OFF, TLSSocket::Off),
169 DECLARE_NAPI_FUNCTION(TLSSocket::FUNCTION_GET_SOCKET_FD, TLSSocket::GetSocketFd),
170 };
171 ModuleTemplate::DefineClass(env, exports, functions, INTERFACE_TLS_SOCKET);
172 }
173
InitProtocol(napi_env env,napi_value exports)174 void TLSSocketModuleExports::InitProtocol(napi_env env, napi_value exports)
175 {
176 std::initializer_list<napi_property_descriptor> properties = {
177 DECLARE_NAPI_STATIC_PROPERTY(PROTOCOL_TLSV12, NapiUtils::CreateStringUtf8(env, PROTOCOL_TLS_V12)),
178 DECLARE_NAPI_STATIC_PROPERTY(PROTOCOL_TLSV13, NapiUtils::CreateStringUtf8(env, PROTOCOL_TLS_V13)),
179 };
180
181 napi_value protocol = NapiUtils::CreateObject(env);
182 NapiUtils::DefineProperties(env, protocol, properties);
183 NapiUtils::SetNamedProperty(env, exports, INTERFACE_PROTOCOL, protocol);
184 }
185
ConstructTLSSocketInstance(napi_env env,napi_callback_info info)186 napi_value TLSSocketModuleExports::ConstructTLSSocketInstance(napi_env env, napi_callback_info info)
187 {
188 napi_value result = ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_TLS_SOCKET, Finalize);
189 if (result == nullptr) {
190 return nullptr;
191 }
192
193 size_t paramsCount = MAX_PARAM_NUM;
194 napi_value params[MAX_PARAM_NUM] = {nullptr};
195 NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, nullptr, nullptr));
196 if (paramsCount == 0) {
197 return result;
198 }
199
200 std::shared_ptr<EventManager> *sharedManager = nullptr;
201 auto napiRet = napi_unwrap(env, result, reinterpret_cast<void **>(&sharedManager));
202 if (napiRet != napi_ok) {
203 NETSTACK_LOGE("get event manager in napi_unwrap failed, napiRet is %{public}d", napiRet);
204 return nullptr;
205 }
206 std::shared_ptr<EventManager> manager = nullptr;
207 if (sharedManager != nullptr && *sharedManager != nullptr) {
208 manager = *sharedManager;
209 }
210
211 auto context = new TLSInitContext(env, manager);
212 if (context == nullptr) {
213 NETSTACK_LOGE("new TLSInitContext failed, no enough memory");
214 return nullptr;
215 }
216
217 context->ParseParams(params, paramsCount);
218 if (context->IsParseOK()) {
219 TLSSocketAsyncWork::ExecInit(env, (void *)context);
220 }
221
222 if (context->IsNeedThrowException()) { // only api9 or later need throw exception.
223 napi_throw_error(env, std::to_string(context->GetErrorCode()).c_str(), context->GetErrorMessage().c_str());
224 delete context;
225 return nullptr;
226 }
227
228 delete context;
229 return result;
230 }
231
InitTLSSocketProperties(napi_env env,napi_value exports)232 void TLSSocketModuleExports::InitTLSSocketProperties(napi_env env, napi_value exports)
233 {
234 std::initializer_list<napi_property_descriptor> properties = {
235 DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_TLS_SOCKET_INSTANCE, ConstructTLSSocketInstance),
236 };
237 NapiUtils::DefineProperties(env, exports, properties);
238 }
239
InitTLSSocketModule(napi_env env,napi_value exports)240 napi_value TLSSocketModuleExports::InitTLSSocketModule(napi_env env, napi_value exports)
241 {
242 DefineTLSSocketClass(env, exports);
243 InitTLSSocketProperties(env, exports);
244 InitProtocol(env, exports);
245 return exports;
246 }
247 } // namespace TlsSocket
248 } // namespace NetStack
249 } // namespace OHOS
250