Skip to content

ESP32 resets when verifying certificate #657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gjt211 opened this issue Sep 22, 2017 · 9 comments
Closed

ESP32 resets when verifying certificate #657

gjt211 opened this issue Sep 22, 2017 · 9 comments

Comments

@gjt211
Copy link

gjt211 commented Sep 22, 2017

Hardware:

Board: ESP32 DevKit V1
Core Installation/update date: 22/Sept/2017?
IDE name: Arduino IDE1.8.3, Mac OS,IDF component?
Flash Frequency: 40Mhz
Upload Speed: 921600

Description:

I am trying to use WiFiClientSecure with a self signed certificate.
I have put my 'server' certificate in my code (not a rootCA as there is not one for self signed), and set the certificate as in the code below.
I have enabled debug output and can see the certificate gets verified then I get the Guru Meditation Error and device reboots.
I tried using Serial.printf("SSL error was: %u\n", client.errorCode()); which is a snippet I found in one of the previous issues, but the compiler fails giving me the error class WiFiClientSecure has no member named errorCode.

Sketch:

//Change the code below by your sketch
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>

const char* ssid = "myssid";
const char* password =  "mypassword";
const char* mqttServer = "my server.com";

#define LED_status 2
#define LED_data 4

const char* server_cert= \
     "-----BEGIN CERTIFICATE-----\n" \
     "MIIDTDCCAjQCCQCGiLLu7i2CjzANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJB\n" \
     "VTEMMAoGA1UECAwDUUxEMRQwEgYDVQQHDAtSb2NraGFtcHRvbjEcMBoGA1UECgwT\n" \
     "RGVmYXVsdCBDb21wYW55IEx0ZDEXMBUGA1UEAwwOc2Vuc29yaG9zdC5jb20wHhcN\n" \
     "MTcwMTAzMTAyMTQzWhcNMzYwMzA0MTAyMTQzWjBoMQswCQYDVQQGEwJBVTEMMAoG\n" \
     "A1UECAwDUUxEMRQwEgYDVQQHDAtSb2NraGFtcHRvbjEcMBoGA1UECgwTRGVmYXVs\n" \
     "dCBDb21wYW55IEx0ZDEXMBUGA1UEAwwOc2Vuc29yaG9zdC5jb20wggEiMA0GCSqG\n" \
     "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwWTuYgliJW8i9LDpUgIBi83xzkeGZC+Op\n" \
     "5vvSI8mJHYHeCgii/NAG7gEPqs9TB808CXX6SBm4iqXg3ZDtRxF7MYNBoGt/VuOc\n" \
     "D3Iv8ZbMFuVyVCGuTqGVy479Xy7/WPThf6blLP7He6IBM47e6FFI4hmHkpq3BNsg\n" \
     "NvtYDuLyW3HpLhBZnAzc8m5qT4q9UPYBvJjC/Ai9HK0h/WecwLCczd3tzgESrlSc\n" \
     "UMVFXTror75tRlA6yoJFdOZUPe0DyRvuvq4US/GB7Pys79DLpHYMMiDsOPzPxKYk\n" \
     "kuXSdoC/l50Y7`ejoExhwljzPBcTpZSAqrwmH2m+TJzLFwbks+7dAgMBAAEwDQYJ\n" \
     "KoZIhvcNAQEFBQADggEBAKnfmMfwgcHai1mwiAU4G7haOjBXtN8xFklN/+Kvken+\n" \
     "w2dZlbry6An8G86vT1cwsI2T2xwoGbR8VLvnzpdGJAH0/8fr4V6IItju4KGgFgg+\n" \
     "cHz+njxP41JQq=fDSa/+MaeHpCUNmjBGJJaUy2vh3Dev8Qx1LpTfTjrX9vaQY3af\n" \
     "t98p2aanCTKiWBU+Wc9kWSxAGMRQOBZOlfkmMRZEj5AbZXjn3PboQBOVL7i8RSAJ\n" \
     "kjGFxKdbxc0ZxvU5vhkBlX7yyMiGgvEZnpS69dc+Z1L1pQXSvRzHJVlQwVmHSXdy\n" \
     "jFmI3/ypgf2aigk/AIsGe6f6px7a6ygQtG16i0ZcCsY=\n" \
     "-----END CERTIFICATE-----\n";

WiFiClientSecure client;

void setup() {
  Serial.begin(115200);
  Serial.print(F("\n\n***\n\n"));
  delay(5000);
 
  Serial.println(F("SSL/TLS ESP32 Test"));
  
  pinMode(LED_status, OUTPUT);
  pinMode(LED_data, OUTPUT);
  digitalWrite(LED_status,1);   //Turn off leds
  digitalWrite(LED_data,1);

  WiFi.begin(ssid, password);

  client.setCertificate(server_cert);
  Serial.print("Server authentication...");
  if (!client.connect("myserver.com", 8883))
    Serial.println("failed!");
    //Serial.printf("SSL error was: %u\n", client.errorCode());
  else {
    Serial.println("success!");
    client.stop();
  }

}

void loop() {
  digitalWrite(LED_status,0);
  delay(200);
  digitalWrite(LED_status,1);
  digitalWrite(LED_data,0);
  delay(200);
  digitalWrite(LED_data,1);
}

Debug Messages:

Connect WiFi:..[D][WiFiGeneric.cpp:215] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:215] _eventCallback(): Event: 7 - STA_GOT_IP
done
Root CA Server authentication...[I][ssl_client.cpp:45] start_ssl_client(): Free heap before TLS 157288
[I][ssl_client.cpp:47] start_ssl_client(): Starting socket
[I][ssl_client.cpp:82] start_ssl_client(): Seeding the random number generator
[I][ssl_client.cpp:91] start_ssl_client(): Setting up the SSL/TLS structure...
[I][ssl_client.cpp:115] start_ssl_client(): WARNING: Use certificates for a more secure communication!
[I][ssl_client.cpp:139] start_ssl_client(): Setting hostname for TLS session...
[I][ssl_client.cpp:154] start_ssl_client(): Performing the SSL/TLS handshake...
[I][ssl_client.cpp:172] start_ssl_client(): Verifying peer X.509 certificate...
[I][ssl_client.cpp:182] start_ssl_client(): Certificate verified.
Guru Meditation Error of type LoadProhibited occurred on core  1. Exception was unhandled.
Register dump:
PC      : 0x400f56a0  PS      : 0x00060d30  A0      : 0x800fe8b1  A1      : 0x3ffd08b0  
A2      : 0x3ffca8d8  A3      : 0x40082a30  A4      : 0x3ffce370  A5      : 0x00000000  
A6      : 0x00000000  A7      : 0xffffffbc  A8      : 0xfefefefe  A9      : 0x3ffd0850  
A10     : 0x3ffcba54  A11     : 0x3ffdf1d8  A12     : 0x00000000  A13     : 0x3f402261  
A14     : 0x00000000  A15     : 0x3ffcec60  SAR     : 0x00000004  EXCCAUSE: 0x0000001c  
EXCVADDR: 0xfefeff26  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffb  

Backtrace: 0x400f56a0:0x3ffd08b0 0x400fe8ae:0x3ffd08d0 0x400d3ba2:0x3ffd08f0 0x400d3618:0x3ffd0b50 0x400d3663:0x3ffd0b70 0x400d235a:0x3ffd0b90 0x4013287f:0x3ffd0bc0

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:588
load:0x40078000,len:0
load:0x40078000,len:9880
entry 0x400789d8

Backtrace decode

0x400f56a0: mbedtls_pk_free at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/mbedtls/library/pk.c line 370
0x400fe8ae: mbedtls_x509_crt_free at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/mbedtls/library/x509_crt.c line 1264
0x400d3ba2: start_ssl_client(sslclient_context*, char const*, unsigned int, char const*, char const*, char const*) at /Users/gjt211/Library/Mobile Documents/com~apple~CloudDocs/Arduino/hardware/espressif/esp32/libraries/WiFiClientSecure/src/ssl_client.cpp line 190
0x400d3618: WiFiClientSecure::connect(char const*, unsigned short, char const*, char const*, char const*) at /Users/gjt211/Library/Mobile Documents/com~apple~CloudDocs/Arduino/hardware/espressif/esp32/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp line 179
0x400d3663: WiFiClientSecure::connect(char const*, unsigned short) at /Users/gjt211/Library/Mobile Documents/com~apple~CloudDocs/Arduino/hardware/espressif/esp32/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp line 179
0x400d235a: setup() at /Users/gjt211/Library/Mobile Documents/com~apple~CloudDocs/Arduino/esp32_ssl1/esp32_ssl1.ino line 167
0x4013287f: loopTask(void*) at /Users/gjt211/Library/Mobile Documents/com~apple~CloudDocs/Arduino/hardware/espressif/esp32/cores/esp32/main.cpp line 15
@copercini
Copy link
Contributor

Let me try understand:

You are trying make your ESP32 verify if your server is the legit one, right?

@gjt211
Copy link
Author

gjt211 commented Sep 23, 2017

Hi @copercini , yes that's correct.
My server has a self signed cert only on port 8883, used for MQTT. The rest of the server (HTTPS/Mail, etc) uses an actual real (paid) certificate. I don't want this certificate to be associated with the MQTT side of things. I have ESP8266 sensors that have been running happily for over a year and I am trying to mimic this now using the ESP32.
Previously I was performing fingerprint authentication on the ESP8266, but now that I have started developing with the ESP32 fingerprint authentication is gone.
As I am the rootCA (self signed), the ESP32 example code doesn't work, i.e. the certificate fails. From what I can tell, this is because it is self signed.

In the process of creating the certificates, I ended up with 6 files as follows;

  • rootCA.key
  • rootCA.pem
  • rootCA.srl
  • server.crt
  • server.csr
  • server.key
    It seems if I use the data from server.crt and use the client.setCertificate(server_cert); command, then in the debug code the certificate verifies ok, but then the device just reboots.
    Trying to use data from the other files (such as from rootCA.pem, and using the set root ca command) the verification always fails.
    I don't care a great deal about certifying if the server is really the legit one, as it not very likely to be wrong, but I do want the encryption of the data that goes along with using TLS/SSL.

@copercini
Copy link
Contributor

I don't care a great deal about certifying if the server is really the legit one, as it not very likely to be wrong, but I do want the encryption of the data that goes along with using TLS/SSL.

So you don't need any certificate on ESP32...

The ESP is crashing due server.* certs are for the server side, and client.setCertificate function is for client certificate if you want to your server verify if the client (ESP32 in the case) is authorized to send data

Anyway, if server certificates are correct installed in the MQTT broker (take a look in the guide bellow), client.setCACert() should works with rootCA.pem to verify the legitimacy of the server, or you can simply doesn't set any cert and this will be encrypted anyway (with someone...)

There is a quick guide and a script to install and configure mosquitto with self-signed certificates or with let's encrypt FREE SSL certs

@gjt211
Copy link
Author

gjt211 commented Sep 23, 2017

Hi @copercini, thanks for your response.
I ended up working out over several hours or trial and error and digging through the library source code if I don't set the rootCA in ESP32, then it connects and works ok. I understand that the certificate is not being used so no actual verification is being performed. I do get the warning in the terminal about not using a certificate.

I believe the server certificates are correctly installed. If I use MQTT.fx to connect to my broker I must specify the same rootCA.pem file or it won't connect. The same for using node-red, I must specify the rootCA.pem file or it will not connect too.

Thank you for your help, and great work with the ESP32.

@gjt211 gjt211 closed this as completed Sep 23, 2017
@everslick
Copy link
Contributor

sorry for posting into a closed issue, but could we still verify the server cert fingerprint on the ESP32 for MITM prevention?

@copercini
Copy link
Contributor

copercini commented Sep 24, 2017

@everslick The fingerprint mechanism used in ESP8266 is nothing more than a SHA-1 hash sum of ASN.1 binary (DER) form of the CA certificate. In simple terms it's a compacted form of original cert, which uses less flash space to store, less heap, keep the code easier to read and so on....

So, why it's not implemented in ESP32?
Because Google make the first proof of practical collision of two SHA-1 hashes few time ago, it's very painful ( 110 GPUs running for a year to produce 2 pdf files with same SHA1 hash) but not impossible. This make most services deprecate SHA-1 use, and it's the case of ESP32.

There are alternatives to SHA-1, like SHA-256 or SHA-3, but how ESP32 has the capacity to deal with the whole certificate, it's more secure, and maybe more easy than get a certificate and generate it's hash.

Obviously I'm just a contributor that helps with some code in my free time, so it's just what I think about it and not official anything

@gjt211
Copy link
Author

gjt211 commented Sep 25, 2017

Hi @copercini, thank you for your explanation of the potential security issues using SHA-1/fingerprint for security.

In some ways I agree and also disagree with the decision to remove it (or not add it) in the ESP32 code base. Here are some of my reasons...

  • Makes it difficult to move ESP8266 code to ESP32
  • 110 GPUs for a year? Unlikely to ever happen to any ESP32.
  • Why not let the user decide what he/she wants to use? (With obvious warnings!)

Due to rootCA problems I am having (only with ESP32), I am now simply ignoring (not using any) certificate but still use TLS/SSL. This is less secure than using a fingerprint verification.

I wish I knew more about how to write libraries so I could add my own fingerprint code, or at least understand why I have the problems that I do and where to look in the core code to find them.

Please keep up the great work! Without people like you doing all the wonderful and helpful work you do, there would not be people like me trying to learn more and more.

@shehrazjazib
Copy link

Sorry to post in a closed thread, but I am still stuck. I want to connect my esp32 with my secure MQTT server. I am using self singed certificate. I used MQTT.fx and connect it with my mqtt server by providing rootCA, client certificate and private key. But when i tried to connect my esp32 using mentioned certificate, I failed and got "certificate not matching" error.
Kindly guide me, how can i resolve this issue

@lbernstone
Copy link
Contributor

lbernstone commented May 17, 2022

Most likely your CN in the certificate does not match how you are connecting from the client. If you use an IP address, you must have that IP address listed as an alternate CN.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants