Issue setting CA Certificate in WiFiClientSecure
Posted: Mon Aug 07, 2017 3:28 pm
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:
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:
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 all
Set 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");
}