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 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 67174d5..54fde7a 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 secure_random (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); + secure_random (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); + 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); @@ -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); + secure_random (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); + 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 458d6c5..0782b7b 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 secure_random (void *s, int l); #endif diff --git a/queries.c b/queries.c index ec35d15..bd5a86d 100644 --- a/queries.c +++ b/queries.c @@ -309,10 +309,7 @@ extern struct dc *DC_working; 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 +768,10 @@ 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) { + int t; + secure_random (&t, 4); + out_int (t); } *encr_extra = ((packet_ptr - encr_extra) - 1) * 4 * 256 + 0xfe; @@ -883,10 +882,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 +1295,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 +1372,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); @@ -1505,16 +1502,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); @@ -2263,8 +2255,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]; + secure_random (random_here, 256); + for (i = 0; i < 256; i++) { + random[i] ^= random_here[i]; } BIGNUM *b = BN_bin2bn (random, 256, 0); assert (b); @@ -2360,8 +2354,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 ();