android: voice messages + attachments architecture plan, build fixes
This commit is contained in:
1 parent
f8d7c21a79
commit
e751e6ee69
17 files changed
+299
-329
No files matched your search
+29
-2
@@ -226,6 +226,27 @@ static struct ETCP_CONN* cs_find_conn_for_node(struct UTUN_INSTANCE* inst, uint6
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ── helper: find active ETCP_CONN by pubkey (for invite: same physical node, different node_id) ── */
|
||||
|
||||
static struct ETCP_CONN* cs_find_conn_by_pubkey(struct UTUN_INSTANCE* inst,
|
||||
const uint8_t* pubkey_bin,
|
||||
uint64_t* out_node_id) {
|
||||
struct ll_entry* entry = inst->connections ? inst->connections->head : NULL;
|
||||
while (entry) {
|
||||
struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data;
|
||||
struct ETCP_CONN* conn = ce->conn;
|
||||
if (conn && conn->initialized && conn->links_up
|
||||
&& memcmp(conn->crypto_ctx.peer_public_key, pubkey_bin, 32) == 0) {
|
||||
*out_node_id = conn->peer_node_id;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "%s: find_conn_by_pubkey MATCH conn=%s peer=0x%016llx",
|
||||
CS_ID, conn->log_name, (unsigned long long)conn->peer_node_id);
|
||||
return conn;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ── helper: check if peer has active ETCP link ── */
|
||||
|
||||
static int cs_is_peer_online(struct UTUN_INSTANCE* inst, uint64_t peer_id) {
|
||||
@@ -642,11 +663,17 @@ static void cm_invite_trampoline(void* arg) {
|
||||
}
|
||||
|
||||
struct ETCP_CONN* existing = instance_find_conn(inst, node_id);
|
||||
if (!existing) existing = cs_find_conn_by_pubkey(inst, inv->pubkey, &node_id);
|
||||
|
||||
if (existing) {
|
||||
if (existing->links_up) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "%s: invite conn already UP node=0x%016llx, reusing", CS_ID, (unsigned long long)node_id);
|
||||
if (g_cs && g_cs->pending_invite_ch_id != 0 && !g_cs->info_req_timer)
|
||||
if (g_cs && g_cs->pending_invite_ch_id != 0 && !g_cs->info_req_timer) {
|
||||
if (node_id != existing->peer_node_id)
|
||||
DEBUG_WARN(DEBUG_CATEGORY_DB_SYNC,
|
||||
"%s: invite node_id mismatch: derived=%016llx ETCP=%016llx — using ETCP",
|
||||
CS_ID, (unsigned long long)node_id, (unsigned long long)existing->peer_node_id);
|
||||
cs_on_conn_up(existing, NULL);
|
||||
}
|
||||
} else {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "%s: invite conn in progress node=0x%016llx, waiting UP", CS_ID, (unsigned long long)node_id);
|
||||
}
|
||||
|
||||
+3
-6
@@ -10,7 +10,7 @@
|
||||
#include "../../lib/debug_config.h"
|
||||
#include "../../lib/mem.h"
|
||||
#include "../../lib/u_async.h"
|
||||
#include "../../lib/sha256.h"
|
||||
#include <openssl/sha.h>
|
||||
#include "../../lib/sqlite3.h"
|
||||
#include "../../lib/platform_compat.h"
|
||||
#include <string.h>
|
||||
@@ -131,10 +131,7 @@ static void db_sqlite_close(struct DB_SYNC* db)
|
||||
|
||||
static void db_sha256(const uint8_t* data, size_t len, uint8_t hash[32])
|
||||
{
|
||||
SC_SHA256_CTX ctx;
|
||||
sc_sha256_init(&ctx);
|
||||
sc_sha256_update(&ctx, data, len);
|
||||
sc_sha256_final(&ctx, hash);
|
||||
SHA256(data, len, hash);
|
||||
}
|
||||
|
||||
static uint64_t db_hash64(const uint8_t* data, size_t len)
|
||||
@@ -1220,7 +1217,7 @@ static void db_sync_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
||||
const char* tbl = (const char*)sqlite3_column_text(st, 0);
|
||||
const char* ch_id = (const char*)sqlite3_column_text(st, 1);
|
||||
if (!ch_id || !ch_id[0]) continue;
|
||||
uint64_t h; { uint8_t sh[32]; SC_SHA256_CTX ctx; sc_sha256_init(&ctx); sc_sha256_update(&ctx, (const uint8_t*)ch_id, strlen(ch_id)); sc_sha256_final(&ctx, sh); memcpy(&h, sh, 8); }
|
||||
uint64_t h; { uint8_t sh[32]; SHA256((const uint8_t*)ch_id, strlen(ch_id), sh); memcpy(&h, sh, 8); }
|
||||
if (h == hash) {
|
||||
si = db_sync_instance_add(db->inst, tbl, hash, 1);
|
||||
if (si) { si_peer_add(si, src); }
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "crc32.h"
|
||||
#include "../lib/sha256.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/sha.h>
|
||||
@@ -99,29 +98,29 @@ static sc_status_t verify_and_strip_crc32(uint8_t *plaintext_with_crc, size_t to
|
||||
}
|
||||
|
||||
static void sc_derive_session_key(const uint8_t *shared_secret, uint8_t *session_key) {
|
||||
SC_SHA256_CTX sha_ctx;
|
||||
SHA256_CTX sha_ctx;
|
||||
uint8_t hash[SC_HASH_SIZE];
|
||||
sc_sha256_init(&sha_ctx);
|
||||
sc_sha256_update(&sha_ctx, shared_secret, SC_SHARED_SECRET_SIZE);
|
||||
sc_sha256_update(&sha_ctx, (const uint8_t *)"uTun-v3-session", 15);
|
||||
sc_sha256_final(&sha_ctx, hash);
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, shared_secret, SC_SHARED_SECRET_SIZE);
|
||||
SHA256_Update(&sha_ctx, (const uint8_t *)"uTun-v3-session", 15);
|
||||
SHA256_Final(hash, &sha_ctx);
|
||||
memcpy(session_key, hash, SC_SESSION_KEY_SIZE);
|
||||
}
|
||||
|
||||
// Derive 12-byte nonce for stream cipher from session key + stream_id
|
||||
static void sc_stream_derive_nonce(const uint8_t *session_key, uint32_t stream_id, uint8_t *nonce_out) {
|
||||
SC_SHA256_CTX sha_ctx;
|
||||
SHA256_CTX sha_ctx;
|
||||
uint8_t hash[SC_HASH_SIZE];
|
||||
uint8_t stream_id_le[4];
|
||||
stream_id_le[0] = (uint8_t)(stream_id >> 0);
|
||||
stream_id_le[1] = (uint8_t)(stream_id >> 8);
|
||||
stream_id_le[2] = (uint8_t)(stream_id >> 16);
|
||||
stream_id_le[3] = (uint8_t)(stream_id >> 24);
|
||||
sc_sha256_init(&sha_ctx);
|
||||
sc_sha256_update(&sha_ctx, session_key, SC_SESSION_KEY_SIZE);
|
||||
sc_sha256_update(&sha_ctx, stream_id_le, sizeof(stream_id_le));
|
||||
sc_sha256_update(&sha_ctx, (const uint8_t *)"uTun3-stream", 12);
|
||||
sc_sha256_final(&sha_ctx, hash);
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, session_key, SC_SESSION_KEY_SIZE);
|
||||
SHA256_Update(&sha_ctx, stream_id_le, sizeof(stream_id_le));
|
||||
SHA256_Update(&sha_ctx, (const uint8_t *)"uTun3-stream", 12);
|
||||
SHA256_Final(hash, &sha_ctx);
|
||||
memcpy(nonce_out, hash, SC_STREAM_NONCE_SIZE);
|
||||
}
|
||||
|
||||
@@ -424,8 +423,8 @@ sc_status_t sc_derive_ed25519_pubkey(const uint8_t *x25519_privkey, uint8_t *ed2
|
||||
|
||||
uint64_t sc_derive_node_id_from_pubkey(const uint8_t *public_key) {
|
||||
if (!public_key) { DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_derive_node_id_from_pubkey: NULL public_key"); return 0; }
|
||||
uint8_t sha_hash[SC_HASH_SIZE]; SC_SHA256_CTX ctx;
|
||||
sc_sha256_init(&ctx); sc_sha256_update(&ctx, public_key, SC_PUBKEY_SIZE); sc_sha256_final(&ctx, sha_hash);
|
||||
uint8_t sha_hash[SC_HASH_SIZE];
|
||||
SHA256(public_key, SC_PUBKEY_SIZE, sha_hash);
|
||||
uint64_t node_id;
|
||||
memcpy(&node_id, sha_hash, 8);
|
||||
node_id &= 0x7FFFFFFFFFFFFFFFULL;
|
||||
@@ -572,10 +571,7 @@ sc_status_t sc_ed25519_verify(const uint8_t pubkey[32], const uint8_t* msg, size
|
||||
sc_status_t sc_sha_transcode(const uint8_t *key, size_t key_len, uint8_t *data, size_t data_len) {
|
||||
if (!key || !data || key_len == 0 || data_len == 0) return SC_ERR_INVALID_ARG;
|
||||
uint8_t sha_hash[SC_HASH_SIZE];
|
||||
SC_SHA256_CTX ctx;
|
||||
sc_sha256_init(&ctx);
|
||||
sc_sha256_update(&ctx, key, key_len);
|
||||
sc_sha256_final(&ctx, sha_hash);
|
||||
SHA256(key, key_len, sha_hash);
|
||||
for (size_t i = 0; i < data_len; i++) data[i] ^= sha_hash[i % SC_HASH_SIZE];
|
||||
return SC_OK;
|
||||
}
|
||||
@@ -583,15 +579,15 @@ sc_status_t sc_sha_transcode(const uint8_t *key, size_t key_len, uint8_t *data,
|
||||
sc_status_t sc_obfuscate_pubkey(const uint8_t *salt, const uint8_t *peer_pubkey, const uint8_t *pubkey, uint8_t *output) {
|
||||
if (!salt || !peer_pubkey || !pubkey || !output) return SC_ERR_INVALID_ARG;
|
||||
uint8_t sha[SC_HASH_SIZE*2];
|
||||
SC_SHA256_CTX ctx;
|
||||
sc_sha256_init(&ctx);
|
||||
sc_sha256_update(&ctx, salt, SC_PUBKEY_ENC_SALT_SIZE);
|
||||
sc_sha256_update(&ctx, peer_pubkey, SC_PUBKEY_SIZE);
|
||||
sc_sha256_final(&ctx, sha);
|
||||
sc_sha256_init(&ctx);
|
||||
sc_sha256_update(&ctx, peer_pubkey, SC_PUBKEY_SIZE);
|
||||
sc_sha256_update(&ctx, salt, SC_PUBKEY_ENC_SALT_SIZE);
|
||||
sc_sha256_final(&ctx, sha+SC_HASH_SIZE);
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, salt, SC_PUBKEY_ENC_SALT_SIZE);
|
||||
SHA256_Update(&ctx, peer_pubkey, SC_PUBKEY_SIZE);
|
||||
SHA256_Final(sha, &ctx);
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, peer_pubkey, SC_PUBKEY_SIZE);
|
||||
SHA256_Update(&ctx, salt, SC_PUBKEY_ENC_SALT_SIZE);
|
||||
SHA256_Final(sha + SC_HASH_SIZE, &ctx);
|
||||
for (size_t i = 0; i < SC_PUBKEY_SIZE; i++) output[i] = pubkey[i] ^ sha[i];
|
||||
return SC_OK;
|
||||
}
|
||||
+15
-7
@@ -21,7 +21,6 @@
|
||||
|
||||
#include "../lib/u_async.h"
|
||||
#include "../lib/debug_config.h"
|
||||
#include "../lib/sha256.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -101,12 +100,21 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Derive node_id from pubkey if not set in config
|
||||
if (!instance->node_id) {
|
||||
uint8_t pubkey[SC_PUBKEY_SIZE];
|
||||
sc_compute_public_key_from_private(instance->my_keys.private_key, pubkey);
|
||||
instance->node_id = sc_derive_node_id_from_pubkey(pubkey);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "node_id derived from pubkey: %016llx", (unsigned long long)instance->node_id);
|
||||
/* Always verify node_id matches pubkey, fix if mismatched */
|
||||
{
|
||||
uint8_t pub_bin[SC_PUBKEY_SIZE];
|
||||
sc_compute_public_key_from_private(instance->my_keys.private_key, pub_bin);
|
||||
uint64_t derived = sc_derive_node_id_from_pubkey(pub_bin);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "node_id check: config=%016llx derived=%016llx match=%d",
|
||||
(unsigned long long)instance->node_id, (unsigned long long)derived,
|
||||
(instance->node_id == derived));
|
||||
if (!instance->node_id || instance->node_id != derived) {
|
||||
if (instance->node_id)
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "node_id mismatch: config=%016llx derived=%016llx — fixing",
|
||||
(unsigned long long)instance->node_id, (unsigned long long)derived);
|
||||
instance->node_id = derived;
|
||||
config->global.my_node_id = derived;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc_derive_ed25519_pubkey(instance->my_keys.private_key, instance->my_ed25519_pubkey) != SC_OK) {
|
||||
|
||||
Reference in new issue
Block a user