CTBot icon indicating copy to clipboard operation
CTBot copied to clipboard

Avoiding hard-coding the fingerprint in the library

Open GoTVm opened this issue 2 years ago • 2 comments

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:

  • going the Universal Telegram Bot way, creating an X509List object and setting Trust Anchors with the existing certificate, which I've been trying to do to no avail (testConnection does not pass);
  • grabbing the fingerprint every setup / on demand from by scraping (maybe with XHTML?), though that would be an heavy task.

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.

GoTVm avatar Apr 29 '22 15:04 GoTVm

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

shurillu avatar Apr 29 '22 17:04 shurillu

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.

GoTVm avatar Apr 29 '22 17:04 GoTVm