From f8793376a5a4956c9203bfe89e4d1c0a6121afd2 Mon Sep 17 00:00:00 2001 From: vysheng Date: Wed, 25 Dec 2013 03:42:05 +0400 Subject: [PATCH 1/6] Fixed random on sensible parts (generation auth_key, session_id and keys for secret chats) --- main.c | 4 ++++ mtproto-client.c | 19 ++++++++++++++----- mtproto-client.h | 1 + queries.c | 6 ++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index 1de65d8..f0cd56d 100644 --- a/main.c +++ b/main.c @@ -78,6 +78,7 @@ char *binlog_file_name; int binlog_enabled; extern int log_level; int sync_from_start; +int allow_weak_random; void set_default_username (const char *s) { if (default_username) { @@ -375,6 +376,9 @@ void args_parse (int argc, char **argv) { case 'E': disable_auto_accept = 1; break; + case 'w': + allow_weak_random = 1; + break; case 'h': default: usage (); diff --git a/mtproto-client.c b/mtproto-client.c index c22bb5a..a010d85 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -69,7 +69,7 @@ char new_nonce[256]; char server_nonce[256]; extern int binlog_enabled; extern int disable_auto_accept; - +extern int allow_weak_random; int total_packets_sent; long long total_data_sent; @@ -98,6 +98,15 @@ double get_utime (int clock_id) { return res; } +void do_rand (void *s, int l) { + if (RAND_bytes (s, l) < 0) { + if (allow_weak_random) { + RAND_pseudo_bytes (s, l); + } else { + assert (0 && "End of random. If you want, you can start with -w"); + } + } +} #define STATS_BUFF_SIZE (64 << 10) @@ -223,7 +232,7 @@ int rpc_send_message (struct connection *c, void *data, int len) { int send_req_pq_packet (struct connection *c) { assert (c_state == st_init); - assert (RAND_pseudo_bytes ((unsigned char *) nonce, 16) >= 0); + do_rand (nonce, 16); unenc_msg_header.out_msg_id = 0; clear_packet (); out_int (CODE_req_pq); @@ -371,7 +380,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) { //out_int (0x0501); // q=5 out_ints ((int *) nonce, 4); out_ints ((int *) server_nonce, 4); - assert (RAND_pseudo_bytes ((unsigned char *) new_nonce, 32) >= 0); + do_rand (new_nonce, 32); out_ints ((int *) new_nonce, 8); sha1 ((unsigned char *) (packet_buffer + 5), (packet_ptr - packet_buffer - 5) * 4, (unsigned char *) packet_buffer); @@ -564,7 +573,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) { BN_init (&dh_g); BN_set_word (&dh_g, g); - assert (RAND_pseudo_bytes ((unsigned char *)s_power, 256) >= 0); + do_rand (s_power, 256); BIGNUM *dh_power = BN_new (); assert (BN_bin2bn ((unsigned char *)s_power, 256, dh_power) == dh_power); @@ -683,7 +692,7 @@ void init_enc_msg (struct session *S, int useful) { // assert (DC->server_salt); enc_msg.server_salt = DC->server_salt; if (!S->session_id) { - assert (RAND_pseudo_bytes ((unsigned char *) &S->session_id, 8) >= 0); + do_rand (&S->session_id, 8); } enc_msg.session_id = S->session_id; //enc_msg.auth_key_id2 = auth_key_id; diff --git a/mtproto-client.h b/mtproto-client.h index 458d6c5..5f04dea 100644 --- a/mtproto-client.h +++ b/mtproto-client.h @@ -29,4 +29,5 @@ void work_update_binlog (void); int check_g (unsigned char p[256], BIGNUM *g); int check_g_bn (BIGNUM *p, BIGNUM *g); int check_DH_params (BIGNUM *p, int g); +void do_rand (void *s, int l); #endif diff --git a/queries.c b/queries.c index ec35d15..3719de7 100644 --- a/queries.c +++ b/queries.c @@ -2263,8 +2263,10 @@ void do_send_accept_encr_chat (struct secret_chat *E, unsigned char *random) { } } if (ok) { return; } // Already generated key for this chat - for (i = 0; i < 64; i++) { - *(((int *)random) + i) ^= mrand48 (); + unsigned char random_here[256]; + do_rand (random_here, 256); + for (i = 0; i < 256; i++) { + random[i] ^= random_here[i]; } BIGNUM *b = BN_bin2bn (random, 256, 0); assert (b); From 5cde89b5c881ce92d4cba052c178769c9b1cabac Mon Sep 17 00:00:00 2001 From: vysheng Date: Wed, 25 Dec 2013 04:44:36 +0400 Subject: [PATCH 2/6] do_rand () renamed to secure_random () --- mtproto-client.c | 10 +++++----- mtproto-client.h | 2 +- queries.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mtproto-client.c b/mtproto-client.c index a010d85..906efbe 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -98,7 +98,7 @@ double get_utime (int clock_id) { return res; } -void do_rand (void *s, int l) { +void secure_random (void *s, int l) { if (RAND_bytes (s, l) < 0) { if (allow_weak_random) { RAND_pseudo_bytes (s, l); @@ -232,7 +232,7 @@ int rpc_send_message (struct connection *c, void *data, int len) { int send_req_pq_packet (struct connection *c) { assert (c_state == st_init); - do_rand (nonce, 16); + secure_random (nonce, 16); unenc_msg_header.out_msg_id = 0; clear_packet (); out_int (CODE_req_pq); @@ -380,7 +380,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) { //out_int (0x0501); // q=5 out_ints ((int *) nonce, 4); out_ints ((int *) server_nonce, 4); - do_rand (new_nonce, 32); + secure_random (new_nonce, 32); out_ints ((int *) new_nonce, 8); sha1 ((unsigned char *) (packet_buffer + 5), (packet_ptr - packet_buffer - 5) * 4, (unsigned char *) packet_buffer); @@ -573,7 +573,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) { BN_init (&dh_g); BN_set_word (&dh_g, g); - do_rand (s_power, 256); + secure_random (s_power, 256); BIGNUM *dh_power = BN_new (); assert (BN_bin2bn ((unsigned char *)s_power, 256, dh_power) == dh_power); @@ -692,7 +692,7 @@ void init_enc_msg (struct session *S, int useful) { // assert (DC->server_salt); enc_msg.server_salt = DC->server_salt; if (!S->session_id) { - do_rand (&S->session_id, 8); + secure_random (&S->session_id, 8); } enc_msg.session_id = S->session_id; //enc_msg.auth_key_id2 = auth_key_id; diff --git a/mtproto-client.h b/mtproto-client.h index 5f04dea..0782b7b 100644 --- a/mtproto-client.h +++ b/mtproto-client.h @@ -29,5 +29,5 @@ void work_update_binlog (void); int check_g (unsigned char p[256], BIGNUM *g); int check_g_bn (BIGNUM *p, BIGNUM *g); int check_DH_params (BIGNUM *p, int g); -void do_rand (void *s, int l); +void secure_random (void *s, int l); #endif diff --git a/queries.c b/queries.c index 3719de7..51ab012 100644 --- a/queries.c +++ b/queries.c @@ -2264,7 +2264,7 @@ void do_send_accept_encr_chat (struct secret_chat *E, unsigned char *random) { } if (ok) { return; } // Already generated key for this chat unsigned char random_here[256]; - do_rand (random_here, 256); + secure_random (random_here, 256); for (i = 0; i < 256; i++) { random[i] ^= random_here[i]; } From 5ea4683d16d666e0f575d310638b3e42f8449825 Mon Sep 17 00:00:00 2001 From: vysheng Date: Wed, 25 Dec 2013 12:35:13 +0400 Subject: [PATCH 3/6] Fixed secure random. --- queries.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/queries.c b/queries.c index 51ab012..962ccd5 100644 --- a/queries.c +++ b/queries.c @@ -1505,16 +1505,11 @@ void do_send_photo (int type, peer_id_t to_id, char *file_name) { if (get_peer_type (f->to_id) == PEER_ENCR_CHAT) { f->encr = 1; f->iv = malloc (32); - int i; - for (i = 0; i < 8; i++) { - ((int *)f->iv)[i] = mrand48 (); - } + secure_random (f->iv, 32); f->init_iv = malloc (32); memcpy (f->init_iv, f->iv, 32); f->key = malloc (32); - for (i = 0; i < 8; i++) { - ((int *)f->key)[i] = mrand48 (); - } + secure_random (f->key, 32); } if (f->part_size > (512 << 10)) { close (fd); @@ -2362,8 +2357,10 @@ void do_create_keys_end (struct secret_chat *U) { void do_send_create_encr_chat (void *x, unsigned char *random) { int user_id = (long)x; int i; - for (i = 0; i < 64; i++) { - *(((int *)random) + i) ^= mrand48 (); + unsigned char random_here[256]; + secure_random (random_here, 256); + for (i = 0; i < 256; i++) { + random[i] ^= random_here[i]; } if (!ctx) { ctx = BN_CTX_new (); From cb29ce45235bc2acd672e166b85cf8752fcc3843 Mon Sep 17 00:00:00 2001 From: vysheng Date: Wed, 25 Dec 2013 12:56:46 +0400 Subject: [PATCH 4/6] Some other things changed to secure_random --- queries.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/queries.c b/queries.c index 962ccd5..af48ff3 100644 --- a/queries.c +++ b/queries.c @@ -310,9 +310,7 @@ void out_random (int n) { assert (n <= 32); static char buf[32]; int i; - for (i = 0; i < n; i++) { - buf[i] = lrand48 () & 255; - } + secure_random (buf, n); out_cstring (buf, n); } @@ -771,8 +769,8 @@ void encr_start (void) { void encr_finish (struct secret_chat *E) { int l = packet_ptr - (encr_extra + 8); - while (((packet_ptr - encr_extra) - 3) & 3) { - out_int (mrand48 ()); + while (((packet_ptr - encr_extra) - 3) & 3) { + out_rand (4); } *encr_extra = ((packet_ptr - encr_extra) - 1) * 4 * 256 + 0xfe; @@ -883,10 +881,7 @@ void do_send_encr_msg (struct message *M) { out_int (CODE_decrypted_message); out_long (M->id); static int buf[4]; - int i; - for (i = 0; i < 3; i++) { - buf[i] = mrand48 (); - } + secure_random (buf, 16); out_cstring ((void *)buf, 16); out_cstring ((void *)M->message, M->message_len); out_int (CODE_decrypted_message_media_empty); @@ -1299,8 +1294,9 @@ void send_part (struct send_file *f) { if (f->encr) { if (x & 15) { assert (f->offset == f->size); - while (x & 15) { - buf[x ++] = lrand48 () & 255; + if (x & 15) { + secure_random (buf + x, (-x) & 15); + x = (x + 15) & ~15; } } @@ -1375,7 +1371,7 @@ void send_part (struct send_file *f) { peer_t *P = user_chat_get (f->to_id); assert (P); out_long (P->encr_chat.access_hash); - long long r = -lrand48 () * (1ll << 32) - lrand48 (); + long long r = -lrand48 () * (1ll << 32) - lrand48 (); out_long (r); encr_start (); out_int (CODE_decrypted_message); From df3dc013061f5fdce9498319b1f0cd610a9e5a79 Mon Sep 17 00:00:00 2001 From: vysheng Date: Wed, 25 Dec 2013 13:07:10 +0400 Subject: [PATCH 5/6] Fixed CE --- queries.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/queries.c b/queries.c index af48ff3..bd5a86d 100644 --- a/queries.c +++ b/queries.c @@ -309,7 +309,6 @@ extern struct dc *DC_working; void out_random (int n) { assert (n <= 32); static char buf[32]; - int i; secure_random (buf, n); out_cstring (buf, n); } @@ -770,7 +769,9 @@ void encr_start (void) { void encr_finish (struct secret_chat *E) { int l = packet_ptr - (encr_extra + 8); while (((packet_ptr - encr_extra) - 3) & 3) { - out_rand (4); + int t; + secure_random (&t, 4); + out_int (t); } *encr_extra = ((packet_ptr - encr_extra) - 1) * 4 * 256 + 0xfe; From 567afd1aa578b4750ac2d4febf43f8d73fef426a Mon Sep 17 00:00:00 2001 From: vysheng Date: Thu, 26 Dec 2013 19:08:35 +0300 Subject: [PATCH 6/6] fixed Typo in Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53c48f0..0be4923 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Clone GitHub Repository $ git clone https://github.com/vysheng/tg.git && cd tg -or download and extrac zip +or download and extract zip $ wget https://github.com/vysheng/tg/archive/master.zip -O tg-master.zip $ tar xzf tg-master.zip && cd tg-master