Search code examples
windowsmqttmosquitto

Issues establishing a secure connection to Mosquitto Broker 2.0.10 using M2MQTT v4.3.0.0 and signed certificates


I'm trying to implement MQTT in my program using M2MQTT v4.3.0.0 (github), but when I try to connect using signed certificates my code cannot establish a connection. I'm on a Windows 10 system, and using C# with .NET 4.8. The version of Mosquitto I have installed is 2.0.10.

To make the server certificate I followed this tutorial: http://www.steves-internet-guide.com/mosquitto-tls/#server

To make the client certificate I followed this tutorial: http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/

I also made a host name in my etc/hosts file for 127.0.0.1 that points to localhost.conrad.com.

The configuration for my Mosquitto Broker is:

bind_address localhost.conrad.com
port 8883
allow_anonymous true
cafile C:/mosquitto/certs/ca.crt
keyfile C:/mosquitto/certs/server.key
certfile C:/mosquitto/certs/server.crt
require_certificate true
tls_version tlsv1.2
log_dest file C:/mosquitto/log/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information

I successfully tested that this configuration works using Mosquitto's command line publish tool with

mosquitto_pub --cafile C:\mosquitto\certs\ca.crt --cert C:\mosquitto\certs\client.crt --key C:\mosquitto\certs\client.key -d -h localhost.conrad.com -p 8883 -t herp/derp/test -m "hi"

I received this message after using the command.

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'herp/derp/test', ... (2 bytes))
Client (null) sending DISCONNECT

My Mosquitto log confirms a successful connection:

1621547553: New connection from 127.0.0.1:57874 on port 8883.
1621547553: New client connected from 127.0.0.1:57874 as auto-6A8387C3-E091-0EC6-CED7-0A78BAA63099 (p2, c1, k60).
1621547553: Client auto-6A8387C3-E091-0EC6-CED7-0A78BAA63099 disconnected.

However when I try to connect using M2MQTT I run into a problem when trying to connect using signed certificates. My code is as follows:

int securePort = 8883;
MqttClient client = null;
string subTopic1 = "herp/derp/test";
string subTopic2 = "herp/derp/test2";
X509Certificate caCert = new X509Certificate("C:/mosquitto/certs/ca.crt");
X509Certificate clientCert = new X509Certificate("C:/mosquitto/certs/client.crt");
string clientID = "TestClientID";

public MQTTTest()
{
    try
    {
        client = new MqttClient("localhost.conrad.com", securePort, true, caCert, clientCert, MqttSslProtocols.TLSv1_2, RemoteCertificateValidationCallback);
        client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
        client.MqttMsgPublished += client_MqttMsgPublished;
        client.MqttMsgSubscribed += client_MqttMsgSubscribed;
        client.ConnectionClosed += client_ConnectionClosed;

        client.Connect(clientID, "", "", true, 1000);
        client.Subscribe(new string[] { subTopic1, subTopic2 }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

I get the following exception when trying at client.Connect.

Exception message: "A call to SSPI failed, see inner exception."
Inner exception: "The message received was unexpected or badly formatted"

My Mosquitto logs show:

1621547793: New connection from 127.0.0.1:57896 on port 8883.
1621547793: OpenSSL Error[0]: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate
1621547793: Client <unknown> disconnected: protocol error.

I can establish insecure connections just fine. As it is written my code also connects when I set require_certificate to false in my Mosquitto config file; however I am worried that if require_certificate is set to false that I won't have the security I want. Any help would be greatly appreciated.


Solution

  • Thanks to Brits' comment I was able to figure it out (link to answer). I made a pfx certificate and used that instead of using a crt.

    Instead of...

    X509Certificate caCert = new X509Certificate("C:/mosquitto/certs/ca.crt");
    X509Certificate clientCert = new X509Certificate("C:/mosquitto/certs/client.crt");
    

    I used...

    X509Certificate2 caCert = new X509Certificate2("C:/mosquitto/certs/ca.pfx", "password");
    X509Certificate2 clientCert = new X509Certificate2("C:/mosquitto/certs/client.pfx", "password");