mirror of
https://gitee.com/openharmony/communication_netstack
synced 2025-02-11 05:35:56 +00:00
commit
b6aa842ee7
@ -103,6 +103,7 @@ ohos_shared_library("http") {
|
||||
"cache/lru_cache/src/lru_cache_disk_handler.cpp",
|
||||
"constant/src/constant.cpp",
|
||||
"http_exec/src/http_exec.cpp",
|
||||
"http_exec/src/http_tls_config.cpp",
|
||||
"http_module/src/http_module.cpp",
|
||||
"options/src/http_request_options.cpp",
|
||||
"options/src/http_response.cpp",
|
||||
|
@ -104,6 +104,12 @@ public:
|
||||
|
||||
void ParseClientCert(napi_value optionsValue);
|
||||
|
||||
void ParseRemoteValidationMode(napi_value optionsValue);
|
||||
|
||||
void ParseTlsOption(napi_value optionsValue);
|
||||
|
||||
void ParseServerAuthentication(napi_value optionsValue);
|
||||
|
||||
void CachePerformanceTimingItem(const std::string &key, double value);
|
||||
|
||||
void StopAndCacheNapiPerformanceTiming(const char *key);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "constant.h"
|
||||
#include "http_exec.h"
|
||||
#include "http_tls_config.h"
|
||||
#include "napi_utils.h"
|
||||
#include "netstack_common_utils.h"
|
||||
#include "netstack_log.h"
|
||||
@ -234,6 +235,97 @@ void RequestContext::ParseNumberOptions(napi_value optionsValue)
|
||||
}
|
||||
}
|
||||
|
||||
void RequestContext::ParseRemoteValidationMode(napi_value optionsValue)
|
||||
{
|
||||
if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_REMOTE_VALIDATION)) {
|
||||
NETSTACK_LOGD("no remote validation mode config");
|
||||
return;
|
||||
}
|
||||
napi_value value = NapiUtils::GetNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_REMOTE_VALIDATION);
|
||||
if (NapiUtils::GetValueType(GetEnv(), value) == napi_string) {
|
||||
auto remoteValidationMode = NapiUtils::GetStringFromValueUtf8(GetEnv(), value);
|
||||
if (remoteValidationMode == "skip") {
|
||||
NETSTACK_LOGI("ParseRemoteValidationMode remoteValidationMode skip");
|
||||
options.SetCanSkipCertVerifyFlag(true);
|
||||
} else if (remoteValidationMode != "system") {
|
||||
NETSTACK_LOGE("RemoteValidationMode config error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RequestContext::ParseTlsOption(napi_value optionsValue)
|
||||
{
|
||||
if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_TLS_OPTION)) {
|
||||
NETSTACK_LOGD("no tls config");
|
||||
return;
|
||||
}
|
||||
napi_value tlsVersionValue = NapiUtils::GetNamedProperty(
|
||||
GetEnv(), optionsValue, HttpConstant::PARAM_KEY_TLS_OPTION);
|
||||
napi_valuetype type = NapiUtils::GetValueType(GetEnv(), tlsVersionValue);
|
||||
if (type != napi_object && type != napi_string) {
|
||||
NETSTACK_LOGE("tlsVersionValue type error");
|
||||
return;
|
||||
}
|
||||
uint32_t tlsVersionMin = NapiUtils::GetUint32Property(GetEnv(), tlsVersionValue, "tlsVersionMin");
|
||||
uint32_t tlsVersionMax = NapiUtils::GetUint32Property(GetEnv(), tlsVersionValue, "tlsVersionMax");
|
||||
NETSTACK_LOGD("tlsVersionMin = %{public}d, tlsVersionMax = %{public}d", tlsVersionMin, tlsVersionMax);
|
||||
TlsOption tlsOption;
|
||||
tlsOption.tlsVersionMin = static_cast<TlsVersion>(tlsVersionMin);
|
||||
tlsOption.tlsVersionMax = static_cast<TlsVersion>(tlsVersionMax);
|
||||
if (!NapiUtils::HasNamedProperty(GetEnv(), tlsVersionValue, "cipherSuites")) {
|
||||
NETSTACK_LOGD("no cipherSuites");
|
||||
options.SetTlsOption(tlsOption);
|
||||
return;
|
||||
}
|
||||
auto cipherSuiteNapi = NapiUtils::GetNamedProperty(GetEnv(), tlsVersionValue, "cipherSuites");
|
||||
if (!NapiUtils::IsArray(GetEnv(), cipherSuiteNapi)) {
|
||||
options.SetTlsOption(tlsOption);
|
||||
return;
|
||||
}
|
||||
auto length = NapiUtils::GetArrayLength(GetEnv(), cipherSuiteNapi);
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
auto standardNameNapi = NapiUtils::GetArrayElement(GetEnv(), cipherSuiteNapi, i);
|
||||
auto cipherSuite = GetTlsCipherSuiteFromStandardName(
|
||||
NapiUtils::GetStringFromValueUtf8(GetEnv(), standardNameNapi));
|
||||
if (cipherSuite != CipherSuite::INVALID) {
|
||||
tlsOption.cipherSuite.emplace(cipherSuite);
|
||||
}
|
||||
}
|
||||
|
||||
options.SetTlsOption(tlsOption);
|
||||
}
|
||||
|
||||
void RequestContext::ParseServerAuthentication(napi_value optionsValue)
|
||||
{
|
||||
if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_SERVER_AUTH)) {
|
||||
NETSTACK_LOGD("no server authentication config");
|
||||
return;
|
||||
}
|
||||
napi_value serverAuthenticationValue = NapiUtils::GetNamedProperty(
|
||||
GetEnv(), optionsValue, HttpConstant::PARAM_KEY_SERVER_AUTH);
|
||||
napi_valuetype type = NapiUtils::GetValueType(GetEnv(), serverAuthenticationValue);
|
||||
if (type != napi_object) {
|
||||
NETSTACK_LOGE("server authentication type error");
|
||||
return;
|
||||
}
|
||||
ServerAuthentication serverAuthentication;
|
||||
auto credentialNapi = NapiUtils::GetNamedProperty(GetEnv(), serverAuthenticationValue, "credential");
|
||||
NapiUtils::GetSecureDataPropertyUtf8(GetEnv(),
|
||||
credentialNapi, "username", serverAuthentication.credential.username);
|
||||
NapiUtils::GetSecureDataPropertyUtf8(GetEnv(),
|
||||
credentialNapi, "password", serverAuthentication.credential.password);
|
||||
auto authenticationType = NapiUtils::GetStringPropertyUtf8(GetEnv(),
|
||||
serverAuthenticationValue, "authenticationType");
|
||||
if (authenticationType == "basic") {
|
||||
serverAuthentication.authenticationType = AuthenticationType::BASIC;
|
||||
} else if (authenticationType == "ntlm") {
|
||||
serverAuthentication.authenticationType = AuthenticationType::NTLM;
|
||||
} else if (authenticationType == "digest") {
|
||||
serverAuthentication.authenticationType = AuthenticationType::DIGEST;
|
||||
}
|
||||
options.SetServerAuthentication(serverAuthentication);
|
||||
}
|
||||
|
||||
void RequestContext::ParseHeader(napi_value optionsValue)
|
||||
{
|
||||
if (!NapiUtils::HasNamedProperty(GetEnv(), optionsValue, HttpConstant::PARAM_KEY_HEADER)) {
|
||||
@ -449,6 +541,9 @@ void RequestContext::UrlAndOptions(napi_value urlValue, napi_value optionsValue)
|
||||
ParseDnsServers(optionsValue);
|
||||
ParseMultiFormData(optionsValue);
|
||||
ParseCertificatePinning(optionsValue);
|
||||
ParseRemoteValidationMode(optionsValue);
|
||||
ParseTlsOption(optionsValue);
|
||||
ParseServerAuthentication(optionsValue);
|
||||
SetParseOK(true);
|
||||
}
|
||||
|
||||
|
@ -156,6 +156,9 @@ public:
|
||||
static const char *const PARAM_KEY_CLIENT_CERT;
|
||||
static const char *const PARAM_KEY_MULTI_FORM_DATA_LIST;
|
||||
static const char *const PARAM_KEY_CERTIFICATE_PINNING;
|
||||
static const char *const PARAM_KEY_REMOTE_VALIDATION;
|
||||
static const char *const PARAM_KEY_TLS_OPTION;
|
||||
static const char *const PARAM_KEY_SERVER_AUTH;
|
||||
|
||||
static const char *const HTTP_PROXY_KEY_HOST;
|
||||
static const char *const HTTP_PROXY_KEY_PORT;
|
||||
@ -174,6 +177,11 @@ public:
|
||||
static const char *const HTTP_CERT_TYPE_DER;
|
||||
static const char *const HTTP_CERT_TYPE_P12;
|
||||
|
||||
static const char *const TLS_VERSION_1_0;
|
||||
static const char *const TLS_VERSION_1_1;
|
||||
static const char *const TLS_VERSION_1_2;
|
||||
static const char *const TLS_VERSION_1_3;
|
||||
|
||||
static const char *const HTTP_MULTI_FORM_DATA_NAME;
|
||||
static const char *const HTTP_MULTI_FORM_DATA_CONTENT_TYPE;
|
||||
static const char *const HTTP_MULTI_FORM_DATA_REMOTE_FILE_NAME;
|
||||
|
@ -54,6 +54,10 @@ const char *const HttpConstant::PARAM_KEY_MULTI_FORM_DATA_LIST = "multiFormDataL
|
||||
|
||||
const char *const HttpConstant::PARAM_KEY_CERTIFICATE_PINNING = "certificatePinning";
|
||||
|
||||
const char *const HttpConstant::PARAM_KEY_REMOTE_VALIDATION = "remoteValidation";
|
||||
const char *const HttpConstant::PARAM_KEY_TLS_OPTION = "tlsOptions";
|
||||
const char *const HttpConstant::PARAM_KEY_SERVER_AUTH = "serverAuthentication";
|
||||
|
||||
const char *const HttpConstant::HTTP_PROXY_KEY_HOST = "host";
|
||||
const char *const HttpConstant::HTTP_PROXY_KEY_PORT = "port";
|
||||
const char *const HttpConstant::HTTP_PROXY_KEY_EXCLUSION_LIST = "exclusionList";
|
||||
@ -70,6 +74,11 @@ const char *const HttpConstant::HTTP_CERT_TYPE_PEM = "PEM";
|
||||
const char *const HttpConstant::HTTP_CERT_TYPE_DER = "DER";
|
||||
const char *const HttpConstant::HTTP_CERT_TYPE_P12 = "P12";
|
||||
|
||||
const char *const HttpConstant::TLS_VERSION_1_0 = "TLS_V_1_0";
|
||||
const char *const HttpConstant::TLS_VERSION_1_1 = "TLS_V_1_1";
|
||||
const char *const HttpConstant::TLS_VERSION_1_2 = "TLS_V_1_2";
|
||||
const char *const HttpConstant::TLS_VERSION_1_3 = "TLS_V_1_3";
|
||||
|
||||
const char *const HttpConstant::HTTP_PROXY_EXCLUSIONS_SEPARATOR = ",";
|
||||
|
||||
const char *const HttpConstant::RESPONSE_KEY_RESULT = "result";
|
||||
|
@ -92,6 +92,8 @@ private:
|
||||
|
||||
static bool SetOtherOption(CURL *curl, RequestContext *context);
|
||||
|
||||
static bool SetAuthOptions(CURL *curl, OHOS::NetStack::Http::RequestContext *context);
|
||||
|
||||
static bool SetRequestOption(void *curl, RequestContext *context);
|
||||
|
||||
static bool SetSSLCertOption(CURL *curl, RequestContext *context);
|
||||
@ -158,6 +160,8 @@ private:
|
||||
static void SetFormDataOption(MultiFormData &multiFormData, curl_mimepart *part,
|
||||
void *curl, RequestContext *context);
|
||||
|
||||
static bool IsBuiltWithOpenSSL();
|
||||
|
||||
#if !HAS_NETMANAGER_BASE
|
||||
static void AddRequestInfo();
|
||||
#endif
|
||||
|
70
frameworks/js/napi/http/http_exec/include/http_tls_config.h
Normal file
70
frameworks/js/napi/http/http_exec/include/http_tls_config.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NETSTACK_HTTP_TLS_CONFIG_H
|
||||
#define NETSTACK_HTTP_TLS_CONFIG_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "securec.h"
|
||||
|
||||
namespace OHOS::NetStack::Http {
|
||||
enum class CipherSuite {
|
||||
INVALID = -1,
|
||||
TLS_AES_128_GCM_SHA256 = 0x1301,
|
||||
TLS_AES_256_GCM_SHA384 = 0x1302,
|
||||
TLS_CHACHA20_POLY1305_SHA256 = 0x1303,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xc02b,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xc02c,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xc030,
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xcca9,
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xcca8,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0x009c,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0x009d,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xc009,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xc013,
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256 = 0xc00a,
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384 = 0xc014,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA = 0x002f,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035,
|
||||
TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000a,
|
||||
};
|
||||
|
||||
enum class TlsVersion {
|
||||
DEFAULT = 0,
|
||||
TLSv1_0 = 4,
|
||||
TLSv1_1 = 5,
|
||||
TLSv1_2 = 6,
|
||||
TLSv1_3 = 7,
|
||||
};
|
||||
|
||||
struct TlsCipherString {
|
||||
std::string ciperSuiteString;
|
||||
std::string tlsV13CiperSuiteString;
|
||||
};
|
||||
|
||||
[[nodiscard]] CipherSuite GetTlsCipherSuiteFromStandardName(const std::string &standardName);
|
||||
[[nodiscard]] std::string GetInnerNameFromCipherSuite(CipherSuite cipherSuite);
|
||||
[[nodiscard]] TlsCipherString ConvertCipherSuiteToCipherString(const std::unordered_set<CipherSuite> &cipherSuite);
|
||||
|
||||
} // namespace OHOS::NetStack::Http
|
||||
#endif // NETSTACK_HTTP_TLS_CONFIG_H
|
@ -891,6 +891,49 @@ bool HttpExec::Initialize()
|
||||
}
|
||||
#endif
|
||||
|
||||
bool HttpExec::IsBuiltWithOpenSSL()
|
||||
{
|
||||
const auto data = curl_version_info(CURLVERSION_NOW);
|
||||
if (!data || !data->ssl_version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto sslVersion = CommonUtils::ToLower(data->ssl_version);
|
||||
return sslVersion.find("openssl") != std::string::npos;
|
||||
}
|
||||
|
||||
unsigned long GetTlsVersion(TlsVersion tlsVersionMin, TlsVersion tlsVersionMax)
|
||||
{
|
||||
unsigned long tlsVersion = CURL_SSLVERSION_DEFAULT;
|
||||
if (tlsVersionMin == TlsVersion::DEFAULT || tlsVersionMax == TlsVersion::DEFAULT) {
|
||||
return tlsVersion;
|
||||
}
|
||||
if (tlsVersionMin > tlsVersionMax) {
|
||||
return tlsVersion;
|
||||
}
|
||||
if (tlsVersionMin == TlsVersion::TLSv1_0) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_TLSv1_0);
|
||||
} else if (tlsVersionMin == TlsVersion::TLSv1_1) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_TLSv1_1);
|
||||
} else if (tlsVersionMin == TlsVersion::TLSv1_2) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_TLSv1_2);
|
||||
} else if (tlsVersionMin == TlsVersion::TLSv1_3) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_TLSv1_3);
|
||||
}
|
||||
|
||||
if (tlsVersionMax == TlsVersion::TLSv1_0) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_MAX_TLSv1_0);
|
||||
} else if (tlsVersionMax == TlsVersion::TLSv1_1) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_MAX_TLSv1_1);
|
||||
} else if (tlsVersionMax == TlsVersion::TLSv1_2) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_MAX_TLSv1_2);
|
||||
} else if (tlsVersionMax == TlsVersion::TLSv1_3) {
|
||||
tlsVersion |= static_cast<unsigned long>(CURL_SSLVERSION_MAX_TLSv1_3);
|
||||
}
|
||||
|
||||
return tlsVersion;
|
||||
}
|
||||
|
||||
bool HttpExec::SetOtherOption(CURL *curl, OHOS::NetStack::Http::RequestContext *context)
|
||||
{
|
||||
std::string url = context->options.GetUrl();
|
||||
@ -905,8 +948,29 @@ bool HttpExec::SetOtherOption(CURL *curl, OHOS::NetStack::Http::RequestContext *
|
||||
auto proxyType = (host.find("https://") != std::string::npos) ? CURLPROXY_HTTPS : CURLPROXY_HTTP;
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_PROXYTYPE, proxyType, context);
|
||||
}
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2, context);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_CIPHER_LIST, TLS12_SECURITY_CIPHER_SUITE, context);
|
||||
const auto &tlsOption = context->options.GetTlsOption();
|
||||
unsigned long tlsVersion = GetTlsVersion(tlsOption.tlsVersionMin, tlsOption.tlsVersionMax);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSLVERSION, static_cast<long>(tlsVersion), context);
|
||||
const auto &cipherSuite = tlsOption.cipherSuite;
|
||||
const auto &cipherSuiteString = ConvertCipherSuiteToCipherString(cipherSuite);
|
||||
const auto &normalString = cipherSuiteString.ciperSuiteString;
|
||||
const auto &tlsV13String = cipherSuiteString.tlsV13CiperSuiteString;
|
||||
if (tlsVersion == CURL_SSLVERSION_DEFAULT) {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2, context);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_CIPHER_LIST, TLS12_SECURITY_CIPHER_SUITE, context);
|
||||
} else if (normalString.empty() && tlsV13String.empty()) {
|
||||
NETSTACK_LOGD("no cipherSuite config");
|
||||
} else if (!normalString.empty()) {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_CIPHER_LIST, normalString.c_str(), context);
|
||||
if (!tlsV13String.empty() && IsBuiltWithOpenSSL()) {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_TLS13_CIPHERS, tlsV13String.c_str(), context);
|
||||
}
|
||||
} else if (!tlsV13String.empty() && IsBuiltWithOpenSSL()) {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_TLS13_CIPHERS, tlsV13String.c_str(), context);
|
||||
} else {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2, context);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_CIPHER_LIST, TLS12_SECURITY_CIPHER_SUITE, context);
|
||||
}
|
||||
|
||||
#ifdef NETSTACK_PROXY_PASS
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_PROXYUSERPWD, NETSTACK_PROXY_PASS, context);
|
||||
@ -922,6 +986,37 @@ bool HttpExec::SetOtherOption(CURL *curl, OHOS::NetStack::Http::RequestContext *
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpExec::SetAuthOptions(CURL *curl, OHOS::NetStack::Http::RequestContext *context)
|
||||
{
|
||||
long authType = CURLAUTH_ANY;
|
||||
auto authentication = context->options.GetServerAuthentication();;
|
||||
switch (authentication.authenticationType) {
|
||||
case AuthenticationType::BASIC:
|
||||
authType = CURLAUTH_BASIC;
|
||||
break;
|
||||
case AuthenticationType::NTLM:
|
||||
authType = CURLAUTH_NTLM;
|
||||
break;
|
||||
case AuthenticationType::DIGEST:
|
||||
authType = CURLAUTH_DIGEST;
|
||||
break;
|
||||
case AuthenticationType::AUTO:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
auto username = authentication.credential.username;
|
||||
auto password = authentication.credential.password;
|
||||
if (!username.empty()) {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_HTTPAUTH, authType, context);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_USERNAME, username.c_str(), context);
|
||||
}
|
||||
if (!password.empty()) {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_PASSWORD, password.c_str(), context);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpExec::SetSSLCertOption(CURL *curl, OHOS::NetStack::Http::RequestContext *context)
|
||||
{
|
||||
std::string cert;
|
||||
@ -1092,13 +1187,18 @@ bool HttpExec::SetServerSSLCertOption(CURL *curl, OHOS::NetStack::Http::RequestC
|
||||
NETSTACK_LOGE("GetTrustAnchorsForHostName error. ret [%{public}d]", ret);
|
||||
}
|
||||
#ifdef HTTP_MULTIPATH_CERT_ENABLE
|
||||
// add user cert path
|
||||
TrustUser0AndUserCa(certs);
|
||||
// add system cert path
|
||||
certs.emplace_back(HttpConstant::HTTP_PREPARE_CA_PATH);
|
||||
context->SetCertsPath(std::move(certs), context->options.GetCaPath());
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYPEER, 1L, context);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYHOST, 2L, context);
|
||||
if (context->options.GetCanSkipCertVerifyFlag()) {
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYPEER, 0L, context);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYHOST, 0L, context);
|
||||
} else {
|
||||
// add user cert path
|
||||
TrustUser0AndUserCa(certs);
|
||||
// add system cert path
|
||||
certs.emplace_back(HttpConstant::HTTP_PREPARE_CA_PATH);
|
||||
context->SetCertsPath(std::move(certs), context->options.GetCaPath());
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYPEER, 1L, context);
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYHOST, 2L, context);
|
||||
}
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_CAINFO, nullptr, context);
|
||||
#else
|
||||
NETSTACK_CURL_EASY_SET_OPTION(curl, CURLOPT_CAINFO, nullptr, context);
|
||||
@ -1325,6 +1425,10 @@ bool HttpExec::SetOption(CURL *curl, RequestContext *context, struct curl_slist
|
||||
if (!SetOtherOption(curl, context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetAuthOptions(curl, context)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
167
frameworks/js/napi/http/http_exec/src/http_tls_config.cpp
Normal file
167
frameworks/js/napi/http/http_exec/src/http_tls_config.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "http_tls_config.h"
|
||||
|
||||
namespace OHOS::NetStack::Http {
|
||||
struct CipherSuiteConvertor {
|
||||
CipherSuite cipherSuite = CipherSuite::INVALID;
|
||||
const char *innerName = nullptr;
|
||||
const char *standardName = nullptr;
|
||||
};
|
||||
|
||||
static constexpr const CipherSuiteConvertor CIPHER_SUITE_CONVERTOR[] = {
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_AES_128_GCM_SHA256,
|
||||
.innerName = "TLS_AES_128_GCM_SHA256",
|
||||
.standardName = "TLS_AES_128_GCM_SHA256",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_AES_256_GCM_SHA384,
|
||||
.innerName = "TLS_AES_256_GCM_SHA384",
|
||||
.standardName = "TLS_AES_256_GCM_SHA384",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_CHACHA20_POLY1305_SHA256,
|
||||
.innerName = "TLS_CHACHA20_POLY1305_SHA256",
|
||||
.standardName = "TLS_CHACHA20_POLY1305_SHA256",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
.innerName = "ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
.standardName = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
.innerName = "ECDHE-RSA-AES128-GCM-SHA256",
|
||||
.standardName = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
.innerName = "ECDHE-ECDSA-AES256-GCM-SHA384",
|
||||
.standardName = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
.innerName = "ECDHE-RSA-AES256-GCM-SHA384",
|
||||
.standardName = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
.innerName = "ECDHE-ECDSA-CHACHA20-POLY1305",
|
||||
.standardName = "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
.innerName = "ECDHE-RSA-CHACHA20-POLY1305",
|
||||
.standardName = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
.innerName = "AES128-GCM-SHA256",
|
||||
.standardName = "TLS_RSA_WITH_AES_128_GCM_SHA256",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
.innerName = "AES256-GCM-SHA384",
|
||||
.standardName = "TLS_RSA_WITH_AES_256_GCM_SHA384",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
.innerName = "ECDHE-ECDSA-AES128-SHA",
|
||||
.standardName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
.innerName = "ECDHE-RSA-AES128-SHA",
|
||||
.standardName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
.innerName = "ECDHE-ECDSA-AES256-SHA",
|
||||
.standardName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
.innerName = "ECDHE-RSA-AES256-SHA",
|
||||
.standardName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
.innerName = "AES128-SHA",
|
||||
.standardName = "TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
.innerName = "AES256-SHA",
|
||||
.standardName = "TLS_RSA_WITH_AES_256_CBC_SHA",
|
||||
},
|
||||
{
|
||||
.cipherSuite = CipherSuite::TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
.innerName = "DES-CBC3-SHA",
|
||||
.standardName = "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||
},
|
||||
};
|
||||
|
||||
CipherSuite GetTlsCipherSuiteFromStandardName(const std::string &standardName)
|
||||
{
|
||||
for (const auto &suite : CIPHER_SUITE_CONVERTOR) {
|
||||
if (suite.standardName == standardName) {
|
||||
return suite.cipherSuite;
|
||||
}
|
||||
}
|
||||
return CipherSuite::INVALID;
|
||||
}
|
||||
|
||||
std::string GetInnerNameFromCipherSuite(CipherSuite cipherSuite)
|
||||
{
|
||||
for (const auto &suite : CIPHER_SUITE_CONVERTOR) {
|
||||
if (suite.cipherSuite == cipherSuite) {
|
||||
return suite.innerName;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static bool IsTlsV13Cipher(const std::string &innerName)
|
||||
{
|
||||
return innerName == "TLS_AES_128_GCM_SHA256" || innerName == "TLS_AES_256_GCM_SHA384" ||
|
||||
innerName == "TLS_CHACHA20_POLY1305_SHA256";
|
||||
}
|
||||
|
||||
TlsCipherString ConvertCipherSuiteToCipherString(const std::unordered_set<CipherSuite> &cipherSuite)
|
||||
{
|
||||
TlsCipherString cipherString;
|
||||
for (const auto &cipher : cipherSuite) {
|
||||
auto innerName = GetInnerNameFromCipherSuite(cipher);
|
||||
if (innerName.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (IsTlsV13Cipher(innerName)) {
|
||||
cipherString.tlsV13CiperSuiteString.append(innerName).append(":");
|
||||
} else {
|
||||
cipherString.ciperSuiteString.append(innerName).append(":");
|
||||
}
|
||||
}
|
||||
if (!cipherString.tlsV13CiperSuiteString.empty()) {
|
||||
cipherString.tlsV13CiperSuiteString.pop_back();
|
||||
}
|
||||
if (!cipherString.ciperSuiteString.empty()) {
|
||||
cipherString.ciperSuiteString.pop_back();
|
||||
}
|
||||
return cipherString;
|
||||
}
|
||||
|
||||
} // namespace OHOS::NetStack::Http
|
@ -56,6 +56,7 @@ public:
|
||||
static constexpr const char *INTERFACE_CERT_TYPE = "CertType";
|
||||
static constexpr const char *INTERFACE_HTTP_RESPONSE_CACHE = "OHOS_NET_HTTP_HttpResponseCache";
|
||||
static constexpr const char *INTERFACE_HTTP_DATA_TYPE = "HttpDataType";
|
||||
static constexpr const char *INTERFACE_TLS_VERSION = "TlsVersion";
|
||||
|
||||
static napi_value InitHttpModule(napi_env env, napi_value exports);
|
||||
|
||||
@ -74,6 +75,8 @@ private:
|
||||
|
||||
static void InitResponseCode(napi_env env, napi_value exports);
|
||||
|
||||
static void InitTlsVersion(napi_env env, napi_value exports);
|
||||
|
||||
static void InitHttpProtocol(napi_env env, napi_value exports);
|
||||
|
||||
static void InitCertType(napi_env env, napi_value exports);
|
||||
|
@ -134,6 +134,7 @@ void HttpModuleExports::InitHttpProperties(napi_env env, napi_value exports)
|
||||
InitCertType(env, exports);
|
||||
InitHttpProtocol(env, exports);
|
||||
InitHttpDataType(env, exports);
|
||||
InitTlsVersion(env, exports);
|
||||
}
|
||||
|
||||
void HttpModuleExports::InitRequestMethod(napi_env env, napi_value exports)
|
||||
@ -198,6 +199,25 @@ void HttpModuleExports::InitResponseCode(napi_env env, napi_value exports)
|
||||
NapiUtils::SetNamedProperty(env, exports, INTERFACE_RESPONSE_CODE, responseCode);
|
||||
}
|
||||
|
||||
void HttpModuleExports::InitTlsVersion(napi_env env, napi_value exports)
|
||||
{
|
||||
std::initializer_list<napi_property_descriptor> properties = {
|
||||
DECLARE_NAPI_STATIC_PROPERTY(HttpConstant::TLS_VERSION_1_0,
|
||||
NapiUtils::CreateUint32(env, static_cast<uint32_t>(TlsVersion::TLSv1_0))),
|
||||
DECLARE_NAPI_STATIC_PROPERTY(HttpConstant::TLS_VERSION_1_1,
|
||||
NapiUtils::CreateUint32(env, static_cast<uint32_t>(TlsVersion::TLSv1_1))),
|
||||
DECLARE_NAPI_STATIC_PROPERTY(HttpConstant::TLS_VERSION_1_2,
|
||||
NapiUtils::CreateUint32(env, static_cast<uint32_t>(TlsVersion::TLSv1_2))),
|
||||
DECLARE_NAPI_STATIC_PROPERTY(HttpConstant::TLS_VERSION_1_3,
|
||||
NapiUtils::CreateUint32(env, static_cast<uint32_t>(TlsVersion::TLSv1_3))),
|
||||
};
|
||||
|
||||
napi_value tlsVersion = NapiUtils::CreateObject(env);
|
||||
NapiUtils::DefineProperties(env, tlsVersion, properties);
|
||||
|
||||
NapiUtils::SetNamedProperty(env, exports, INTERFACE_TLS_VERSION, tlsVersion);
|
||||
}
|
||||
|
||||
void HttpModuleExports::InitHttpProtocol(napi_env env, napi_value exports)
|
||||
{
|
||||
std::initializer_list<napi_property_descriptor> properties = {
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "constant.h"
|
||||
#include "secure_char.h"
|
||||
#include "http_tls_config.h"
|
||||
#include "napi_utils.h"
|
||||
|
||||
namespace OHOS::NetStack::Http {
|
||||
enum class HttpProtocol {
|
||||
@ -52,6 +54,29 @@ enum class HashAlgorithm {
|
||||
INVALID,
|
||||
};
|
||||
|
||||
enum class AuthenticationType {
|
||||
AUTO,
|
||||
BASIC,
|
||||
NTLM,
|
||||
DIGEST,
|
||||
};
|
||||
|
||||
struct Credential {
|
||||
NapiUtils::SecureData username;
|
||||
NapiUtils::SecureData password;
|
||||
};
|
||||
|
||||
struct ServerAuthentication {
|
||||
Credential credential;
|
||||
AuthenticationType authenticationType = AuthenticationType::AUTO;
|
||||
};
|
||||
|
||||
struct TlsOption {
|
||||
std::unordered_set<CipherSuite> cipherSuite;
|
||||
TlsVersion tlsVersionMin = TlsVersion::DEFAULT;
|
||||
TlsVersion tlsVersionMax = TlsVersion::DEFAULT;
|
||||
};
|
||||
|
||||
struct CertificatePinning {
|
||||
HashAlgorithm hashAlgorithm = HashAlgorithm::SHA256;
|
||||
std::string publicKeyHash;
|
||||
@ -95,8 +120,14 @@ public:
|
||||
|
||||
void AddMultiFormData(const MultiFormData &multiFormData);
|
||||
|
||||
void SetTlsOption(const TlsOption &tlsOption);
|
||||
|
||||
void SetServerAuthentication(const ServerAuthentication &serverAuthentication);
|
||||
|
||||
void SetCertificatePinning(std::string certPIN);
|
||||
|
||||
void SetCanSkipCertVerifyFlag(bool canCertVerify);
|
||||
|
||||
[[nodiscard]] std::string GetCertificatePinning() const;
|
||||
|
||||
[[nodiscard]] const std::string &GetUrl() const;
|
||||
@ -137,9 +168,15 @@ public:
|
||||
|
||||
[[nodiscard]] const std::vector<std::string> &GetDnsServers() const;
|
||||
|
||||
[[nodiscard]] bool GetCanSkipCertVerifyFlag() const;
|
||||
|
||||
void GetClientCert(std::string &cert, std::string &certType, std::string &key, Secure::SecureChar &keyPasswd);
|
||||
|
||||
std::vector<MultiFormData> GetMultiPartDataList();
|
||||
|
||||
[[nodiscard]] const TlsOption GetTlsOption() const;
|
||||
|
||||
[[nodiscard]] const ServerAuthentication GetServerAuthentication() const;
|
||||
private:
|
||||
std::string url_;
|
||||
|
||||
@ -189,9 +226,15 @@ private:
|
||||
|
||||
Secure::SecureChar keyPasswd_;
|
||||
|
||||
bool canSkipCertVerify_ = false;
|
||||
|
||||
std::vector<MultiFormData> multiFormDataList_;
|
||||
|
||||
std::string certificatePinning_;
|
||||
|
||||
TlsOption tlsOption_;
|
||||
|
||||
ServerAuthentication serverAuthentication_;
|
||||
};
|
||||
} // namespace OHOS::NetStack::Http
|
||||
|
||||
|
@ -177,6 +177,15 @@ uint32_t HttpRequestOptions::GetPriority() const
|
||||
return priority_;
|
||||
}
|
||||
|
||||
void HttpRequestOptions::SetCanSkipCertVerifyFlag(bool canCertVerify)
|
||||
{
|
||||
canSkipCertVerify_ = canCertVerify;
|
||||
}
|
||||
|
||||
bool HttpRequestOptions::GetCanSkipCertVerifyFlag() const
|
||||
{
|
||||
return canSkipCertVerify_;
|
||||
}
|
||||
void HttpRequestOptions::SetUsingHttpProxyType(UsingHttpProxyType type)
|
||||
{
|
||||
usingHttpProxyType_ = type;
|
||||
@ -238,6 +247,30 @@ const std::string &HttpRequestOptions::GetCaPath() const
|
||||
return caPath_;
|
||||
}
|
||||
|
||||
void HttpRequestOptions::SetTlsOption(const TlsOption &tlsOption)
|
||||
{
|
||||
tlsOption_.tlsVersionMax = tlsOption.tlsVersionMax;
|
||||
tlsOption_.tlsVersionMin = tlsOption.tlsVersionMin;
|
||||
tlsOption_.cipherSuite = tlsOption.cipherSuite;
|
||||
}
|
||||
|
||||
const TlsOption HttpRequestOptions::GetTlsOption() const
|
||||
{
|
||||
return tlsOption_;
|
||||
}
|
||||
|
||||
void HttpRequestOptions::SetServerAuthentication(const ServerAuthentication &serverAuthentication)
|
||||
{
|
||||
serverAuthentication_.authenticationType = serverAuthentication.authenticationType;
|
||||
serverAuthentication_.credential.password = serverAuthentication.credential.password;
|
||||
serverAuthentication_.credential.username = serverAuthentication.credential.username;
|
||||
}
|
||||
|
||||
const ServerAuthentication HttpRequestOptions::GetServerAuthentication() const
|
||||
{
|
||||
return serverAuthentication_;
|
||||
}
|
||||
|
||||
void HttpRequestOptions::SetDohUrl(const std::string &dohUrl)
|
||||
{
|
||||
if (dohUrl.empty()) {
|
||||
|
@ -39,6 +39,7 @@ ohos_fuzztest("HttpFuzzTest") {
|
||||
"$NETSTACK_DIR/utils/napi_utils/include",
|
||||
"$NETSTACK_NAPI_ROOT/http/constant/include",
|
||||
"$NETSTACK_NAPI_ROOT/http/options/include",
|
||||
"$NETSTACK_NAPI_ROOT/http/http_exec/include",
|
||||
]
|
||||
include_dirs += utils_include
|
||||
|
||||
@ -72,6 +73,7 @@ ohos_fuzztest("HttpFuzzTest") {
|
||||
]
|
||||
|
||||
external_deps = common_external_deps
|
||||
external_deps += [ "napi:ace_napi" ]
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
@ -67,11 +67,13 @@ ohos_unittest("http_unittest") {
|
||||
}
|
||||
|
||||
external_deps = common_external_deps
|
||||
external_deps += [ "napi:ace_napi" ]
|
||||
|
||||
sources = [
|
||||
"$NETSTACK_NAPI_ROOT/http/async_context/src/request_context.cpp",
|
||||
"$NETSTACK_NAPI_ROOT/http/constant/src/constant.cpp",
|
||||
"$NETSTACK_NAPI_ROOT/http/http_exec/src/http_exec.cpp",
|
||||
"$NETSTACK_NAPI_ROOT/http/http_exec/src/http_tls_config.cpp",
|
||||
"$NETSTACK_NAPI_ROOT/http/options/src/http_request_options.cpp",
|
||||
"$NETSTACK_NAPI_ROOT/http/options/src/http_response.cpp",
|
||||
"$SUBSYSTEM_DIR/netstack/utils/common_utils/src/netstack_common_utils.cpp",
|
||||
|
2
test/unittest/http/cache/BUILD.gn
vendored
2
test/unittest/http/cache/BUILD.gn
vendored
@ -45,10 +45,12 @@ ohos_unittest("http_cache_unittest") {
|
||||
"$NETSTACK_NAPI_ROOT/http/constant/include",
|
||||
"$NETSTACK_NAPI_ROOT/http/options/include",
|
||||
"$NETSTACK_NAPI_ROOT/http/cache/base64/include",
|
||||
"$NETSTACK_NAPI_ROOT/http/http_exec/include",
|
||||
]
|
||||
include_dirs += utils_include
|
||||
|
||||
external_deps = common_external_deps
|
||||
external_deps += [ "napi:ace_napi" ]
|
||||
|
||||
deps = [ "$SUBSYSTEM_DIR/netstack/utils/napi_utils:napi_utils" ]
|
||||
|
||||
|
@ -44,6 +44,7 @@ ohos_unittest("netstack_network_profiler_utils_test") {
|
||||
"$NETSTACK_UTILS_ROOT/profiler_utils/include",
|
||||
"$NETSTACK_UTILS_ROOT/tlv_utils/include",
|
||||
"$NETSTACK_DIR/utils/common_utils/include",
|
||||
"$NETSTACK_NAPI_ROOT/http/http_exec/include",
|
||||
]
|
||||
include_dirs += utils_include
|
||||
|
||||
@ -53,6 +54,7 @@ ohos_unittest("netstack_network_profiler_utils_test") {
|
||||
"curl:curl_shared",
|
||||
"hiprofiler:libnetwork_profiler",
|
||||
"init:libbegetutil",
|
||||
"napi:ace_napi",
|
||||
"time_service:time_client",
|
||||
]
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "napi/native_api.h"
|
||||
#include "uv.h"
|
||||
|
||||
#include "securec.h"
|
||||
|
||||
namespace OHOS::NetStack::NapiUtils {
|
||||
static constexpr int NETSTACK_NAPI_INTERNAL_ERROR = 2300002;
|
||||
using UvHandler = std::function<void()>;
|
||||
@ -38,6 +40,14 @@ private:
|
||||
std::mutex mutex;
|
||||
};
|
||||
|
||||
struct SecureData : public std::string {
|
||||
~SecureData()
|
||||
{
|
||||
// Clear Data, to keep the memory safe
|
||||
(void)memset_s(data(), size(), 0, size());
|
||||
}
|
||||
};
|
||||
|
||||
napi_valuetype GetValueType(napi_env env, napi_value value);
|
||||
|
||||
bool IsInstanceOf(napi_env env, napi_value object, const std::string &name);
|
||||
@ -86,6 +96,11 @@ std::string GetStringFromValueUtf8(napi_env env, napi_value value);
|
||||
|
||||
std::string GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName);
|
||||
|
||||
void GetSecureDataFromValueUtf8(napi_env env, napi_value value, SecureData &data);
|
||||
|
||||
void GetSecureDataPropertyUtf8(
|
||||
napi_env env, napi_value object, const std::string &propertyName, SecureData &data);
|
||||
|
||||
std::string NapiValueToString(napi_env env, napi_value value);
|
||||
|
||||
void SetStringPropertyUtf8(napi_env env, napi_value object, const std::string &name, const std::string &value);
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "napi/native_common.h"
|
||||
#include "netstack_log.h"
|
||||
#include "node_api.h"
|
||||
#include "securec.h"
|
||||
|
||||
namespace OHOS::NetStack::NapiUtils {
|
||||
static constexpr const char *GLOBAL_JSON = "JSON";
|
||||
@ -291,6 +290,44 @@ napi_value CreateStringUtf8(napi_env env, const std::string &str)
|
||||
return value;
|
||||
}
|
||||
|
||||
void GetSecureDataPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName,
|
||||
SecureData &data)
|
||||
{
|
||||
if (!HasNamedProperty(env, object, propertyName)) {
|
||||
return;
|
||||
}
|
||||
napi_value value = GetNamedProperty(env, object, propertyName);
|
||||
GetSecureDataFromValueUtf8(env, value, data);
|
||||
}
|
||||
|
||||
void GetSecureDataFromValueUtf8(napi_env env, napi_value value, SecureData &data)
|
||||
{
|
||||
if (GetValueType(env, value) != napi_string) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t stringLength = 0;
|
||||
NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, value, nullptr, 0, &stringLength));
|
||||
if (stringLength == 0 || stringLength > SIZE_MAX - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto deleter = [](char *s) { free(reinterpret_cast<void *>(s)); };
|
||||
auto mem = malloc(stringLength + 1);
|
||||
if (mem == nullptr) {
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<char, decltype(deleter)> str(static_cast<char *>(mem), deleter);
|
||||
if (memset_s(str.get(), stringLength + 1, 0, stringLength + 1) != EOK) {
|
||||
return;
|
||||
}
|
||||
size_t length = 0;
|
||||
NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, value, str.get(), stringLength + 1, &length));
|
||||
if (length > 0) {
|
||||
data.append(str.get(), length);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetStringFromValueUtf8(napi_env env, napi_value value)
|
||||
{
|
||||
if (GetValueType(env, value) != napi_string) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user