TLS with libmosquitto pub-client

81 Views Asked by At

In an educational context I would like the students to build a mqtt publisher using TLS. I tested the following sample code:

#include <stdlib.h>
#include <stdio.h>
#include <mosquitto.h>

int main(){
    int rc;
    struct mosquitto * mosq;

    //der pfad zu pseudodatei mit dem temperaturwert des sensors
    //muss vorab auf dem raspberry ermittelt werden
    //jeder sensor hat eine eigene ID ---\
    //                                   |
    //                                   V
    char *pfad="/sys/bus/w1/devices/28-f8eccb0664ff/temperature";
    char tWert[80];
  
    //datei zum lesen (r) oeffnen
    FILE *fpin;
    if((fpin = fopen(pfad,"r"))==NULL){
      fprintf(stderr, "Can't open %s\n", pfad);
      exit(1);
    };
    
    //erste und einzige zeile aus der datei "/sys/bus/w1/devices/28-f8eccb0664ff/temperature" einlesen
    while(fgets(tWert, 80, fpin)){
      //auf dem raspberry zu debug-zwecken ausgeben
      printf("temperatur: %s", tWert);
    }
    
    mosquitto_lib_init();

    mosq = mosquitto_new("publisher-test", true, NULL);

    //tls einschalten
    // If set to true, no hostname checking is performed and the connection is insecure.
    mosquitto_tls_insecure_set(mosq,true);

    //tls version auf tlsv1.2 setzen
    int ltsVersionSetCode = mosquitto_tls_opts_set(
                             mosq,
                             1, //1=SSL_VERIFY_PEER => server-cert pruefen
                             "tlsv1.2",
                             NULL);  //ciphers einstellen, NULL=default-ciphers
    
    //muss vor dem aufruf mosquitto_connect(...) erfolgen
    int tlsCode = mosquitto_tls_set(
              mosq,
              "/home/pi/development/mqtt/pubTempAufRaspberry/ca.crt",
              NULL,
              NULL,
              NULL,
              NULL);

    printf("tls_set_code: %d\n", tlsCode);
    
    //broker soll der schueler-PC sein; hier zu hause ist es eine andere IP:
    rc = mosquitto_connect(mosq, "10.10.0.1", 8883, 60);
    if(rc != 0){
        printf("Client could not connect to broker! Error Code: %d\n", rc);
        mosquitto_destroy(mosq);
        return -1;
    }
    printf("Verbindung mit dem Broker hat funktioniert!\n");

    //als topic senden wir einen beliebigen pfad-string (hier "labor/temp1")
    //als message uebergeben wir den pointer auf das char-array, das wir oben
    //eingelesen haben (tWert)
    mosquitto_publish(mosq, NULL, "labor/temp1", 6, tWert, 0, false);

    mosquitto_disconnect(mosq);
    mosquitto_destroy(mosq);

    mosquitto_lib_cleanup();
    return 0;

I generated the pki as described here: https://mosquitto.org/man/mosquitto-tls-7.html

publishing from the raspberry (10.10.0.117):

mosquitto_pub -h 10.10.0.1 -t labor/temp1 -p 8883 --insecure --cafile ca.crt --tls-version tlsv1.2 -m "tlsWorks!"

and subscribing on a linux host (10.10.0.1):

mosquitto_sub -h 10.10.0.1 -t labor/temp1 -p 8883 --insecure --cafile ca.crt --tls-version tlsv1.2

works perfectly fine. But publishing with the c-code from above gives the following errror in mosquitto.log:

1694796151: New connection from 10.10.0.117:37784 on port 8883.
1694796151: OpenSSL Error[0]: error:0A000126:SSL routines::unexpected eof while reading
1694796151: Client  disconnected: Protocol error.

As I understand it, the client does not terminate the TLS session properly. However, the mosquitto clients from the installed Raspbian packages (lib, server, clients: version 2.0.11) work fine.

So there should be a way to fix the code, but I haven't figured out how yet. Does anyone have an idea?

Many thanks for your help.

michael

0

There are 0 best solutions below