• 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 "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