esp8266 OTA update with Web Browser: sign the firmware and HTTPS (SSL/TLS) – 2

Spread the love

OTA (Over the Air) update is the process of uploading firmware to an ESP module using a Wi-Fi connection rather than a serial port. Such functionality becomes extremely useful in case of limited or no physical access to the module.

esp8266 OTA update with Web Browser: sign the firmware and HTTPS (SSL/TLS)
esp8266 OTA update with Web Browser: sign the firmware and HTTPS (SSL/TLS)

OTA may be done using:

  • Arduino IDE
  • Web Browser
  • HTTP Server

First of all read the tutorial “esp8266: flash firmware binary (.bin) compiled and signed“.

In this article, we are going to explain OTA via Web Browser of signed firmware and HTTPS with a self-signed certificate.

Introduction

First we look that the core component of esp8266 core need python installed, and when install It remember to add to path (for windows)

ESP Tools Install Python and add It to path
ESP Tools Install Python and add It to path

Sign compiled binary

Another form of security is to sign the firmware with a private key and validate with a public key, this form of security allow you to prevent manipulation and falsification of your firmware, and no other people can upload a firmware without private key. You can get more information on the article “esp8266 OTA update with Arduino IDE: filesystem, signed and password“.

Generate public and private keys

To sign you must generate 2 key: private and public, and you need a program like openssl, you can download linux version from all packet manager, or download for windows from here, to use It with more simplicity add to bin pah.

The command to generate the private key:

openssl genrsa -out private.key 2048

here the file content of the private.key:

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA12xlf4ADAPkxAmU3nFGXJ4mBZigM3xaWukJv6m8huG5ILQjx
reY95alFBFJPut2JIrz7T2Mol5Q9C9Ca5qcXSgSrliwGjd86Ex/5P64ZGLgMiShe
drAgaOReFN6Sj4+f4onzK2K2W2EGeUGWM9b+np4Gw9vRotOO7HRryuh+cMD6cKrs
uNURpxWP/fO9vCtwpucz+8qHsYpVxHptg2UH+gDoFKjmS0ctrwwGvC2hTbsjqA7J
pG5ryymMRbZAkhtwO8SJV2ivtrWqyeDYcUT8qAqeck1EngVcIvaHq8oCrt633A76
b8iCXc1WwEMJPEJ/ksiG7K/ZavYFdZDspt/OrQIDAQABAoIBADs1quwRZkH1O/g5
k8BeWJpgW/WVGnySu9jz+8jGxNDpVuMx6yNt/iNKlBKtAQcObuviX3yhd326G9FM
g9bTpD4O7I55CVAjQ9YP2rUbCADYTXHBa71ZiX7rDcTUrBnTUxGz8udA2XhiQaJA
WaVj+VXlf1yD5anIVic9lIcPwfkBQHvR+mnrWqMbGDUoACCqG5B7s8HQqrMMDEMb
m44OunnlbR9yml8Nwve7k1TgQcP3FOPDRzBoB65aKUDYU9qEqLQcmlwEutWJeGbM
FphAcIXyKGCM0MU5WGwgUwRFA3nTA9qz19tJRGCltNBvKN4fySae+8HgpBCiGhxk
cO1nI80CgYEA7JgCEIZ5XFRQzWh9NHj7vx4yFF5RJ1S/kfkZ4fH+LFgctclw5iO2
mFabQJQN59CvbIFyEV7QjhBBY02/okJqmScDCL/ow+xMQ7I5gK/T7YiTwii5zpCJ
RxRgwlUx7lDd6Q/wydwXsnwiLjNi4Rns9naKWO1MhdkebKGBU2Za3LcCgYEA6Rfa
hxGLztAi1rua30OGJ+H/WWEfxuQ/88WUm772F7nTYilXYhgSZSVMVWvK+9dHl6xt
+jSon5NmXinz6H/5yXgiv3/SQMY+SNTSdNBy8DE0kkLvsTPIxma7MFwtzmAoCZFb
FH4EA3yBtbOTPMQOkkVxAq55QZ24k29cglvZE7sCgYEAsQ2AXgWERIgEf/M131K6
cmeSapO6f4h4ZDDaIbAK2fyGX7QD/PW064PEYytozJXq8XRdfIpL4ERh6oKAaljx
lPMQ3jdfZV8sI2z4g0kRe6y9hosboW2gjcS+NC+1UfbKWmNHeohuY29p1NE3qeTQ
5BAJsErE/VVh40FpmpP6YzkCgYEAs4/SojZcE0e3buA64D8uO88XXI07Y4Y11d6h
KpGjFofqVTYvwLt2gECJW0ycpAElf6wvVI34UGXGeEetQ7BChndrnUYkfA27sXNx
ZNenk2z0aK/z4fhYdK5zCUAZcWAVt7koBtNE2EKz0Xuysx79cqTX+A7cDjYoGDuz
ciC7Sz0CgYEA4OfQK3fsGR9wuBkDzlSS6NBpgXEKpkcTSuY8+SAq+BA0i981Hehz
rkSJU6kd5FK/q+7bk0zgwhQf7RKa2O+ChDSGYnwD38ns06mn8AZIMgltITmxzliK
N8fcchAv5ETo/+zeHTIR32PJe+s+U8pyuquheZi+nrVRjXgyo0uyqi0=
-----END RSA PRIVATE KEY-----

And the relative public key

openssl rsa -in private.key -outform PEM -pubout -out public.key

and here my public.key:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA12xlf4ADAPkxAmU3nFGX
J4mBZigM3xaWukJv6m8huG5ILQjxreY95alFBFJPut2JIrz7T2Mol5Q9C9Ca5qcX
SgSrliwGjd86Ex/5P64ZGLgMiShedrAgaOReFN6Sj4+f4onzK2K2W2EGeUGWM9b+
np4Gw9vRotOO7HRryuh+cMD6cKrsuNURpxWP/fO9vCtwpucz+8qHsYpVxHptg2UH
+gDoFKjmS0ctrwwGvC2hTbsjqA7JpG5ryymMRbZAkhtwO8SJV2ivtrWqyeDYcUT8
qAqeck1EngVcIvaHq8oCrt633A76b8iCXc1WwEMJPEJ/ksiG7K/ZavYFdZDspt/O
rQIDAQAB
-----END PUBLIC KEY-----

Copy the private key on sketch folder.

Public Private key sign and verify process
Public Private key sign and verify process

Now we modify the code: to enable the verify of the sign, we insert the public.key and add It to the SignVerifier

BearSSL::PublicKey signPubKey{R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA12xlf4ADAPkxAmU3nFGX
J4mBZigM3xaWukJv6m8huG5ILQjxreY95alFBFJPut2JIrz7T2Mol5Q9C9Ca5qcX
SgSrliwGjd86Ex/5P64ZGLgMiShedrAgaOReFN6Sj4+f4onzK2K2W2EGeUGWM9b+
np4Gw9vRotOO7HRryuh+cMD6cKrsuNURpxWP/fO9vCtwpucz+8qHsYpVxHptg2UH
+gDoFKjmS0ctrwwGvC2hTbsjqA7JpG5ryymMRbZAkhtwO8SJV2ivtrWqyeDYcUT8
qAqeck1EngVcIvaHq8oCrt633A76b8iCXc1WwEMJPEJ/ksiG7K/ZavYFdZDspt/O
rQIDAQAB
-----END PUBLIC KEY-----)"};
BearSSL::HashSHA256 hash;
BearSSL::SigningVerifier sign{&signPubKey};

Then we are going to install the verifier to the Updater.

  Update.installSignature(&hash, &sign);

With the private.key in the sketch folder when you export compiled binary you get this information on Arduino IDE.

[...]
Creating BIN file "C:\Users\renzo\AppData\Local\Temp\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin" using "C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2/bootloaders/eboot/eboot.elf" and "C:\Users\renzo\AppData\Local\Temp\arduino_build_153716/ArduinoOTAesp8266_web.ino.elf"
"C:\\Users\\renzo\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\python3\\3.7.2-post1/python3" -I "C:\\Users\\renzo\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\3.0.2/tools/signing.py" --mode sign --privatekey "D:\\Projects\\Arduino\\sloeber-workspace-OTA\\ArduinoOTAesp8266_web/private.key" --bin "C:\\Users\\renzo\\AppData\\Local\\Temp\\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin" --out "C:\\Users\\renzo\\AppData\\Local\\Temp\\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin.signed" --legacy "C:\\Users\\renzo\\AppData\\Local\\Temp\\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin.legacy_sig"
Signed binary: C:\Users\renzo\AppData\Local\Temp\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin.signed
Legacy signed binary: C:\Users\renzo\AppData\Local\Temp\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin.legacy_sig
"C:\\Users\\renzo\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\python3\\3.7.2-post1/python3" -I "C:\\Users\\renzo\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\3.0.2/tools/sizes.py" --elf "C:\\Users\\renzo\\AppData\\Local\\Temp\\arduino_build_153716/ArduinoOTAesp8266_web.ino.elf" --path "C:\\Users\\renzo\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.0.4-gcc10.3-1757bed/bin" --mmu "-DMMU_IRAM_SIZE=0x8000 -DMMU_ICACHE_SIZE=0x8000"
Executable segment sizes:
ICACHE : 32768           - flash instruction cache 
IROM   : 338612          - code in flash         (default or ICACHE_FLASH_ATTR) 
IRAM   : 27753   / 32768 - code in IRAM          (IRAM_ATTR, ISRs...) 
DATA   : 1508  )         - initialized variables (global, static) in RAM/HEAP 
RODATA : 1928  ) / 81920 - constants             (global, static) in RAM/HEAP 
BSS    : 26392 )         - zeroed variables      (global, static) in RAM/HEAP 
Using library ESP8266WiFi at version 1.0 in folder: C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WiFi 
Using library ESP8266WebServer at version 1.0 in folder: C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer 
Using library ESP8266mDNS at version 1.2 in folder: C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266mDNS 
Using library ESP8266HTTPUpdateServer at version 1.0 in folder: C:\Users\renzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266HTTPUpdateServer 
"C:\\Users\\renzo\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\xtensa-lx106-elf-gcc\\3.0.4-gcc10.3-1757bed/bin/xtensa-lx106-elf-size" -A "C:\\Users\\renzo\\AppData\\Local\\Temp\\arduino_build_153716/ArduinoOTAesp8266_web.ino.elf"
Sketch uses 369801 bytes (35%) of program storage space. Maximum is 1044464 bytes.
Global variables use 29828 bytes (36%) of dynamic memory, leaving 52092 bytes for local variables. Maximum is 81920 bytes.

You can find the path of the signed binary

Signed binary: C:\Users\renzo\AppData\Local\Temp\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin.signed
Legacy signed binary: C:\Users\renzo\AppData\Local\Temp\arduino_build_153716/ArduinoOTAesp8266_web.ino.bin.legacy_sig

If you try to upload the standard binary file you get this error on web page.

Update error: ERROR[12]: Signature verification failed

To solve this problem rename ArduinoOTAesp8266_web.ino.bin.signed to ArduinoOTAesp8266_web.ino.bin and upload from the web interface, now the upload will be fine.

Example sketch with sign verification

Here the complete sketch

/*
 * Upload signed binary and check the validity
 *
 * Renzo Mischianti <www.mischianti.org>
 *
 * https://mischianti.org
*/

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>

#ifndef STASSID
#define STASSID "<YOUR-SSID>"
#define STAPSK  "<YOUR-PASSWD>"
#endif

const char* host = "esp8266-webupdate";
const char* ssid = STASSID;
const char* password = STAPSK;

ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;

BearSSL::PublicKey signPubKey{R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA12xlf4ADAPkxAmU3nFGX
J4mBZigM3xaWukJv6m8huG5ILQjxreY95alFBFJPut2JIrz7T2Mol5Q9C9Ca5qcX
SgSrliwGjd86Ex/5P64ZGLgMiShedrAgaOReFN6Sj4+f4onzK2K2W2EGeUGWM9b+
np4Gw9vRotOO7HRryuh+cMD6cKrsuNURpxWP/fO9vCtwpucz+8qHsYpVxHptg2UH
+gDoFKjmS0ctrwwGvC2hTbsjqA7JpG5ryymMRbZAkhtwO8SJV2ivtrWqyeDYcUT8
qAqeck1EngVcIvaHq8oCrt633A76b8iCXc1WwEMJPEJ/ksiG7K/ZavYFdZDspt/O
rQIDAQAB
-----END PUBLIC KEY-----)"};
BearSSL::HashSHA256 hash;
BearSSL::SigningVerifier sign{&signPubKey};

void setCrossOrigin(){
	httpServer.sendHeader(F("Access-Control-Allow-Origin"), F("*"));
	httpServer.sendHeader(F("Access-Control-Max-Age"), F("600"));
	httpServer.sendHeader(F("Access-Control-Allow-Methods"), F("PUT,POST,GET,OPTIONS"));
	httpServer.sendHeader(F("Access-Control-Allow-Headers"), F("*"));
};

void sendCrossOriginHeader(){
    httpServer.sendHeader(F("access-control-allow-credentials"), F("false"));
    setCrossOrigin();
    httpServer.send(204);
}

void setup(void) {

  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting Sketch...");
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);

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

  MDNS.begin(host);

  Update.installSignature(&hash, &sign);

  httpServer.on("/update", HTTP_OPTIONS, [&](){
	  return sendCrossOriginHeader();
  });


  httpUpdater.setup(&httpServer);
  httpServer.begin();

  MDNS.addService("http", "tcp", 80);
  Serial.printf("HTTPUpdateServer modified ready! Open http://%s.local/update in your browser\n", host);
}

void loop(void) {
  httpServer.handleClient();
  MDNS.update();
}

SSL/TLS encrypted, password-protected firmware update

First I think It’s a nonsense use a self signed certificate in this case, because if you want to use internally (in the private LAN network) you don’t add a certificate, you are already inside a secure network, and if you want export to the internet a better solution is to use a proxy with a single entry point with a complete certificate (like myhostname.org) and a set of end point that point to a set of device.

HTTPS TLS SSL encryption Arduino OTA
HTTPS TLS SSL encryption Arduino OTA

Generate self signed certificate

But if you want use a self signed certificate you can use OpenSSL for generation of private key and certificate.

You can get openssl by download linux version from all packet manager, or download for windows from here, to use It with more simplicity add to bin pah.

openssl req -new -x509 -sha256 -newkey rsa:2048 -nodes -keyout key.pem -days 365 -out cert.pem -subj "/CN=esp8266-webupdate.local"

and here the response

Generating a RSA private key
................................+++++
..........................................................+++++
writing new private key to 'key.pem'
-----

Now you can grab data from key.pem

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDO6ep+PPJyteLw
VfsRYW+xE+QDWEmz/ef30nQUWuOXaEl9k2Smf4fY8v2JGgTPZDWxaJH3mH3iRZJB
0bc3+uXMyl/LuHfWAmrhoPjag+O9Ujnh5d+uDt6R/pP5XnUhGcux/TOGt5lxva9A
qujyUWPOviXQsATgKRg933/YUvDXJ3NKaODOCN/zswehxoil0Q9MIux2f7esjuGU
dp8FkGgywpdRnav1ksFv0RQFXGAeFDxiWKcVafQnVoZvS3PvCD6S/wAOJdS8yhfb
tjuRHv30UY5wY6K/aZkXekIuZNHsdFRQCQWhvlMefqgxqF2uokvFnz2MMUhrjEzG
M9D6/qwNAgMBAAECggEAOW33Zd5otKoDOQ3ER8ixhYatzLfejRS2I7TH/zZS4R1S
+IXGc+gFvpODB2CvYRjBRmJt0TkEB5+jvp0Eq4b57WNmP1cN+9pj7AgPyia9OTjv
U+HHubnq0L7GN3qeK/fK77YFbSjccBNj5yEI0ukAOMvSFyAj2kvNrK6x/0rWCgEr
DzhhQflUeX2JBw+HD1i/G6xD2iiWFdsbQ34WhyrBoCuwQfeNZgvbewPUBN6GWYW/
GRKgRgKdcdJaZiwziYspsS2lvkUpMFWor7wJxcxJrrT66FCIvQvskYa/o3sKRTN0
6B4sBAUETDAXgdbPlxExZDdcgnUKKybX8m9NAykRwQKBgQD2sV22F8tRx7hpWu1G
d2mb9qS6HEZeTaS8FdWw6yzss5ym93TfRnRKTolCIxV359/0QdZMrAWM7mLGhgtV
o2YWSzPiyj/xhtBNuYtEQNoFNLNxohrkOQMmCAHVGjNgRtnwfiRm+3m5xK+X9Qyx
HXpRSv2PNzK1YJmeNlxocnk7yQKBgQDWuFnxywFB6Lwft8vNafA9e3HDIuiI4JKX
rhDmX4AY2vl1xoBKVuM4zK3sgF92aVGEodmefbrvj9+72bua0qV2Gl93SBRILrOp
AzlFl/W3UfJAFZbWmMyZ/vUhamYccQcX6ZsnPuywwKAlZ45z77Epfk7q6Fog/LDx
QMlCDKTIJQKBgBUF3neTJYeNnqCT2B6mNIDPDxCxMin9Mem5bqGKGST+1X3BHtuc
NHLUqIvTU5QJVaOKLMoR6tMsyYwjhjnBGAUUWZKdK7/Yfk3xXvXtFOdWq2gmqWYD
mcoW6pkPh4tP3mjJRy7jhWcYZOJtRqydV3wwCNW4nYCpf83k0hEwmDZJAoGBAIUD
EoTcctz3ZYJogxGurKoJjIGLYG1aYLUhmUp8oofDLoGtA9AJXxzSfnNhWsGpoFv/
PyYVUPYSNFDUIolYMDOnRrhHqHjGpXjvjEz2Q7raQq08MoKhiS1kaUnX9YVs5y4D
AqAfNNSRnyNMsUxUkXTYz95pLVv97UamEYae+n0ZAoGBAILovmkobGoX47ar982f
DSBE4/mP+XDxTdlCnvQlayte/kPkxuXGoQLeYMCjVaEXj3VpvGiCrmXDY06zTWEU
il0LUxmJAHMAhlThAcGDX7E9Pe074IjXcEimLIymlA2y+lKjjBw4tCAJ9AE1IoOW
jT5dHIIrcEvWfzPD7vYLUsuG
-----END PRIVATE KEY-----

and cert.pem

-----BEGIN CERTIFICATE-----
MIIDJTCCAg2gAwIBAgIUBmbGoJSq0xzDIafpLUCUOErHjhMwDQYJKoZIhvcNAQEL
BQAwIjEgMB4GA1UEAwwXZXNwODI2Ni13ZWJ1cGRhdGUubG9jYWwwHhcNMjEwOTA2
MTUzMzU3WhcNMjIwOTA2MTUzMzU3WjAiMSAwHgYDVQQDDBdlc3A4MjY2LXdlYnVw
ZGF0ZS5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7p6n48
8nK14vBV+xFhb7ET5ANYSbP95/fSdBRa45doSX2TZKZ/h9jy/YkaBM9kNbFokfeY
feJFkkHRtzf65czKX8u4d9YCauGg+NqD471SOeHl364O3pH+k/ledSEZy7H9M4a3
mXG9r0Cq6PJRY86+JdCwBOApGD3ff9hS8Ncnc0po4M4I3/OzB6HGiKXRD0wi7HZ/
t6yO4ZR2nwWQaDLCl1Gdq/WSwW/RFAVcYB4UPGJYpxVp9CdWhm9Lc+8IPpL/AA4l
1LzKF9u2O5Ee/fRRjnBjor9pmRd6Qi5k0ex0VFAJBaG+Ux5+qDGoXa6iS8WfPYwx
SGuMTMYz0Pr+rA0CAwEAAaNTMFEwHQYDVR0OBBYEFCCiLnO7vzfy6hLQwGpfi2Hx
liMbMB8GA1UdIwQYMBaAFCCiLnO7vzfy6hLQwGpfi2HxliMbMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAMllu6J/fdKwzkngUvVJJXIjdtTeXrSj
xPI8weEVhyHb4EHyRsXv0J7TmJRmSHtCyiLvmvW0tOKzrofe1uDTUTnMR6fldsU0
WtQv5bHeFaij5uyoAKvjJtBhWleR1+Sry94htEv30dZu8P1vppeiwoFiOwxYoxq3
wncRBb+T5WrjOTh6xJM5zuloHdgA47NC0htW5N68uAH2M+55cFcFKq3haU5uSMqz
wdf0UDFGM1JtRa96W2a5wdtpIv/BQ0wTZcsKhXuyou2jXqBkQWIjR7Vk2k3pZiJN
iOFjRPL4HLA5RGZfoSkl0AvIPTmheusZknkroRq+j1OBAKd7Ss9GQD0=
-----END CERTIFICATE-----

HTTPS example sketch

Now we add the certificates to the example code

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServerSecure.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>

#ifndef STASSID
#define STASSID "<YOUR-SSID>"
#define STAPSK  "<YOUR-PASSWD>"
#endif

const char* host = "esp8266-webupdate";
const char* update_path = "/firmware";
const char* update_username = "mischianti";
const char* update_password = "passwd";
const char* ssid = STASSID;
const char* password = STAPSK;

ESP8266WebServerSecure httpServer(443);
ESP8266HTTPUpdateServerSecure httpUpdater;

static const char serverCert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDJTCCAg2gAwIBAgIUBmbGoJSq0xzDIafpLUCUOErHjhMwDQYJKoZIhvcNAQEL
BQAwIjEgMB4GA1UEAwwXZXNwODI2Ni13ZWJ1cGRhdGUubG9jYWwwHhcNMjEwOTA2
MTUzMzU3WhcNMjIwOTA2MTUzMzU3WjAiMSAwHgYDVQQDDBdlc3A4MjY2LXdlYnVw
ZGF0ZS5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7p6n48
8nK14vBV+xFhb7ET5ANYSbP95/fSdBRa45doSX2TZKZ/h9jy/YkaBM9kNbFokfeY
feJFkkHRtzf65czKX8u4d9YCauGg+NqD471SOeHl364O3pH+k/ledSEZy7H9M4a3
mXG9r0Cq6PJRY86+JdCwBOApGD3ff9hS8Ncnc0po4M4I3/OzB6HGiKXRD0wi7HZ/
t6yO4ZR2nwWQaDLCl1Gdq/WSwW/RFAVcYB4UPGJYpxVp9CdWhm9Lc+8IPpL/AA4l
1LzKF9u2O5Ee/fRRjnBjor9pmRd6Qi5k0ex0VFAJBaG+Ux5+qDGoXa6iS8WfPYwx
SGuMTMYz0Pr+rA0CAwEAAaNTMFEwHQYDVR0OBBYEFCCiLnO7vzfy6hLQwGpfi2Hx
liMbMB8GA1UdIwQYMBaAFCCiLnO7vzfy6hLQwGpfi2HxliMbMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAMllu6J/fdKwzkngUvVJJXIjdtTeXrSj
xPI8weEVhyHb4EHyRsXv0J7TmJRmSHtCyiLvmvW0tOKzrofe1uDTUTnMR6fldsU0
WtQv5bHeFaij5uyoAKvjJtBhWleR1+Sry94htEv30dZu8P1vppeiwoFiOwxYoxq3
wncRBb+T5WrjOTh6xJM5zuloHdgA47NC0htW5N68uAH2M+55cFcFKq3haU5uSMqz
wdf0UDFGM1JtRa96W2a5wdtpIv/BQ0wTZcsKhXuyou2jXqBkQWIjR7Vk2k3pZiJN
iOFjRPL4HLA5RGZfoSkl0AvIPTmheusZknkroRq+j1OBAKd7Ss9GQD0=
-----END CERTIFICATE-----
)EOF";

static const char serverKey[] PROGMEM =  R"EOF(
-----BEGIN RSA PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDO6ep+PPJyteLw
VfsRYW+xE+QDWEmz/ef30nQUWuOXaEl9k2Smf4fY8v2JGgTPZDWxaJH3mH3iRZJB
0bc3+uXMyl/LuHfWAmrhoPjag+O9Ujnh5d+uDt6R/pP5XnUhGcux/TOGt5lxva9A
qujyUWPOviXQsATgKRg933/YUvDXJ3NKaODOCN/zswehxoil0Q9MIux2f7esjuGU
dp8FkGgywpdRnav1ksFv0RQFXGAeFDxiWKcVafQnVoZvS3PvCD6S/wAOJdS8yhfb
tjuRHv30UY5wY6K/aZkXekIuZNHsdFRQCQWhvlMefqgxqF2uokvFnz2MMUhrjEzG
M9D6/qwNAgMBAAECggEAOW33Zd5otKoDOQ3ER8ixhYatzLfejRS2I7TH/zZS4R1S
+IXGc+gFvpODB2CvYRjBRmJt0TkEB5+jvp0Eq4b57WNmP1cN+9pj7AgPyia9OTjv
U+HHubnq0L7GN3qeK/fK77YFbSjccBNj5yEI0ukAOMvSFyAj2kvNrK6x/0rWCgEr
DzhhQflUeX2JBw+HD1i/G6xD2iiWFdsbQ34WhyrBoCuwQfeNZgvbewPUBN6GWYW/
GRKgRgKdcdJaZiwziYspsS2lvkUpMFWor7wJxcxJrrT66FCIvQvskYa/o3sKRTN0
6B4sBAUETDAXgdbPlxExZDdcgnUKKybX8m9NAykRwQKBgQD2sV22F8tRx7hpWu1G
d2mb9qS6HEZeTaS8FdWw6yzss5ym93TfRnRKTolCIxV359/0QdZMrAWM7mLGhgtV
o2YWSzPiyj/xhtBNuYtEQNoFNLNxohrkOQMmCAHVGjNgRtnwfiRm+3m5xK+X9Qyx
HXpRSv2PNzK1YJmeNlxocnk7yQKBgQDWuFnxywFB6Lwft8vNafA9e3HDIuiI4JKX
rhDmX4AY2vl1xoBKVuM4zK3sgF92aVGEodmefbrvj9+72bua0qV2Gl93SBRILrOp
AzlFl/W3UfJAFZbWmMyZ/vUhamYccQcX6ZsnPuywwKAlZ45z77Epfk7q6Fog/LDx
QMlCDKTIJQKBgBUF3neTJYeNnqCT2B6mNIDPDxCxMin9Mem5bqGKGST+1X3BHtuc
NHLUqIvTU5QJVaOKLMoR6tMsyYwjhjnBGAUUWZKdK7/Yfk3xXvXtFOdWq2gmqWYD
mcoW6pkPh4tP3mjJRy7jhWcYZOJtRqydV3wwCNW4nYCpf83k0hEwmDZJAoGBAIUD
EoTcctz3ZYJogxGurKoJjIGLYG1aYLUhmUp8oofDLoGtA9AJXxzSfnNhWsGpoFv/
PyYVUPYSNFDUIolYMDOnRrhHqHjGpXjvjEz2Q7raQq08MoKhiS1kaUnX9YVs5y4D
AqAfNNSRnyNMsUxUkXTYz95pLVv97UamEYae+n0ZAoGBAILovmkobGoX47ar982f
DSBE4/mP+XDxTdlCnvQlayte/kPkxuXGoQLeYMCjVaEXj3VpvGiCrmXDY06zTWEU
il0LUxmJAHMAhlThAcGDX7E9Pe074IjXcEimLIymlA2y+lKjjBw4tCAJ9AE1IoOW
jT5dHIIrcEvWfzPD7vYLUsuG
-----END RSA PRIVATE KEY-----
)EOF";


void setup()
{

  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting Sketch...");
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);

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

  configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");

  MDNS.begin(host);

  httpServer.getServer().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);
  Serial.printf("BearSSLUpdateServer ready!\nOpen https://%s.local%s in "\
                "your browser and login with username '%s' and password "\
                "'%s'\n", host, update_path, update_username, update_password);
}

void loop()
{
  httpServer.handleClient();
  MDNS.update();
}

With self signed certificate without a real certification autority when you try to open It browser send you a message to inform you of potential risk

self signed certificate on Web Arduino OTA browser message
self signed certificate on Web Arduino OTA browser message

Thanks

  1. Firmware management
    1. esp8266: flash firmware binary (.bin) compiled and signed
    2. esp8266: flash firmware and filesystem binary (.bin) compiled with GUI tools
  2. OTA update with Arduino IDE
    1. esp8266 OTA update with Arduino IDE: filesystem, signed and password
  3. OTA update with Web Browser
    1. esp8266 OTA update with Web Browser: firmware, filesystem and authentication
    2. esp8266 OTA update with Web Browser: sign the firmware and HTTPS (SSL/TLS)
    3. esp8266 OTA update with Web Browser: custom web interface
  4. Self OTA uptate from HTTP server
    1. esp8266 self OTA update firmware from server
    2. esp8266 self OTA update firmware from server with version check
    3. esp8266 self OTA update in HTTPS (SSL/TLS) with trusted self signed certificate
  5. Non standard Firmware update
    1. esp8266 firmware and filesystem update from SD card
    1. esp8266 firmware and filesystem update with FTP client


Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *