Imroy / pubsubclient

A client library for the ESP8266 that provides support for MQTT
MIT License
434 stars 115 forks source link

SSL Support #18

Closed Namphibian closed 3 months ago

Namphibian commented 9 years ago

Hi

Started using your library and it is easy and fun to work with. Excellent work. Nice to know you are close by in NSW. I just wanted to check with you if the library handles SSL yet? I thought asking a question would be easier than bashing my head against a brick wall for while.

If not I am more than willing to help in getting this done just my C/C++ skills is little rusty so the going might be a little slow...

N

Imroy commented 9 years ago

No, the library does not support SSL/TLS. To be honest, I haven't even checked username/password authentication. I think I read that the Espressif SDK supports SSL/TLS, so it might be relatively simple to add.

Imroy commented 9 years ago

Doesn't look good: esp8266/Arduino#43 It sounds like wee need to work on getting SSL/TLS support in WiFiClient first.

Namphibian commented 9 years ago

Right I will do some testing of the authentication this weekend. Lets get that resolved/verified as working. I see the official MQTT client claims to support SSL and maybe we can have a look at that for some guidelines on how to implement.

igrr commented 8 years ago

Just dropping a note here that with staging version of ESP8266 Arduino core, it is now possible to use MQTT over TLS.

Testato commented 8 years ago

Thanks for the info Il 01/ott/2015 17:26, "Ivan Grokhotkov" notifications@github.com ha scritto:

Just dropping a note here that with staging version of ESP8266 Arduino core, it is now possible to use MQTT over TLS.

— Reply to this email directly or view it on GitHub https://github.com/Imroy/pubsubclient/issues/18#issuecomment-144762435.

mtnbrit commented 8 years ago

Is there an example sketch for MQTT over TLS please?

or is it as simple as

WiFiClientSecure client; PubSubClient client(client, server);

and proceed as usual?

Imroy commented 8 years ago

@mtnbrit I've tried that and it doesn't seem to work. I'm not sure if I've set up my broker correctly though.

mtnbrit commented 8 years ago

Yep it crashes the esp for me, so i think the issue is client-side. Perhaps @igrr can chime in with a working example?

mtnbrit commented 8 years ago

Folks, any progress on getting TLS to work? I can test anything needed on client or broker.

mtnbrit commented 8 years ago

Its working. http://github.com/esp8266/Arduino/issues/43#issuecomment-154773929

probonopd commented 8 years ago

@Imroy please consider using WiFiClientSecure client; now as it seems to be working now. See https://github.com/adafruit/Adafruit_MQTT_Library/commit/e77be5b9ac0200bdb5036194e05576c3cca868e0 for another MQTT library doing exactly this.

ftruzzi commented 8 years ago

I got it working with SSL (+ user/pass authentication) by modifying a couple of functions.

The set_auth method is already present in MQTT.h.

Problem is, the ESP8266 crashes when using username and password authentication in non-SSL mode (SSL works fine) and, in either case, floods the console with the error "please start sntp first!"

EDIT: all you need to do to get SSL working is declare WiFiClientSecure client; and use port 8883. Once you set up user/pass auth though (through the connect.set_auth() method) it breaks.

probonopd commented 8 years ago

Excellent, thank you very much! I have also had some success using SSL and https://github.com/adafruit/Adafruit_MQTT_Library

chuank commented 6 years ago

@ftruzzi, @probonopd, @mtnbrit, how did you get this to work? I'm getting the following error:

1513209887: New connection from 192.168.254.11 on port 8883.
1513209887: OpenSSL Error: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher
1513209887: Socket error on client <unknown>, disconnecting.

I'm not sure where to define and verify the cipher (which I assumed to be the SHA1 fingerprint). I've define the fingerprint as a constant C string but where does this get included in the PubSubClient instance? I tried verifying the fingerprint it on the WiFiClientSecure instance but that didn't work.

Here's a breakdown of my code:

WiFiClientSecure wsclient;
PubSubClient mqttClient(wsclient, MQTT_IP, 8883);

void setup() {
  Serial.begin(115200);
  delay(10);

  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PWD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  //  This didn't work:
  //  Serial.print("connecting to ");
  //  Serial.println(HOSTNAME);
  //  if (!wsclient.connect(MQTT_IP, MQTT_PORT)) {
  //    Serial.println("connection failed");
  //    return;
  //  }
  //  if (wsclient.verify(SHA1_FINGERPRINT, HOSTNAME)) {
  //    Serial.println("certificate matches");
  //  } else {
  //    Serial.println("certificate doesn't match");
  //  }
}

void loop() {
  if (mqttClient.connected()) {
    mqttClient.loop();
  } else {    // reconnect if mqttClient drops for any reason
    if (!mqttCheckConnection())
      return;     // abort rest of the loop and try reconnection again
  }

  // blink LED to show that the device is working and looping
  int lState = digitalRead(LED_BUILTIN);
  digitalWrite(LED_BUILTIN, !lState);

  delay(1000);
}

boolean mqttCheckConnection() {
  if (mqttClient.connect(MQTT::Connect(devID)
                         .set_auth(MQTT_USER, MQTT_PWD)
                         .set_will("ESP_TLS_test", "disconnect:" + displayIPAddress(WiFi.localIP()), 2, true)
                         .set_keepalive(10)
                         .set_clean_session(false)      // false = durable connection; subscriptions and queued messages will remain when we reconnect
                        )) {

    // just connected, so broadcast its existence via MQTT
    String payload = "online:" + displayIPAddress(WiFi.localIP());
    mqttClient.publish(MQTT::Publish("ESP_TLS_test", payload)
                       .set_qos(2));

    return true;
  }
  return false;
}
tedder commented 6 years ago

on an esp32, this connection string worked:

client.connect(clientId.c_str(), "user", "pass")

I'd suggest commenting out some of the extra bits, or simplify and call a basic .connect().

chuank commented 6 years ago

thanks @tedder, it was a badly configured user/password in mosquitto that caused the issue for me.

fwiw the chainable setter methods do work, as with set_auth.