diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index 7fef8191593..d3d00794105 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -72,31 +72,26 @@ void X509Certificate::_bind_methods() { Ref TLSOptions::client(Ref p_trusted_chain, const String &p_common_name_override) { Ref opts; opts.instantiate(); + opts->mode = MODE_CLIENT; opts->trusted_ca_chain = p_trusted_chain; opts->common_name = p_common_name_override; - opts->verify_mode = TLS_VERIFY_FULL; return opts; } Ref TLSOptions::client_unsafe(Ref p_trusted_chain) { Ref opts; opts.instantiate(); + opts->mode = MODE_CLIENT_UNSAFE; opts->trusted_ca_chain = p_trusted_chain; - if (p_trusted_chain.is_null()) { - opts->verify_mode = TLS_VERIFY_NONE; - } else { - opts->verify_mode = TLS_VERIFY_CERT; - } return opts; } Ref TLSOptions::server(Ref p_own_key, Ref p_own_certificate) { Ref opts; opts.instantiate(); - opts->server_mode = true; + opts->mode = MODE_SERVER; opts->own_certificate = p_own_certificate; opts->private_key = p_own_key; - opts->verify_mode = TLS_VERIFY_NONE; return opts; } @@ -104,6 +99,13 @@ void TLSOptions::_bind_methods() { ClassDB::bind_static_method("TLSOptions", D_METHOD("client", "trusted_chain", "common_name_override"), &TLSOptions::client, DEFVAL(Ref()), DEFVAL(String())); ClassDB::bind_static_method("TLSOptions", D_METHOD("client_unsafe", "trusted_chain"), &TLSOptions::client_unsafe, DEFVAL(Ref())); ClassDB::bind_static_method("TLSOptions", D_METHOD("server", "key", "certificate"), &TLSOptions::server); + + ClassDB::bind_method(D_METHOD("is_server"), &TLSOptions::is_server); + ClassDB::bind_method(D_METHOD("is_unsafe_client"), &TLSOptions::is_unsafe_client); + ClassDB::bind_method(D_METHOD("get_common_name_override"), &TLSOptions::get_common_name_override); + ClassDB::bind_method(D_METHOD("get_trusted_ca_chain"), &TLSOptions::get_trusted_ca_chain); + ClassDB::bind_method(D_METHOD("get_private_key"), &TLSOptions::get_private_key); + ClassDB::bind_method(D_METHOD("get_own_certificate"), &TLSOptions::get_own_certificate); } /// HMACContext diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index fbd01be86dc..16649422cff 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -72,17 +72,15 @@ public: class TLSOptions : public RefCounted { GDCLASS(TLSOptions, RefCounted); -public: - enum TLSVerifyMode { - TLS_VERIFY_NONE = 0, - TLS_VERIFY_CERT = 1, - TLS_VERIFY_FULL = 2, +private: + enum Mode { + MODE_CLIENT = 0, + MODE_CLIENT_UNSAFE = 1, + MODE_SERVER = 2, }; -private: - bool server_mode = false; + Mode mode = MODE_CLIENT; String common_name; - TLSVerifyMode verify_mode = TLS_VERIFY_FULL; Ref trusted_ca_chain; Ref own_certificate; Ref private_key; @@ -95,12 +93,12 @@ public: static Ref client_unsafe(Ref p_trusted_chain); static Ref server(Ref p_own_key, Ref p_own_certificate); - TLSVerifyMode get_verify_mode() const { return verify_mode; } - String get_common_name() const { return common_name; } + String get_common_name_override() const { return common_name; } Ref get_trusted_ca_chain() const { return trusted_ca_chain; } Ref get_own_certificate() const { return own_certificate; } Ref get_private_key() const { return private_key; } - bool is_server() const { return server_mode; } + bool is_server() const { return mode == MODE_SERVER; } + bool is_unsafe_client() const { return mode == MODE_CLIENT_UNSAFE; } }; class HMACContext : public RefCounted { diff --git a/doc/classes/TLSOptions.xml b/doc/classes/TLSOptions.xml index aed100ec077..3bc0bb7e03c 100644 --- a/doc/classes/TLSOptions.xml +++ b/doc/classes/TLSOptions.xml @@ -40,6 +40,42 @@ [b]Note:[/b] On the Web platform, TLS verification is always enforced against the CA list of the web browser. This is considered a security feature. + + + + Returns the common name (domain name) override specified when creating with [method TLSOptions.client]. + + + + + + Returns the [X509Certificate] specified when creating with [method TLSOptions.server]. + + + + + + Returns the [CryptoKey] specified when creating with [method TLSOptions.server]. + + + + + + Returns the CA [X509Certificate] chain specified when creating with [method TLSOptions.client] or [method TLSOptions.client_unsafe]. + + + + + + Returns [code]true[/code] if created with [method TLSOptions.server], [code]false[/code] otherwise. + + + + + + Returns [code]true[/code] if created with [method TLSOptions.client_unsafe], [code]false[/code] otherwise. + + diff --git a/modules/mbedtls/tls_context_mbedtls.cpp b/modules/mbedtls/tls_context_mbedtls.cpp index aab082f488d..eaea7b92933 100644 --- a/modules/mbedtls/tls_context_mbedtls.cpp +++ b/modules/mbedtls/tls_context_mbedtls.cpp @@ -152,21 +152,23 @@ Error TLSContextMbedTLS::init_client(int p_transport, const String &p_hostname, ERR_FAIL_COND_V(p_options.is_null() || p_options->is_server(), ERR_INVALID_PARAMETER); int authmode = MBEDTLS_SSL_VERIFY_REQUIRED; - if (p_options->get_verify_mode() == TLSOptions::TLS_VERIFY_NONE) { + bool unsafe = p_options->is_unsafe_client(); + if (unsafe && p_options->get_trusted_ca_chain().is_valid()) { authmode = MBEDTLS_SSL_VERIFY_NONE; } Error err = _setup(MBEDTLS_SSL_IS_CLIENT, p_transport, authmode); ERR_FAIL_COND_V(err != OK, err); - if (p_options->get_verify_mode() == TLSOptions::TLS_VERIFY_FULL) { - String cn = p_options->get_common_name(); + if (unsafe) { + // No hostname verification for unsafe clients. + mbedtls_ssl_set_hostname(&tls, nullptr); + } else { + String cn = p_options->get_common_name_override(); if (cn.is_empty()) { cn = p_hostname; } mbedtls_ssl_set_hostname(&tls, cn.utf8().get_data()); - } else { - mbedtls_ssl_set_hostname(&tls, nullptr); } X509CertificateMbedTLS *cas = nullptr;