|
|
effb77 |
From 683dd65f2b3dd67e64ef4d4aaadf390d08b481aa Mon Sep 17 00:00:00 2001
|
|
|
3f476a |
From: =?UTF-8?q?Jan=20Stan=C4=9Bk?= <jstanek@redhat.com>
|
|
|
effb77 |
Date: Wed, 13 Jul 2022 14:27:40 +0200
|
|
|
effb77 |
Subject: [PATCH] Backport necessary OpenSSL features
|
|
|
3f476a |
MIME-Version: 1.0
|
|
|
3f476a |
Content-Type: text/plain; charset=UTF-8
|
|
|
3f476a |
Content-Transfer-Encoding: 8bit
|
|
|
3f476a |
|
|
|
3f476a |
- Remove uses of SSL_CTX_{get,set}_{min,max}_proto_version()
|
|
|
3f476a |
|
|
|
3f476a |
These functions are not provided by OpenSSL v1.0,
|
|
|
3f476a |
and unfortunately cannot be fully re-implemented using available APIs.
|
|
|
3f476a |
|
|
|
3f476a |
- Implement SSL_{get,set}_{min,max}_proto_version on NodeJS level
|
|
|
3f476a |
|
|
|
3f476a |
The shim layer cannot provide implementation for the above functions,
|
|
|
3f476a |
as there is no place to store the current boundary information.
|
|
|
3f476a |
Setting them can be simulated by using SSL_CTX options,
|
|
|
3f476a |
but getting them is tricky and starts to fail once the boundaries meet.
|
|
|
3f476a |
|
|
|
3f476a |
Since Node wraps the secure context in it's own structure,
|
|
|
3f476a |
that structure can be extended to record the last set boundaries,
|
|
|
3f476a |
and then set the appropriate options on the OpenSSL structure.
|
|
|
3f476a |
|
|
|
3f476a |
This patch is a first draft of this implementation.
|
|
|
3f476a |
The boundaries are stored directly as private members of
|
|
|
3f476a |
`node::crypto::SecureContext`.
|
|
|
3f476a |
In order to actually apply them, a new private `_SyncMinMaxProto()`
|
|
|
3f476a |
method has to be called.
|
|
|
3f476a |
This will modify the option mask of the associated SSL_CTX structure
|
|
|
3f476a |
to match the recorded boundaries.
|
|
|
3f476a |
Use with care!
|
|
|
3f476a |
|
|
|
3f476a |
- Provide locking mechanism for legacy OpenSSL
|
|
|
3f476a |
|
|
|
3f476a |
This commit is probably a good candidate for inclusion in the shim,
|
|
|
3f476a |
although probably as some sort of extras – it is not trivial!
|
|
|
3f476a |
|
|
|
f0ceb1 |
- Setup ECDHE curve negotiation
|
|
|
f0ceb1 |
|
|
|
f0ceb1 |
- SSL_OP_SINGLE_ECDH_USE is no-op and default in OpenSSL 1.1,
|
|
|
f0ceb1 |
but should be specified in OpenSSL 1.0
|
|
|
f0ceb1 |
- SSL_CTX_set_ecdh_auto() is presumably the same case;
|
|
|
f0ceb1 |
does not even exist in OpenSSL 1.1
|
|
|
f0ceb1 |
|
|
|
f0ceb1 |
Without this setup, ECDHE curve negotiation is broken: rhbz#1910749
|
|
|
f0ceb1 |
|
|
|
3f476a |
Signed-off-by: Jan Staněk <jstanek@redhat.com>
|
|
|
3f476a |
---
|
|
|
f0ceb1 |
src/node_crypto.cc | 196 +++++++++++++++++++++++++++++++++++++++------
|
|
|
3f476a |
src/node_crypto.h | 14 ++++
|
|
|
f0ceb1 |
2 files changed, 184 insertions(+), 26 deletions(-)
|
|
|
3f476a |
|
|
|
3f476a |
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
|
|
|
effb77 |
index de8b26930b..975a148fc8 100644
|
|
|
3f476a |
--- a/src/node_crypto.cc
|
|
|
3f476a |
+++ b/src/node_crypto.cc
|
|
|
effb77 |
@@ -557,6 +557,11 @@ inline void SecureContext::Reset() {
|
|
|
3f476a |
ctx_.reset();
|
|
|
3f476a |
cert_.reset();
|
|
|
3f476a |
issuer_.reset();
|
|
|
3f476a |
+
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ _min_proto_version = 0;
|
|
|
3f476a |
+ _max_proto_version = 0;
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
}
|
|
|
3f476a |
|
|
|
3f476a |
SecureContext::~SecureContext() {
|
|
|
effb77 |
@@ -570,7 +575,11 @@ void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
|
|
|
3f476a |
// A maxVersion of 0 means "any", but OpenSSL may support TLS versions that
|
|
|
3f476a |
// Node.js doesn't, so pin the max to what we do support.
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+const int MAX_SUPPORTED_VERSION = TLS1_2_VERSION;
|
|
|
3f476a |
+#else // OPENSSL_IS_LEGACY
|
|
|
3f476a |
const int MAX_SUPPORTED_VERSION = TLS1_3_VERSION;
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
|
|
|
3f476a |
void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
SecureContext* sc;
|
|
|
effb77 |
@@ -625,38 +634,23 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
max_version = MAX_SUPPORTED_VERSION;
|
|
|
3f476a |
method = TLS_client_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_method") {
|
|
|
3f476a |
- min_version = TLS1_VERSION;
|
|
|
3f476a |
- max_version = TLS1_VERSION;
|
|
|
3f476a |
+ method = TLSv1_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_server_method") {
|
|
|
3f476a |
- min_version = TLS1_VERSION;
|
|
|
3f476a |
- max_version = TLS1_VERSION;
|
|
|
3f476a |
- method = TLS_server_method();
|
|
|
3f476a |
+ method = TLSv1_server_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_client_method") {
|
|
|
3f476a |
- min_version = TLS1_VERSION;
|
|
|
3f476a |
- max_version = TLS1_VERSION;
|
|
|
3f476a |
- method = TLS_client_method();
|
|
|
3f476a |
+ method = TLSv1_client_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_1_method") {
|
|
|
3f476a |
- min_version = TLS1_1_VERSION;
|
|
|
3f476a |
- max_version = TLS1_1_VERSION;
|
|
|
3f476a |
+ method = TLSv1_1_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_1_server_method") {
|
|
|
3f476a |
- min_version = TLS1_1_VERSION;
|
|
|
3f476a |
- max_version = TLS1_1_VERSION;
|
|
|
3f476a |
- method = TLS_server_method();
|
|
|
3f476a |
+ method = TLSv1_1_server_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_1_client_method") {
|
|
|
3f476a |
- min_version = TLS1_1_VERSION;
|
|
|
3f476a |
- max_version = TLS1_1_VERSION;
|
|
|
3f476a |
- method = TLS_client_method();
|
|
|
3f476a |
+ method = TLSv1_1_client_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_2_method") {
|
|
|
3f476a |
- min_version = TLS1_2_VERSION;
|
|
|
3f476a |
- max_version = TLS1_2_VERSION;
|
|
|
3f476a |
+ method = TLSv1_2_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_2_server_method") {
|
|
|
3f476a |
- min_version = TLS1_2_VERSION;
|
|
|
3f476a |
- max_version = TLS1_2_VERSION;
|
|
|
3f476a |
- method = TLS_server_method();
|
|
|
3f476a |
+ method = TLSv1_2_server_method();
|
|
|
3f476a |
} else if (sslmethod == "TLSv1_2_client_method") {
|
|
|
3f476a |
- min_version = TLS1_2_VERSION;
|
|
|
3f476a |
- max_version = TLS1_2_VERSION;
|
|
|
3f476a |
- method = TLS_client_method();
|
|
|
3f476a |
+ method = TLSv1_2_client_method();
|
|
|
3f476a |
} else {
|
|
|
3f476a |
const std::string msg("Unknown method: ");
|
|
|
3f476a |
THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, (msg + * sslmethod).c_str());
|
|
|
effb77 |
@@ -686,8 +680,14 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
SSL_SESS_CACHE_NO_INTERNAL |
|
|
|
3f476a |
SSL_SESS_CACHE_NO_AUTO_CLEAR);
|
|
|
3f476a |
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ sc->_min_proto_version = min_version;
|
|
|
3f476a |
+ sc->_max_proto_version = max_version;
|
|
|
3f476a |
+ sc->_SyncMinMaxProto();
|
|
|
3f476a |
+#else
|
|
|
3f476a |
SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version);
|
|
|
3f476a |
SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version);
|
|
|
3f476a |
+#endif // !OPENSSL_IS_LEGACY
|
|
|
3f476a |
|
|
|
3f476a |
// OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
|
|
|
3f476a |
// exposed in the public API. To retain compatibility, install a callback
|
|
|
effb77 |
@@ -1232,6 +1232,10 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
|
|
|
f0ceb1 |
THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "ECDH curve name");
|
|
|
f0ceb1 |
|
|
|
f0ceb1 |
node::Utf8Value curve(env->isolate(), args[0]);
|
|
|
f0ceb1 |
+#if OPENSSL_IS_LEGACY
|
|
|
f0ceb1 |
+ SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_SINGLE_ECDH_USE);
|
|
|
f0ceb1 |
+ SSL_CTX_set_ecdh_auto(sc->ctx_.get(), 1);
|
|
|
f0ceb1 |
+#endif
|
|
|
f0ceb1 |
|
|
|
f0ceb1 |
if (strcmp(*curve, "auto") == 0)
|
|
|
f0ceb1 |
return;
|
|
|
effb77 |
@@ -1283,6 +1287,65 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
return env->ThrowTypeError("Error setting temp DH parameter");
|
|
|
3f476a |
}
|
|
|
3f476a |
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+int SecureContext::_SyncMinMaxProto() {
|
|
|
3f476a |
+ // Node explicitly disables SSLv2 and v3 – do not intefere with that
|
|
|
3f476a |
+ static const auto ALL_SUPPORTED_VERSIONS =
|
|
|
3f476a |
+ SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
|
|
|
3f476a |
+
|
|
|
3f476a |
+ auto mask = long(0);
|
|
|
3f476a |
+
|
|
|
3f476a |
+ // Setup minimum version
|
|
|
3f476a |
+ switch (_min_proto_version) {
|
|
|
3f476a |
+ default: return 0; // unsupported version
|
|
|
3f476a |
+ case TLS1_3_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_TLSv1_2;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case TLS1_2_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_TLSv1_1;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case TLS1_1_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_TLSv1;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case TLS1_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_SSLv3;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case SSL3_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_SSLv2;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case 0: // any supported version
|
|
|
3f476a |
+ break;
|
|
|
3f476a |
+ }
|
|
|
3f476a |
+
|
|
|
3f476a |
+ // Setup maximum version
|
|
|
3f476a |
+ switch (_max_proto_version) {
|
|
|
3f476a |
+ default: return 0; // unsupported version
|
|
|
3f476a |
+ case SSL3_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_TLSv1;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case TLS1_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_TLSv1_1;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case TLS1_1_VERSION:
|
|
|
3f476a |
+ mask |= SSL_OP_NO_TLSv1_2;
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case TLS1_2_VERSION:
|
|
|
3f476a |
+ // no-op, legacy OpenSSL does not know about TLSv1.3
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case TLS1_3_VERSION:
|
|
|
3f476a |
+ [[fallthrough]];
|
|
|
3f476a |
+ case 0: // any version
|
|
|
3f476a |
+ break;
|
|
|
3f476a |
+ }
|
|
|
3f476a |
+
|
|
|
3f476a |
+ // Reset current context mask
|
|
|
3f476a |
+ auto *raw_context = ctx_.get();
|
|
|
3f476a |
+ SSL_CTX_clear_options(raw_context, ALL_SUPPORTED_VERSIONS);
|
|
|
3f476a |
+ SSL_CTX_set_options(raw_context, mask);
|
|
|
3f476a |
+
|
|
|
3f476a |
+ return 1;
|
|
|
3f476a |
+}
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
|
|
|
3f476a |
void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
SecureContext* sc;
|
|
|
effb77 |
@@ -1293,7 +1356,12 @@ void SecureContext::SetMinProto(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
|
|
|
3f476a |
int version = args[0].As<Int32>()->Value();
|
|
|
3f476a |
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ sc->_min_proto_version = version;
|
|
|
3f476a |
+ CHECK(sc->_SyncMinMaxProto());
|
|
|
3f476a |
+#else // OPENSSL_IS_LEGACY
|
|
|
3f476a |
CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), version));
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
}
|
|
|
3f476a |
|
|
|
3f476a |
|
|
|
effb77 |
@@ -1306,7 +1374,12 @@ void SecureContext::SetMaxProto(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
|
|
|
3f476a |
int version = args[0].As<Int32>()->Value();
|
|
|
3f476a |
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ sc->_max_proto_version = version;
|
|
|
3f476a |
+ CHECK(sc->_SyncMinMaxProto());
|
|
|
3f476a |
+#else // OPENSSL_IS_LEGACY
|
|
|
3f476a |
CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), version));
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
}
|
|
|
3f476a |
|
|
|
3f476a |
|
|
|
effb77 |
@@ -1317,7 +1390,11 @@ void SecureContext::GetMinProto(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
CHECK_EQ(args.Length(), 0);
|
|
|
3f476a |
|
|
|
3f476a |
long version = // NOLINT(runtime/int)
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ sc->_min_proto_version;
|
|
|
3f476a |
+#else // OPENSSL_IS_LEGACY
|
|
|
3f476a |
SSL_CTX_get_min_proto_version(sc->ctx_.get());
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
args.GetReturnValue().Set(static_cast<uint32_t>(version));
|
|
|
3f476a |
}
|
|
|
3f476a |
|
|
|
effb77 |
@@ -1329,11 +1406,14 @@ void SecureContext::GetMaxProto(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
CHECK_EQ(args.Length(), 0);
|
|
|
3f476a |
|
|
|
3f476a |
long version = // NOLINT(runtime/int)
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ sc->_max_proto_version;
|
|
|
3f476a |
+#else // OPENSSL_IS_LEGACY
|
|
|
3f476a |
SSL_CTX_get_max_proto_version(sc->ctx_.get());
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
args.GetReturnValue().Set(static_cast<uint32_t>(version));
|
|
|
3f476a |
}
|
|
|
3f476a |
|
|
|
3f476a |
-
|
|
|
3f476a |
void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
SecureContext* sc;
|
|
|
3f476a |
ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
|
|
|
effb77 |
@@ -6883,8 +6963,72 @@ void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
|
|
|
3f476a |
CRYPTO_memcmp(buf1.data(), buf2.data(), buf1.length()) == 0);
|
|
|
3f476a |
}
|
|
|
3f476a |
|
|
|
3f476a |
+
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+// Array of mutexes provided for OpenSSL internal use
|
|
|
3f476a |
+static std::unique_ptr<Mutex[]> openssl_lock_array = nullptr;
|
|
|
3f476a |
+
|
|
|
3f476a |
+// OpenSSL callback – lock/unlock a mutex
|
|
|
3f476a |
+static void openssl_lock_callback(
|
|
|
3f476a |
+ int mode, int which, const char *file [[maybe_unused]], int line [[maybe_unused]])
|
|
|
3f476a |
+{
|
|
|
3f476a |
+ // Exactly one of CRYPTO_LOCK or CRYPTO_UNLOCK is set
|
|
|
3f476a |
+ CHECK(!(mode & CRYPTO_LOCK) ^ !(mode & CRYPTO_UNLOCK));
|
|
|
3f476a |
+ // Exactly one of CRYPTO_READ or CRYPTO_WRITE is set
|
|
|
3f476a |
+ CHECK(!(mode & CRYPTO_READ) ^ !(mode & CRYPTO_WRITE));
|
|
|
3f476a |
+ // FIXME: No easy way to make a array bounds check
|
|
|
3f476a |
+
|
|
|
3f476a |
+ auto mtx = &openssl_lock_array[which];
|
|
|
3f476a |
+ if (mode & CRYPTO_LOCK) {
|
|
|
3f476a |
+ mtx->Lock();
|
|
|
3f476a |
+ } else {
|
|
|
3f476a |
+ mtx->Unlock();
|
|
|
3f476a |
+ }
|
|
|
3f476a |
+}
|
|
|
3f476a |
+
|
|
|
3f476a |
+// OpenSSL callback - retrieve current thread ID
|
|
|
3f476a |
+static void openssl_threadid_callback(CRYPTO_THREADID *thread_id) {
|
|
|
3f476a |
+ static_assert(sizeof (uv_thread_t) <= sizeof (void *), "uv_thread_t does not fit in a pointer");
|
|
|
3f476a |
+ CRYPTO_THREADID_set_pointer(thread_id, reinterpret_cast<void *>(uv_thread_self()));
|
|
|
3f476a |
+}
|
|
|
3f476a |
+
|
|
|
3f476a |
+// Initialize (reset) the provided locking mechanism
|
|
|
3f476a |
+static void openssl_reset_locking() {
|
|
|
3f476a |
+ openssl_lock_array = std::make_unique<Mutex[]>(CRYPTO_num_locks());
|
|
|
3f476a |
+
|
|
|
3f476a |
+ CRYPTO_THREADID_set_callback(openssl_threadid_callback);
|
|
|
3f476a |
+ CRYPTO_set_locking_callback(openssl_lock_callback);
|
|
|
3f476a |
+}
|
|
|
3f476a |
+
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
+
|
|
|
3f476a |
void InitCryptoOnce() {
|
|
|
3f476a |
-#ifndef OPENSSL_IS_BORINGSSL
|
|
|
3f476a |
+#if defined(OPENSSL_IS_BORINGSSL) || OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ SSL_load_error_strings();
|
|
|
3f476a |
+ OPENSSL_no_config();
|
|
|
3f476a |
+
|
|
|
3f476a |
+ if (!per_process::cli_options->openssl_config.empty()) {
|
|
|
3f476a |
+ OPENSSL_load_builtin_modules();
|
|
|
3f476a |
+#ifndef OPENSSL_NO_ENGINE
|
|
|
3f476a |
+ ENGINE_load_builtin_engines();
|
|
|
3f476a |
+#endif // OPENSSL_NO_ENGINE
|
|
|
3f476a |
+ ERR_clear_error();
|
|
|
3f476a |
+
|
|
|
3f476a |
+ const char *conf_path = per_process::cli_options->openssl_config.c_str();
|
|
|
3f476a |
+ CONF_modules_load_file(conf_path, nullptr, CONF_MFLAGS_DEFAULT_SECTION);
|
|
|
3f476a |
+ auto err = ERR_get_error();
|
|
|
3f476a |
+ if (err != 0) {
|
|
|
3f476a |
+ fprintf(stderr, "openssl config failed: %s\n", ERR_error_string(err, nullptr));
|
|
|
3f476a |
+ CHECK_NE(err, 0);
|
|
|
3f476a |
+ }
|
|
|
3f476a |
+ }
|
|
|
3f476a |
+
|
|
|
3f476a |
+ // Initialize OpenSSL library
|
|
|
3f476a |
+ SSL_library_init();
|
|
|
3f476a |
+ OpenSSL_add_all_algorithms();
|
|
|
3f476a |
+ // Provide mutex array for OpenSSL
|
|
|
3f476a |
+ openssl_reset_locking();
|
|
|
3f476a |
+#else
|
|
|
3f476a |
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
|
|
|
3f476a |
|
|
|
3f476a |
// --openssl-config=...
|
|
|
3f476a |
diff --git a/src/node_crypto.h b/src/node_crypto.h
|
|
|
3f476a |
index dbc46fbec8..d27125042b 100644
|
|
|
3f476a |
--- a/src/node_crypto.h
|
|
|
3f476a |
+++ b/src/node_crypto.h
|
|
|
3f476a |
@@ -183,6 +183,20 @@ class SecureContext final : public BaseObject {
|
|
|
3f476a |
|
|
|
3f476a |
SecureContext(Environment* env, v8::Local<v8::Object> wrap);
|
|
|
3f476a |
void Reset();
|
|
|
3f476a |
+
|
|
|
3f476a |
+#if OPENSSL_IS_LEGACY
|
|
|
3f476a |
+ private:
|
|
|
3f476a |
+ // Legacy OpenSSL does not store min-max allowed versions of SSL/TLS;
|
|
|
3f476a |
+ // instead it relies on flags and enabling/disabling specific versions.
|
|
|
3f476a |
+ //
|
|
|
3f476a |
+ // In order to provide enough information for *getting* the allowed
|
|
|
3f476a |
+ // versions last set, record the boundaries on our secure context.
|
|
|
3f476a |
+ int _min_proto_version = 0;
|
|
|
3f476a |
+ int _max_proto_version = 0;
|
|
|
3f476a |
+
|
|
|
3f476a |
+ /** Sync _{min,max}_proto_version to wrapped context. */
|
|
|
3f476a |
+ int _SyncMinMaxProto();
|
|
|
3f476a |
+#endif // OPENSSL_IS_LEGACY
|
|
|
3f476a |
};
|
|
|
3f476a |
|
|
|
3f476a |
// SSLWrap implicitly depends on the inheriting class' handle having an
|
|
|
3f476a |
--
|
|
|
effb77 |
2.36.1
|
|
|
3f476a |
|