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