espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.37k stars 7.37k forks source link

Using files (SPIFFS) to setCertificate. #3248

Closed JoaquimFlavio closed 4 years ago

JoaquimFlavio commented 5 years ago

I need get file in the flash of ESP32 to set certificate for connect to my Broker MQTT, but the code return me a connecte error. I search in the network for sollution but don`t found...

I try using loadCertificate and setCertificate but both return the ssl error in the monitor:

rc=-2
  WiFiClientSecure SSL error: X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected
ferologics commented 4 years ago

Hey @JoaquimFlavio have you been able to resolve your issue? I'm receiving the same error

JoaquimFlavio commented 4 years ago

@ferologics I don't resolving this complete problem. The loadCertificate method don't working in ESP32, but work in ESP8266! I do not know the reason occurs.... For resolve my problem i need copy the file to char array and poiter to null after end file. I write a simple example:

char array[max lenght of file + 1];//this variable need be global
int i=0;
while(begin to end file){
    array[i] = file.read();
    i++;
}
array[i] = '\0';

esp. setCertificate(array);
KevinHunter12 commented 4 years ago

I also have the same problem :( [V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 257816 [V][ssl_client.cpp:58] start_ssl_client(): Starting socket [V][ssl_client.cpp:93] start_ssl_client(): Seeding the random number generator [V][ssl_client.cpp:102] start_ssl_client(): Setting up the SSL/TLS structure... [V][ssl_client.cpp:115] start_ssl_client(): Loading CA cert [E][ssl_client.cpp:33] _handle_error(): [start_ssl_client():122]: (-8576) X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected [E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -8576 [V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection. ---> mqtt failed, rc=-2

If i connect to the same server using the same certificate but HTTPS rather than MQTTS it works !

Im reading the certificate from SPIFFS and loading using wifiClient.loadCACert(ca, ca.size())

Any clues?? Thanks Kevin

stale[bot] commented 4 years ago

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

stale[bot] commented 4 years ago

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

pulquero commented 4 years ago

I also have this problem, specifically when trying to connect to AWS IoT with cacert, cert and private key.

pulquero commented 4 years ago

Found the problem! Fix is edit C:\Users\<...>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFiClientSecure\src\WiFiClientSecure.cpp and modify

char *WiFiClientSecure::_streamLoad(Stream& stream, size_t size) {
  /* original code uses a static ptr so the next load overwrites the previous certificate!!!
  static char *dest = nullptr;
  if(dest) {
      free(dest);
  }
  */
  char* dest = (char*)malloc(size);
  if (!dest) {
    return nullptr;
  }
  if (size != stream.readBytes(dest, size)) {
    free(dest);
    dest = nullptr;
  }
  return dest;
}

@me-no-dev please re-open and mark as a bug.

lbernstone commented 4 years ago

Please submit as a PR. Bugs don't fix themselves around here.

JaronrH commented 4 years ago

Thank you, @pulquero!

This fixed my issue with trying to connect to MQTT using PubSubClient and cert verification.

cjkarande commented 3 years ago

@pulquero , well i am still getting the same error even after the said code change. I am using esp32s2 code branch. Am i missing something?

Found the problem! Fix is edit C:\Users<...>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFiClientSecure\src\WiFiClientSecure.cpp and modify

char *WiFiClientSecure::_streamLoad(Stream& stream, size_t size) {
  /* original code uses a static ptr so the next load overwrites the previous certificate!!!
  static char *dest = nullptr;
  if(dest) {
      free(dest);
  }
  */
  char* dest = (char*)malloc(size);
  if (!dest) {
    return nullptr;
  }
  if (size != stream.readBytes(dest, size)) {
    free(dest);
    dest = nullptr;
  }
  return dest;
}

@me-no-dev please re-open and mark as a bug.

NarinLab commented 3 years ago

Same on here, how can i load spiffs ca.cert.pem to pass to setCACert method:

#include <WiFiClientSecure.h>
#include <MQTTClient.h>

//short code
ssl.setCACert("/ca.cert.pem");
iot.setOptions(900, true, 10000);
pulquero commented 3 years ago

I use something like this to load the certificates:


template<typename L> void loadFromFile(const char* fname, L&& load) {
  if (SPIFFS.exists(fname)) {
    File f = SPIFFS.open(fname);
    bool rc = load(f, f.size());
    f.close();
  }
}

void loadCertificates(WiFiClientSecure* client) {
  SPIFFS.begin();
  loadFromFile("/ca.cert.pem", [client](Stream& stream, size_t size){return client->loadCACert(stream, size);});
  loadFromFile("/client.cert.pem", [client](Stream& stream, size_t size){return client->loadCertificate(stream, size);});
  loadFromFile("/private.key.pem", [client](Stream& stream, size_t size){return client->loadPrivateKey(stream, size);});
  SPIFFS.end();
}

`