[NET] Refactor TLS configuration.

Use a TLSOptions configuration object which is created via static
functions.

- "TLSOptions.client": uses the standard CA and common name verification.
- "TLSOptions.client_unsafe": uses optional CA verification (i.e. if specified)
- "TLSOptions.server": is the standard server configuration (chain + key)

This will allow us to expand the TLS configuration options to include
e.g. mutual authentication without bloating the classes that uses
StreamPeerTLS and PacketPeerDTLS as underlying peers.
This commit is contained in:
Fabio Alessandrelli
2023-01-20 01:51:35 +01:00
parent 2afa175195
commit adba870534
47 changed files with 338 additions and 203 deletions

View File

@@ -84,19 +84,17 @@
</method>
<method name="dtls_client_setup">
<return type="int" enum="Error" />
<param index="0" name="certificate" type="X509Certificate" />
<param index="1" name="hostname" type="String" />
<param index="2" name="verify" type="bool" default="true" />
<param index="0" name="hostname" type="String" />
<param index="1" name="client_options" type="TLSOptions" default="null" />
<description>
Configure this ENetHost to use the custom Godot extension allowing DTLS encryption for ENet clients. Call this before [method connect_to_host] to have ENet connect using DTLS with [code]certificate[/code] and [code]hostname[/code] verification. Verification can be optionally turned off via the [code]verify[/code] parameter.
Configure this ENetHost to use the custom Godot extension allowing DTLS encryption for ENet clients. Call this before [method connect_to_host] to have ENet connect using DTLS validating the server certificate against [code]hostname[/code]. You can pass the optional [param client_options] parameter to customize the trusted certification authorities, or disable the common name verification. See [method TLSOptions.client] and [method TLSOptions.client_unsafe].
</description>
</method>
<method name="dtls_server_setup">
<return type="int" enum="Error" />
<param index="0" name="key" type="CryptoKey" />
<param index="1" name="certificate" type="X509Certificate" />
<param index="0" name="server_options" type="TLSOptions" />
<description>
Configure this ENetHost to use the custom Godot extension allowing DTLS encryption for ENet servers. Call this right after [method create_host_bound] to have ENet expect peers to connect using DTLS.
Configure this ENetHost to use the custom Godot extension allowing DTLS encryption for ENet servers. Call this right after [method create_host_bound] to have ENet expect peers to connect using DTLS. See [method TLSOptions.server].
</description>
</method>
<method name="flush">

View File

@@ -273,10 +273,11 @@ TypedArray<ENetPacketPeer> ENetConnection::_get_peers() {
return out;
}
Error ENetConnection::dtls_server_setup(Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert) {
Error ENetConnection::dtls_server_setup(const Ref<TLSOptions> &p_options) {
#ifdef GODOT_ENET
ERR_FAIL_COND_V_MSG(!host, ERR_UNCONFIGURED, "The ENetConnection instance isn't currently active.");
return enet_host_dtls_server_setup(host, p_key.ptr(), p_cert.ptr()) ? FAILED : OK;
ERR_FAIL_COND_V(p_options.is_null() || !p_options->is_server(), ERR_INVALID_PARAMETER);
return enet_host_dtls_server_setup(host, const_cast<TLSOptions *>(p_options.ptr())) ? FAILED : OK;
#else
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "ENet DTLS support not available in this build.");
#endif
@@ -291,10 +292,11 @@ void ENetConnection::refuse_new_connections(bool p_refuse) {
#endif
}
Error ENetConnection::dtls_client_setup(Ref<X509Certificate> p_cert, const String &p_hostname, bool p_verify) {
Error ENetConnection::dtls_client_setup(const String &p_hostname, const Ref<TLSOptions> &p_options) {
#ifdef GODOT_ENET
ERR_FAIL_COND_V_MSG(!host, ERR_UNCONFIGURED, "The ENetConnection instance isn't currently active.");
return enet_host_dtls_client_setup(host, p_cert.ptr(), p_verify, p_hostname.utf8().get_data()) ? FAILED : OK;
ERR_FAIL_COND_V(p_options.is_null() || p_options->is_server(), ERR_INVALID_PARAMETER);
return enet_host_dtls_client_setup(host, p_hostname.utf8().get_data(), const_cast<TLSOptions *>(p_options.ptr())) ? FAILED : OK;
#else
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "ENet DTLS support not available in this build.");
#endif
@@ -351,8 +353,8 @@ void ENetConnection::_bind_methods() {
ClassDB::bind_method(D_METHOD("channel_limit", "limit"), &ENetConnection::channel_limit);
ClassDB::bind_method(D_METHOD("broadcast", "channel", "packet", "flags"), &ENetConnection::_broadcast);
ClassDB::bind_method(D_METHOD("compress", "mode"), &ENetConnection::compress);
ClassDB::bind_method(D_METHOD("dtls_server_setup", "key", "certificate"), &ENetConnection::dtls_server_setup);
ClassDB::bind_method(D_METHOD("dtls_client_setup", "certificate", "hostname", "verify"), &ENetConnection::dtls_client_setup, DEFVAL(true));
ClassDB::bind_method(D_METHOD("dtls_server_setup", "server_options"), &ENetConnection::dtls_server_setup);
ClassDB::bind_method(D_METHOD("dtls_client_setup", "hostname", "client_options"), &ENetConnection::dtls_client_setup, DEFVAL(Ref<TLSOptions>()));
ClassDB::bind_method(D_METHOD("refuse_new_connections", "refuse"), &ENetConnection::refuse_new_connections);
ClassDB::bind_method(D_METHOD("pop_statistic", "statistic"), &ENetConnection::pop_statistic);
ClassDB::bind_method(D_METHOD("get_max_channels"), &ENetConnection::get_max_channels);

View File

@@ -128,8 +128,8 @@ public:
int get_local_port() const;
// Godot additions
Error dtls_server_setup(Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert);
Error dtls_client_setup(Ref<X509Certificate> p_cert, const String &p_hostname, bool p_verify = true);
Error dtls_server_setup(const Ref<TLSOptions> &p_options);
Error dtls_client_setup(const String &p_hostname, const Ref<TLSOptions> &p_options);
void refuse_new_connections(bool p_refuse);
ENetConnection() {}