Merge pull request #93178 from Faless/crypto/expose_tls_options_getters

[Crypto] Expose TLSOptions getters
This commit is contained in:
Rémi Verschelde 2024-06-17 10:58:51 +02:00
commit c3336aa110
No known key found for this signature in database
GPG Key ID: C3336907360768E1
4 changed files with 62 additions and 24 deletions

View File

@ -72,31 +72,26 @@ void X509Certificate::_bind_methods() {
Ref<TLSOptions> TLSOptions::client(Ref<X509Certificate> p_trusted_chain, const String &p_common_name_override) { Ref<TLSOptions> TLSOptions::client(Ref<X509Certificate> p_trusted_chain, const String &p_common_name_override) {
Ref<TLSOptions> opts; Ref<TLSOptions> opts;
opts.instantiate(); opts.instantiate();
opts->mode = MODE_CLIENT;
opts->trusted_ca_chain = p_trusted_chain; opts->trusted_ca_chain = p_trusted_chain;
opts->common_name = p_common_name_override; opts->common_name = p_common_name_override;
opts->verify_mode = TLS_VERIFY_FULL;
return opts; return opts;
} }
Ref<TLSOptions> TLSOptions::client_unsafe(Ref<X509Certificate> p_trusted_chain) { Ref<TLSOptions> TLSOptions::client_unsafe(Ref<X509Certificate> p_trusted_chain) {
Ref<TLSOptions> opts; Ref<TLSOptions> opts;
opts.instantiate(); opts.instantiate();
opts->mode = MODE_CLIENT_UNSAFE;
opts->trusted_ca_chain = p_trusted_chain; 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; return opts;
} }
Ref<TLSOptions> TLSOptions::server(Ref<CryptoKey> p_own_key, Ref<X509Certificate> p_own_certificate) { Ref<TLSOptions> TLSOptions::server(Ref<CryptoKey> p_own_key, Ref<X509Certificate> p_own_certificate) {
Ref<TLSOptions> opts; Ref<TLSOptions> opts;
opts.instantiate(); opts.instantiate();
opts->server_mode = true; opts->mode = MODE_SERVER;
opts->own_certificate = p_own_certificate; opts->own_certificate = p_own_certificate;
opts->private_key = p_own_key; opts->private_key = p_own_key;
opts->verify_mode = TLS_VERIFY_NONE;
return opts; 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<X509Certificate>()), DEFVAL(String())); ClassDB::bind_static_method("TLSOptions", D_METHOD("client", "trusted_chain", "common_name_override"), &TLSOptions::client, DEFVAL(Ref<X509Certificate>()), DEFVAL(String()));
ClassDB::bind_static_method("TLSOptions", D_METHOD("client_unsafe", "trusted_chain"), &TLSOptions::client_unsafe, DEFVAL(Ref<X509Certificate>())); ClassDB::bind_static_method("TLSOptions", D_METHOD("client_unsafe", "trusted_chain"), &TLSOptions::client_unsafe, DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_static_method("TLSOptions", D_METHOD("server", "key", "certificate"), &TLSOptions::server); 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 /// HMACContext

View File

@ -72,17 +72,15 @@ public:
class TLSOptions : public RefCounted { class TLSOptions : public RefCounted {
GDCLASS(TLSOptions, RefCounted); GDCLASS(TLSOptions, RefCounted);
public: private:
enum TLSVerifyMode { enum Mode {
TLS_VERIFY_NONE = 0, MODE_CLIENT = 0,
TLS_VERIFY_CERT = 1, MODE_CLIENT_UNSAFE = 1,
TLS_VERIFY_FULL = 2, MODE_SERVER = 2,
}; };
private: Mode mode = MODE_CLIENT;
bool server_mode = false;
String common_name; String common_name;
TLSVerifyMode verify_mode = TLS_VERIFY_FULL;
Ref<X509Certificate> trusted_ca_chain; Ref<X509Certificate> trusted_ca_chain;
Ref<X509Certificate> own_certificate; Ref<X509Certificate> own_certificate;
Ref<CryptoKey> private_key; Ref<CryptoKey> private_key;
@ -95,12 +93,12 @@ public:
static Ref<TLSOptions> client_unsafe(Ref<X509Certificate> p_trusted_chain); static Ref<TLSOptions> client_unsafe(Ref<X509Certificate> p_trusted_chain);
static Ref<TLSOptions> server(Ref<CryptoKey> p_own_key, Ref<X509Certificate> p_own_certificate); static Ref<TLSOptions> server(Ref<CryptoKey> p_own_key, Ref<X509Certificate> p_own_certificate);
TLSVerifyMode get_verify_mode() const { return verify_mode; } String get_common_name_override() const { return common_name; }
String get_common_name() const { return common_name; }
Ref<X509Certificate> get_trusted_ca_chain() const { return trusted_ca_chain; } Ref<X509Certificate> get_trusted_ca_chain() const { return trusted_ca_chain; }
Ref<X509Certificate> get_own_certificate() const { return own_certificate; } Ref<X509Certificate> get_own_certificate() const { return own_certificate; }
Ref<CryptoKey> get_private_key() const { return private_key; } Ref<CryptoKey> 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 { class HMACContext : public RefCounted {

View File

@ -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. [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.
</description> </description>
</method> </method>
<method name="get_common_name_override" qualifiers="const">
<return type="String" />
<description>
Returns the common name (domain name) override specified when creating with [method TLSOptions.client].
</description>
</method>
<method name="get_own_certificate" qualifiers="const">
<return type="X509Certificate" />
<description>
Returns the [X509Certificate] specified when creating with [method TLSOptions.server].
</description>
</method>
<method name="get_private_key" qualifiers="const">
<return type="CryptoKey" />
<description>
Returns the [CryptoKey] specified when creating with [method TLSOptions.server].
</description>
</method>
<method name="get_trusted_ca_chain" qualifiers="const">
<return type="X509Certificate" />
<description>
Returns the CA [X509Certificate] chain specified when creating with [method TLSOptions.client] or [method TLSOptions.client_unsafe].
</description>
</method>
<method name="is_server" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if created with [method TLSOptions.server], [code]false[/code] otherwise.
</description>
</method>
<method name="is_unsafe_client" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if created with [method TLSOptions.client_unsafe], [code]false[/code] otherwise.
</description>
</method>
<method name="server" qualifiers="static"> <method name="server" qualifiers="static">
<return type="TLSOptions" /> <return type="TLSOptions" />
<param index="0" name="key" type="CryptoKey" /> <param index="0" name="key" type="CryptoKey" />

View File

@ -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); ERR_FAIL_COND_V(p_options.is_null() || p_options->is_server(), ERR_INVALID_PARAMETER);
int authmode = MBEDTLS_SSL_VERIFY_REQUIRED; 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; authmode = MBEDTLS_SSL_VERIFY_NONE;
} }
Error err = _setup(MBEDTLS_SSL_IS_CLIENT, p_transport, authmode); Error err = _setup(MBEDTLS_SSL_IS_CLIENT, p_transport, authmode);
ERR_FAIL_COND_V(err != OK, err); ERR_FAIL_COND_V(err != OK, err);
if (p_options->get_verify_mode() == TLSOptions::TLS_VERIFY_FULL) { if (unsafe) {
String cn = p_options->get_common_name(); // 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()) { if (cn.is_empty()) {
cn = p_hostname; cn = p_hostname;
} }
mbedtls_ssl_set_hostname(&tls, cn.utf8().get_data()); mbedtls_ssl_set_hostname(&tls, cn.utf8().get_data());
} else {
mbedtls_ssl_set_hostname(&tls, nullptr);
} }
X509CertificateMbedTLS *cas = nullptr; X509CertificateMbedTLS *cas = nullptr;