espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.64k stars 7.41k forks source link

ESP32 WifiClientSecure #2646

Closed LazarBozic94 closed 5 years ago

LazarBozic94 commented 5 years ago

I'm trying to connect to a mqtt broker with a ca.crt, using PubSubClient and WifiClientSecure, but i always get the -2(connect failed) error code. I've seen people having the same issue, but haven't found a proper working solution. The connection request doesn't get through to the broker. When I try the unsecured 1883 port with WifiClient, everything works just fine.

martinius96 commented 5 years ago

I had similar problems with HTTPS connections, when CA cert (and also client cert) was generated from 1024-bit key. When i tried 2048-bit or higher, it worked.

LazarBozic94 commented 5 years ago

Thank you! I will try that.

martinius96 commented 5 years ago

Does it work? :)

LazarBozic94 commented 5 years ago

I've been preoccupied with other stuff lately. I will post here as soon as I've tried it. Hopefully I'll find some time by the end of this or the next week.

LazarBozic94 commented 5 years ago

Tried the 2048-bit generated CA cert and it still fails :/

martinius96 commented 5 years ago

Hello, I was using OpenSSL on VPS with Cent OS. I have all files in my repo: https://github.com/martinius96/OpenSSL-generator-cert There is example for EC certificates and for RSA certificates. Both were tested and working. You can try it too. Some conf files must be edited like CN (common name), it is domain, for instance example.com. After generating i set these certificates (CA, server to webserver in httpd conf.d file), And also CA and client cert (if you using it, also need to enable it on server side to ask for client certificate) to ESP32.

roberthro commented 5 years ago

Hello, I am facing the same issue, my esp will not connect using this script (based on WiFiClientSecure and pubsubclient): https://github.com/nhatuan84/esp32-mqtts/blob/master/esp32mqtts.ino (with modified credentials and ca.crt) Error messages

V][ssl_client.cpp:192] start_ssl_client(): Performing the SSL/TLS handshake... [E][ssl_client.cpp:33] handle_error(): X509 - Certificate verification failed, e.g. CRL, CA or signature check failed [E][ssl_client.cpp:35] handle_error(): MbedTLS message code: -9984

Connecting to the broker via mqtt.fx works (using the same ca.crt on port 8883) and also works a connect from the esp32 without encryption.

lbernstone commented 5 years ago

As mentioned by @martinius96, the CN of your certificate must match the domain name used to connect, or else you should have an alternative CN in the cert.

martinius96 commented 5 years ago

@roberthro I had same error code -9984 when I was using own CA certificate that was generated from 1024-bit RSA key. When I regenerated it with 2048-bit key, it worked.

If you are not using RSA certificate, but EC certificate. I was testing prime256v1 eliptic curve and it worked on first attempt.

roberthro commented 5 years ago

@martinius96 Tranks a lot für your answer. Could you please give me some more Information? I also was generating own CA certificate with OpenSSL, but from a 2048-bit RSA-key. Acording to this tutorial: http://www.steves-internet-guide.com/mosquitto-tls/ I have done the following steps: openssl genrsa -des3 -out ca.key 2048 openssl req -new -x509 -days 1826 -key ca.key -out ca.crt openssl genrsa -out server.key 2048 openssl req -new -out server.csr -key server.key openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360 I used the ca.crt file as certificate to authorize the Server. This was successful with the mqtt-client mqtt.fx. Could I try something else?

martinius96 commented 5 years ago

@roberthro Try to look into my repository: https://github.com/martinius96/OpenSSL-generator-cert I was generating under OpenSSL. I see some difference between your and mine commands, but i don't know if it is error or something like that.

There are commands, these I was using: https://github.com/martinius96/OpenSSL-generator-cert/blob/master/gen_cert_rsa.bat (in repository there are also configuration files where I have set my domain, etc).

I was generating CA certificate, server certificate and certificate for client (ESP, Windows client). It is from my Bachelor Thesis from this year. Then I have used CA certificate and client key, certificate for my PHP webapplication, I was using WifiClientSecure.h library. I havent tested it under some MQTT library. CA certificate, server certificate I have linked there HTTPD configuration file from my webserver (in your case it is little bit different).

I have put to repo also my implementations from my application (code of ESP32 that I was using).

roberthro commented 5 years ago

@lbernstone yes probably this could be the solution. in client.connect (wificlientsecure) i was using the IP address as server but in the certificate the mqtt broker host name for the CN. I will try the host name tomorrow and let you know wether I have success. Thank you...

roberthro commented 5 years ago

I meant the client.setserver method from wificlientsecure, not client connect. But client.setserver needs the IP Adress of the server and cant be set to the hostname. Server.crt and ca.crt do have identical server information, including the same CN. Next thing I will try, generating new certificate and key with ip adress as CN and if this fails generating certificate and key according to @martinius96 reccommendations.

roberthro commented 5 years ago

So far I was not successful connecting the esp32 to the mqtt broker: I tested the openssl commands from the repository/gen_cert_rsa.bat from @martinius96, the same error occurs: [V][ssl_client.cpp:192] start_ssl_client(): Performing the SSL/TLS handshake... [E][ssl_client.cpp:33] handle_error(): X509 - Certificate verification failed, e.g. CRL, CA or signature check failed [E][ssl_client.cpp:35] handle_error(): MbedTLS message code: -9984 [E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -9984

mqtt.fx can still connect to the mqtt broker successful with the new ca.crt, server.crt and server.key.

does somebody has some ideas, what to try next?

roberthro commented 5 years ago

Yes! (https://github.com/debsahu/ESP_MQTT_Secure/tree/master/ESP32_MQTT_SSL/Arduino) This repo from Debashish Sahu pointed me to the solution. According to his script, the current version of the WiFiclientsecure library does not work for TLS/MQTT connects. He provided an older WiFiClientSecure library that was working for me. But I had to change line 28 in src/dependencies/WiFiClientSecure.h from "class WiFiClientSecure : public Client" into "class WiFiClientSecure : public WiFiClient" After that I could get an TLS encrypted connect to the local MQTT-broker and publish/subscribe to topics.

asetyde commented 5 years ago

Interesting to implemented on our library !

lbernstone commented 5 years ago

Which version worked? Can you git bisect to find what commit broke it?

martinius96 commented 5 years ago

Congratulation @roberthro :) In my case I was using Arduino core 1.0.0, later 1.0.1 without changes of library WiFiClientSecure.h

roberthro commented 5 years ago

@lbernstone I am sorry, I dont know which commit of WiFiclientsecure the project https://github.com/debsahu/ESP_MQTT_Secure/tree/master/ESP32_MQTT_SSL/Arduino is using, therefore I can't do the git bisect, I guess. Additional I changed the mqtt library from pubsubclient to arduino-MQTT (https://github.com/256dpi/arduino-mqtt). Now I have a TLS connect and can publish with qos1/2 (pubsubclient only supports publishing with qos 0 ).

stale[bot] commented 5 years ago

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

stale[bot] commented 5 years ago

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

SERIDJ commented 4 years ago

hi @martinius96 u can help me, i try to use wifiClientSecure library to send small data like (temperature and humidity)from client esp32 (wifi) to server rasberry (wire Ethernet of wifi).

in this library there is 3 EXEMPLE:

WiFiClientSecure : (root certificate authority (CA) cert). WiFiClientSecureEnterprise : (root CA cert plus a client cert and key.) WiFiClientPSK : (pre-shared key (PSK). )

with methode is the best and how can generate certificate for client and server and how i can write code in server raspbeery to read data sended by esp32 with secure ... ?

i try with norme x509 RSA and savouds commande in rasspberry :

i have 3 file : private key fileName is : savouds.com.key certificat fileName is : savouds.com.cert intermediate file for self-signed certificate fileName is : savouds.com.csr

i think private key (savouds.com.key) is my root certificate

but how i can got those :

// You can use x.509 client certificates if you want //const char test_client_key = ""; //to verify the client //const char test_client_cert = ""; //to verify the client

//client.setCertificate(test_client_key); // for client verification //client.setPrivateKey(test_client_cert); // for client verification

and i dont know if i need those file too ???? :

certificat-autorité-options.conf
client.ext
gen_cert_ec.bat gen_cert_rsa.bat
options.conf
server.ext

Best regards, Mohammed SERIDJ

image

martinius96 commented 4 years ago

Hi @SERIDJ . You contacted me a few days ago via Fiverr, so I will describe one more time how to realize your project... Examples you named:

For example, you can generate certificates through OpenSSL. When I was generating certificates it was necessary to define in the hostname configuration files, in my case esp32.sk and www.esp32.sk, as well as in .ext files for CN (Common name).

The certificate for the server and the certificate of the certificate authority is stored on the web server and it contains access to these files (Apache server contains the path to these certificates) in the ssl.conf file it is also possible to enable client authentication. I was configuring Apache package named HTTPD under CentOS Linux server.

ESP32 as a client with the WiFiClientSecure library, source code contains Root CA certificate in .pem format, which is written into the source code. It also contains a client certificate in .pem format and a client (private) key in .key format (only if you use it!). I just opened the .pem file in PsPad (or similar text editor) and copied the code into the Arduino IDE program. I added \n and a slash \ to the end of the lines. You can see it in example of using certificates in this example I used in my Bachelor thesis - using eduroam - Enterprise WiFi: https://pastebin.com/fu9pCSpt

I cannot help you more with your project, I think I gave you enough information how to do it. Finally, an important point. If you use RSA certificates, you need to generate a certificate from at least a 2048-bit key! If you use EC certificates, I recommend prime256v1 curve, it works with this curve, I tested it. You don't need other files after you generate the certificates.