esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
15.99k stars 13.33k forks source link

Add documentation for WiFiClientSecure (including usage of client side certificates) #1743

Closed HW-Siew closed 5 years ago

HW-Siew commented 8 years ago

Hi,

I am using Mqtt with esp8266. I am wondering does esp8266 support clients certificate for authentication?

Thanks for the advice.

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Links2004 commented 8 years ago

yes there are functions for it: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/WiFiClientSecure.h#L52-L66

HW-Siew commented 8 years ago

Hi @Links2004, Thank you so much for the information. Any documentation or guide on how the certificate can be uploaded to the wifi module and so?

igrr commented 8 years ago

@HW-Siew we don't have documentation for this. You can upload files to the ESP8266 filesystem (we have a plugin which simplifies this task), and then you can pass these files to WiFiClientSecure.

noelgeorgi commented 8 years ago

I could use esptool.py to upload the crt file, but how to use it in the function _void setCertificate(const uint8t cert_data, size_t size); void setPrivateKey(const uint8_t\ pk, size_t size);

bool loadCertificate(Stream& stream, size_t size); bool loadPrivateKey(Stream& stream, size_t size);

template bool loadCertificate(TFile& file) { return loadCertificate(file, file.size()); }

template bool loadPrivateKey(TFile& file) { return loadPrivateKey(file, file.size()); } An**y help regarding this post will be greatly appreciated by me and the MySensors community, enabling us to have secure MQTT communication for brokers running in the cloud

noelgeorgi commented 8 years ago

@HW-Siew @igrr solved the issue. I am using pubsubclient mqtt library for arduino. First install https://github.com/esp8266/arduino-esp8266fs-plugin and upload the crt file to the filesystem.

this is my pubsubclient code:

#include "FS.h"
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "yourssid";
const char* password = "yourpassword";
const char* mqtt_server = "172.16.0.95"; //MQTT broker ip 
//IPAddress server(172, 16, 0, 95);
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

}
WiFiClientSecure espClient;
PubSubClient client(mqtt_server,8883,callback,espClient); //set  MQTT port number to 8883 as per //standard
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

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

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client","mqttusername","mqttpass")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  delay(1000);
  if (!SPIFFS.begin()) {
    Serial.println("Failed to mount file system");
    return;
  }

File ca = SPIFFS.open("/ca.crt", "r"); //replace ca.crt eith your uploaded file name
  if (!ca) {
    Serial.println("Failed to open ca file");
  }
  else
  Serial.println("Success to open ca file");

if(espClient.loadCertificate(ca))
  Serial.println("loaded");
  else
  Serial.println("not loaded");

  //client.setServer(mqtt_server, 8883);
  //client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}
noelgeorgi commented 8 years ago

errors popped up are: Error: Invalid X509 ASN.1 file (X509 not ok) please start sntp first !

even though there are some errors MQTT data gets published, but frequent MQTT disconnects, help please??

Potato-Matic commented 8 years ago

In the meantime, if someone has gotten something working for their project with either the wifi client or wifit client secure, it's probably worth posting the code as an example, especially for the latter.

jyotirajsharma commented 7 years ago

Where to put "ca.crt" file ? I kept in the same folder where my arduino sketch is and it gives following error: "Failed to open ca file". Please help to resolve it.

gl3nni3 commented 7 years ago

@jyotirajsharma First install https://github.com/esp8266/arduino-esp8266fs-plugin and upload the crt file to the filesystem.

jyotirajsharma commented 7 years ago

@gl3nni3, I have already installed it and SPIFFS.begin()) code is executed succesfully.

Problem is it does not find the file at this path. Where to keep ca.txt ??

File ca = SPIFFS.open("/ca.txt", "r"); //replace ca.crt eith your uploaded file name if (!ca) { Serial.println("Failed to open ca file"); } else Serial.println("Success to open ca file");

Potato-Matic commented 7 years ago

I should have come back to this thread and stated this, but I've since figured out some examples for wificlientsecure, which can be found in a repo I have here on github.

I have not tried using a cert though (and my last attempt to play with the flash filesystem resulted in my arduino install breaking for ESPs, forcing the (beneficial) move to platformio; I should really look into it again)

jyotirajsharma commented 7 years ago

I am able to load the "ca.file" file now and loaded successfully. I am able to load the ca.crt now.

Do we really need to load espClient.loadCertificate(ca) file as well ? //for loading ca.crt file

I have seen many forums and they only mention about setting client certificate and key file as below -

espClient.setCertificate(client_bin_crt, client_bin_crt_len); espClient.setPrivateKey(client_bin_key, client_bin_key_len);

From ESP8266,I can connect to broker if I just remove "require_certificate true" flag. However, if I enable it, it is giving "routines:ssl3_get_client_certificate:certificate verify failed". Please help to fix it, I generated correct "certificates.h" which has client cert and key. I tried with MQTT.fx 1.0 CLIENT and observed the exact problem (i.e it works as long as require_certificate is false)

While listening for incoming client, .conf file we use, should have server cert/key files that are different from client cert/key files which were used in ESP8266 code ? Both client and server cert/key files created from common ca.crt file ??

dvoelkel commented 7 years ago

Hi there, I try the same at the moment. I solved the part to upload a certificate. But I don't get it to connect to WiFi. The scenario is as follows. The Client doesn't use a username and pass to authetify, it uses this certificate. I think it's called client side certificate. But I don't see the connectoin between WiFi and WiFiClientSecure. WiFi has no place for certificates, but wants a SSID and password (which is not needed). And WiFiClientSecure doesn't have a place for an SSID, to which it could connect with the loaded certificate. What i'm doing wrong?

igrr commented 7 years ago

@dvoelkel what you are looking for is called WPA2 Enterprise, and it is not supported in the ESP8266 Arduino core. It is supported to some extent by the underlying SDK, but not exposed in Arduino. Search this issue tracker for "wpa2 enterprise" to find the relevant issue. This one is about TLS connections using TLS.

Potato-Matic commented 7 years ago

There has been some limited, experimental success on the issue thread, so you might try the procedures posted there. No promises though, since it's experimental and only some people have been able to get it to work. Hopefully it'll make it's way towards official releases soon.

manhnguyen86 commented 7 years ago

I'm have same problem with Jyotirajsharma if I set "require_certificate true". anyone resolved it??

kikice010 commented 7 years ago

@igrr hi! Could you please point me out to the plugin you use to transfer the certificates to the FS of the ESP8266? Tried to find some good references and examples regarding this topic but usually my search has ended up deadens :/

torntrousers commented 6 years ago

If it helps anyone, there is an example of how to use the certificate and private key just as strings without needing to using spiffs here: https://github.com/HarringayMakerSpace/awsiot/blob/master/Esp8266AWSIoTExample/Esp8266AWSIoTExample.ino