MQTTnet
MQTTnet copied to clipboard
Connection to mosquitto using tls1.3 with only ca.crt
I am working on an app which is to connect to a mosquitto broker using tls1.3. I will only get a ca.crt from the broker and no client certificates will be used. My 1st question is am I doing it in a correct way (code below) as I could not find any example of connection using only a ca.crt. My 2nd question is, When I use below code and configuration I keep getting the following exception: "The client and server cannot communicate, because they do not possess a common algorithm". The exception does not change when I downgrade to tls1.2. Also, when I try to connect using a python app it works like a charm.
I am using .NetFramework 4.6.2,
mosquitto.conf
acl_file ./configs/acl.acl
password_file ./configs/pwfile
allow_anonymous false
listener 8883
cafile ./certs/ca.crt
certfile ./certs/root.crt
keyfile ./certs/root.key
tls_version tlsv1.3
I am creating the client in the following way:
ServicePointManager.SecurityProtocol = (SecurityProtocolType) 12288;
var caCert = X509Certificate.CreateFromSignedFile(CertificatePath);
var mqttFactory = new MqttFactory();
var tlsOptions = new MqttClientTlsOptions
{
UseTls = true,
Certificates = new List<X509Certificate> { caCert },
SslProtocol = (SslProtocols)12288,
CertificateValidationHandler = delegate { return true; },
IgnoreCertificateChainErrors = true,
IgnoreCertificateRevocationErrors = true,
AllowUntrustedCertificates = true
};
var options = new MqttClientOptions
{
ClientId = clientId,
ProtocolVersion = MqttProtocolVersion.V311,
ChannelOptions = new MqttClientTcpOptions
{
Server = "localhost",
Port = 8883,
TlsOptions = tlsOptions
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
options.Credentials = new MqttClientCredentials
{
Username = "username",
Password = Encoding.UTF8.GetBytes("password")
};
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
var client = mqttFactory.CreateMqttClient();
client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(ShowConnected);
client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(ShowDisConnected);
await client.ConnectAsync(options);
I'm also trying to connect to the free emqx broker (https://www.emqx.io/mqtt/public-mqtt5-broker), but I cannot connect using TLS. Even if I download the certificate and add it to the TLSBuilder, it doesn't work.
Here is the code I am using:
public Client(ClientConfiguration configuration) {
Logger = new MqttNetLogger();
Logger.LogMessagePublished += Logger_LogMessagePublished;
_client = _mqttFactory.CreateManagedMqttClient(Logger);
Configuration = configuration;
IMqttClientOptions clientOptions;
MqttClientOptionsBuilder clientOptionsBuilder;
ManagedMqttClientOptionsBuilder managedOptionsBuilder;
MqttClientOptionsBuilderTlsParameters tlsBuilder;
clientOptionsBuilder = new MqttClientOptionsBuilder()
.WithClientId(Configuration.ClientID)
.WithTcpServer(Configuration.BrokerAddress, Configuration.BrokerPort)
.WithCleanSession()
.WithProtocolVersion(configuration.MqttProtocolVersion);
if (configuration.EncryptionProtocol != System.Security.Authentication.SslProtocols.None)
{
tlsBuilder = new MqttClientOptionsBuilderTlsParameters();
tlsBuilder.UseTls = true;
tlsBuilder.AllowUntrustedCertificates = true;
tlsBuilder.CertificateValidationHandler = CertificateValidationHandler;
if (!string.IsNullOrEmpty(configuration.CertificateFile))
{
tlsBuilder.Certificates = new List<X509Certificate>() { X509Certificate.CreateFromCertFile(configuration.CertificateFile) };
}
tlsBuilder.IgnoreCertificateChainErrors = true;
tlsBuilder.IgnoreCertificateRevocationErrors = true;
tlsBuilder.SslProtocol = Configuration.EncryptionProtocol;
clientOptionsBuilder.WithTls(tlsBuilder);
}
if (configuration.UseCredentials)
clientOptionsBuilder.WithCredentials(configuration.LoginName, configuration.LoginPassword);
clientOptions = clientOptionsBuilder.Build();
managedOptionsBuilder = new ManagedMqttClientOptionsBuilder()
.WithClientOptions(clientOptions)
.WithAutoReconnectDelay(new TimeSpan(0, 0, 0, 0, Configuration.ReconnectDelay))
.WithPendingMessagesOverflowStrategy(MQTTnet.Server.MqttPendingMessagesOverflowStrategy.DropOldestQueuedMessage);
if (configuration.UseMessageStorage)
managedOptionsBuilder.WithStorage(new RetainedClientMessageStorage(configuration.MessageStorageFilePath));
_managedOptions = managedOptionsBuilder.Build();
_client.UseConnectedHandler(e => InternalClientConnected(e));
_client.UseDisconnectedHandler(e => InternalClientDisconnected(e));
_client.UseApplicationMessageReceivedHandler(e => NewMessage(e));
}
Other applications work the added certificate or with the open CA server signed certificate.
There are the only errors I get:
5/19/2021 3:19:02 PM 32060031: Start client... 5/19/2021 3:19:02 PM 32060031: Cleaning up... 5/19/2021 3:19:02 PM 32060031: Started 5/19/2021 3:19:02 PM 32060031: Trying to connect with server 'broker.emqx.io:8883' (Timeout=00:00:10). 5/19/2021 3:19:02 PM 32060046: Error while connecting with server. 5/19/2021 3:19:02 PM 32060046: Disconnecting [Timeout=00:00:10] 5/19/2021 3:19:02 PM 32060046: Disconnected from adapter. 5/19/2021 3:19:02 PM 32060046: Disconnected. 5/19/2021 3:19:02 PM 32060046: Stopped 5/19/2021 3:19:42 PM 32100062: Initializing...
Here's a simple example may help you as a reference: https://github.com/emqx/MQTT-Client-Examples/blob/master/mqtt-client-Csharp-MqttNet/mqtt-client-Csharp-MqttNet/Program.cs