Skip to content
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

Stack Trace using SSL example #55

Open
PhracturedBlue opened this issue Jul 11, 2017 · 25 comments
Open

Stack Trace using SSL example #55

PhracturedBlue opened this issue Jul 11, 2017 · 25 comments

Comments

@PhracturedBlue
Copy link

PhracturedBlue commented Jul 11, 2017

I'm getting the following stack-trace when connecting to an SSL enabled mosquitto broker. Could this be related to my mosquitto configuration? I didn't modify anything other than the necessary vaeriables at the top of the code.
Build was: platformio run --target upload

I am using Mosquitto as the broker if that is helpful. The only log messages from the broker are:

1499780241: New connection from 192.168.1.3 on port 8883.
1499780331: Client (null) has exceeded timeout, disconnecting.
1499780448: mosquitto version 1.3.4 terminating

Stacktrace:

Exception 3: LoadStoreError: Processor internal physical address or data error during load or store
Decoding 28 results
0x4020e647: __memcpy_aux at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/memcpy.S line 92
0x40246114: chip_v6_unset_chanfreq at ?? line ?
0x402204fb: SHA512_Final at crypto/sha512.c line 207 (discriminator 3)
0x40219770: x509_new at ssl/x509.c line 201
0x4023d427: pp_attach at ?? line ?
0x4023d476: pp_attach at ?? line ?
0x402178f5: process_certificate at ssl/tls1.c line 2005
0x40218cd2: do_clnt_handshake at ssl/tls1_clnt.c line 107
0x4010020c: _umm_free at umm_malloc.c line ?
0x402069b6: ax_port_read at ?? line ?
0x4021871c: do_handshake at ssl/tls1.c line 2005
:  (inlined by) basic_read at ssl/tls1.c line 1481
0x40100688: free at ?? line ?
0x40218884: ssl_read at ssl/tls1.c line 2005
0x4020677d: tcp_ssl_read at ?? line ?
0x40205fa9: AsyncClient::_recv(tcp_pcb*, pbuf*, signed char) at ?? line ?
0x40212b1e: tcp_output at /Users/ivan/e/arduino-esp8266/tools/sdk/lwip/src/core/tcp_out.c line 925
0x40205fdb: AsyncClient::_s_recv(void*, tcp_pcb*, pbuf*, signed char) at ?? line ?
0x4021681c: tcp_input at /Users/ivan/e/arduino-esp8266/tools/sdk/lwip/src/core/tcp_in.c line 394 (discriminator 1)
0x401068f8: pvPortMalloc at ?? line ?
0x40214dd5: ip_input at /Users/ivan/e/arduino-esp8266/tools/sdk/lwip/src/core/ipv4/ip.c line 559
0x40214271: ethernet_input at /Users/ivan/e/arduino-esp8266/tools/sdk/lwip/src/netif/etharp.c line 1379
0x40103c12: lmacTxFrame at ?? line ?
0x4010402d: ppEnqueueRxq at ?? line ?
0x40103dc3: ppProcessTxQ at ?? line ?
0x40103dfe: ppProcessTxQ at ?? line ?
0x4022641b: ets_snprintf at ?? line ?
@PhracturedBlue
Copy link
Author

FYI, I found that the issue was that my cert was generated using SHA512. I used the openssl defaults and everything worked fine.

Feel free to close the issue, but you may want to note it as a caveat that SHA512 certs aren't supported currently.

FYI, The reason I used SHA512 was because I generated my keys with this:
https://github.com/owntracks/tools/blob/master/TLS/generate-CA.sh

Which was linked from this tutorial:
https://stackoverflow.com/questions/26657319/how-do-you-set-up-encrypted-mosquitto-broker-like-a-webpage-which-has-https

@allanbartley
Copy link
Contributor

Thank you for figuring this out.

I've just done a few tests:
SHA1 - OK
SHA256 - OK
SHA512 - Fail (same error as above)

I also note that test.mosquitto.org:8883 uses a certificate with an SHA512 certificate, which explains why I can't connect to that server.

@allanbartley
Copy link
Contributor

Further tests:
SHA224 - OK
SHA384 - Fail
MD5 - OK

@PhracturedBlue
Copy link
Author

I guess this is a bug in the 2.4 staging core? I'm not sure how to provide a test-case though, since the connection goes through many layers.
Thanks for confirming this with various encryption. I have extended your fingerprint code to detect the encryption and warn my users about it:
https://github.com/PhracturedBlue/ESP8266MQTTMesh/blob/master/utils/get_mqtt_fingerprint.py

I hardcoded the patterns, which is crude, but means I don't need to require that any other libraries be installed to use it. Also, I did not see MD5 as a legal signature in the reference docs here:
https://tools.ietf.org/html/rfc5754#section-3

@allanbartley
Copy link
Contributor

MD5 is broken, and I hope no one is using it, I tested it because it listed in the tool I was generating the certificates from. Maybe they removed it from the standard?

I'll make some amendments to the documentation.

@gjt211
Copy link

gjt211 commented Aug 27, 2017

UPDATE
I found the solution in #53 changing the file async_config.h for ESPAsyncTCP as follows;

#ifndef ASYNC_TCP_SSL_ENABLED
#define ASYNC_TCP_SSL_ENABLED 0
#endif

to

#ifndef ASYNC_TCP_SSL_ENABLED
#define ASYNC_TCP_SSL_ENABLED 1
#endif

Sorry for the trouble.

I would like to implement TLS using the arduino IDE, not with PlatformIO. I am using the staging 2.4.0-rc1 core with the appropriate Async libraries.

When I added the TLS parts and try to compile I get the error;
class AsyncMqttClient has no member named 'setSecure'

I understand that somehow I need to add the compiler flag
build_flags = -DASYNC_TCP_SSL_ENABLED=1
but have no idea how to do this.

I have been (and still am) using TLS fingerprint with PubSubClient and I have quite a few sensors that run 24/7.
I have been porting my code over to the Async libraries step by step and now have everything running except for TLS. If anyone can help or provide guidance (or even some clues!) it would be appreciated.

@timpur
Copy link
Collaborator

timpur commented Aug 27, 2017

I got it working with Arduino ide.

I found you also need to import the esp wifi lib as the first thing of your sketch

Example
#include <ESP8266WiFi.h>

#if ASYNC_TCP_SSL_ENABLED
Homie.getLogger() << F("ESP Homie Using TLS") << endl;
Homie.getMqttClient().setSecure(true);
//Homie.getMqttClient().addServerFingerprint((const uint8_t[])MQTT_SERVER_FINGERPRINT);
#endif

// Before homie setup

@barrenechea
Copy link

@timpur did you achieve stability while running over SSL? I'm running it with Arduino IDE, and it crashes and reboots the ESP12 several times while connecting to the MQTT broker (it reboots between 2 to 10 times, until it finally connects).

Using SHA256 cert btw.

@timpur
Copy link
Collaborator

timpur commented Sep 2, 2017

Tbh haven't tested lately, but from memory it seemed fine. No crashes, just a bit longer to connect, but that would make sense.

You can try a combo of these options. Try with better wifi signal. Also try with 160mhz over clock. I'd try the best case, both better wifi signal and over clock. Then work back to see which one make the most significant difference, assuming this effect the crashes at all.

This might tell you if it's performance issues that's causing the crashes.

Also not sure about this but in my tests I was using sha256 like you but I remember making sure the RSA key was only 2048. This might also effect it but not sure.

The picture I get it try use the lowest security on the eap8266 that is still reasonable.

Hope this helps. I'll try do some tests over the weekend and get back to you on these details.

@barrenechea
Copy link

Tried overclocking the device and still the same behavior (I didn't test a better wifi signal because I have an access point like 50cm from my desk).

And I'm using Let's Encrypt certificates, SHA256 and 2048 RSA Key, so it's the same as your tests.

Maybe it's my code, I have to dig deeper in order to detect why it (sometimes) crashes on boot, I guess I'll do that when I have more time.

@timpur
Copy link
Collaborator

timpur commented Sep 4, 2017

Ill do some tests and get back to you with a sketch which is stable for me.

@josep112
Copy link

josep112 commented Feb 6, 2018

I am using mqtt async and I want to implement tls, I followed this tutorial to program the mqtt of linux: https://myles.eftos.id.au/blog/2016/08/07/adding-tls/#.WnhwI5M-fR1 Now I am having trouble programming the esp8266 interface, if anyone can help me thank you, I already researched a lot on Google and found nothing consistent; my code:

#include <ESP8266WiFi.h>
#include <Ticker.h>
#include <AsyncMqttClient.h>

#if ASYNC_TCP_SSL_ENABLED
#define MQTT_SECURE true
#define MQTT_SERVER_FINGERPRINT {0x7e, 0x36, 0x22, 0x01, 0xf9, 0x7e, 0x99, 0x2f, 0xc5, 0xdb, 0x3d, 0xbe, 0xac, 0x48, 0x67, 0x5b, 0x5d, 0x47, 0x94, 0xd2}
#define MQTT_PORT 8883
#else
#define MQTT_PORT 1883
#endif

#define WIFI_SSID "MyHome"
#define WIFI_PASSWORD "1234567"

const char* host = "xxxx.xxxx.net.br";
const char* mqtt_user = "user"; //usuário do mosquitto
const char* mqtt_pwd = "12345"; //senha do mqtt

AsyncMqttClient mqttClient;
Ticker mqttReconnectTimer;

WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
Ticker wifiReconnectTimer;
//=========================================
void connectToWifi()
{
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
//=========================================
void onWifiConnect(const WiFiEventStationModeGotIP& event)
{
Serial.println("Connected to Wi-Fi.");
connectToMqtt();
}
//=========================================
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event)
{
Serial.println("Disconnected from Wi-Fi.");
mqttReconnectTimer.detach(); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
wifiReconnectTimer.once(2, connectToWifi);
}
//=========================================
void connectToMqtt()
{
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
//=========================================
void onMqttConnect(bool sessionPresent) // MQTT Subscribe
{
String clientName;
clientName += "LS";
if (mqttClient.subscribe(clientName.c_str(), 2))
{
Serial.print(">>> [Mosquitto] Subscribe LS : ");
Serial.println(clientName);
}

}
//=========================================
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason)
{
Serial.println("Disconnected from MQTT.");

if (WiFi.isConnected())
{
mqttReconnectTimer.once(2, connectToMqtt);
}
}
//=========================================
/void onMqttSubscribe(uint16_t packetId, uint8_t qos)
{
Serial.println("Subscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
Serial.print(" qos: ");
Serial.println(qos);
}
/

/void onMqttUnsubscribe(uint16_t packetId)
{
Serial.println("Unsubscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
/
//=========================================
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)
{
char message_buff[150];
int i;
for(i=0; i<len; i++) {
message_buff[i] = payload[i];
}
message_buff[i] = '\0';
String msgString = String(message_buff);
Serial.println(msgString);

}
//=========================================
/void onMqttPublish(uint16_t packetId) {
Serial.println("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
/
//=========================================
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();

wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
mqttClient.onMessage(onMqttMessage);
mqttClient.setServer(host, 1883);
mqttClient.setCredentials(mqtt_user,mqtt_pwd);
connectToWifi();

#if ASYNC_TCP_SSL_ENABLED
mqttClient.setSecure(MQTT_SECURE);
if (MQTT_SECURE) {
mqttClient.addServerFingerprint((const uint8_t[])MQTT_SERVER_FINGERPRINT);
}
#endif
}

void loop() {
}

@timpur
Copy link
Collaborator

timpur commented Feb 6, 2018

you defined MQTT_PORT but never used it in mqttClient.setServer(host, 1883); .... so the port never changes based of this define which will definitely cause a issue for you with tls.

@josep112
Copy link

josep112 commented Feb 6, 2018

Does this mean that I should just remove this line and the code will work?

mqttClient.onMessage(onMqttMessage);
//mqttClient.setServer(host, 1883);
mqttClient.setCredentials(mqtt_user,mqtt_pwd);
connectToWifi();

@timpur
Copy link
Collaborator

timpur commented Feb 6, 2018

sorry no should of added, use mqttClient.setServer(host, MQTT_PORT); instead.

@josep112
Copy link

josep112 commented Feb 7, 2018

I made the change you said but I still can not connect to the linux server, is there any more detail I should do in esp?Thank you for your help

@timpur
Copy link
Collaborator

timpur commented Feb 7, 2018

Assuming the fingerprint is the same as your broker ssl fingerprint ?

Assuming your broker certificate is the right format (see docs / known issues)

Should be all g

@timpur
Copy link
Collaborator

timpur commented Feb 7, 2018

When I'm testing SSL connection I normally disable the fingerprint check on the esp and when working then work out the fingerprint

@josep112
Copy link

josep112 commented Feb 8, 2018

Sorry for my experience! So I have to generate a FINGERPRINT of my linux server and for this there is the get-fingerprint.py script, but I can not generate this code I get the following error:
python get-fingerprint.py --host site.net.br --port 8883
site.net.br
Traceback (most recent call last):
File "get-fingerprint.py", line 14, in
cert_pem = ssl.get_server_certificate((args.host, args.port))
File "/usr/lib/python2.7/ssl.py", line 964, in get_server_certificate
with closing(create_connection(addr)) as sock:
File "/usr/lib/python2.7/socket.py", line 571, in create_connection
raise err
socket.error: [Errno 111] Connection refused

@timpur
Copy link
Collaborator

timpur commented Feb 8, 2018

I don't know what your doing sorry, this is beyond this repo, I recommend following a guide on the mqtt broker you are trying to set up. In that they should run through how to set up SSL and to get the fingerprint from the certificate.

@josep112
Copy link

josep112 commented Feb 8, 2018

Thanks, I'm looking for a complete esp and linux tutorial with tls but I'm not finding

@josep112
Copy link

josep112 commented Feb 8, 2018

I have now managed to create my fingerprint but I get the error on the linux side when esp tries to connect
Client connection from xxx.xxx.xxx.xxx failed: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number.

@josep112
Copy link

josep112 commented Feb 8, 2018

My question now is whether to load the ca.crt file into esp spiffs or only fingerprint resolves?

@timpur
Copy link
Collaborator

timpur commented Feb 9, 2018

So on the Linux side there are to ways you can set up the SSL certificate generate a CA certificate and then generate a server certificate from the CA or just create a server certificate. Rather way the esp only checks the server certificate fingerprint, it doesn't check certificate chaining (to my knowledge), so only use the server certificate not the CA certificate. Thus get the server certificate (the one directly used in the mqtt broker) and get the sha1 fingerprint of the certificate

But as I said in one of my posts, I'd test SSL with no fingerprint check enabled on the esp, so you can just test the TLS, and then work out the certificate verification.

@josep112
Copy link

josep112 commented Feb 9, 2018

Yes, now I understand. Debugging better I realized that my code can not activate SSL:
#if ASYNC_TCP_SSL_ENABLED
#define MQTT_SECURE true
#define MQTT_SERVER_FINGERPRINT {0x7e, 0x36, 0x22, 0x01, 0xf9, 0x7e, 0x99, 0x2f, 0xc5, 0xdb, 0x3d, 0xbe, 0xac, 0x48, 0x67, 0x5b, 0x5d, 0x47, 0x94, 0xd2}
#define MQTT_PORT 8883
#else
#define MQTT_PORT 1883
#endif

according to this one above I tried to change
async_config.h for ESPAsyncTCP as follows;

#ifndef ASYNC_TCP_SSL_ENABLED
#define ASYNC_TCP_SSL_ENABLED 0
#endif
to

#ifndef ASYNC_TCP_SSL_ENABLED
#define ASYNC_TCP_SSL_ENABLED 1
#endif

but receive error

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

6 participants