From 3ea307b11d34acd2c54f45c49246e56f7c9cafc8 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 29 Dec 2023 15:31:06 +0100 Subject: [PATCH] Add support for X.509 Client Certificates --- .../Client/HiveMQClientOptionsBuilder.cs | 39 +++++++++++++++++++ Source/HiveMQtt/Client/HiveMQClientSocket.cs | 1 + .../Client/Options/HiveMQClientOptions.cs | 7 +++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Source/HiveMQtt/Client/HiveMQClientOptionsBuilder.cs b/Source/HiveMQtt/Client/HiveMQClientOptionsBuilder.cs index 62694686..cafbad82 100644 --- a/Source/HiveMQtt/Client/HiveMQClientOptionsBuilder.cs +++ b/Source/HiveMQtt/Client/HiveMQClientOptionsBuilder.cs @@ -15,6 +15,7 @@ */ namespace HiveMQtt.Client; +using System.Security.Cryptography.X509Certificates; using HiveMQtt.Client.Options; /// @@ -130,6 +131,44 @@ public HiveMQClientOptionsBuilder WithUseTls(bool useTls) return this; } + /// + /// Adds an X.509 certificate to be used for client authentication. This can be called + /// multiple times to add multiple certificates. + /// + /// The client X.509 certificate to be used for client authentication. + /// The HiveMQClientOptionsBuilder instance. + public HiveMQClientOptionsBuilder WithClientCertificate(X509Certificate2 clientCertificate) + { + this.options.ClientCertificates.Add(clientCertificate); + return this; + } + + /// + /// Adds a list of X.509 certificates to be used for client authentication. + /// + /// The list of client X.509 certificates to be used for client authentication. + /// The HiveMQClientOptionsBuilder instance. + public HiveMQClientOptionsBuilder WithClientCertificates(List clientCertificates) + { + foreach (var certificate in clientCertificates) + { + this.options.ClientCertificates.Add(certificate); + } + + return this; + } + + /// + /// Adds an X.509 certificate to be used for client authentication. + /// + /// The path to the client X.509 certificate to be used for client authentication. + /// The HiveMQClientOptionsBuilder instance. + public HiveMQClientOptionsBuilder WithClientCertificate(string clientCertificatePath) + { + this.options.ClientCertificates.Add(new X509Certificate2(clientCertificatePath)); + return this; + } + /// /// Sets whether to use a clean start. /// diff --git a/Source/HiveMQtt/Client/HiveMQClientSocket.cs b/Source/HiveMQtt/Client/HiveMQClientSocket.cs index 070f12d1..2d1f02c0 100644 --- a/Source/HiveMQtt/Client/HiveMQClientSocket.cs +++ b/Source/HiveMQtt/Client/HiveMQClientSocket.cs @@ -198,6 +198,7 @@ private async Task CreateTLSConnectionAsync(Stream stream) { TargetHost = this.Options.Host, EnabledSslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12, + ClientCertificates = this.Options.ClientCertificates, }; if (this.Options.AllowInvalidBrokerCertificates) diff --git a/Source/HiveMQtt/Client/Options/HiveMQClientOptions.cs b/Source/HiveMQtt/Client/Options/HiveMQClientOptions.cs index 5bec723e..3e51eef8 100644 --- a/Source/HiveMQtt/Client/Options/HiveMQClientOptions.cs +++ b/Source/HiveMQtt/Client/Options/HiveMQClientOptions.cs @@ -17,7 +17,7 @@ namespace HiveMQtt.Client.Options; using System; using System.Linq; - +using System.Security.Cryptography.X509Certificates; using HiveMQtt.Client; using HiveMQtt.Client.Exceptions; @@ -156,6 +156,11 @@ public HiveMQClientOptions() /// public bool UseTLS { get; set; } + /// + /// Gets or sets the collection of client X509 certificates. + /// + public X509CertificateCollection ClientCertificates { get; set; } + /// /// Gets or sets a value indicating whether the MQTT client should allow invalid broker TLS certificates. ///