MQTTnet
MQTTnet copied to clipboard
SSL/TLS Handshake Fails when Connecting with MQTTnet
Describe your question
The following command works perfectly well when sending a message to my EMQX server:
mosquitto_pub -h "dummyserver.com" -p 8883 -t "peaches" -m "Hello World" -u "dummyuser" -P 'dummypassword' --cafile ca.pem --cert client.pem --key client.key
I'm trying to replicate the above in a C# function:
const string serverIp = "dummyserver.com";
const int port = 8883;
const string topic = "peaches";
const string message = "Hello World";
const string username = "dummyuser";
const string password = "dummypassword";
// eg: /home/user/src/pem
string sslFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "src", "pem");
string capem = Path.Combine(sslFolderPath, "ca.pem");
string clientpem = Path.Combine(sslFolderPath, "client.pem");
string clientkey = Path.Combine(sslFolderPath, "client.key");
// Validate inputs
if (string.IsNullOrEmpty(topic) || string.IsNullOrEmpty(message))
{
throw new ArgumentException("Topic and message cannot be null or empty.");
}
if (!string.IsNullOrEmpty(sslFolderPath) && (!File.Exists(capem) || !File.Exists(clientpem) || !File.Exists(clientkey)))
{
throw new ArgumentException("SSL files are missing in the provided folder path.");
}
var logger = new MqttNetEventLogger("");
logger.LogMessagePublished += (s, e) =>
{
// put breakpoints here to debug
Console.WriteLine(e.LogMessage);
Console.WriteLine(Environment.NewLine);
Console.WriteLine(Environment.NewLine);
};
var mqttFactory = new MqttFactory();
using IMqttClient mqttClient = mqttFactory.CreateMqttClient(logger);
try
{
MqttClientOptions mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(serverIp, port)
.WithProtocolVersion(MqttProtocolVersion.V311)
.WithCredentials(username, password)
.WithTlsOptions(o =>
{
o.UseTls(true);
o.WithAllowUntrustedCertificates(false);
o.WithClientCertificates(new[]
{
new X509Certificate2(capem),
new X509Certificate2(clientpem, clientkey)
});
o.WithSslProtocols(SslProtocols.None);
o.WithCertificateValidationHandler(args =>
{
// Console.WriteLine(args);
return true;
});
})
.Build();
MqttClientConnectResult res = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine(res.ResultCode);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
MqttApplicationMessage applicationMessage = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(message)
.Build();
await mqttClient.PublishAsync(applicationMessage, CancellationToken.None);
await mqttClient.DisconnectAsync();
Does anyone know what I'm doing wrong or missing?
When executing the code above I'm getting the following logs from MqttNetEventLogger
:
[2023-09-05T23:16:58.7647014Z] [] [6] [MqttClient] [Error]: Error while connecting with server
MQTTnet.Adapter.MqttConnectingFailedException: Error while authenticating. One or more errors occurred. (One or more errors occurred. (The decryption operation failed, see inner exception.))
---> System.AggregateException: One or more errors occurred. (One or more errors occurred. (The decryption operation failed, see inner exception.))
---> MQTTnet.Exceptions.MqttCommunicationException: One or more errors occurred. (The decryption operation failed, see inner exception.)
---> System.AggregateException: One or more errors occurred. (The decryption operation failed, see inner exception.)
---> System.IO.IOException: The decryption operation failed, see inner exception.
---> Interop+OpenSsl+SslException: Decrypt failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:0A00045C:SSL routines::tlsv13 alert certificate required
--- End of inner exception stack trace ---
at Interop.OpenSsl.Decrypt(SafeSslHandle context, Span`1 buffer, SslErrorCode& errorCode)
at System.Net.Security.SslStreamPal.DecryptMessage(SafeDeleteSslContext securityContext, Span`1 buffer, Int32& offset, Int32& count)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory`1 buffer, CancellationToken cancellationToken)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
at MQTTnet.Implementations.MqttTcpChannel.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
at MQTTnet.Adapter.MqttChannelAdapter.ReadFixedHeaderAsync(CancellationToken cancellationToken)
at MQTTnet.Adapter.MqttChannelAdapter.ReceiveAsync(CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at MQTTnet.Adapter.MqttChannelAdapter.ReceivePacketAsync(CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at MQTTnet.Adapter.MqttChannelAdapter.WrapAndThrowException(Exception exception)
at MQTTnet.Adapter.MqttChannelAdapter.ReceivePacketAsync(CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at MQTTnet.Client.MqttClient.Receive(CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.Authenticate(IMqttChannelAdapter channelAdapter, MqttClientOptions options, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at MQTTnet.Client.MqttClient.Authenticate(IMqttChannelAdapter channelAdapter, MqttClientOptions options, CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectInternal(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken)
4
MQTTnet.Diagnostics.MqttNetEventLogger
[2023-09-05T23:16:58.7801885Z] [] [6] [MqttClient] [Verbose]: Disconnecting [Timeout=00:01:40]
4
MQTTnet.Diagnostics.MqttNetEventLogger
[2023-09-05T23:16:58.7831013Z] [] [6] [MqttClient] [Verbose]: Disconnected from adapter.
4
MQTTnet.Diagnostics.MqttNetEventLogger
[2023-09-05T23:16:58.7843253Z] [] [6] [MqttClient] [Info]: Disconnected.
Are you using the latest nuget version 4.3.0.858. I am having issue with TLS where my MqttNet for Aspnet is version 4.2.1.781 and my managed client is 4.3.0.858, without TLS it connects.
The error I get is "Error while authenticating" from the client side but no messages or connection attempt on the Server Side.
Yes, using the latest nuget packages
@alberk8 A fix for the TLS issue in the client will be released soon. Here it says "certificate required" so I assume that the root cause is something different.