Using CA certificate in mqtt paho

1.2k Views Asked by At

I'm writing application that collect some hardware inputs and send it to MQTT broker. Currently, broker use credentials only, no SSL, and all works fine. (Program is written in C++, Linux. I use Paho MQTT library- by including source code, not compiled library) But the next feature that I need to develop is TLS- protected connection. I have a pem-formatted CA root certificate file. In MQTT.fx application I set path to this file to "CA Certificate file" field and all works. But in code, I can't find how I can set this file.

My code:

//initialize options
    MQTTClient client;
    char * address = "our broker address:8883";
    char * clientID = "Our ID";
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
    conn_opts.MQTTVersion =MQTTVERSION_3_1_1;

    conn_opts.serverURIcount  =0;
    conn_opts.serverURIs = NULL;
    conn_opts.username= creds->getUser(); 
    conn_opts.password= creds->getPwd();  
    
    // starting ssl setting
    ssl_opts = MQTTClient_SSLOptions_initializer;
    
    ssl_opts.CApath = [filepath]/ca.pem; // I tried to use trustStore and keyStore- the same effect
    
    ssl_opts.sslVersion = 3;
    ssl_opts.ssl_error_cb = SSL_err_handler;
    conn_opts.ssl = & ssl_opts;
    ssl_opts.struct_version =1;
    conn_opts.struct_version = 1;
    MQTTClient_create(&client, address, clientID, MQTTCLIENT_PERSISTENCE_NONE, NULL );
    int rc;
    if ( (rc = MQTTClient_connect( client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf( "failed to connect, code is %d\n", rc);
        return rc;
    }
    // continue execution

MQTTClient_connect returns -1- bad socket

Where I wrong?

1

There are 1 best solutions below

0
softeky On

I spent half a day on a similar issue. I thought using the SSL options would tell the paho library functions I was relying on encryption and decryption. No such luck. It turned out I needed to prepend the address with "ssl://" e.g.

char *address = "ssl://our broker address:8883"

and used that with:

conn_opts.ssl->trustStore = "/...path to.../certs/ca/ca.crt";
conn_opts.ssl->keyStore = "/...path to.../certs/client/client.pem";

Aside: I used bash cli to build the .pem with:

cat /...path to.../certs/client/client.{crt,key} > /...path to.../certs/client/client.pem

Which worked!