-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Added SSL support. #251
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
base: master
Are you sure you want to change the base?
Added SSL support. #251
Conversation
A new constructor allows specifying the server's SSL certificate's fingerprint, which is used to verify the server's identity after the client is securely connected. It only works on the ESP8266, which has the computation power and memory necessary to do SSL in practice, using WiFiClientSecure.
The MQTT loop now processes all incoming messages at once, instead of stopping at the first one. For the HTTPS client, this ensures the axTLS's read buffer has been completely useed before exiting the function, leaving it available for writing in any subsequent publish() calls.
|
Thanks for this. Don't know how soon I'll be able to look at it properly to get it merged. Have you got a link to the relevant ESP8266 docs for the TLS support? One observation; the client allows publishing from the message-arrived callback. According to the comments you've added, doing so would trash the axTLS buffer and you'd lose messages? |
|
In their master as it is now (esp8266/Arduino@04df3ad), yes, trying to publish inside the message handler would trash the buffer and any further read would return garbage. Then, what usually happens is PubSubClient halts (or times out) because the read message length is a arbitrary large number and the socket will wait to get that many bytes. I've fix that in my fork of Arduino, so WiFiClientSecure::write() returns an error instead of trashing the buffer (see pull request esp8266/Arduino#3019). Hence, mqtt.publish() might fail inside the message callback. Since WiFiClientSecure uses axTLS, a general never-fail publish-in-onmessage is not possible without an additional buffer, because two messages could come in the same SSL packet, and the first one will never be able to publish without killing the buffer for the second. |
|
As a sidenote, one disadvantage of the code is that since it loops reading messages, there is a possible case where the client is overflown with new messages and mqtt.loop() never returns, so the rest of the user code never executes. Although this situation is very extreme, it may still happen. Only axTLS is half duplex, the internal ClientContext has its own (non-decrypted) buffer. So, the collisions only start when doing ssl_read(), which reads from the ClientContext into its own buffer and decrypts (i.e. the collisions do not start immediately when the data arrives to the device). Therefore, there are moments where there may still be a non-decrypted message in the ClientContext but the axTLS buffer is empty. These moments are ideal to exit from the loop. |
The MQTT loop processes all messages to avoid having buffer collisions on axTLS. However, this introduces the possibility of an infinite loop because of heavy inbound traffic, giving no chance to the rest of the user code to run. A new availability cache has been introduced to avoid inducing buffer reads if possible. If after a message has been processed the buffer looks empty, the loop will exit (even if there is information in a secondary buffer or the real non-cached availability has grown). The only way to trap the loop forever now would be to receive a continuous stream of "misaligned" messages which never end on buffer boundaries.
New functionality used C++11 in-class initialization. It has been replaced with initialization in the constructor.
|
hi @diegopx. btw did you get this behavior while using WifiClientSecure with the mqtt server? The WifiClientSecure.write method returns with success even though there is no internet connection? (so the device is connect to a router, sending data to a clouded mqtt server and even with no internet it returns success) This behaivor leads to a memory problem and freezes the device after a while (the WifiClientSecure continues to allocate memory to encrypt the message even it does not send it). |
|
Has this not been merged? |
|
@knolleary Any progress on this? I really like this library and would like to be able to continue using it to securely subscribe to MQTT topics. |
|
@diegopx I noticed that you're using |
|
It's been a while, but from what I can see, you're correct; the connect return value should be checked before verifying. |
A new constructor (available only on the ESP8266) allows the user to verify the SSL certificate fingerprint. Also, to avoid read/write collisions in axTLS buffer, mqtt.loop processes all incoming messages instead of just one.