blynkkk / blynk-library

Blynk library for IoT boards. Works with Arduino, ESP32, ESP8266, Raspberry Pi, Particle, ARM Mbed, etc.
https://blynk.io
MIT License
3.81k stars 1.38k forks source link

SSL support on ESP8266 broken when using ESP8266 Arduino core 2.5.0 #462

Closed tssva closed 3 years ago

tssva commented 5 years ago

The latest ESP8266 Arduino core, 2.5.0, has switched to BearSSL as the default SSL implementation and deprecated the axTLS based implementation. The WiFiClientSecure API differs between the BearSSL and axTLS implementations which means BlynkSimpleEsp8266_SSL.h no longer compiles properly out of the box.

truglodite commented 5 years ago

Interesting that BlynkSimpleEsp8266_SSL.h fails to compile in PIO, but it succeeds for me in Arduino IDE. The first error that shows:

C:\Users\Kevin\.platformio\lib\Blynk_ID415\src/BlynkSimpleEsp8266_SSL.h:76:34: error: there are no arguments to 'time' that depend on a template parameter, so a declaration of 'time' mus
t be available [-fpermissive]

I researched this error a little and I've tried renaming time.h to _time.h etc... nothing I try will remove that error.

tssva commented 5 years ago

The issue with the change in SSL library is only present in the ESP8266 Arduino core >= 2.50. Possibly you have a prior version install with the Arduino IDE?

The time.h error occurs systems with case insensitive file systems such as Windows and macOS because the TimeLib library contains a header named Time.h. On case sensitive systems this conflicts with the platform time.h headers file. Using PIO by default the library header files are searched before the platform header files.

This can be fixed in several ways.

  1. The Time.h header file in the TimeLib library directory can be renamed to something else. Every time the library is installed by PIO you will need to rename it.

  2. On macOS create a disk image formatted with a case sensitive file system. Mount it and use it as the directory for your project.

  3. If running Windows 10 version 1803 (April 2018 update) or higher issue the following the command fsutil.exe file SetCaseSensitiveInfo C:\folder\path enable with the path to your project replacing C:\folder\path and Windows 10 will treat your project folder and subfolders as case sensitive.

truglodite commented 5 years ago

Thank you tssva, I solved the problem after uninstalling conflicting a global library (Time.h). It is a bit frustrating dealing with the Windows case insensitivity, but it is what it is (not a problem with Blynk).

truglodite commented 5 years ago

After further testing of BlynkSimpleEsp8266_SSL.h using securebearssl class to handle an ota server (like SecureBearSSLUpdater.ino) with core 2.5.2 and esp8266, it seems to compile but with several "...deprecated axTLS API" warnings. The 12f module resets after running out of memory every time I try to connect with my browser. This (cropped a bit) shows up in the debug log when this occurs:

SDK:2.2.1(cfd48f3)/Core:2.5.2=20502000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020
...
:urd 2, 52, 10
WS:ac
:rn 517
:ref 1
:oom(16709)@?

Abort called

>>>stack>>>

ctx: cont
sp: 3ffffb90 end: 3fffffc0 offset: 01b0
3ffffd40: ...memory content...
...more memory content...
3fffffb0: ...memory content...
<<<stack<<<

last failed alloc call: 40212321(16721)

This reduced version of my code reproduces the crash:

//testBlynkSecureBear.ino

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServerSecure.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#include <BlynkSimpleEsp8266_SSL.h>
extern "C" {
  #include "user_interface.h"
}

#ifndef STASSID
#define STASSID "yourAP"
#define STAPSK  "yourWPA2password"
#endif
char auth[] = "yourAuthToken";// Blynk app auth token

const char* host = "test";
const char* update_path = "/firmware";
const char* update_username = "admin";
const char* update_password = "pass";
const char* ssid = STASSID;
const char* password = STAPSK;

unsigned long otaStartTime = 0;      // Holder for OTA timeout timer
unsigned long otaTimeout =  300;     // Seconds to wait for FW before restart
unsigned long startConnectTime = 0;  // Holder for time when connection attempts are started
unsigned long blynkTimeout = 5;      // Seconds to wait before restart when attempting to connect wifi+blynk

BearSSL::ESP8266WebServerSecure httpServer(443);
ESP8266HTTPUpdateServer httpUpdater;

static const char serverCert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIID+zCCAuOgAwIBAgIJAODWBV7BPBpaMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
VQQGEwJ1czELMAkGA1UECAwCY2ExDTALBgNVBAcMBGNpdHkxHzAdBgNVBAoMFmJs
eW5rU2VjdXJlQmVhclNTTHRlc3QxFTATBgNVBAsMDGJseW5rVGVzdGVyczESMBAG
A1UEAwwJYmx5bmtUZXN0MRwwGgYJKoZIhvcNAQkBFg1ub25lQG5vbmUuY29tMB4X
DTE5MDUyMjIzNDEzNVoXDTMwMDgwODIzNDEzNVowgZMxCzAJBgNVBAYTAnVzMQsw
CQYDVQQIDAJjYTENMAsGA1UEBwwEY2l0eTEfMB0GA1UECgwWYmx5bmtTZWN1cmVC
ZWFyU1NMdGVzdDEVMBMGA1UECwwMYmx5bmtUZXN0ZXJzMRIwEAYDVQQDDAlibHlu
a1Rlc3QxHDAaBgkqhkiG9w0BCQEWDW5vbmVAbm9uZS5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC4pbssbfWaKooBm/1YtqKS8yXbufV1NOMX4/qI
u5tAsqYWi7uUOahSavLb0m9pPH7OOxetnT0cIbvUjVWIGhqatQjTYq+PEPprquSo
eWTeFLN/z1cRwVQTiLx/JBcx0xA1A9oh/1Sz2hbKxgat3SNKfOSmJn/XsC7jPebV
xWRbKuADYSHhpTtr6Akh/hBotbwYb834MWnUgwMSzWVxAL4Zo584C8Amk1ZtHoFm
3bIqN4NY/NYvmqAkjmHyWPRevOJXNzfJ+azzSvUeAG6y7xrBtbMyV4HO8xRaNTps
dF9Csv0RS8arpajJp5y1ptuSQa2us6eJgTG5j1LFToUuGN7bAgMBAAGjUDBOMB0G
A1UdDgQWBBQGB0UaHvVbF/zpadVMNmNvNkSO0zAfBgNVHSMEGDAWgBQGB0UaHvVb
F/zpadVMNmNvNkSO0zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBR
Vbz8bIX0B+ZtBKtCwjUnaLuggI9JcS9McOvplemq9juDuoy55X4Hn4GlE80I8DlM
583ff5TdjHkTwmkeHTdTb1lNfkKD2j9wll4VJDwzMu7nyYb6Khmy7iJqsSTcfPpD
/8L87eZWjWT1N1DXQy1AwJffen8gCvra9g++4c9fGUJ1CDNk4qw4zt9CB2rbPtLM
mnEZ3V1i1a4DXiIjMerApm04/JxbASIbEbWTdQW4xqYSk1qb/WxVW7DUMliA3Lq3
TNidOPxEWq+8aLrgZPRI6gxiwe7kFUnPBXpZtfDKSOqG41pZjLZ0OsEVwTPre50A
GurCOEEs6PNR9KvW5ZpJ
-----END CERTIFICATE-----
)EOF";

static const char serverKey[] PROGMEM =  R"EOF(
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4pbssbfWaKooB
m/1YtqKS8yXbufV1NOMX4/qIu5tAsqYWi7uUOahSavLb0m9pPH7OOxetnT0cIbvU
jVWIGhqatQjTYq+PEPprquSoeWTeFLN/z1cRwVQTiLx/JBcx0xA1A9oh/1Sz2hbK
xgat3SNKfOSmJn/XsC7jPebVxWRbKuADYSHhpTtr6Akh/hBotbwYb834MWnUgwMS
zWVxAL4Zo584C8Amk1ZtHoFm3bIqN4NY/NYvmqAkjmHyWPRevOJXNzfJ+azzSvUe
AG6y7xrBtbMyV4HO8xRaNTpsdF9Csv0RS8arpajJp5y1ptuSQa2us6eJgTG5j1LF
ToUuGN7bAgMBAAECggEANugRYITSI6XCo/feviKQ9WGYQF5rvw6a+N+yADbJU9PL
z6h9fvYmN1vWG8fXmVOD4Y9w2w+GvHbLg8kDRhV9E8QBe9o8mi5SSPHoTLDMbb16
Iudk3MLAXY6rfqMcwpQgnaMnmjRy24hefq2kDs9TTzMUStPn8BtT1f7yRV8NGI6F
W0BMFyLw5Nwi2XeOC9MUB9/lWLRH/OdLZLt9fFRpGy27zGKg5TtXtl75qJkGTTKY
jFm21JxqDtwtv9E4CghOBXaqQIqAQyuMVsBETpjVG9fuTgYGTg1SGWp1TAdA64e2
Z18co6dxaVulmqRxFeWqhI5/Jm7aXzxtAjP6owIIAQKBgQDwSBXqEP/2+5C15NHy
gqnBQDtQ6blhMXrh0aljy6A28yGHVgJmjqYIodLhF9Ph7kQGvtipqwEQwzxBGAA/
zpHUBGwj1aKiNBtyW3RMSUJU2LwuxXyqEEnVN7OIaRycbgPQwUt45n6swVpb9FZ6
0mwnqEmhle/T/ANrqiVQrvEz+wKBgQDEufVeLjBNKfg45IyzgLmXSQU7/2tp71Y1
Rhg1CZu6Os5MFcL5pdkqq+QBu6qdtYdg30LRiCFar9iwP6rIYeyGyUYJj5nebeaV
pWB7VYj+YyDl3u0SVOSD/EyJXOzRt5Dhtd3IDxUNd4alWVpQAl9lheAYl77BLlL+
PnVU+6AqoQKBgQCCtJPHKcwzTBEiAQD7zHwPNaOOljVTW5kesfBU6vWSLpu0hOL1
au+CjpSqAU4u/m9ew/4T/YOs3KcwOaAZFYNaM7WnoJTBa1rq0DjpLoi4otVrE96G
nCmtpIky0QrRRT8qFZu6fpe13dALaVSJp2FSCUdUcL1vMQ2jSYDW7PMkdQKBgQCi
F5LLwgT8X3tt7SrdcE/7Diho8iCgDZsblCC3+q28eV2npTqcloFkPnNE1ktTXNIq
CGs22BKbdU52kk72gnDv8gFqOU8Pzb/zR2tC1AxnhmgB33e45gfPlF+/wrhCaBzR
TRdrErpG+VgQ/5mBWSMfNHqb6NQ8uh2Z7P6iQh4LYQKBgQDvjUfJ5RKcB1RrInIK
Z0B7TxZ80wBYFhReeriywUb5AC7ifoJxu/JwJUSuoZYLm5iSQFO/HPdMOI22Zyp/
O32qqCvYlaOlTXc0nOWe46zsGB4tzzhbdXHxGcWNadWA6l0wF588PraK3SEgA+8+
MIjcYRgeFTbylTOtmqwYUHPdEg==
-----END PRIVATE KEY-----
)EOF";

void setup()
{

  Serial.begin(115200);
  Serial.println("Booting Sketch...");

  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);
  Blynk.config(auth);

  while(WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
    Serial.println("WiFi failed, retrying.");
  }

  if(!Blynk.connect()) {
    startConnectTime = millis();
    while (!Blynk.connect()) {
      if(millis() - startConnectTime > 1000*blynkTimeout) {
        ESP.restart();
        yield();
      }
      yield();
    }
  }

  configTime(-8 * 3600, 0, "pool.ntp.org", "time.nist.gov");
  MDNS.begin(host);
  httpServer.setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey));
  httpUpdater.setup(&httpServer, update_path, update_username, update_password);
  httpServer.begin();
  MDNS.addService("https", "tcp", 443);

  IPAddress myip = WiFi.localIP();
  Serial.println("OTA Waiting...");
  Serial.printf("https://%s%s\n", myip.toString().c_str(), update_path);
  Serial.println("or");
  Serial.printf("https://%s.local%s\n", host, update_path);
}

void loop()
{
  Blynk.run();
  httpServer.handleClient();
  MDNS.update();
  if(millis() - otaStartTime > 1000*otaTimeout)  {
    ESP.reset();
    yield();
  }
}

Otherwise in a far more upscale version of the code, Blynk seems to function as expected, outside the ota portion where the crash is exactly the same. Also, of course the securebearsslupdater sketch works fine on it's own. At this point I am pretty certain this is related to the OP. Fixing this is likely above my head, but it would be great to have encrypted browser update working.

vshymanskyy commented 3 years ago

Should be fixed in the latest (upcoming) v0.6.6