-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add WiFiServerSecure and ESP8266WebServerSecure, SSL enabled servers for HTTPS/SSH/etc. #3001
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
Conversation
a57c768
to
d77c3d3
Compare
Codecov Report
@@ Coverage Diff @@
## master #3001 +/- ##
========================================
Coverage ? 27.6%
========================================
Files ? 20
Lines ? 3655
Branches ? 678
========================================
Hits ? 1009
Misses ? 2468
Partials ? 178 Continue to review full report at Codecov.
|
e9e11f5
to
2ae0c29
Compare
02bc803
to
22bfaa6
Compare
Latest commit adds in a new HTTPS server class, ESP8266WebServerSecure and example HelloServerSecure. Both use the WiFiSecureServer in the previous commits. I learned more than I wanted to about C++ object slicing and hidden class variables, thanks to the existing object hierarchy, but it's run a loop of WGET's against the HelloServerSecure overnight on my system. |
84b2f05
to
a98465f
Compare
Added and tested a SSL-encrypted SecureWebUpdater example. Since the SecureWebServer class is passed by pointer, there's only 2-lines of change (+key/cert addition) to enable secure, SSL encrypted, password-protected ESPP updates. I'll squash everything to a single commit closer to the 2.5.0 release for easier merging, assuming it's accepted. |
Thanks, this is a really awesome feature. I intend to review and merge this (along with other changes, such as @d-a-v 's LwIP PR) once 2.4.0 is released, which hopefully can be done soon — the release candidate has been out for a few weeks and no major issues (aside from memory use) have been found. |
Happy to help out. Hopefully this will make it easier for everyone to make more secure IoT things! |
Hi, |
@jmseight , You'll need to use GIT and get the head of the main branch then use the GitHub instructions to get this pull (#3001) merged into your local copy. See https://help.github.com/articles/checking-out-pull-requests-locally/ for more info. |
Sorry for not understanding how to get the items. I tried "git fetch origin pull/#3001/esp8266:master" and got "fatal: Not a git repository (or any of the parent directories): .git", for "Modifying an inactive pull request locally". Also, I cannot find "Near the bottom of the pull request, in the merge box, click command line instructions. Follow the sequence of steps to bring down the proposed pull request." as instructed for "Modifying an active pull request locally". |
@jmseight, I think you just didn't change into the cloned Arduino directory. Here's my exact command output: earle@server:/tmp$ git clone https://github.com/esp8266/Arduino.git |
Hi,
Thank you for the instructions. I was able to download the items.
Sorry for not understanding this well. However, when I tried to Include Libraries as ZIP file and chose the folder, but I get errors with enum of WEP (in user_interface.h) and errors with udp.h.
I tried to replace user_interface.h and udp.h with the ones that I got from the download, but I get many other errors with the library.
Currently I am using V2.3.0 of the ESP8266 board SW. I think the version that you are using have is 3.2.3, correct? I can only get up to 2.3.0 form the Board manger in Arduino IDE on mac. Is this why there is a conflict?
Thanks
James
---
James H-J Yeh, Ph.D.
Assistant Professor, Engineering and Computer Science
Azusa Pacific University
On Aug 16, 2017, at 9:21 PM, Earle F. Philhower, III <[email protected]> wrote:
@jmseight <https://github.com/jmseight>, I think you just didn't change into the cloned Arduino directory. Here's my exact command output:
earle@server:/tmp$ git clone https://github.com/esp8266/Arduino.git <https://github.com/esp8266/Arduino.git>
Cloning into 'Arduino'...
remote: Counting objects: 14632, done.
remote: Compressing objects: 100% (27/27), done.
remote: Total 14632 (delta 11), reused 19 (delta 7), pack-reused 14597
Receiving objects: 100% (14632/14632), 36.66 MiB | 8.23 MiB/s, done.
Resolving deltas: 100% (8477/8477), done.
Checking connectivity... done.
earle@server:/tmp$ cd Arduino/
earle@server:/tmp/Arduino$ git fetch origin pull/3001/head:pull3001
From https://github.com/esp8266/Arduino <https://github.com/esp8266/Arduino>
[new ref] refs#3001/head -> pull3001
earle@server:/tmp/Arduino$ git checkout pull3001
Switched to branch 'pull3001'
earle@server:/tmp/Arduino$ head libraries/ESP8266WiFi/src/WiFiServerSecure.cpp
/*
WiFiServerSecure.cpp - SSL server for esp8266, mostly compatible
with Arduino WiFi shield library
...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#3001 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AdQr--vvv-SU8GinZtx5A6_EXm6YgBjcks5sY7_cgaJpZM4MN9n8>.
|
@igrr Hi, Any update on when this might be merged? |
// Base class's destructor will be called to clean up itself | ||
} | ||
|
||
// We need to basically cut-n-paste these from WebServer because of the problem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes no sense to me. Where is there an assignment such as ESP8266Webserver = ESP8266WebServerSecure? If there is anywhere where an assignment is done, then there is likely a bug there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is not the webserver, but the WiFiServer.available() model...
...
WiFiClient(Secure) client = _server(Secure).available();
...
Because WiFiServer and it's children return a copy of a object, not a pointer to a new()'d one, the caller needs to know how big it will be/etc. So the WebServerSecure class can't fall back on the WebServer::handle() method and let the vtable work its magic. Object slicing, if I remember the term properly, is the problem here.
If there was an method like "virtual WiFiClient *WiFiServer.available();" it would be easier to reuse the WebServer code. The Secure HTTPS Updater example shows this use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know about object slicing. When you encounter it, it's usually a sign of a bug or of bad design (not always).
I should investigate this. Sigh, so much to do!
In any case, not a fault in your implementation, which is why I only commented and approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can also be solved with the template-based implementation and passing by reference, to some extent. Plus a few helper methods to clear the current client and get a new one from the WebServer. Will handle in another PR.
@earlephilhower thanks for this PR and @igrr for the commit. Any chance of seeing an example for remote OTA updates rather than local OTA updates? |
@pieman64 here's the list of cipher suites supported by axTLS: Regarding key sizes: no theoretical limit in the library, however memory constraints of the application may limit key sizes which will be achievable. |
@igrr thanks for the link to the available cipher suites and the info on key sizes. Yes I think bin updates from remote servers with SSL are probably more popular than local updates because generally you can trust your own local network. |
Ok, essentially that's There's some work in progress to make it possible to verify server certificate using root certificate rather than using a fingerprint. Once done, i will add an example about ESPhttpUpdate with root cert verification. |
@igrr we are already using the fingerprint system and it's working OK with a basic sketch and bin files hosted on GitHub. The problem is once you start building a meaningful sketch it runs out of memory. |
The only real solution to that is to allocate most of the things dynamically in the sketch. Then you can go into "update" mode or "normal" mode and enable features separately. There will be some improvement in memory usage down the road once we fix the support for fragment length negotiation extension. That will, however, require having a server which supports that extension. |
Thanks for this ! |
Thanks all for the input and feedback to make it a better patch. @pieman64 while it does support 2048 bits, you may run into out of RAM issues during SSL negotiations. It has worked before (you can change the # of bits in the make-cert.sh script and try w/your own self-signed ones), but practically it puts you in a very tight RAM situation... @igrr 's comment about dynamically allocating things is exactly what I'm doing in my own self-contained ESP8266 power plug firmware. To get enough RAM for upgrade w/SSL I have to stop and free pretty much everything when a toggle is set, then after a timeout force a system reset to get back to normal mode in case the upgrade is not done. |
Hi, i'm unable to get the HelloServerSecure example working correctly, and would greatly appreciate your help. I modified the example to use a AWS IOT client certificate, and then after a couple of resets and an occasional watchdog, I get the "Hello from esp8266 over HTTPS!", Chome only complaining about net::ERR_CERT_AUTHORITY_INVALID, which is normal for self-signed certificates, right? Don't know if the "Error : ..." statement has anything to do with my problem; it seems to come from the axtls library, but i'm using the libaxtls.a from the repo. . I modified the example with a AWS IOT client certificate, and then after a couple of resets and an occasional watchdog, I get the "Hello from esp8266 over HTTPS!", with the following serial output : . Exception (29): ctx: cont
ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x4010f000, len 1384, room 16 scandone connected with TP-LINK, channel 6 |
That error's actually quite good compared to the normal "randomly crash when something's wrong" we seem to have everywhere! Can you put your code up (obfuscate your client cert, of course!) and decode the exception? You're only allowed a single cert per SSL connection, so on an server.available() it removes the old SSL context + cert and stuffs in its host + pricate key. It dos its work and then the server's wificlientsecure goes away. At that point, the orig client will have its connection dropped and reconnect after manually reloading its client certs. Or at least that's the theory. |
Hi, |
Howdy @stefaandesmet2003 . The HelloServerSecure runs fine for me, as does a SSL MQTT client in parallel not using client SSL certs (I do that w/psychoplug). Due to axtls SSL limitations, when an incoming web SSL request comes in, the outgoign SSL MQTT link gets dropped (and reconnected next pass thru the loop). Are you saying your attached ZIP, with the code as-commented, also gives you a failure? It looks like it's effectively the same as the base example, no? If you're really brave, in #4273 I've replaced axtls w/BearSSL which allows for multiple SSL contexts and user-defined buffer sizes so you really can have parallel incoming and outgoing connections. I've run the mqtt_esp8266 example w/client certs on it (to my own server) for several hours w/o incident. |
Hi @earlephilhower , |
Hi @earlephilhower , The HelloServerSecure example now works without reset for 1 browser request (i used lwip v2 lower memory variant), but |
Great, thanks @stefaandesmet2003! Well, not really great but now I can reproduce what you're seeing. There is obviously a memory leak somewhere in here when used with the WebServerSecure. There's some ugly refcount stuff going on in all the SSL code (to share the single SSL_CTX memory), and I believe some logic in the Server/Client is borked when the refcnt is higher than expected that I've flubbed. Since this pull is closed and merged, would you like to open a new issue so it's tracked properly? Memory leak in WebServerSecure on repeated connections. |
Anyone running this in their own apps, please check #4305 as I've done significant cleanup and it's now way more stable and usable, allowing parallel client and server connections, each with their own certs, and no interference between the two. |
thanks for your big effort. Will give it go very soon! |
Thanks to all who have worked on this! I was able to get the HTTPS example running. |
Thanks for the reply @d-a-v. I added the x509 certificate and rsakey arrays. Then I had to comment out a bunch of lines that the compiler complained about: By the time all the stuff was commented out that the compiler choked on, it won't actually do telnet - in fact it never even outputs the "Connecting to " message on the serial port. |
Use WiFiClientSecure, not the webserver.
*edit*: I mean WiFiServerSecure of course :-]
|
Thanks again, @d-a-v . I think I have it working now. Next I just have to find a telnet client that is capable of using SSL so I can test it. |
You can try with
|
Howdy,
First of all, thanks for the amazing work in making the ESP8266 toolchain very approachable. I'd like to give back with a change that I did this weekend to support a SSL server (useful for SSH or HTTPS) mode of operations.
Example code is included with a self-signed certificate generation script to get users up to speed quickly.