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 "tls_socket.h"
30
31 namespace OHOS {
32 namespace NetStack {
33 namespace {
34 constexpr const char *CERTIFICATA_DATA = "data";
35 constexpr const char *CERTIFICATA_ENCODING_FORMAT = "encodingFormat";
36 } // namespace
ExecGetCertificate(GetCertificateContext * context)37 bool TLSSocketExec::ExecGetCertificate(GetCertificateContext *context)
38 {
39 auto manager = context->GetManager();
40 if (manager == nullptr) {
41 NETSTACK_LOGE("manager is nullptr");
42 return false;
43 }
44 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
45 if (tlsSocket == nullptr) {
46 NETSTACK_LOGE("ExecGetCertificate tlsSocket is null");
47 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
48 return false;
49 }
50 tlsSocket->GetCertificate([&context](int32_t errorNumber, const X509CertRawData &cert) {
51 context->localCert_ = cert;
52 context->errorNumber_ = errorNumber;
53 if (errorNumber != TLSSOCKET_SUCCESS) {
54 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
55 }
56 });
57 return context->errorNumber_ == TLSSOCKET_SUCCESS;
58 }
59
ExecConnect(TLSConnectContext * context)60 bool TLSSocketExec::ExecConnect(TLSConnectContext *context)
61 {
62 auto manager = context->GetManager();
63 if (manager == nullptr) {
64 NETSTACK_LOGE("manager is nullptr");
65 return false;
66 }
67 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
68 if (tlsSocket == nullptr) {
69 NETSTACK_LOGE("ExecConnect tlsSocket is null");
70 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
71 return false;
72 }
73 tlsSocket->Connect(context->connectOptions_, [&context](int32_t errorNumber) {
74 context->errorNumber_ = errorNumber;
75 if (errorNumber != TLSSOCKET_SUCCESS) {
76 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
77 }
78 });
79 return context->errorNumber_ == TLSSOCKET_SUCCESS;
80 }
81
ExecGetCipherSuites(GetCipherSuitesContext * context)82 bool TLSSocketExec::ExecGetCipherSuites(GetCipherSuitesContext *context)
83 {
84 auto manager = context->GetManager();
85 if (manager == nullptr) {
86 NETSTACK_LOGE("manager is nullptr");
87 return false;
88 }
89 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
90 if (tlsSocket == nullptr) {
91 NETSTACK_LOGE("ExecGetCipherSuites tlsSocket is null");
92 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
93 return false;
94 }
95 tlsSocket->GetCipherSuite([&context](int32_t errorNumber, const std::vector<std::string> &suite) {
96 context->cipherSuites_ = suite;
97 context->errorNumber_ = errorNumber;
98 if (errorNumber != TLSSOCKET_SUCCESS) {
99 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
100 }
101 });
102 return context->errorNumber_ == TLSSOCKET_SUCCESS;
103 }
104
ExecGetRemoteCertificate(GetRemoteCertificateContext * context)105 bool TLSSocketExec::ExecGetRemoteCertificate(GetRemoteCertificateContext *context)
106 {
107 auto manager = context->GetManager();
108 if (manager == nullptr) {
109 NETSTACK_LOGE("manager is nullptr");
110 return false;
111 }
112 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
113 if (tlsSocket == nullptr) {
114 NETSTACK_LOGE("ExecGetRemoteCertificate tlsSocket is null");
115 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
116 return false;
117 }
118 tlsSocket->GetRemoteCertificate([&context](int32_t errorNumber, const X509CertRawData &cert) {
119 context->remoteCert_ = cert;
120 context->errorNumber_ = errorNumber;
121 if (errorNumber != TLSSOCKET_SUCCESS) {
122 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
123 }
124 });
125 return context->errorNumber_ == TLSSOCKET_SUCCESS;
126 }
127
ExecGetProtocol(GetProtocolContext * context)128 bool TLSSocketExec::ExecGetProtocol(GetProtocolContext *context)
129 {
130 auto manager = context->GetManager();
131 if (manager == nullptr) {
132 NETSTACK_LOGE("manager is nullptr");
133 return false;
134 }
135 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
136 if (tlsSocket == nullptr) {
137 NETSTACK_LOGE("ExecGetProtocol tlsSocket is null");
138 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
139 return false;
140 }
141 tlsSocket->GetProtocol([&context](int32_t errorNumber, const std::string &protocol) {
142 context->protocol_ = protocol;
143 context->errorNumber_ = errorNumber;
144 if (errorNumber != TLSSOCKET_SUCCESS) {
145 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
146 }
147 });
148 return context->errorNumber_ == TLSSOCKET_SUCCESS;
149 }
150
ExecGetSignatureAlgorithms(GetSignatureAlgorithmsContext * context)151 bool TLSSocketExec::ExecGetSignatureAlgorithms(GetSignatureAlgorithmsContext *context)
152 {
153 auto manager = context->GetManager();
154 if (manager == nullptr) {
155 NETSTACK_LOGE("manager is nullptr");
156 return false;
157 }
158 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
159 if (tlsSocket == nullptr) {
160 NETSTACK_LOGE("ExecGetSignatureAlgorithms tlsSocket is null");
161 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
162 return false;
163 }
164 tlsSocket->GetSignatureAlgorithms([&context](int32_t errorNumber, const std::vector<std::string> &algorithms) {
165 context->signatureAlgorithms_ = algorithms;
166 context->errorNumber_ = errorNumber;
167 if (errorNumber != TLSSOCKET_SUCCESS) {
168 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
169 }
170 });
171 return context->errorNumber_ == TLSSOCKET_SUCCESS;
172 }
173
ExecSend(TLSSendContext * context)174 bool TLSSocketExec::ExecSend(TLSSendContext *context)
175 {
176 auto manager = context->GetManager();
177 if (manager == nullptr) {
178 NETSTACK_LOGE("manager is nullptr");
179 return false;
180 }
181 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
182 if (tlsSocket == nullptr) {
183 NETSTACK_LOGE("ExecSend tlsSocket is null");
184 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
185 return false;
186 }
187 TCPSendOptions tcpSendOptions;
188 tcpSendOptions.SetData(context->data_);
189 tlsSocket->Send(tcpSendOptions, [&context](int32_t errorNumber) {
190 context->errorNumber_ = errorNumber;
191 if (errorNumber != TLSSOCKET_SUCCESS) {
192 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
193 }
194 });
195 return context->errorNumber_ == TLSSOCKET_SUCCESS;
196 }
197
ExecClose(TLSNapiContext * context)198 bool TLSSocketExec::ExecClose(TLSNapiContext *context)
199 {
200 auto manager = context->GetManager();
201 if (manager == nullptr) {
202 NETSTACK_LOGE("manager is nullptr");
203 return false;
204 }
205 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
206 if (tlsSocket == nullptr) {
207 NETSTACK_LOGE("ExecClose tlsSocket is null");
208 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
209 return false;
210 }
211 tlsSocket->Close([&context](int32_t errorNumber) {
212 context->errorNumber_ = errorNumber;
213 if (errorNumber != TLSSOCKET_SUCCESS) {
214 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
215 }
216 });
217 delete tlsSocket;
218 manager->SetData(nullptr);
219 return context->errorNumber_ == TLSSOCKET_SUCCESS;
220 }
221
ExecBind(TLSBindContext * context)222 bool TLSSocketExec::ExecBind(TLSBindContext *context)
223 {
224 auto manager = context->GetManager();
225 if (manager == nullptr) {
226 NETSTACK_LOGE("manager is nullptr");
227 return false;
228 }
229 auto tlsSocket = new TLSSocket();
230 tlsSocket->Bind(context->address_, [&context](int32_t errorNumber) {
231 context->errorNumber_ = errorNumber;
232 if (errorNumber != TLSSOCKET_SUCCESS) {
233 std::string errorString = MakeErrorMessage(errorNumber);
234 context->SetError(errorNumber, errorString);
235 }
236 });
237 manager->SetData(tlsSocket);
238 return context->errorNumber_ == TLSSOCKET_SUCCESS;
239 }
240
ExecGetRemoteAddress(TLSGetRemoteAddressContext * context)241 bool TLSSocketExec::ExecGetRemoteAddress(TLSGetRemoteAddressContext *context)
242 {
243 auto manager = context->GetManager();
244 if (manager == nullptr) {
245 NETSTACK_LOGE("manager is nullptr");
246 return false;
247 }
248 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
249 if (tlsSocket == nullptr) {
250 NETSTACK_LOGE("ExecGetRemoteAddress tlsSocket is null");
251 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
252 return false;
253 }
254 tlsSocket->GetRemoteAddress([&context](int32_t errorNumber, const NetAddress address) {
255 context->address_ = address;
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
ExecGetState(TLSGetStateContext * context)264 bool TLSSocketExec::ExecGetState(TLSGetStateContext *context)
265 {
266 auto manager = context->GetManager();
267 if (manager == nullptr) {
268 NETSTACK_LOGE("manager is nullptr");
269 context->state_.SetIsClose(true);
270 return true;
271 }
272 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
273 if (tlsSocket == nullptr) {
274 NETSTACK_LOGE("ExecGetState tlsSocket is null");
275 context->state_.SetIsClose(true);
276 return true;
277 }
278 tlsSocket->GetState([&context](int32_t errorNumber, const SocketStateBase state) {
279 context->state_ = state;
280 context->errorNumber_ = errorNumber;
281 if (errorNumber != TLSSOCKET_SUCCESS) {
282 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
283 }
284 });
285 return context->errorNumber_ == TLSSOCKET_SUCCESS;
286 }
287
ExecSetExtraOptions(TLSSetExtraOptionsContext * context)288 bool TLSSocketExec::ExecSetExtraOptions(TLSSetExtraOptionsContext *context)
289 {
290 auto manager = context->GetManager();
291 if (manager == nullptr) {
292 NETSTACK_LOGE("manager is nullptr");
293 return false;
294 }
295 auto tlsSocket = reinterpret_cast<TLSSocket *>(manager->GetData());
296 if (tlsSocket == nullptr) {
297 NETSTACK_LOGE("ExecSetExtraOptions tlsSocket is null");
298 context->SetError(TLS_ERR_NO_BIND, MakeErrorMessage(TLS_ERR_NO_BIND));
299 return false;
300 }
301 tlsSocket->SetExtraOptions(context->options_, [&context](int32_t errorNumber) {
302 context->errorNumber_ = errorNumber;
303 if (errorNumber != TLSSOCKET_SUCCESS) {
304 context->SetError(errorNumber, MakeErrorMessage(errorNumber));
305 }
306 });
307 return context->errorNumber_ == TLSSOCKET_SUCCESS;
308 }
309
GetCertificateCallback(GetCertificateContext * context)310 napi_value TLSSocketExec::GetCertificateCallback(GetCertificateContext *context)
311 {
312 void *data = nullptr;
313 napi_value arrayBuffer = NapiUtils::CreateArrayBuffer(context->GetEnv(),
314 context->localCert_.data.Length(), &data);
315 if (data != nullptr && arrayBuffer != nullptr) {
316 if (memcpy_s(data, context->localCert_.data.Length(),
317 reinterpret_cast<const uint8_t *>(context->localCert_.data.Data()),
318 context->localCert_.data.Length()) != EOK) {
319 NETSTACK_LOGE("memcpy_s failed!");
320 return NapiUtils::GetUndefined(context->GetEnv());
321 }
322 }
323 napi_value outData = nullptr;
324 napi_create_typedarray(context->GetEnv(), napi_uint8_array, context->localCert_.data.Length(), arrayBuffer, 0,
325 &outData);
326 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
327 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
328 return NapiUtils::GetUndefined(context->GetEnv());
329 }
330 NapiUtils::SetNamedProperty(context->GetEnv(), obj, CERTIFICATA_DATA, outData);
331 NapiUtils::SetInt32Property(context->GetEnv(), obj, CERTIFICATA_ENCODING_FORMAT,
332 context->localCert_.encodingFormat);
333 return obj;
334 }
335
ConnectCallback(TLSConnectContext * context)336 napi_value TLSSocketExec::ConnectCallback(TLSConnectContext *context)
337 {
338 return NapiUtils::GetUndefined(context->GetEnv());
339 }
340
GetCipherSuitesCallback(GetCipherSuitesContext * context)341 napi_value TLSSocketExec::GetCipherSuitesCallback(GetCipherSuitesContext *context)
342 {
343 napi_value cipherSuites = NapiUtils::CreateArray(context->GetEnv(), 0);
344 int index = 0;
345 for (const auto &cipher : context->cipherSuites_) {
346 napi_value cipherSuite = NapiUtils::CreateStringUtf8(context->GetEnv(), cipher);
347 NapiUtils::SetArrayElement(context->GetEnv(), cipherSuites, index++, cipherSuite);
348 }
349 return cipherSuites;
350 }
351
GetRemoteCertificateCallback(GetRemoteCertificateContext * context)352 napi_value TLSSocketExec::GetRemoteCertificateCallback(GetRemoteCertificateContext *context)
353 {
354 void *data = nullptr;
355 napi_value arrayBuffer = NapiUtils::CreateArrayBuffer(context->GetEnv(),
356 context->remoteCert_.data.Length(), &data);
357 if (data != nullptr && arrayBuffer != nullptr) {
358 if (memcpy_s(data, context->remoteCert_.data.Length(),
359 reinterpret_cast<const uint8_t *>(context->remoteCert_.data.Data()),
360 context->remoteCert_.data.Length()) != EOK) {
361 NETSTACK_LOGE("memcpy_s failed!");
362 return NapiUtils::GetUndefined(context->GetEnv());
363 }
364 }
365 napi_value outData = nullptr;
366 napi_create_typedarray(context->GetEnv(), napi_uint8_array, context->remoteCert_.data.Length(), arrayBuffer, 0,
367 &outData);
368 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
369 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
370 return NapiUtils::GetUndefined(context->GetEnv());
371 }
372 NapiUtils::SetNamedProperty(context->GetEnv(), obj, CERTIFICATA_DATA, outData);
373 NapiUtils::SetInt32Property(context->GetEnv(), obj, CERTIFICATA_ENCODING_FORMAT,
374 context->remoteCert_.encodingFormat);
375 return obj;
376 }
377
GetProtocolCallback(GetProtocolContext * context)378 napi_value TLSSocketExec::GetProtocolCallback(GetProtocolContext *context)
379 {
380 return NapiUtils::CreateStringUtf8(context->GetEnv(), context->protocol_);
381 }
382
GetSignatureAlgorithmsCallback(GetSignatureAlgorithmsContext * context)383 napi_value TLSSocketExec::GetSignatureAlgorithmsCallback(GetSignatureAlgorithmsContext *context)
384 {
385 napi_value signatureAlgorithms = NapiUtils::CreateArray(context->GetEnv(), 0);
386 int index = 0;
387 for (const auto &algorithm : context->signatureAlgorithms_) {
388 napi_value signatureAlgorithm = NapiUtils::CreateStringUtf8(context->GetEnv(), algorithm);
389 NapiUtils::SetArrayElement(context->GetEnv(), signatureAlgorithms, index++, signatureAlgorithm);
390 }
391 return signatureAlgorithms;
392 }
393
SendCallback(TLSSendContext * context)394 napi_value TLSSocketExec::SendCallback(TLSSendContext *context)
395 {
396 return NapiUtils::GetUndefined(context->GetEnv());
397 }
398
CloseCallback(TLSNapiContext * context)399 napi_value TLSSocketExec::CloseCallback(TLSNapiContext *context)
400 {
401 return NapiUtils::GetUndefined(context->GetEnv());
402 }
403
BindCallback(TLSBindContext * context)404 napi_value TLSSocketExec::BindCallback(TLSBindContext *context)
405 {
406 context->Emit(EVENT_LISTENING, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
407 NapiUtils::GetUndefined(context->GetEnv())));
408 return NapiUtils::GetUndefined(context->GetEnv());
409 }
410
GetStateCallback(TLSGetStateContext * context)411 napi_value TLSSocketExec::GetStateCallback(TLSGetStateContext *context)
412 {
413 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
414 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
415 return NapiUtils::GetUndefined(context->GetEnv());
416 }
417 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->state_.IsBound());
418 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->state_.IsClose());
419 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->state_.IsConnected());
420 return obj;
421 }
422
GetRemoteAddressCallback(TLSGetRemoteAddressContext * context)423 napi_value TLSSocketExec::GetRemoteAddressCallback(TLSGetRemoteAddressContext *context)
424 {
425 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
426 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
427 return NapiUtils::GetUndefined(context->GetEnv());
428 }
429 NapiUtils::SetStringPropertyUtf8(context->GetEnv(), obj, KEY_ADDRESS, context->address_.GetAddress());
430 NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_FAMILY, context->address_.GetJsValueFamily());
431 NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_PORT, context->address_.GetPort());
432 return obj;
433 }
434
SetExtraOptionsCallback(TLSSetExtraOptionsContext * context)435 napi_value TLSSocketExec::SetExtraOptionsCallback(TLSSetExtraOptionsContext *context)
436 {
437 return NapiUtils::GetUndefined(context->GetEnv());
438 }
439
440 } // namespace NetStack
441 } // namespace OHOS
442