Skip to content

ESPhttpUpdate Error[12] Signature verification failed #8707

Closed
@seism0saurus

Description

@seism0saurus

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [D1 Mini]
  • Core Version: [git fff12e3]
  • Development Env: [Arduino IDE 1.8.13]
  • Operating System: [Debian stable]

Settings in IDE

  • Module: [Lolin(Wemos) D1 mini r2 & mini]
  • Flash Size: [4MB (2MB FS 1MB OTA)]
  • lwip Variant: [v2 Lower Memory]
  • CPU Frequency: [80Mhz]
  • Upload Using: [First SERIAL than OTA]
  • Upload Speed: [921600]
  • Debug Level: [HTTP_UPDATE]
  • They are the default settings after selecting the D1 mini as board

Problem Description

Since I used the latest version from the master branch the autosigning of the bin files does no longer work correctly. It worked with the last release. I switched to the git version because a bugfix for a component is not released yet.

I made a simplified MCVE with only WLAN and ESP8266httpUpdate to test that problem.

  • create a project folder in your Arduino IDE folder
  • You need a keypair in the project folder to enable the signing:
    openssl genrsa -out private.key 2048
    openssl rsa -in private.key -outform PEM -pubout -out public.key
  • You have to set your WLAN credentials and the ip of your development pc and compile the scratch
  • Upload it to the D1 mini
  • Export the scratch as bin with the Arduino IDE feature
  • Start a small server to deliver the bin file
    { echo -ne "HTTP/1.0 200 OK\r\nContent-Length: $(wc -c <MCRE.ino.d1_mini.bin)\r\n\r\n"; cat MCRE.ino.d1_mini.bin; } | nc -l 9090
  • Restart the D1 mini and watch the serial output. The update will fail because it can't verify the signature
  • In the export log was also a signed file mentioned. Copy it
    cp /tmp/arduino_build_113468/MCRE.ino.bin.signed MCRE.ino.d1_mini.bin.signed
  • Start a small server to deliver the signed bin file
    { echo -ne "HTTP/1.0 200 OK\r\nContent-Length: $(wc -c <MCRE.ino.d1_mini.bin.signed)\r\n\r\n"; cat MCRE.ino.d1_mini.bin.signed; } | nc -l 9090
  • Restart the D1 mini and watch the serial output. The update will fail again because it can't verify the signature

Is it intentional that the exported bin is not the signed bin? I can see that the signed bin from the tmp folder is 260 bytes bigger. I had expected that the signed bin would be exported, since it already detected, that it should be signed.

The main problem is that the signature verification does not work anymore. I searched through the documentation if i missed any change but could not find anything. Could you please help me with this MCVE?

MCVE Sketch

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>

// Please replace the ip with the ip of your computer and make port 9090 accessable so that netcat can deliver the update
String ipOfThisComputer = "192.168.179.222";

// Please replace with the WLAN credentials, so that your computer and the ESP are in the same network
String ssid = "mywlan";
String wlanPassword = "mypassword";
WiFiClient client;

void setup() {
  delay(1000);
  Serial.begin(9600);
  Serial.println(F("Serial inteface for debugging is initialized with 9600 baud."));
  
  initWlan();

  ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW); 
  t_httpUpdate_return ret = ESPhttpUpdate.update(client, ipOfThisComputer, 9090, "/");
  handleUpdateResult(ret);
}

void loop() { 
  delay(1000);
  Serial.println(F("Sleeping..."));
}

void initWlan(){
  Serial.print(F("Connecting to "));
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, wlanPassword);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println(F("WiFi connected"));
}

void handleUpdateResult(t_httpUpdate_return ret){
  String logMessage;
  switch (ret) {
    case HTTP_UPDATE_FAILED:
      logMessage = "Firmware update canceled. Error (";
      logMessage += ESPhttpUpdate.getLastError();
      logMessage += "): ";
      logMessage += ESPhttpUpdate.getLastErrorString().c_str();
      break;
    case HTTP_UPDATE_NO_UPDATES:
      logMessage = "Already using the latest firmware. No update needed";
      break;
    case HTTP_UPDATE_OK:
      logMessage = "Firmware update done";
      break;
  }
  Serial.println(logMessage);
}

Debug Messages

[httpUpdate] Header read fin.
[httpUpdate] Server header:
[httpUpdate]  - code: 200
[httpUpdate]  - len: 342964
[httpUpdate] ESP8266 info:
[httpUpdate]  - free Space: 1748992
[httpUpdate]  - current Sketch Size: 346080
[httpUpdate] runUpdate flash...
sleep disable
[httpUpdate] Update.end failed! (ERROR[12]: Signature verification failed)
[httpUpdate] Update failed
Firmware update canceled. Error (12): Update error: ERROR[12]: Signature verification failed
pm open,type:0 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions