shurillu / CTBot

A simple (and easy to use) Arduino Telegram BOT Library for ESP8266/ESP32
MIT License
147 stars 34 forks source link

CTBotSecureConnection::connect() not working #78

Closed MicDG closed 3 years ago

MicDG commented 3 years ago

Hello,

after updating the Espressif 32 platform on Platformio to v3.1.0 this method doesn't work anymore. This happens because these lines have been added to ssl_client.cpp in the start_ssl_client(...) method:

if (rootCABuff == NULL && pskIdent == NULL && psKey == NULL && !insecure) {
        return -1;
}

So, since right now there is no rootCA set (nor PSK, but I don't think Telegram supports it), this check fails and the WiFiClientSecure::connect(const char *host, uint16_t port) method fails consequently, bringing therefore any connection we attempt to an halt.

From what I gathered we could both use an insecure connection by adding m_telegramServer.setInsecure(); to CTBotSecureConnection::CTBotSecureConnection() (thus getting the behaviour we had pre-update), otherwise adding a rootCA should be considered for proper, secure connection.

shurillu commented 3 years ago

Hello MicDG, thank you for your feedback! I'll make a fix for this issue this evening (or ASAP).

Stefano

shurillu commented 3 years ago

Hello MicDG, I've just uploaded a new version in the master branch (v2.1.5) and an update for the v.3.0.0 branch that fix the issue: now the library support the SSL Certificate verification for the ESP32 SOC. So please could you check it and give me a feedback?

Cheers, Stefano

MicDG commented 3 years ago

Ciao Stefano, Sorry for being late but I'm quite busy these days, I tried (v3.0.0) but I get this error:

13:56:19.133 > [V][ssl_client.cpp:59] start_ssl_client(): Free internal heap before TLS 219656
13:56:19.140 > [V][ssl_client.cpp:65] start_ssl_client(): Starting socket
13:56:19.171 > [V][ssl_client.cpp:104] start_ssl_client(): Seeding the random number generator
13:56:19.178 > [V][ssl_client.cpp:113] start_ssl_client(): Setting up the SSL/TLS structure...
13:56:19.185 > [V][ssl_client.cpp:129] start_ssl_client(): Loading CA cert
13:56:19.191 > [V][ssl_client.cpp:197] start_ssl_client(): Setting hostname for TLS session...
13:56:19.199 > [V][ssl_client.cpp:212] start_ssl_client(): Performing the SSL/TLS handshake...
13:56:19.290 > [E][ssl_client.cpp:36] _handle_error(): [start_ssl_client():216]: (-9984) X509 - Certificate verification failed, e.g. CRL, CA or signature check failed
13:56:19.304 > [E][WiFiClientSecure.cpp:127] connect(): start_ssl_client: -9984
13:56:19.310 > [V][ssl_client.cpp:265] stop_ssl_socket(): Cleaning SSL connection.

So i guess something's wrong in the certificate formatting. I think uploading the .pem file directly in SPIFFS and load it with a helper function instead of hard-coding could help, maybe, and also make it easier to mantain in case something needs to be changed. I wanted to try this myself but, as I said, I'm a bit constrained lately. If I find some time to spare, however, I'll gladly get my hands dirty.

Thank you, Michele

shurillu commented 3 years ago

Hi Michele, weird behavior! Anyway, you can find the certificate in the CTBotSecureConnection.h file and the procedure that I used to get it. I tried to recompile & upload and the library still works... I have to investigate!

BTW I have already added the possibility to skip the certificate check by setting CTBOT_USE_FINGERPRINT to zero in theCTBotDefines.h

Cheers, Stefano

MicDG commented 3 years ago

Found the error...duh... it was before my eyes all this time but I didn't notice it until just now! In line 45 of CTBotSecureConnection.cpp (v3.0.0, I didn't test v2.1.5):

m_useDNS = false;

should be actually set to true or the common name in the certificate (api.telegram.org) won't match the domain name we're trying to connect to (which is actually an IP) and the verification will fail.

So that's it, just need to change one line.

Michele

shurillu commented 3 years ago

Hi Michele! Thank you for your feedback! As you pointed out the useDNS setting, I noticed that at the beginning of my test sketch there is a useDNS(true)! For that reason I didn't realize why you can't pass the certificate check! I modified both library with m_useDNS= true as default and I added a check in the useDNS method in order to block it when compiling for ESP32 and CTBOT_USE_FINGERPRINT == 1.

Again, thank you! Cheers

Stefano