Some code related to encrypted chat. Nothing works yet, but I believe it would work in the nearest future

This commit is contained in:
Vysheng 2013-11-02 21:01:22 +04:00
parent 5b8a4fdc60
commit 9dd3627afa
5 changed files with 310 additions and 8 deletions

View File

@ -919,6 +919,26 @@ void print_chat_name (peer_id_t id, peer_t *C) {
pop_color ();
}
void print_encr_chat_name (peer_id_t id, peer_t *C) {
push_color (COLOR_MAGENTA);
if (!C) {
printf ("encr_chat#%d", get_peer_id (id));
} else {
printf ("%s", C->print_name);
}
pop_color ();
}
void print_encr_chat_name_full (peer_id_t id, peer_t *C) {
push_color (COLOR_MAGENTA);
if (!C) {
printf ("encr_chat#%d", get_peer_id (id));
} else {
printf ("%s", C->print_name);
}
pop_color ();
}
static char *monthes[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
void print_date (long t) {
struct tm *tm = localtime (&t);

View File

@ -45,6 +45,8 @@ union peer;
void print_message (struct message *M);
void print_chat_name (peer_id_t id, union peer *C);
void print_user_name (peer_id_t id, union peer *U);
void print_encr_chat_name_full (peer_id_t id, peer_t *C);
void print_encr_chat_name (peer_id_t id, peer_t *C);
//void print_media (struct message_media *M);
void pop_color (void);
void push_color (const char *color);

View File

@ -956,27 +956,79 @@ void work_update (struct connection *c UU, long long msg_id UU) {
break;
case CODE_update_new_encrypted_message:
{
logprintf ("New encrypted message. Unsupported yet\n");
struct message *M = fetch_alloc_encrypted_message ();
unread_messages ++;
print_message (M);
update_prompt ();
fetch_qts ();
}
break;
case CODE_update_encryption:
{
logprintf ("New encrypted chat. Unsupported yet\n");
struct secret_chat *E = fetch_alloc_encrypted_chat ();
print_start ();
push_color (COLOR_YELLOW);
switch (E->state) {
case sc_none:
assert (0);
break;
case sc_waiting:
printf ("Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in wait state\n");
break;
case sc_request:
printf ("Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in request state. Sending request ok\n");
break;
case sc_ok:
printf ("Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in ok state\n");
break;
case sc_deleted:
printf ("Encrypted chat ");
print_encr_chat_name (E->id, (void *)E);
printf (" is now in deleted state\n");
break;
}
/*if (E->state == state_requested) {
do_accept_encr_chat_request (E);
}*/
fetch_int (); // date
}
break;
case CODE_update_encrypted_chat_typing:
{
logprintf ("Typing in encrypted chat. Unsupported yet\n");
peer_id_t id = MK_ENCR_CHAT (fetch_int ());
peer_t *P = user_chat_get (id);
print_start ();
push_color (COLOR_YELLOW);
if (P) {
printf ("User ");
peer_id_t user_id = MK_USER (P->encr_chat.user_id);
print_user_name (user_id, user_chat_get (user_id));
printf (" typing in secret chat ");
print_encr_chat_name (id, P);
printf ("\n");
} else {
printf ("Some user is typing in unknown secret chat\n");
}
pop_color ();
print_end ();
}
break;
case CODE_update_encrypted_messages_read:
{
fetch_int (); // chat_id
peer_id_t id = MK_ENCR_CHAT (fetch_int ()); // chat_id
fetch_int (); // max_date
fetch_int (); // date
print_start ();
push_color (COLOR_YELLOW);
printf ("Messages in encrypted chat mark read \n");
printf ("Messages in encrypted chat ");
print_encr_chat_name_full (id, user_chat_get (id));
printf (" marked read \n");
pop_color ();
print_end ();
}

View File

@ -192,6 +192,55 @@ void fetch_user (struct user *U) {
}
}
void fetch_encrypted_chat (struct secret_chat *U) {
unsigned x = fetch_int ();
assert (x == CODE_encrypted_chat_empty || x == CODE_encrypted_chat_waiting || x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat || x == CODE_encrypted_chat_discarded);
U->id = MK_ENCR_CHAT (fetch_int ());
U->flags &= ~(FLAG_EMPTY | FLAG_DELETED);
if (x == CODE_encrypted_chat_empty) {
U->state = sc_none;
U->flags |= FLAG_EMPTY;
return;
}
if (x == CODE_encrypted_chat_discarded) {
U->state = sc_deleted;
U->flags |= FLAG_DELETED;
return;
}
U->access_hash = fetch_long ();
U->date = fetch_int ();
U->admin_id = fetch_int ();
U->user_id = fetch_int () + U->admin_id - our_id;
if (x == CODE_encrypted_chat_waiting) {
U->state = sc_waiting;
} else if (x == CODE_encrypted_chat_requested) {
U->state = sc_request;
if (!U->g_key) {
U->g_key = malloc (256);
}
if (!U->nonce) {
U->nonce = malloc (256);
}
assert (prefetch_strlen () == 256);
memcpy (U->g_key, fetch_str (256), 256);
assert (prefetch_strlen () == 256);
memcpy (U->nonce, fetch_str (256), 256);
} else {
U->state = sc_ok;
if (!U->g_key) {
U->g_key = malloc (256);
}
if (!U->nonce) {
U->nonce = malloc (256);
}
assert (prefetch_strlen () == 256);
memcpy (U->g_key, fetch_str (256), 256);
assert (prefetch_strlen () == 256);
memcpy (U->nonce, fetch_str (256), 256);
U->key_fingerprint = fetch_long ();
}
}
void fetch_notify_settings (void);
void fetch_user_full (struct user *U) {
assert (fetch_int () == CODE_user_full);
@ -501,6 +550,87 @@ void fetch_message_media (struct message_media *M) {
}
}
void fetch_message_media_encrypted (struct message_media *M) {
memset (M, 0, sizeof (*M));
unsigned x = fetch_int ();
int l;
switch (M->type) {
case CODE_decrypted_message_media_empty:
M->type = CODE_message_media_empty;
break;
case CODE_decrypted_message_media_photo:
M->type = x;
l = prefetch_strlen ();
fetch_str (l); // thumb
fetch_int (); // thumb_w
fetch_int (); // thumb_h
M->encr_photo.w = fetch_int ();
M->encr_photo.h = fetch_int ();
M->encr_photo.size = fetch_int ();
l = fetch_int ();
assert (l > 0);
M->encr_photo.key = malloc (l);
memcpy (M->encr_photo.key, fetch_str (l), l);
l = fetch_int ();
assert (l > 0);
M->encr_photo.iv = malloc (l);
memcpy (M->encr_photo.iv, fetch_str (l), l);
break;
case CODE_decrypted_message_media_video:
M->type = x;
l = prefetch_strlen ();
fetch_str (l); // thumb
fetch_int (); // thumb_w
fetch_int (); // thumb_h
M->encr_video.w = fetch_int ();
M->encr_video.h = fetch_int ();
M->encr_video.size = fetch_int ();
M->encr_video.duration = fetch_int ();
l = fetch_int ();
assert (l > 0);
M->encr_video.key = malloc (l);
memcpy (M->encr_video.key, fetch_str (l), l);
l = fetch_int ();
assert (l > 0);
M->encr_video.iv = malloc (l);
memcpy (M->encr_video.iv, fetch_str (l), l);
break;
/* case CODE_decrypted_message_media_file:
M->type = x;
M->encr_file.filename = fetch_str_dup ();
l = prefetch_strlen ();
fetch_str (l); // thumb
l = fetch_int ();
assert (l > 0);
M->encr_file.key = malloc (l);
memcpy (M->encr_file.key, fetch_str (l), l);
l = fetch_int ();
assert (l > 0);
M->encr_file.iv = malloc (l);
memcpy (M->encr_file.iv, fetch_str (l), l);
break;
*/
case CODE_decrypted_message_media_geo_point:
M->geo.longitude = fetch_double ();
M->geo.latitude = fetch_double ();
M->type = CODE_message_media_geo;
break;
case CODE_decrypted_message_media_contact:
M->type = CODE_message_media_contact;
M->phone = fetch_str_dup ();
M->first_name = fetch_str_dup ();
M->last_name = fetch_str_dup ();
M->user_id = fetch_int ();
break;
default:
logprintf ("type = 0x%08x\n", M->type);
assert (0);
}
}
peer_id_t fetch_peer_id (void) {
unsigned x =fetch_int ();
if (x == CODE_peer_user) {
@ -629,6 +759,7 @@ void fetch_encrypted_message (struct message *M) {
assert (!(len & 15));
decr_ptr = (void *)fetch_str (len);
decr_end = in_ptr;
M->flags |= FLAG_ENCRYPTED;
if (P && decrypt_encrypted_message (&P->encr_chat) >= 0) {
in_ptr = decr_ptr;
unsigned x = fetch_int ();
@ -643,7 +774,29 @@ void fetch_encrypted_message (struct message *M) {
fetch_str (l); // random_bytes
M->from_id = MK_USER (fetch_int ());
M->date = fetch_int ();
if (x == CODE_decrypted_message) {
M->message = fetch_str_dup ();
fetch_encrypted_message_file (&M->media);
} else {
assert (fetch_int () == (int)CODE_decrypted_message_action_set_message_t_t_l);
P->encr_chat.ttl = fetch_int ();
}
}
}
void fetch_encrypted_message_file (struct message_media *M) {
unsigned x = fetch_int ();
assert (x == CODE_encrypted_file || x == CODE_encrypted_file_empty);
if (x == CODE_encrypted_file_empty) {
assert (M->type != CODE_decrypted_message_media_photo && M->type != CODE_decrypted_message_media_video);
} else {
assert (M->type == CODE_decrypted_message_media_photo || M->type == CODE_decrypted_message_media_video);
M->encr_photo.id = fetch_long ();
M->encr_photo.access_hash = fetch_long ();
assert (M->encr_photo.size == fetch_int ());
M->encr_photo.dc_id = fetch_int ();
M->encr_photo.key_fingerprint = fetch_int ();
}
}
@ -689,6 +842,24 @@ struct user *fetch_alloc_user (void) {
}
}
struct secret_chat *fetch_alloc_encrypted_chat (void) {
int data[2];
prefetch_data (data, 8);
peer_t *U = user_chat_get (MK_ENCR_CHAT (data[1]));
if (U) {
fetch_encrypted_chat (&U->encr_chat);
return &U->encr_chat;
} else {
chats_allocated ++;
U = malloc (sizeof (*U));
memset (U, 0, sizeof (*U));
fetch_encrypted_chat (&U->encr_chat);
peer_tree = tree_insert_peer (peer_tree, U, lrand48 ());
Peers[(chat_num ++) + user_num] = U;
return &U->encr_chat;
}
}
struct user *fetch_alloc_user_full (void) {
int data[3];
prefetch_data (data, 12);
@ -759,6 +930,14 @@ void free_message_media (struct message_media *M) {
case CODE_message_media_unsupported:
free (M->data);
return;
case CODE_decrypted_message_media_photo:
free (M->encr_photo.key);
free (M->encr_photo.iv);
return;
case CODE_decrypted_message_media_video:
free (M->encr_video.key);
free (M->encr_video.iv);
return;
default:
logprintf ("%08x\n", M->type);
assert (0);

View File

@ -35,6 +35,7 @@ typedef struct { int id; } peer_id_t;
#define FLAG_CHAT_IN_CHAT 128
#define FLAG_ENCRYPTED 4096
struct file_location {
int dc;
@ -68,6 +69,40 @@ struct photo {
struct photo_size *sizes;
};
struct encr_photo {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
int w;
int h;
unsigned char *key;
unsigned char *iv;
};
struct encr_video {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
int w;
int h;
int duration;
unsigned char *key;
unsigned char *iv;
};
struct encr_file {
char *filename;
unsigned char *key;
unsigned char *iv;
};
struct user_status {
int online;
int when;
@ -113,9 +148,10 @@ struct chat {
enum secret_chat_state {
sc_none,
sc_sent_request,
sc_waiting,
sc_request,
sc_ok,
sc_bad
sc_deleted
};
struct secret_chat {
@ -125,6 +161,13 @@ struct secret_chat {
struct file_location photo_big;
struct file_location photo_small;
struct photo photo;
int user_id;
int admin_id;
int date;
int ttl;
long long access_hash;
unsigned char *g_key;
unsigned char *nonce;
enum secret_chat_state state;
int key[64];
@ -185,6 +228,9 @@ struct message_media {
char *last_name;
int user_id;
};
struct encr_photo encr_photo;
struct encr_video encr_video;
struct encr_file encr_file;
void *data;
};
};
@ -218,10 +264,13 @@ struct user *fetch_alloc_user (void);
struct user *fetch_alloc_user_full (void);
struct chat *fetch_alloc_chat (void);
struct chat *fetch_alloc_chat_full (void);
struct secret_chat *fetch_alloc_encrypted_chat (void);
struct message *fetch_alloc_message (void);
struct message *fetch_alloc_geo_message (void);
struct message *fetch_alloc_message_short (void);
struct message *fetch_alloc_message_short_chat (void);
struct message *fetch_alloc_encrypted_message (void);
void fetch_encrypted_message_file (struct message_media *M);
peer_id_t fetch_peer_id (void);
void free_user (struct user *U);