1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
|
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Nikolay Durov, Andrey Lopatin 2012-2013
Vitaly Valtman 2013-2015
*/
#ifndef __MTPROTO_COMMON_H__
#define __MTPROTO_COMMON_H__
#include <string.h>
#include "crypto/rsa_pem.h"
#include "crypto/bn.h"
#include <stdio.h>
#include <assert.h>
#if defined(_MSC_VER) || defined(__MINGW32__)
#define INT64_PRINTF_MODIFIER "I64"
#else
#define INT64_PRINTF_MODIFIER "ll"
#endif
//#include "interface.h"
#include "tools.h"
#include "auto/constants.h"
#include "tgl.h"
#include "tgl-inner.h"
/* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463
#define CODE_req_DH_params 0xd712e4be
#define CODE_p_q_inner_data 0x83c95aec
#define CODE_p_q_inner_data_temp 0x3c6a84d4
#define CODE_server_DH_inner_data 0xb5890dba
#define CODE_server_DH_params_fail 0x79cb045d
#define CODE_server_DH_params_ok 0xd0e8075c
#define CODE_set_client_DH_params 0xf5045f1f
#define CODE_client_DH_inner_data 0x6643b654
#define CODE_dh_gen_ok 0x3bcbf734
#define CODE_dh_gen_retry 0x46dc1fb9
#define CODE_dh_gen_fail 0xa69dae02
#define CODE_bind_auth_key_inner 0x75a3f765
/* service messages */
#define CODE_rpc_result 0xf35c6d01
#define CODE_rpc_error 0x2144ca19
#define CODE_msg_container 0x73f1f8dc
#define CODE_msg_copy 0xe06046b2
#define CODE_msgs_ack 0x62d6b459
#define CODE_bad_msg_notification 0xa7eff811
#define CODE_bad_server_salt 0xedab447b
#define CODE_msgs_state_req 0xda69fb52
#define CODE_msgs_state_info 0x04deb57d
#define CODE_msgs_all_info 0x8cc0d131
#define CODE_new_session_created 0x9ec20908
#define CODE_msg_resend_req 0x7d861a08
#define CODE_ping 0x7abe77ec
#define CODE_pong 0x347773c5
#define CODE_destroy_session 0xe7512126
#define CODE_destroy_session_ok 0xe22045fc
#define CODE_destroy_session_none 0x62d350c9
#define CODE_destroy_sessions 0x9a6face8
#define CODE_destroy_sessions_res 0xa8164668
#define CODE_get_future_salts 0xb921bd04
#define CODE_future_salt 0x0949d9dc
#define CODE_future_salts 0xae500895
#define CODE_rpc_drop_answer 0x58e4a740
#define CODE_rpc_answer_unknown 0x5e2ad36e
#define CODE_rpc_answer_dropped_running 0xcd78e586
#define CODE_rpc_answer_dropped 0xa43ad8b7
#define CODE_msg_detailed_info 0x276d3ec6
#define CODE_msg_new_detailed_info 0x809db6df
#define CODE_ping_delay_disconnect 0xf3427b8c
#define CODE_gzip_packed 0x3072cfa1
#define CODE_input_peer_notify_settings_old 0x3cf4b1be
#define CODE_peer_notify_settings_old 0xddbcd4a5
#define CODE_user_profile_photo_old 0x990d1493
#define CODE_config_old 0x232d5905
#define CODE_msg_new_detailed_info 0x809db6df
#define CODE_msg_detailed_info 0x276d3ec6
/* not really a limit, for struct encrypted_message only */
// #define MAX_MESSAGE_INTS 16384
#define MAX_MESSAGE_INTS 1048576
#define MAX_PROTO_MESSAGE_INTS 1048576
#define PACKET_BUFFER_SIZE (16384 * 100 + 16) // temp fix
#pragma pack(push,4)
struct encrypted_message {
// unencrypted header
long long auth_key_id;
char msg_key[16];
// encrypted part, starts with encrypted header
long long server_salt;
long long session_id;
// long long auth_key_id2; // removed
// first message follows
long long msg_id;
int seq_no;
int msg_len; // divisible by 4
int message[MAX_MESSAGE_INTS];
};
#pragma pack(pop)
//TGLC_bn_ctx *bn_ctx;
void tgl_prng_seed (struct tgl_state *TLS, const char *password_filename, int password_length);
int tgl_serialize_bignum (TGLC_bn *b, char *buffer, int maxlen);
long long tgl_do_compute_rsa_key_fingerprint (TGLC_rsa *key);
#define packet_buffer tgl_packet_buffer
#define packet_ptr tgl_packet_ptr
extern int *tgl_packet_buffer;
extern int *tgl_packet_ptr;
static inline void out_ints (const int *what, int len) {
assert (packet_ptr + len <= packet_buffer + PACKET_BUFFER_SIZE);
memcpy (packet_ptr, what, len * 4);
packet_ptr += len;
}
static inline void out_int (int x) {
assert (packet_ptr + 1 <= packet_buffer + PACKET_BUFFER_SIZE);
*packet_ptr++ = x;
}
static inline void out_long (long long x) {
assert (packet_ptr + 2 <= packet_buffer + PACKET_BUFFER_SIZE);
*(long long *)packet_ptr = x;
packet_ptr += 2;
}
static inline void out_double (double x) {
assert (packet_ptr + 2 <= packet_buffer + PACKET_BUFFER_SIZE);
*(double *)packet_ptr = x;
packet_ptr += 2;
}
static inline void clear_packet (void) {
packet_ptr = packet_buffer;
}
void tgl_out_cstring (const char *str, long len);
void tgl_out_cstring_careful (const char *str, long len);
void tgl_out_data (const void *data, long len);
#define out_cstring tgl_out_cstring
#define out_cstring_careful tgl_out_cstring_careful
#define out_data tgl_out_data
static inline void out_string (const char *str) {
out_cstring (str, strlen (str));
}
static inline void out_bignum (TGLC_bn *n) {
int l = tgl_serialize_bignum (n, (char *)packet_ptr, (PACKET_BUFFER_SIZE - (packet_ptr - packet_buffer)) * 4);
assert (l > 0);
packet_ptr += l >> 2;
}
#define in_ptr tgl_in_ptr
#define in_end tgl_in_end
extern int *tgl_in_ptr, *tgl_in_end;
//void fetch_pts (void);
//void fetch_qts (void);
//void fetch_date (void);
//void fetch_seq (void);
static inline int prefetch_strlen (void) {
if (in_ptr >= in_end) {
return -1;
}
unsigned l = *in_ptr;
if ((l & 0xff) < 0xfe) {
l &= 0xff;
return (in_end >= in_ptr + (l >> 2) + 1) ? (int)l : -1;
} else if ((l & 0xff) == 0xfe) {
l >>= 8;
return (l >= 254 && in_end >= in_ptr + ((l + 7) >> 2)) ? (int)l : -1;
} else {
return -1;
}
}
static inline char *fetch_str (int len) {
assert (len >= 0);
if (len < 254) {
char *str = (char *) in_ptr + 1;
in_ptr += 1 + (len >> 2);
return str;
} else {
char *str = (char *) in_ptr + 4;
in_ptr += (len + 7) >> 2;
return str;
}
}
static inline char *fetch_str_dup (void) {
int l = prefetch_strlen ();
assert (l >= 0);
int i;
char *s = fetch_str (l);
for (i = 0; i < l; i++) {
if (!s[i]) { break; }
}
char *r = talloc (i + 1);
memcpy (r, s, i);
r[i] = 0;
return r;
}
static inline int fetch_update_str (char **s) {
if (!*s) {
*s = fetch_str_dup ();
return 1;
}
int l = prefetch_strlen ();
char *r = fetch_str (l);
if (memcmp (*s, r, l) || (*s)[l]) {
tfree_str (*s);
*s = talloc (l + 1);
memcpy (*s, r, l);
(*s)[l] = 0;
return 1;
}
return 0;
}
static inline int fetch_update_int (int *value) {
if (*value == *in_ptr) {
in_ptr ++;
return 0;
} else {
*value = *(in_ptr ++);
return 1;
}
}
static inline int fetch_update_long (long long *value) {
if (*value == *(long long *)in_ptr) {
in_ptr += 2;
return 0;
} else {
*value = *(long long *)(in_ptr);
in_ptr += 2;
return 1;
}
}
static inline int set_update_int (int *value, int new_value) {
if (*value == new_value) {
return 0;
} else {
*value = new_value;
return 1;
}
}
static inline void fetch_skip (int n) {
in_ptr += n;
assert (in_ptr <= in_end);
}
static inline void fetch_skip_str (void) {
int l = prefetch_strlen ();
assert (l >= 0);
fetch_str (l);
}
static inline long have_prefetch_ints (void) {
return in_end - in_ptr;
}
int tgl_fetch_bignum (TGLC_bn *x);
#define fetch_bignum tgl_fetch_bignum
static inline int fetch_int (void) {
assert (in_ptr + 1 <= in_end);
return *(in_ptr ++);
}
static inline int fetch_bool (void) {
assert (in_ptr + 1 <= in_end);
assert (*(in_ptr) == (int)CODE_bool_true || *(in_ptr) == (int)CODE_bool_false);
return *(in_ptr ++) == (int)CODE_bool_true;
}
static inline int prefetch_int (void) {
assert (in_ptr < in_end);
return *(in_ptr);
}
static inline void prefetch_data (void *data, int size) {
assert (in_ptr + (size >> 2) <= in_end);
memcpy (data, in_ptr, size);
}
static inline void fetch_data (void *data, int size) {
assert (in_ptr + (size >> 2) <= in_end);
memcpy (data, in_ptr, size);
assert (!(size & 3));
in_ptr += (size >> 2);
}
static inline long long fetch_long (void) {
assert (in_ptr + 2 <= in_end);
long long r = *(long long *)in_ptr;
in_ptr += 2;
return r;
}
static inline double fetch_double (void) {
assert (in_ptr + 2 <= in_end);
double r = *(double *)in_ptr;
in_ptr += 2;
return r;
}
static inline void fetch_ints (void *data, int count) {
assert (in_ptr + count <= in_end);
memcpy (data, in_ptr, 4 * count);
in_ptr += count;
}
static inline void fetch256 (void *buf) {
int l = prefetch_strlen ();
assert (l >= 0);
char *s = fetch_str (l);
if (l < 256) {
memcpy (buf + 256 - l, s, l);
memset (buf, 0, 256 - l);
} else {
memcpy (buf, s + (l - 256), 256);
}
}
static inline int in_remaining (void) {
return 4 * (in_end - in_ptr);
}
//int get_random_bytes (unsigned char *buf, int n);
int tgl_pad_rsa_encrypt (struct tgl_state *TLS, char *from, int from_len, char *to, int size, TGLC_bn *N, TGLC_bn *E);
int tgl_pad_rsa_decrypt (struct tgl_state *TLS, char *from, int from_len, char *to, int size, TGLC_bn *N, TGLC_bn *D);
//extern long long rsa_encrypted_chunks, rsa_decrypted_chunks;
//extern unsigned char aes_key_raw[32], aes_iv[32];
//extern TGLC_aes_key aes_key;
void tgl_init_aes_unauth (const char server_nonce[16], const char hidden_client_nonce[32], int encrypt);
void tgl_init_aes_auth (char auth_key[192], char msg_key[16], int encrypt);
int tgl_pad_aes_encrypt (char *from, int from_len, char *to, int size);
int tgl_pad_aes_decrypt (char *from, int from_len, char *to, int size);
/*
static inline void hexdump_in (void) {
hexdump (in_ptr, in_end);
}
static inline void hexdump_out (void) {
hexdump (packet_buffer, packet_ptr);
}*/
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#endif
#endif
|