Connection failed with SSL with ESP8266

Hi Guys,

I want to create an SSL connection with my site to send data and every time I connect it fails!

here is my code:

#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>

#include <ESP8266WiFi.h>
#include <DHT.h>
#include <TimeLib.h>         // for Date/Time operations
#include <WiFiUdp.h>         // for UDP NTP
#include <WiFiClientSecure.h>


#define DHTPIN D6
#define DHTTYPE DHT11 

unsigned long startMillis1;

unsigned long currentMillis1;


const char* ssid     = "SSID";
const char* password = pass";


char host[] = "mysite.com";
DHT dht(DHTPIN, DHTTYPE);

// NTP Servers:
IPAddress timeServer(195, 186, 4, 101); // 195.186.4.101 (bwntp2.bluewin.ch)
const char* ntpServerName = "pool.ntp.org";
const int timeZone = 3;     // Central European Time (summer time)

WiFiUDP Udp;
unsigned int localPort = 8888;  // local port to listen for UDP packets

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, OUTPUT);
  digitalWrite(LED_BUILTIN, 0);
  startMillis1 = millis();
      startMillis2 = millis();
      startMillis3 = millis();
  Serial.begin(115200);
  delay(100);
  dht.begin();
  Serial.println();
  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());
  Serial.print("Netmask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway: ");
  Serial.println(WiFi.gatewayIP());

  Serial.println("Starting UDP");
  Udp.begin(localPort);
  Serial.print("Local port: ");
  Serial.println(Udp.localPort());

  Serial.print("Using NTP Server ");
  Serial.println(ntpServerName);
  //get a random server from the pool
  WiFi.hostByName(ntpServerName, timeServer);
  Serial.print("NTP Server IP ");
  Serial.println(timeServer);

  Serial.println("waiting for sync");
  setSyncProvider(getNtpTime);
  setSyncInterval(60);

  
}


/*-------- NTP code ----------*/

const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

time_t getNtpTime()
{
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  sendNTPpacket(timeServer);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}


void loop (){
temp ();

  
}

void temp(){
const unsigned long period = 10000; 
currentMillis1 = millis();  //get the current time
  if (currentMillis1 - startMillis1 >= period)  //test whether the period has elapsed
  {
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  
  Serial.print("connecting to ");
  Serial.println(host);

  int httpPort = 443;
  //Add a SSL client
   WiFiClientSecure client;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  String url = "/insert.php?temp=" + String(t) + " ;
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  delay(500);
  
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  
  Serial.println();
  Serial.println("closing connection");
 startMillis1 = currentMillis1;
  
  }  
}

Is the problem in my code or from the site?

  startMillis1 = millis();
      startMillis2 = millis();
      startMillis3 = millis();

These names are useless. They do not describe, usefully, what started.

Is the problem in my code or from the site?

From the looks of the code, I'd go with the site being the problem.

Can you connect to that site, using that port, from a browser?

Here is the problem : https://stackoverflow.com/questions/56198194/connection-failed-with-ssl-with-esp8266

Workaround is to downgrade board firmware to 2.4.x

I’m making secure connections using v2.5.2 of the ESP8266 core, which I believe is the latest. However, I do not mess with NTP, fingerprints or certificates. Of course in my case this means IFTTT.com could be spoofed in some way, and I have no protection against that. The key to making this work is BearSSL. Here’s a code extract:

#include <ESP8266WiFi.h>
const int httpsPort = 443;
const char* server = "maker.ifttt.com";
.
.
.
  BearSSL::WiFiClientSecure client;
  client.setInsecure();                          //don't check fingerprint

  int retries = 6;                               //retry up to 5 times
  while(!client.connect(server, httpsPort) && (retries-- > 0)) {
    Serial.print(".");
    delay(2000);
  }
  Serial.println();
  if(!client.connected()) {
    Serial.println("Failed to connect to server");
    client.stop();
    return;                                      //if no connection, bail out
  }
  Serial.print("Request event: ");               //if good connection, send GET
  Serial.println(event);
  client.print(String("GET ") + event +
                  " HTTP/1.1\r\n" +
                  "Host: " + server + "\r\n" +
                  "Connection: close\r\n\r\n");

My understanding is that this makes an encrypted https connection over port 443, but doesn’t bother to authenticate the server. I think for some things this is just fine.

Also note that BearSSL and WiFiClientSecure are now included within ESP8266WiFi.h.