You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[X ] I have read the documentation at readthedocs and the issue is not addressed there.
[X ] I have tested that the issue is present in current master branch (aka latest git).
[X ] I have searched the issue tracker for a similar issue.
If there is a stack dump, I have decoded it.
[X ] I have filled out all fields below.
Platform
Hardware: [ESP-12]
Core Version: [2.5.2]
Development Env: [Arduino IDE]
Operating System: [Ubuntu]
Settings in IDE
Module: [Nodemcu]
Flash Mode: [qio]
Flash Size: [4MB]
lwip Variant: [v2 Lower Memory]
Reset Method: [none]
Flash Frequency: [40Mhz]
CPU Frequency: [160MHz]
Upload Using: [SERIAL]
Upload Speed: [115200] (serial upload only)
Problem Description
I wish to use BearSSL (TLS) for secure socket connection to servers (for example, a MQTT broker running on a RPi). I suppose a domestic LAN infrastructure based on a cheap ISP router (so, no DNS server is available for LAN hostnames).
I would like to select the best solution for that scenario. I wish server & client authentication and, of course, strong encryption with a high security level immune to MITM attacks.
I have considered three options for server authentication: 1 setTrustAnchors(), 2 setKnownKey() and 3 setFingerprint().
The option 1 setTrustAnchors() seems very promising but BearSSL implementation is not very suitable for cheap IoT solutions. If CN (x509) is not equal to hostname (client->connect(hostname, port)), the connection to the server is rejected with code 56 (Expected server name was not found in the chain). This implementation is probably 100% compliant with the TLS specification, but it requires specific certs for each installation. And this is useless for many IoT solutions. Some tools like openssl s_client or python module ssl allow connections to servers without hostname verifications (using only x509 cert). I believe that such less restrictive option would be very useful for ESP8266 too and I would like to recommend to include it in a future release.
The option 2 setKnownKey() avoids the mentioned problem. According to the comments of the example BearSSL_validation.ino, the option seems secure in relation with MITM attacks too. However no chain verification is provided using this method. So we have to store several public keys if we wish to contact different servers.
The option 3 setFingerprint() is apparently not secure enough: "The SHA-1 fingerprint of an X.509 certificate can be used to validate it instead of the whole certificate. This is not nearly as secure as real X.509 validation, but is better than nothing". I do not know if the handshake involves the use of the private key on the server side. If so, the method could be considered secure and immune to MITM attacks, IMHO. But the lack of documentation and the comment is a serious problem here. In any case, the limitations of the setTrustAnchors() method related to hostname and CN do not apply in this case. So, if the method would be secure, this will be my preferred option. But, it is really insecure this option?.
The comments and what you choose to do all depend on your threat model. If you're worried about your neighbor seeing your traffic, even setInsecure is probably good enough. If you're worried about political or industrial espionage, even the default validation may not be enough for you.
Could be considered a less restrictive option for setTrustAnchors() allowing connections to other hostnames not matching with CN?
This is a BearSSL thing. @pornin is absolutely focused on security and allowing hostnames that don't match the common name seems like it throws away the actual validation work he's doing. You could drop him a line (www.bearssl.org) and see what his thoughts are. You can also put in a pull against my port of his library her on github with some hacks.
Is it really insecure the method setFingerprint()?
It's less secure than a cert validation. It's just checking the hash of the cert matches a known value, vs. actually parsing and validating it (i.e. is it still expired?, is this signed by who I think it is? it it even a valid certificate or just random data with the same hash?). You could in theory generate another cert with the same fingerprint and have no way of telling using this.
The absolute "I just want to encrypt" is setInsecure() which checks absolutely nothing about the peer.
Could be improved the BearSSL documentation related to ESP8266?
PRs are always welcome, but in this case the docs are correct. You are not validating the peer.
Basic Infos
Platform
Settings in IDE
Problem Description
I wish to use BearSSL (TLS) for secure socket connection to servers (for example, a MQTT broker running on a RPi). I suppose a domestic LAN infrastructure based on a cheap ISP router (so, no DNS server is available for LAN hostnames).
I would like to select the best solution for that scenario. I wish server & client authentication and, of course, strong encryption with a high security level immune to MITM attacks.
I have considered three options for server authentication: 1 setTrustAnchors(), 2 setKnownKey() and 3 setFingerprint().
The option 1 setTrustAnchors() seems very promising but BearSSL implementation is not very suitable for cheap IoT solutions. If CN (x509) is not equal to hostname (client->connect(hostname, port)), the connection to the server is rejected with code 56 (Expected server name was not found in the chain). This implementation is probably 100% compliant with the TLS specification, but it requires specific certs for each installation. And this is useless for many IoT solutions. Some tools like openssl s_client or python module ssl allow connections to servers without hostname verifications (using only x509 cert). I believe that such less restrictive option would be very useful for ESP8266 too and I would like to recommend to include it in a future release.
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/bearssl-client-secure-class.html#settrustanchors-bearssl-x509list-ta
The option 2 setKnownKey() avoids the mentioned problem. According to the comments of the example BearSSL_validation.ino, the option seems secure in relation with MITM attacks too. However no chain verification is provided using this method. So we have to store several public keys if we wish to contact different servers.
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/bearssl-client-secure-class.html#setknownkey-const-bearssl-publickey-pk
The option 3 setFingerprint() is apparently not secure enough: "The SHA-1 fingerprint of an X.509 certificate can be used to validate it instead of the whole certificate. This is not nearly as secure as real X.509 validation, but is better than nothing". I do not know if the handshake involves the use of the private key on the server side. If so, the method could be considered secure and immune to MITM attacks, IMHO. But the lack of documentation and the comment is a serious problem here. In any case, the limitations of the setTrustAnchors() method related to hostname and CN do not apply in this case. So, if the method would be secure, this will be my preferred option. But, it is really insecure this option?.
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/bearssl-client-secure-class.html#setfingerprint-const-uint8-t-fp-20-setfingerprint-const-char-fpstr
Summary:
Could be considered a less restrictive option for setTrustAnchors() allowing connections to other hostnames not matching with CN?
Is it really insecure the method setFingerprint()?
Could be improved the BearSSL documentation related to ESP8266?
Thanks for you help.
MCVE Sketch
The text was updated successfully, but these errors were encountered: