Moved the usage of certificate provider into the server listener (#1652)

* Moved the usage of certificate provider into the server listener so that each connection has the posibility of receiving a new SSL cert.

* Removed warning from unused field.

* Reduced changeds on original codebase.

---------

Co-authored-by: Jeff Scherrer <Jeff.Scherrer@vw.com>
This commit is contained in:
Jeffery Michael
2023-01-28 12:18:31 +01:00
committed by GitHub
co-authored by Jeff Scherrer
parent 0234918f30
commit 73f118fe1c
4 changed files with 238 additions and 14 deletions
@@ -14,6 +14,7 @@ using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Internal;
using MQTTnet.Certificates;
namespace MQTTnet.Implementations
{
@@ -38,7 +39,7 @@ namespace MQTTnet.Implementations
if (options.DefaultEndpointOptions.IsEnabled)
{
RegisterListeners(options.DefaultEndpointOptions, null, logger, _cancellationTokenSource.Token);
RegisterListeners(options.DefaultEndpointOptions, logger, _cancellationTokenSource.Token);
}
if (options.TlsEndpointOptions?.IsEnabled == true)
@@ -48,13 +49,7 @@ namespace MQTTnet.Implementations
throw new ArgumentException("TLS certificate is not set.");
}
var tlsCertificate = options.TlsEndpointOptions.CertificateProvider.GetCertificate();
if (!tlsCertificate.HasPrivateKey)
{
throw new InvalidOperationException("The certificate for TLS encryption must contain the private key.");
}
RegisterListeners(options.TlsEndpointOptions, tlsCertificate, logger, _cancellationTokenSource.Token);
RegisterListeners(options.TlsEndpointOptions, logger, _cancellationTokenSource.Token);
}
return CompletedTask.Instance;
@@ -91,11 +86,12 @@ namespace MQTTnet.Implementations
}
}
void RegisterListeners(MqttServerTcpEndpointBaseOptions tcpEndpointOptions, X509Certificate2 tlsCertificate, IMqttNetLogger logger, CancellationToken cancellationToken)
void RegisterListeners(MqttServerTcpEndpointBaseOptions tcpEndpointOptions, IMqttNetLogger logger, CancellationToken cancellationToken)
{
if (!tcpEndpointOptions.BoundInterNetworkAddress.Equals(IPAddress.None))
{
var listenerV4 = new MqttTcpServerListener(AddressFamily.InterNetwork, _serverOptions, tcpEndpointOptions, tlsCertificate, logger)
var listenerV4 = new MqttTcpServerListener(AddressFamily.InterNetwork, _serverOptions, tcpEndpointOptions, logger)
{
ClientHandler = OnClientAcceptedAsync
};
@@ -108,7 +104,7 @@ namespace MQTTnet.Implementations
if (!tcpEndpointOptions.BoundInterNetworkV6Address.Equals(IPAddress.None))
{
var listenerV6 = new MqttTcpServerListener(AddressFamily.InterNetworkV6, _serverOptions, tcpEndpointOptions, tlsCertificate, logger)
var listenerV6 = new MqttTcpServerListener(AddressFamily.InterNetworkV6, _serverOptions, tcpEndpointOptions, logger)
{
ClientHandler = OnClientAcceptedAsync
};
@@ -4,6 +4,7 @@
#if !WINDOWS_UWP
using MQTTnet.Adapter;
using MQTTnet.Certificates;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
using MQTTnet.Internal;
@@ -27,7 +28,7 @@ namespace MQTTnet.Implementations
readonly MqttServerOptions _serverOptions;
readonly MqttServerTcpEndpointBaseOptions _options;
readonly MqttServerTlsTcpEndpointOptions _tlsOptions;
readonly X509Certificate2 _tlsCertificate;
X509Certificate2 _tlsCertificate;
CrossPlatformSocket _socket;
IPEndPoint _localEndPoint;
@@ -36,19 +37,18 @@ namespace MQTTnet.Implementations
AddressFamily addressFamily,
MqttServerOptions serverOptions,
MqttServerTcpEndpointBaseOptions tcpEndpointOptions,
X509Certificate2 tlsCertificate,
IMqttNetLogger logger)
{
_addressFamily = addressFamily;
_serverOptions = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
_options = tcpEndpointOptions ?? throw new ArgumentNullException(nameof(tcpEndpointOptions));
_tlsCertificate = tlsCertificate;
_rootLogger = logger;
_logger = logger.WithSource(nameof(MqttTcpServerListener));
if (_options is MqttServerTlsTcpEndpointOptions tlsOptions)
{
_tlsOptions = tlsOptions;
_tlsCertificate = _tlsOptions.CertificateProvider.GetCertificate();
}
}
@@ -194,8 +194,26 @@ namespace MQTTnet.Implementations
stream = clientSocket.GetStream();
X509Certificate2 clientCertificate = null;
if (_tlsOptions.CertificateProvider != null)
{
var tlsCertificate = _tlsOptions.CertificateProvider.GetCertificate();
if (tlsCertificate != _tlsCertificate)
{
var oldTlsCertificate = _tlsCertificate;
_tlsCertificate = tlsCertificate;
#if !NET452
oldTlsCertificate.Dispose();
#endif
}
}
if (_tlsCertificate != null)
{
if (!_tlsCertificate.HasPrivateKey)
{
throw new InvalidOperationException("The certificate for TLS encryption must contain the private key.");
}
var sslStream = new SslStream(stream, false, _tlsOptions.RemoteCertificateValidationCallback);
#if NETCOREAPP3_1_OR_GREATER