3

I cannot seem to make MQTT+TLS+self signed certs work on my ESP32.

I am using this "setup" in my home network without major hickups with paho-python and mosquitto_pub/sub. The latter works with the following bash command (note the insecure there):

mosquitto_pub -h 192.168.1.X -p 8883 --cafile /etc/mosquitto/ca_certificates/mosq_ca.crt --cert /etc/mosquitto/certs/mosq_client.crt --key /etc/mosquitto/certs/mosq_client.key --debug --insecure --topic "test/message" -m "off"

My broker's mosquitto config file contains these lines apart from cert paths and general settings:

tls_version tlsv1.3
require_certificate true

When I send the sketch to my ESP32, the result is that it is stuck in the reconnect() loop (see sketch below).

When I do not specify a client cert and key ( // for client verification rows are commented in setup()), I get the following error (I guess it is attributable to the config which requires certificate):

1594936874: New connection from 192.168.1.162 on port 8883.
1594936874: OpenSSL Error: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
1594936874: Socket error on client <unknown>, disconnecting.

When I do specify a client certificate, I get this:

1594936887: New connection from 192.168.1.162 on port 8883.
1594936888: Socket error on client <unknown>, disconnecting.

Not sure if it is a host name mismatch on the certificate or what. This would be my main tip, but I am uncertain. I also do not know if a similar option to --insecure can be specified for WiFiClientSecure class, so far I have not found anything like that. But I am a beginner, too.

My sketch if pretty unpolished yet, but it should be still readable:

#include <WiFiClientSecure.h>
#include <time.h>
#include <PubSubClient.h> 



const char* ssid = "mySSID";
const char* password = "myPasswd";

const char*  server = "192.168.1.X";  // Server URL
const char* MQTT_subscribe_topic = "test/esp32";

int timediff_hr = 2;

const char* root_ca = \ 
"-----BEGIN CERTIFICATE-----\n" \ 
"pem format broken into lines\n" \
"pem format broken into lines\n" \
"pem format broken into lines\n" \
"-----END CERTIFICATE-----\n" ;


// You can use x.509 client certificates if you want
const char* test_client_key = \
"-----BEGIN CERTIFICATE-----\n" \ 
"pem format broken into lines\n" \
"pem format broken into lines\n" \
"pem format broken into lines\n" \
"-----END CERTIFICATE-----\n" ;

const char* test_client_cert =  \
"-----BEGIN CERTIFICATE-----\n" \ 
"pem format broken into lines\n" \
"pem format broken into lines\n" \
"pem format broken into lines\n" \
"-----END CERTIFICATE-----\n" ;

WiFiClientSecure wifiClient;
time_t now;

void msgReceived(char* topic, byte* payload, unsigned int len);
PubSubClient pubSubClient(server, 8883, msgReceived, wifiClient); 


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  delay(100);

  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  // attempt to connect to Wifi network:
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    // wait 1 second for re-trying

    delay(1000);
  }

  Serial.print("Connected to ");
  Serial.println(ssid);

  getTime();

  wifiClient.setCACert(root_ca);
  wifiClient.setCertificate(test_client_key); // for client verification
  wifiClient.setPrivateKey(test_client_cert);  // for client verification

  
}


unsigned long lastPublish;
int msgCount;

void loop() {
  
  if (!pubSubClient.connected()) {
    reconnect();
  }
  
  pubSubClient.loop();
  
  if (millis() - lastPublish > 10000) {
    String msg = String("Hello from ESP32: ") + ++msgCount;
    boolean rc = pubSubClient.publish("outTopic", msg.c_str());
    Serial.print("Published, rc="); Serial.print( (rc ? "OK: " : "FAILED: ") );
    Serial.println(msg);
    lastPublish = millis();
  }
}

void msgReceived(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message received on "); Serial.print(topic); Serial.print(": ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void reconnect() {

  Serial.print(F("PubSubClient attempting connection to: ")); Serial.println(server);

    uint8_t i = 0;
    while ( ! pubSubClient.connected()) {

    // Attempt to connect
    if (pubSubClient.connect("ESP32Client")) { //or "ESP8266Client"
      Serial.println("connected");
      // Subscribe
      pubSubClient.subscribe(MQTT_subscribe_topic);
      
    } else { //unsuccessful connect
      Serial.print("failed, rc=");
      Serial.print(pubSubClient.state());
      Serial.print("\nNext try in 5 seconds: connection to "); Serial.println(server);
      
      // Wait 5 seconds before retrying
      delay(5000);
    }
    }
}


void getTime(){
    // Synchronize time useing SNTP. This is necessary to verify that
  // the TLS certificates offered by the server are currently valid.
  Serial.print("Setting time using SNTP");
  configTime(timediff_hr * 3600, 0, "de.pool.ntp.org");
  time_t now = time(nullptr);
  while (now < 1000) {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println("");
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print("Current time: ");
  Serial.print(asctime(&timeinfo));
  
}

P.S.: The base of this sketch is a test sketch of mine for MQTT:1883 unsecured, which also works fine. So the issue should definitely be in the TLS part.

itarill
  • 323
  • 1
  • 14
  • Mine also uses self-signed SSL certificate and client certificate. It's working just fine. You may need to check certificate chains and make sure you pass the correct certificates in wifiClient. That's my tips. – Bao HQ Jun 25 '21 at 06:23
  • Did you set `8883` as the `tls` port in both `mosquitto.conf` and here? I ain't see nothing. – Mohammad Kholghi Mar 09 '22 at 11:24

1 Answers1

0

Your test_client_key contains a certificate.

It would be helpful if you post the sample code with keys and certificates. Obviously not the ones you will be using later, but as you are self signing, generate some test key material that you can post here.

The configuration of your broker would also be useful.

a2800276
  • 3,272
  • 22
  • 33