shurillu / CTBot

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

Avoiding hard-coding the fingerprint in the library #95

Open GoTVm opened 2 years ago

GoTVm commented 2 years ago

After seeing what a fingerprint change caused, is there a way to avoid using the fingerprint certification method, or maybe have the code dynamically update it every time it runs/on demand? I was thinking either:

So far what I've tried is `

elif defined(ARDUINO_ARCH_ESP8266) && CTBOT_USE_FINGERPRINT == 1 // ESP8266 with HTTPS verification

BearSSL::WiFiClientSecure telegramServer; //telegramServer.setFingerprint(m_fingerprint); X509List cert(m_CAcert); telegramServer.setTrustAnchors(&cert); ` in CTBotSecureConnection.cpp. This just implements the same identical code as UTB, though with a different certificate.

The web scraping idea is, at least in my opinion, more versatile than hard-coding, but still relies on the website HTML to never change. Though it would still be easier to implement.

EDIT: I'm trying to format the code decently but it doesn't seem to work.

shurillu commented 2 years ago

Hello GoTVm, I thought a lot about the fingerprint mechanism in the past. Web scraping or build up a webservice/hosting a text file with the updated fingerprint imply that someone that is not you have the bourden of updating it. If that person did not update the fingerprint or the web scraping did not work anymore, you are screwed ;-) For that reason I did two thing;

  1. provide a member function for defining a custom fingerprint CTBot::setFingerPrint(const uint8_t *newFingerprint)
  2. provide a way (detailed in CTBotSecureConnection.h) to generate a new fingerprint. Simply go here, write down the Telegram bot API URL (api.telegram.org) in the textbox and get the updated fingerprint.

So everyone can build up his own method for having the fingerprint always updated on his device, without rely on other persons/services. I have heard too many times about closed devices becoming bricks because the company stop to support it.

Obviuosly all the code is not written in the stone and I'm still open for ideas!

Cheers Stefano

GoTVm commented 2 years ago

First off, for some reason the link did not appear in my original comment. I'm still getting used to GitHub, apologies. When I talked about web scraping, I thought about scraping straight from the grc.com website. Your objection about relying on third party services is more than fair and I could not agree more, but since your library still indirectly relies on the website (instead of pulling it automatically, it relies on you going to grc.com/fingerprints.htm?domain=api.telegram.org and using setFingerprint), it wouldn't change much with respect to dependencies.

Regarding my other point, which is what I'm currently focusing on, is there no other way to certify that you're talking to api.telegram.org that doesn't rely on fingerprints? I'm not too knowledgeable on this matter, though I've worked on it a couple of times in the past. Why won't testConnection pass if it doesn't have a fingerprint? I could still set the certificate and trust anchors in the WiFiClientSecure.