Don't read pubkey from file anymore

This commit is contained in:
Ben Wiederhake 2017-04-10 22:32:38 +02:00
parent 512eeed013
commit 53c92303a2
4 changed files with 10 additions and 140 deletions

View file

@ -281,15 +281,11 @@ Discussion / Help
As we want to avoid OpenSSL, it has become necessary to replace the PEM file format. This means that if you use a custom pubkey (which you really REALLY shouldn't be doing), you have to adapt, sorry.
We no longer ship `tg-server.pub` (old format), but instead `tg-server.tglpub` (new format). If you have a `.pub` and want to continue using telegram-purple, please use this (hopefully highly portable) tool: [pem2bignum](https://github.com/BenWiederhake/pem2bignum)
You can also write your own conversion tool if you prefer. The format is really simple:
1. `e`, the public exponent, encoded as big endian 32 bit fixed length (e.g. `0x00 01 00 01` for 65537)
2. `n_len`, the length of `n` in bytes, encoded as big endian 32 bit fixed length (e.g. `0x00 00 01 00` for a 2048-bit = 256-byte key)
3. `n_raw`, the raw modulus, encoded as big endian, using the previously indicated length (e.g. `0xC1 50 02 3E [248 bytes omitted] 21 79 25 1F` in the case of telegram's public RSA key.)
If you are interested in developing a non-OpenSSL-licensed converter, look into [insane-triangle-banana](https://github.com/BenWiederhake/insane-triangle-banana).
We no longer read the public key of the Telegram servers from a file.
If you really need a different public key, and know what you're doing
(e.g., connecting to some kind of test environment internal to Telegram,
which also is a very bad idea), you need to find the call to `tgl_set_rsa_key_direct` in `telegram-purple.c`,
and provide the key directly by yourself.
FAQ

View file

@ -35,68 +35,6 @@
#define STATE_FILE_MAGIC 0x28949a93
#define SECRET_CHAT_FILE_MAGIC 0x37a1988a
static gboolean read_ui32 (int fd, unsigned int *ret) {
typedef char check_int_size[(sizeof (int) >= 4) ? 1 : -1];
(void) sizeof (check_int_size);
unsigned char buf[4];
if (4 != read (fd, buf, 4)) {
return 0;
}
// Ugly but works.
*ret = 0;
*ret |= buf[0];
*ret <<= 8;
*ret |= buf[1];
*ret <<= 8;
*ret |= buf[2];
*ret <<= 8;
*ret |= buf[3];
return 1;
}
int read_pubkey_file (const char *name, struct rsa_pubkey *dst) {
// Just to make sure nobody reads garbage.
dst->e = 0;
dst->n_len = 0;
dst->n_raw = NULL;
int pubkey_fd = open (name, O_RDONLY | O_BINARY);
if (pubkey_fd < 0) {
return 0;
}
unsigned int e;
unsigned int n_len;
if (!read_ui32 (pubkey_fd, &e) || !read_ui32 (pubkey_fd, &n_len) // Ensure successful reads
|| n_len < 128 || n_len > 1024 || e < 5) { // Ensure (at least remotely) sane parameters.
close (pubkey_fd);
return 0;
}
unsigned char *n_raw = malloc (n_len);
if (!n_raw) {
close (pubkey_fd);
return 0;
}
gint readret;
readret = read (pubkey_fd, n_raw, n_len);
if (readret <= 0 || (n_len != (guint) readret)) {
free (n_raw);
close (pubkey_fd);
return 0;
}
close (pubkey_fd);
dst->e = e;
dst->n_len = n_len;
dst->n_raw = n_raw;
info ("read pubkey file: n_len=%u e=%u", n_len, e);
return 1;
}
void read_state_file (struct tgl_state *TLS) {
char *name = 0;
name = g_strdup_printf("%s/%s", TLS->base_path, "state");
@ -440,20 +378,6 @@ gchar *get_config_dir (char const *username) {
return dir;
}
gchar *get_user_pk_path () {
/*
This can't be conditional on whether or not we're using telepathy, because
then we would need to make sure that `make local_install` also knows about
that location. So we *always* use ${HOME}/.purple/telegram-purple,
even when the other files aren't in this folder.
Note that this is only visible when using Telepathy/Empathy with
local_install, which should be kinda rare anyway (use telepathy-morse!).
*/
return g_strconcat (g_get_home_dir(), G_DIR_SEPARATOR_S, ".purple",
G_DIR_SEPARATOR_S, "telegram-purple",
G_DIR_SEPARATOR_S, user_pk_filename, NULL);
}
gchar *get_download_dir (struct tgl_state *TLS) {
assert (TLS->base_path);
static gchar *dir;

View file

@ -22,14 +22,6 @@
#include "telegram-purple.h"
struct rsa_pubkey {
unsigned int e;
unsigned int n_len;
unsigned char *n_raw;
};
gboolean read_pubkey_file (const char *name, struct rsa_pubkey *dst);
void read_state_file (struct tgl_state *TLS);
void read_auth_file (struct tgl_state *TLS);
void write_auth_file (struct tgl_state *TLS);
@ -40,7 +32,6 @@ void write_secret_chat_file (struct tgl_state *TLS);
void write_secret_chat_gw (struct tgl_state *TLS, void *extra, int success, struct tgl_secret_chat *E);
gchar *get_config_dir (char const *username);
gchar *get_user_pk_path ();
gchar *get_download_dir (struct tgl_state *TLS);
int tgp_visualize_key (struct tgl_state *TLS, unsigned char* sha1_key);

View file

@ -18,6 +18,8 @@
Copyright Matthias Jentsch, Vitaly Valtman, Ben Wiederhake, Christopher Althaus 2014-2015
*/
#include <mtproto-key.h>
#include "telegram-purple.h"
#include "commit.h"
@ -37,12 +39,6 @@ static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret
static void update_on_failed_login (struct tgl_state *TLS);
const char *config_dir = "telegram-purple";
const char *user_pk_filename = "server.tglpub";
#ifdef WIN32
const char *pk_path = "server.tglpub";
#else
const char *pk_path = "/etc/telegram-purple/server.tglpub";
#endif
struct tgl_update_callback tgp_callback = {
.new_msg = update_message_handler,
@ -541,46 +537,9 @@ static void tgprpl_login (PurpleAccount * acct) {
tgl_set_download_directory (TLS, get_download_dir(TLS));
debug ("base configuration path: '%s'", TLS->base_path);
struct rsa_pubkey pubkey;
#ifdef WIN32
gchar *global_pk_path = g_strdup_printf("%s/%s", DATADIR, pk_path);
#else
gchar *global_pk_path = g_strdup(pk_path);
#endif
debug ("trying global pubkey at %s", global_pk_path);
gboolean global_pk_loaded = read_pubkey_file (global_pk_path, &pubkey);
g_free(global_pk_path);
tgl_set_verbosity (TLS, 4);
if (global_pk_loaded) {
info ("using global pubkey");
tgl_set_rsa_key_direct (TLS, pubkey.e, pubkey.n_len, pubkey.n_raw);
} else {
char *user_pk_path = get_user_pk_path ();
debug ("trying local pubkey at %s", user_pk_path);
gboolean user_pk_loaded = read_pubkey_file (user_pk_path, &pubkey);
if (user_pk_loaded) {
info ("using local pubkey");
tgl_set_rsa_key_direct (TLS, pubkey.e, pubkey.n_len, pubkey.n_raw);
} else {
failure ("both didn't work. abort.");
char *cause = g_strdup_printf (_("Unable to sign on as %s: file (public key) not found."),
purple_account_get_username (acct));
purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, cause);
char *long_hint = g_strdup_printf (
_("Make sure telegram-purple is installed properly,\n"
"including the .tglpub file.\n"
"If you're running SELinux (e.g. when using Tails),\n"
"try 'make local_install', or simply copy\n"
"%1$s to %2$s."), pk_path, user_pk_path);
purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR, cause,
long_hint, NULL, NULL, NULL);
g_free (cause);
g_free (long_hint);
return;
}
}
tgl_set_rsa_key_direct (TLS, tglmp_get_default_e(),
tglmp_get_default_key_len(),
tglmp_get_default_key());
tgl_set_ev_base (TLS, conn);
tgl_set_net_methods (TLS, &tgp_conn_methods);