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