L’aggiornamento OTA (Over the Air) è il processo di caricamento del firmware su un modulo ESP utilizzando una connessione Wi-Fi anziché una porta seriale. Tale funzionalità diventa estremamente utile in caso di accesso fisico limitato o nullo al modulo.
Gli aggiornamenti OTA possono essere effettuati utilizzando:
- Arduino IDE
- Web Browser
- Server HTTP
Prima di tutto leggi il tutorial “esp8266: flash del firmware binario(.bin) compilato e firmato”.
In questo articolo spiegheremo gli aggiornamenti OTA tramite Web Browser del firmware firmato e HTTPS con certificato auto firmato.
Introduzione
Per prima cosa osserviamo che il componente principale del core esp8266 necessita dell’installazione di python e durante l’installazione ricorda di aggiungere i binari alla PATH (per Windows)
Firma del binario compilato
Un’altra forma di sicurezza è firmare il firmware con una chiave privata e poi convalidare con una chiave pubblica, questa forma di sicurezza consente di prevenire la manipolazione e la falsificazione del firmware e nessun’altra persona può caricare un firmware senza chiave privata. Puoi ottenere maggiori informazioni sull’articolo “esp8266 aggiornamenti OTA dall’IDE Arduino: filesystem, firmware firmato e password“.
Generare chiavi pubbliche e private
Per firmare devi generare 2 chiavi: privata e pubblica, e ti serve un programma come openssl, puoi scaricare la versione linux da tutti i gestori di pacchetti, oppure scaricarla per windows da qui, per usarla con più semplicità aggiungi i bin al pah.
Ora possiamo generare la chiave privata
openssl genrsa -out private.key 2048
qui il contenuto del file 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-----
E la relativa chiave pubblica
openssl rsa -in private.key -outform PEM -pubout -out public.key
e qui il mio public.key
:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA12xlf4ADAPkxAmU3nFGX
J4mBZigM3xaWukJv6m8huG5ILQjxreY95alFBFJPut2JIrz7T2Mol5Q9C9Ca5qcX
SgSrliwGjd86Ex/5P64ZGLgMiShedrAgaOReFN6Sj4+f4onzK2K2W2EGeUGWM9b+
np4Gw9vRotOO7HRryuh+cMD6cKrsuNURpxWP/fO9vCtwpucz+8qHsYpVxHptg2UH
+gDoFKjmS0ctrwwGvC2hTbsjqA7JpG5ryymMRbZAkhtwO8SJV2ivtrWqyeDYcUT8
qAqeck1EngVcIvaHq8oCrt633A76b8iCXc1WwEMJPEJ/ksiG7K/ZavYFdZDspt/O
rQIDAQAB
-----END PUBLIC KEY-----
Copia la chiave privata nella cartella dello sketch.
Adesso modifichiamo il codice: per abilitare la verifica della firma inseriamo la public.key e la aggiungiamo al 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};
Quindi installeremo il verificatore nell’Updater.
Update.installSignature(&hash, &sign);
Con il private.key
nella cartella dello sketch quando esporti il binario compilato ottieni queste informazioni sull’IDE di Arduino.
[...]
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.
Puoi trovare il percorso del binario firmato
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
Se provi a caricare il file binario standard ricevi questo errore sulla pagina web.
Update error: ERROR[12]: Signature verification failed
Per risolvere questo problema rinomina ArduinoOTAesp8266_web.ino.bin.signed
in ArduinoOTAesp8266_web.ino.bin
e caricare dall’interfaccia web, ora l’upload andrà bene.
Sketch di esempio con verifica della firma
Qui lo sketch completo
/*
* 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();
}
Aggiornamento del firmware crittografato SSL/TLS e protetto da password
Innanzitutto penso che sia una sciocchezza utilizzare un certificato autofirmato in questo caso, perché se si desidera utilizzare internamente (nella rete LAN privata) non si aggiunge un certificato, si è già all’interno di una rete sicura e se si desidera esporre su Internet una soluzione migliore è utilizzare un proxy con un singolo punto di ingresso (come myhostname.org) con un certificato completo e un insieme di end-point che puntano a un insieme di dispositivi.
Generare un certificato autofirmato
Ma se si desidera utilizzare un certificato autofirmato, è possibile utilizzare OpenSSL per la generazione della chiave privata e del certificato.
Puoi ottenere openssl scaricando la versione Linux da tutti i gestori di pacchetti, o scaricandolo per Windows da qui , per usarlo con più semplicità aggiungilo alla pah.
openssl req -new -x509 -sha256 -newkey rsa:2048 -nodes -keyout key.pem -days 365 -out cert.pem -subj "/CN=esp8266-webupdate.local"
e qui la response
Generating a RSA private key
................................+++++
..........................................................+++++
writing new private key to 'key.pem'
-----
Ora puoi prendere i dati da 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-----
e 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-----
Sketch di esempio HTTPS
Ora aggiungiamo i certificati al codice di esempio
#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();
}
Con certificato autofirmato senza un’autorità di certificazione reale quando si tenta di aprire il browser It ti invia un messaggio per informarti del potenziale rischio
Grazie
- Firmware and OTA update
- Gestione del firmware
- Aggiornamenti OTA con Arduino IDE
- Aggiornamenti OTA con Web Browser
- Aggiornamenti OTA automatico da server HTTP
- Aggiornamenti firmware non standard