void tgl_do_create_keys_end (struct tgl_state *TLS, struct tgl_secret_chat *U) { assert (TLS->encr_prime); BIGNUM *g_b = BN_bin2bn (U->g_key, 256, 0); ensure_ptr (g_b); assert (tglmp_check_g_a (TLS, TLS->encr_prime_bn, g_b) >= 0); BIGNUM *p = TLS->encr_prime_bn; ensure_ptr (p); BIGNUM *r = BN_new (); ensure_ptr (r); BIGNUM *a = BN_bin2bn ((void *)U->key, 256, 0); ensure_ptr (a); ensure (BN_mod_exp (r, g_b, a, p, TLS->BN_ctx)); unsigned char *t = talloc (256); memcpy (t, U->key, 256); memset (U->key, 0, sizeof (U->key)); BN_bn2bin (r, (void *)(((char *)(U->key)) + (256 - BN_num_bytes (r)))); static unsigned char sha_buffer[20]; sha1 ((void *)U->key, 256, sha_buffer); long long k = *(long long *)(sha_buffer + 12); if (k != U->key_fingerprint) { vlogprintf (E_WARNING, "Key fingerprint mismatch (my 0x%llx 0x%llx)\n", (unsigned long long)k, (unsigned long long)U->key_fingerprint); U->state = sc_deleted; } memcpy (U->first_key_sha, sha_buffer, 20); tfree_secure (t, 256); BN_clear_free (g_b); BN_clear_free (r); BN_clear_free (a); }
void *tgl_alloc_debug (size_t size) { total_allocated_bytes += size; void *p = malloc (size + RES_PRE + RES_AFTER); ensure_ptr (p); *(int *)p = size ^ 0xbedabeda; *(int *)(p + 4) = size; *(int *)(p + RES_PRE + size) = size ^ 0x7bed7bed; *(int *)(p + RES_AFTER + 4 + size) = used_blocks; blocks[used_blocks ++] = p; if (used_blocks - 1 == 24867) { assert (0); } tcheck (); return p + 8; }
void tgl_do_send_create_encr_chat (struct tgl_state *TLS, void *x, unsigned char *random, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { int user_id = (long)x; int i; unsigned char random_here[256]; tglt_secure_random (random_here, 256); for (i = 0; i < 256; i++) { random[i] ^= random_here[i]; } BIGNUM *a = BN_bin2bn (random, 256, 0); ensure_ptr (a); BIGNUM *p = BN_bin2bn (TLS->encr_prime, 256, 0); ensure_ptr (p); BIGNUM *g = BN_new (); ensure_ptr (g); ensure (BN_set_word (g, TLS->encr_root)); BIGNUM *r = BN_new (); ensure_ptr (r); ensure (BN_mod_exp (r, g, a, p, TLS->BN_ctx)); BN_clear_free (a); static char g_a[256]; memset (g_a, 0, 256); BN_bn2bin (r, (void *)(g_a + (256 - BN_num_bytes (r)))); int t = lrand48 (); while (tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t))) { t = lrand48 (); } //bl_do_encr_chat_init (TLS, t, user_id, (void *)random, (void *)g_a); int state = sc_waiting; bl_do_encr_chat_new (TLS, t, NULL, NULL, &TLS->our_id, &user_id, random, NULL, NULL, &state, NULL, NULL, NULL, NULL, NULL, NULL, TGLPF_CREATE | TGLPF_CREATED); tgl_peer_t *_E = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t)); assert (_E); struct tgl_secret_chat *E = &_E->encr_chat; clear_packet (); out_int (CODE_messages_request_encryption); tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_USER (E->user_id)); assert (U); if (U && U->user.access_hash) { out_int (CODE_input_user_foreign); out_int (E->user_id); out_long (U->user.access_hash); } else { out_int (CODE_input_user_contact); out_int (E->user_id); } out_int (tgl_get_peer_id (E->id)); out_cstring (g_a, 256); //write_secret_chat_file (); BN_clear_free (g); BN_clear_free (p); BN_clear_free (r); tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_request_methods, E, callback, callback_extra); }
void tgl_do_send_accept_encr_chat (struct tgl_state *TLS, struct tgl_secret_chat *E, unsigned char *random, void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { int i; int ok = 0; for (i = 0; i < 64; i++) { if (E->key[i]) { ok = 1; break; } } if (ok) { if (callback) { callback (TLS, callback_extra, 1, E); } return; } // Already generated key for this chat assert (E->g_key); assert (TLS->BN_ctx); unsigned char random_here[256]; tglt_secure_random (random_here, 256); for (i = 0; i < 256; i++) { random[i] ^= random_here[i]; } BIGNUM *b = BN_bin2bn (random, 256, 0); ensure_ptr (b); BIGNUM *g_a = BN_bin2bn (E->g_key, 256, 0); ensure_ptr (g_a); assert (tglmp_check_g_a (TLS, TLS->encr_prime_bn, g_a) >= 0); //if (!ctx) { // ctx = BN_CTX_new (); // ensure_ptr (ctx); //} BIGNUM *p = TLS->encr_prime_bn; BIGNUM *r = BN_new (); ensure_ptr (r); ensure (BN_mod_exp (r, g_a, b, p, TLS->BN_ctx)); static unsigned char kk[256]; memset (kk, 0, sizeof (kk)); BN_bn2bin (r, kk + (256 - BN_num_bytes (r))); static unsigned char sha_buffer[20]; sha1 (kk, 256, sha_buffer); long long fingerprint = *(long long *)(sha_buffer + 12); //bl_do_encr_chat_set_key (TLS, E, kk, *(long long *)(sha_buffer + 12)); //bl_do_encr_chat_set_sha (TLS, E, sha_buffer); int state = sc_ok; bl_do_encr_chat_new (TLS, tgl_get_peer_id (E->id), NULL, NULL, NULL, NULL, kk, NULL, sha_buffer, &state, NULL, NULL, NULL, NULL, NULL, &fingerprint, TGL_FLAGS_UNCHANGED ); clear_packet (); out_int (CODE_messages_accept_encryption); out_int (CODE_input_encrypted_chat); out_int (tgl_get_peer_id (E->id)); out_long (E->access_hash); ensure (BN_set_word (g_a, TLS->encr_root)); ensure (BN_mod_exp (r, g_a, b, p, TLS->BN_ctx)); static unsigned char buf[256]; memset (buf, 0, sizeof (buf)); BN_bn2bin (r, buf + (256 - BN_num_bytes (r))); out_cstring ((void *)buf, 256); out_long (E->key_fingerprint); BN_clear_free (b); BN_clear_free (g_a); BN_clear_free (r); tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_accept_methods, E, callback, callback_extra); }
std::string to_string(std::string const& pre_each = "", std::string const& sep_each = " ") const { ensure_ptr(); return select_from_strings<value_type>::to_string(*p, pre_each, sep_each); }
void from_strings(std::vector<std::string> const& s) { ensure_ptr(); select_from_strings<value_type>::from_strings(s, *p); }
void *tgl_alloc_release (size_t size) { void *p = malloc (size); ensure_ptr (p); return p; }
void *tgl_realloc_release (void *ptr, size_t old_size __attribute__ ((unused)), size_t size) { void *p = realloc (ptr, size); ensure_ptr (p); return p; }