Using the new Arduino IDE for ESP8266 and found bugs, report them here

Moderator: igrr

User avatar
By clegg
#68908 Hi, I am trying to setup a TLS/SSL connection with a remote server using the ESP8266 as the client. I am using the WiFiClientSecure class, and am trying to verify the certificate the server sends back. I am using the platformio command line tool. I am using the esp8266 staging platform to get the latest(ish) source for the ESP8266 Arduino core. I have placed my code at the end of this post for reference.

It seems I am unable to set the CA certificate using WiFiClientSecure::setCACert. While the function returns true (there appears to be a bug in the axTLS library that causes it to not return errors in some cases), I see the following when I enable debug output:

Code: Select allSet CA Cert
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: Invalid X509 ASN.1 file (X509 not ok)
Error: maximum number of CA certs added (10) - change of compile-time configuration required
CA Cert set


I am not quite sure what is the cause of the issue as axTLS does not return an error code here. I have tried it with a CA certificate generated using openssl s_client (then translated to DER format, and placed in a C file using xxd -i), and the CA certificate in the example. Both produce the same result in setCACertificate.

I was wondering if anyone else had encountered this issue or if anyone has any suggestions. Thanks

My code:
Code: Select all#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <time.h>

#include "wifi-information.hpp"
extern const uint8_t * ca_certificate;
extern const uint32_t ca_certificate_len;

static DHT_Unified g_dht(D4, DHT11);
static WiFiClientSecure g_client;

void initSerialPort(HardwareSerial& serial);
void initWifi(ESP8266WiFiClass& wifi,
              const String& ssid,
              const String& password);
void initDhtSensor(DHT_Unified& dht);

void setup()
{
  const WifiInformation& wifiInfo = WifiInformation::instance();
  initSerialPort(Serial);
  initWifi(WiFi, wifiInfo.ssid(), wifiInfo.password());
  initDhtSensor(g_dht);

  Serial.print("Configure time..");
  /* Need to synchronize time so TLS can verify certificates */
  /* First parameter is offset from GMT, second is daylight savings (ignored,
   * and then servers (up to three, minimum two).
   */
  configTime(-(4*3600), 1, "pool.ntp.org", "time.nist.gov");

  /* Wait until we have the current time */
  time_t now = time(nullptr);
  while (now < 1000)
  {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println(" Done");
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print("Current time: ");
  Serial.println(asctime(&timeinfo));

  Serial.println("Set CA Cert");
  if (!g_client.setCACert(ca_certificate, ca_certificate_len ))
  {
    Serial.println("Failed to load CA certificate");
    while(true) yield();
  }
  Serial.println("CA Cert set");
}

void loop()
{
  // Substituted domain name below
  const char * host = "www.example-domain.com";
  const int port = 443;

  Serial.print("Connecting to ");
  Serial.println(host);
  if(!g_client.connect(host, port))
  {
    Serial.println("Connection failed");
    return;
  }

  if(g_client.verifyCertChain(host))
  {
    Serial.println("Server certificate verified");
  }
  else
  {
    Serial.println("ERROR: certificate verification failed!");
    return;
  }

  g_client.stop();
}

void initSerialPort(HardwareSerial& serial)
{
  serial.begin(115200);
  serial.setDebugOutput(true);
  delay(10);
}

void initWifi(ESP8266WiFiClass& wifi,
              const String& ssid,
              const String& password)
{
  wifi.begin(ssid.c_str(), password.c_str());

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

  while(wifi.status() != WL_CONNECTED)
  {
    delay(500);
  }

  Serial.println("Connected");
}

void initDhtSensor(DHT_Unified& dht)
{
  dht.begin();
  Serial.println("DHT Initialized");
}
User avatar
By gbafamily1
#68913
esp8266 staging platform to get the latest(ish) source for the ESP8266 Arduino core.


As far as I know the staging version is old. Or are you referring to 2.4.0rc1? I suggest using the latest version in git. I don't know how to do this using platformio so I only use platformio when using 2.3.0. I use the Arduino IDE when working with the git version.

Does the HTTPSRequestCACert example work? I just add my ssid and password and it works.

EDIT: I just learned platformio supports `platform = espressif8266_stage` which means platformio pulls core files from https://github.com/esp8266/arduino. See the following link for the details. HTTPSRequestCACert works fine using espressif8266_stage.

http://docs.platformio.org/en/latest/pl ... ng-version
User avatar
By clegg
#68917 The staging repo appears to be slightly off from the main repo:

https://github.com/platformio/platformi ... ressif8266

The CA certificate from the example on the main repo did not work. I can try copying it exactly. If that doesn't work I can install the Arduino IDE to see if that works.
User avatar
By RexBrown
#77604 I noticed that you are using the PROGMEM keyword to put the certificate in Flash. You should be using the function that is created to retrieve the cert from flash as follows (this is from my code so the actual cert and length parameters are of course yours):

bool res = client.setCACert_P(CACert, CACertLen);

This seems to work for me. However I am having an unrelated problem in the validation of the cert (at least I think it is unrelated..) where dates that are after 2050 (which use the generalizedtime format) are interpreted incorrectly and cause a verify cert error.